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>
This commit is contained in:
David Benjamin
2024-08-14 20:04:45 +00:00
committed by Boringssl LUCI CQ
parent 1b421be241
commit 99c8a7dbde
+9 -19
View File
@@ -231,27 +231,17 @@ int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator,
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