Simplify and clarify the snum padding logic in BN_div We can use bn_resize_words, which zeros the extra words and updates the width in one step. Also clarify what this is achieving. It's to establish a bunch of invariants that the loop cares about. Bug: 358687140 Change-Id: Id78e81bc08a1ca506b5d6ef6b01936f860fddd86 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/70175 Commit-Queue: David Benjamin <davidben@google.com> Reviewed-by: Bob Beck <bbe@google.com>
diff --git a/crypto/fipsmodule/bn/div.c b/crypto/fipsmodule/bn/div.c index 097c5eb..36e9658 100644 --- a/crypto/fipsmodule/bn/div.c +++ b/crypto/fipsmodule/bn/div.c
@@ -231,27 +231,17 @@ bn_set_minimal_width(snum); snum->neg = 0; - // Since we don't want to have special-case logic for the case where snum is - // larger than sdiv, we pad snum with enough zeroes without changing its - // value. - if (snum->width <= sdiv->width + 1) { - if (!bn_wexpand(snum, sdiv->width + 2)) { - goto err; - } - for (int i = snum->width; i < sdiv->width + 2; i++) { - snum->d[i] = 0; - } - snum->width = sdiv->width + 2; - } else { - if (!bn_wexpand(snum, snum->width + 1)) { - goto err; - } - snum->d[snum->width] = 0; - snum->width++; + // Extend |snum| with zeros to satisfy the long division invariants: + // - |snum|, minus the extra word, must have at least |div_n| + 1 words. + // - |snum|'s most significant word must be zero to guarantee the first loop + // iteration works with a prefix greater than |sdiv|. (This is the extra u0 + // digit in Knuth.) + int div_n = sdiv->width; + int num_n = snum->width <= div_n + 1 ? div_n + 2 : snum->width + 1; + if (!bn_resize_words(snum, num_n)) { + goto err; } - int div_n = sdiv->width; - int num_n = snum->width; int loop = num_n - div_n; // Lets setup a 'window' into snum // This is the part that corresponds to the current