Comment what "normalize" means in BN_div

Also add an assert for the invariant it is maintaining.

Bug: 358687140
Change-Id: I3bcb9838198735b6f42e4f732b00e0fc990c5ffd
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/70172
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: David Benjamin <davidben@google.com>
diff --git a/crypto/fipsmodule/bn/div.c b/crypto/fipsmodule/bn/div.c
index 06bc4f8..1b78dc3 100644
--- a/crypto/fipsmodule/bn/div.c
+++ b/crypto/fipsmodule/bn/div.c
@@ -192,12 +192,6 @@
   // Acıçmez, Shay Gueron, and Jean-Pierre Seifert. We continue to omit them for
   // simplicity, but this function is no longer used with secret inputs. (We
   // implement a variation on "Smooth CRT-RSA" as described in the paper.)
-  int norm_shift, loop;
-  BIGNUM wnum;
-  BN_ULONG *resp, *wnump;
-  BN_ULONG d0, d1;
-  int num_n, div_n;
-
   if (BN_is_zero(divisor)) {
     OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO);
     return 0;
@@ -217,13 +211,19 @@
     goto err;
   }
 
-  // First we normalise the numbers
-  norm_shift = BN_BITS2 - (BN_num_bits(divisor) % BN_BITS2);
+  // First we normalise the numbers such that the divisor's MSB is set. This
+  // ensures, in Knuth's terminology, that v1 >= b/2, needed for the quotient
+  // estimation step.
+  int norm_shift = BN_BITS2 - (BN_num_bits(divisor) % BN_BITS2);
   if (!BN_lshift(sdiv, divisor, norm_shift)) {
     goto err;
   }
   bn_set_minimal_width(sdiv);
   sdiv->neg = 0;
+
+  // TODO(crbug.com/358687140): We also shift the numerator up by one extra
+  // word. This was done for convenience so that |wnump[-2]| below always
+  // exists, but makes the offsets confusing. Remove it.
   norm_shift += BN_BITS2;
   if (!BN_lshift(snum, numerator, norm_shift)) {
     goto err;
@@ -250,25 +250,28 @@
     snum->width++;
   }
 
-  div_n = sdiv->width;
-  num_n = snum->width;
-  loop = num_n - div_n;
+  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
   // 'area' being divided
+  BIGNUM wnum;
   wnum.neg = 0;
   wnum.d = &(snum->d[loop]);
   wnum.width = div_n;
   // only needed when BN_ucmp messes up the values between width and max
   wnum.dmax = snum->dmax - loop;  // so we don't step out of bounds
 
-  // Get the top 2 words of sdiv
-  // div_n=sdiv->width;
-  d0 = sdiv->d[div_n - 1];
-  d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2];
+  // Get the top 2 words of sdiv.
+  const BN_ULONG d0 = sdiv->d[div_n - 1];
+  const BN_ULONG d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2];
+
+  // The normalization step ensures that |sdiv|'s MSB is one.
+  assert(d0 & (((BN_ULONG)1) << (BN_BITS2 - 1)));
 
   // pointer to the 'top' of snum
-  wnump = &(snum->d[num_n - 1]);
+  BN_ULONG *wnump = &(snum->d[num_n - 1]);
 
   // Setup |res|. |numerator| and |res| may alias, so we save |numerator->neg|
   // for later.
@@ -278,7 +281,7 @@
     goto err;
   }
   res->width = loop - 1;
-  resp = &(res->d[loop - 1]);
+  BN_ULONG *resp = &(res->d[loop - 1]);
 
   // space for temp
   if (!bn_wexpand(tmp, div_n + 1)) {