Remove ec_compute_wNAF's failure cases.

Replace them with asserts and better justify why each of the internal
cases are not reachable. Also change the loop to count up to bits+1 so
it is obvious there is no memory error. (The previous loop shape made
more sense when ec_compute_wNAF would return a variable length
schedule.)

Change-Id: I9c7df6abac4290b7a3e545e3d4aa1462108e239e
Reviewed-on: https://boringssl-review.googlesource.com/27705
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/fipsmodule/ec/internal.h b/crypto/fipsmodule/ec/internal.h
index 891591f..a70c869 100644
--- a/crypto/fipsmodule/ec/internal.h
+++ b/crypto/fipsmodule/ec/internal.h
@@ -282,15 +282,15 @@
     const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx);
 
 // ec_compute_wNAF writes the modified width-(w+1) Non-Adjacent Form (wNAF) of
-// |scalar| to |out| and returns one on success or zero on internal error. |out|
-// must have room for |bits| + 1 elements, each of which will be either zero or
-// odd with an absolute value less than  2^w  satisfying
+// |scalar| to |out|. |out| must have room for |bits| + 1 elements, each of
+// which will be either zero or odd with an absolute value less than  2^w
+// satisfying
 //     scalar = \sum_j out[j]*2^j
 // where at most one of any  w+1  consecutive digits is non-zero
 // with the exception that the most significant digit may be only
 // w-1 zeros away from that next non-zero digit.
-int ec_compute_wNAF(const EC_GROUP *group, int8_t *out, const EC_SCALAR *scalar,
-                    size_t bits, int w);
+void ec_compute_wNAF(const EC_GROUP *group, int8_t *out,
+                     const EC_SCALAR *scalar, size_t bits, int w);
 
 int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const EC_SCALAR *g_scalar,
                 const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx);
diff --git a/crypto/fipsmodule/ec/wnaf.c b/crypto/fipsmodule/ec/wnaf.c
index 0209d98..e6f0cf9 100644
--- a/crypto/fipsmodule/ec/wnaf.c
+++ b/crypto/fipsmodule/ec/wnaf.c
@@ -67,6 +67,7 @@
 
 #include <openssl/ec.h>
 
+#include <assert.h>
 #include <string.h>
 
 #include <openssl/bn.h>
@@ -85,82 +86,66 @@
 //   http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13
 //   http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf
 
-int ec_compute_wNAF(const EC_GROUP *group, int8_t *out, const EC_SCALAR *scalar,
-                    size_t bits, int w) {
+void ec_compute_wNAF(const EC_GROUP *group, int8_t *out,
+                     const EC_SCALAR *scalar, size_t bits, int w) {
   // 'int8_t' can represent integers with absolute values less than 2^7.
-  if (w <= 0 || w > 7 || bits == 0) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
-    return 0;
-  }
-  int bit = 1 << w;         // at most 128
-  int next_bit = bit << 1;  // at most 256
+  assert(0 < w && w <= 7);
+  assert(bits != 0);
+  int bit = 1 << w;         // 2^w, at most 128
+  int next_bit = bit << 1;  // 2^(w+1), at most 256
   int mask = next_bit - 1;  // at most 255
 
   int window_val = scalar->words[0] & mask;
-  size_t j = 0;
-  // If j+w+1 >= bits, window_val will not increase.
-  while (window_val != 0 || j + w + 1 < bits) {
+  for (size_t j = 0; j < bits + 1; j++) {
+    assert(0 <= window_val && window_val <= next_bit);
     int digit = 0;
-
-    // 0 <= window_val <= 2^(w+1)
-
     if (window_val & 1) {
-      // 0 < window_val < 2^(w+1)
-
+      assert(0 < window_val && window_val < next_bit);
       if (window_val & bit) {
-        digit = window_val - next_bit;  // -2^w < digit < 0
+        digit = window_val - next_bit;
+        // We know -next_bit < digit < 0 and window_val - digit = next_bit.
 
-#if 1  // modified wNAF
+        // modified wNAF
         if (j + w + 1 >= bits) {
           // special case for generating modified wNAFs:
           // no new bits will be added into window_val,
           // so using a positive digit here will decrease
           // the total length of the representation
 
-          digit = window_val & (mask >> 1);  // 0 < digit < 2^w
+          digit = window_val & (mask >> 1);
+          // We know 0 < digit < bit and window_val - digit = bit.
         }
-#endif
       } else {
-        digit = window_val;  // 0 < digit < 2^w
-      }
-
-      if (digit <= -bit || digit >= bit || !(digit & 1)) {
-        OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
-        return 0;
+        digit = window_val;
+        // We know 0 < digit < bit and window_val - digit = 0.
       }
 
       window_val -= digit;
 
-      // Now window_val is 0 or 2^(w+1) in standard wNAF generation;
-      // for modified window NAFs, it may also be 2^w.
-      if (window_val != 0 && window_val != next_bit && window_val != bit) {
-        OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
-        return 0;
-      }
+      // Now window_val is 0 or 2^(w+1) in standard wNAF generation.
+      // For modified window NAFs, it may also be 2^w.
+      //
+      // See the comments above for the derivation of each of these bounds.
+      assert(window_val == 0 || window_val == next_bit || window_val == bit);
+      assert(-bit < digit && digit < bit);
+
+      // window_val was odd, so digit is also odd.
+      assert(digit & 1);
     }
 
-    out[j++] = digit;
+    out[j] = digit;
 
+    // Incorporate the next bit. Previously, |window_val| <= |next_bit|, so if
+    // we shift and add at most one copy of |bit|, this will continue to hold
+    // afterwards.
     window_val >>= 1;
     window_val +=
-        bit * bn_is_bit_set_words(scalar->words, group->order.width, j + w);
-
-    if (window_val > next_bit) {
-      OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
-      return 0;
-    }
+        bit * bn_is_bit_set_words(scalar->words, group->order.width, j + w + 1);
+    assert(window_val <= next_bit);
   }
 
-  // Fill the rest of the wNAF with zeros.
-  if (j > bits + 1) {
-    OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR);
-    return 0;
-  }
-  for (size_t i = j; i < bits + 1; i++) {
-    out[i] = 0;
-  }
-
-  return 1;
+  // bits + 1 entries should be sufficient to consume all bits.
+  assert(window_val == 0);
 }
 
 // TODO: table should be optimised for the wNAF-based implementation,
@@ -274,8 +259,8 @@
     }
     g_precomp = precomp_storage + total_precomp;
     total_precomp += precomp_len;
-    if (!ec_compute_wNAF(group, g_wNAF, g_scalar, bits, wsize) ||
-        !compute_precomp(group, g_precomp, g, precomp_len, ctx)) {
+    ec_compute_wNAF(group, g_wNAF, g_scalar, bits, wsize);
+    if (!compute_precomp(group, g_precomp, g, precomp_len, ctx)) {
       goto err;
     }
   }
@@ -283,8 +268,8 @@
   if (p_scalar != NULL) {
     p_precomp = precomp_storage + total_precomp;
     total_precomp += precomp_len;
-    if (!ec_compute_wNAF(group, p_wNAF, p_scalar, bits, wsize) ||
-        !compute_precomp(group, p_precomp, p, precomp_len, ctx)) {
+    ec_compute_wNAF(group, p_wNAF, p_scalar, bits, wsize);
+    if (!compute_precomp(group, p_precomp, p, precomp_len, ctx)) {
       goto err;
     }
   }
diff --git a/third_party/fiat/p256.c b/third_party/fiat/p256.c
index 53ae9ed..5920963 100644
--- a/third_party/fiat/p256.c
+++ b/third_party/fiat/p256.c
@@ -1738,9 +1738,7 @@
 
   // Set up the coefficients for |p_scalar|.
   int8_t p_wNAF[257];
-  if (!ec_compute_wNAF(group, p_wNAF, p_scalar, 256, P256_WSIZE_PUBLIC)) {
-    return 0;
-  }
+  ec_compute_wNAF(group, p_wNAF, p_scalar, 256, P256_WSIZE_PUBLIC);
 
   // Set |ret| to the point at infinity.
   int skip = 1;  // Save some point operations.