X-Git-Url: https://www.bearssl.org/gitweb//home/git/?p=BearSSL;a=blobdiff_plain;f=src%2Fec%2Fec_p256_m15.c;h=05800d87f46a68176cbb90b3340ebd9952b5b24e;hp=0d40aef5ba8b416c8f643fb1b8e4dce59e277ce2;hb=dda1f8a0c46e15b4a235163470ff700b2f13dcc5;hpb=3655193439d4e093bb80a2f0d9e02179d424de08 diff --git a/src/ec/ec_p256_m15.c b/src/ec/ec_p256_m15.c index 0d40aef..05800d8 100644 --- a/src/ec/ec_p256_m15.c +++ b/src/ec/ec_p256_m15.c @@ -1101,18 +1101,20 @@ mul_f256(uint32_t *d, const uint32_t *a, const uint32_t *b) } /* - * Propagate carries. Since the operation above really is a - * truncature, followed by the addition of nonnegative values, - * the result will be positive. Moreover, the carry cannot - * exceed 5 bits (we performed 20 additions with values smaller - * than 256 bits). + * Propagate carries. This is a signed propagation, and the + * result may be negative. The loop above may enlarge values, + * but not two much: worst case is the chain involving t[i - 3], + * in which a value may be added to itself up to 7 times. Since + * starting values are 13-bit each, all words fit on 20 bits + * (21 to account for the sign bit). */ cc = norm13(t, t, 20); /* * Perform modular reduction again for the bits beyond 256 (the carry - * and the bits 256..259). This time, we can simply inject full - * word values. + * and the bits 256..259). Since the largest shift below is by 10 + * bits, and the values fit on 21 bits, values fit in 32-bit words, + * thereby allowing injecting full word values. */ cc = (cc << 4) | (t[19] >> 9); t[19] &= 0x01FF; @@ -1120,6 +1122,22 @@ mul_f256(uint32_t *d, const uint32_t *a, const uint32_t *b) t[14] -= cc << 10; t[7] -= cc << 5; t[0] += cc; + + /* + * If the carry is negative, then after carry propagation, we may + * end up with a value which is negative, and we don't want that. + * Thus, in that case, we add the modulus. Note that the subtraction + * result, when the carry is negative, is always smaller than the + * modulus, so the extra addition will not make the value exceed + * twice the modulus. + */ + cc >>= 31; + t[0] -= cc; + t[7] += cc << 5; + t[14] += cc << 10; + t[17] -= cc << 3; + t[19] += cc << 9; + norm13(d, t, 20); } @@ -1172,18 +1190,20 @@ square_f256(uint32_t *d, const uint32_t *a) } /* - * Propagate carries. Since the operation above really is a - * truncature, followed by the addition of nonnegative values, - * the result will be positive. Moreover, the carry cannot - * exceed 5 bits (we performed 20 additions with values smaller - * than 256 bits). + * Propagate carries. This is a signed propagation, and the + * result may be negative. The loop above may enlarge values, + * but not two much: worst case is the chain involving t[i - 3], + * in which a value may be added to itself up to 7 times. Since + * starting values are 13-bit each, all words fit on 20 bits + * (21 to account for the sign bit). */ cc = norm13(t, t, 20); /* * Perform modular reduction again for the bits beyond 256 (the carry - * and the bits 256..259). This time, we can simply inject full - * word values. + * and the bits 256..259). Since the largest shift below is by 10 + * bits, and the values fit on 21 bits, values fit in 32-bit words, + * thereby allowing injecting full word values. */ cc = (cc << 4) | (t[19] >> 9); t[19] &= 0x01FF; @@ -1191,6 +1211,22 @@ square_f256(uint32_t *d, const uint32_t *a) t[14] -= cc << 10; t[7] -= cc << 5; t[0] += cc; + + /* + * If the carry is negative, then after carry propagation, we may + * end up with a value which is negative, and we don't want that. + * Thus, in that case, we add the modulus. Note that the subtraction + * result, when the carry is negative, is always smaller than the + * modulus, so the extra addition will not make the value exceed + * twice the modulus. + */ + cc >>= 31; + t[0] -= cc; + t[7] += cc << 5; + t[14] += cc << 10; + t[17] -= cc << 3; + t[19] += cc << 9; + norm13(d, t, 20); } @@ -1703,7 +1739,7 @@ p256_decode(p256_jacobian *P, const void *src, size_t len) memcpy(P->y, ty, sizeof ty); memset(P->z, 0, sizeof P->z); P->z[0] = 1; - return NEQ(bad, 0) ^ 1; + return EQ(bad, 0); } /* @@ -2003,12 +2039,13 @@ api_mul(unsigned char *G, size_t Glen, p256_jacobian P; (void)curve; + if (Glen != 65) { + return 0; + } r = p256_decode(&P, G, Glen); p256_mul(&P, x, xlen); - if (Glen >= 65) { - p256_to_affine(&P); - p256_encode(G, &P); - } + p256_to_affine(&P); + p256_encode(G, &P); return r; } @@ -2023,16 +2060,6 @@ api_mulgen(unsigned char *R, p256_to_affine(&P); p256_encode(R, &P); return 65; - - /* - const unsigned char *G; - size_t Glen; - - G = api_generator(curve, &Glen); - memcpy(R, G, Glen); - api_mul(R, Glen, x, xlen, curve); - return Glen; - */ } static uint32_t @@ -2045,6 +2072,9 @@ api_muladd(unsigned char *A, const unsigned char *B, size_t len, int i; (void)curve; + if (len != 65) { + return 0; + } r = p256_decode(&P, A, len); p256_mul(&P, x, xlen); if (B == NULL) {