diff --git a/wolfcrypt/src/sp_c32.c b/wolfcrypt/src/sp_c32.c index 70ffb49c4..6b909ea04 100644 --- a/wolfcrypt/src/sp_c32.c +++ b/wolfcrypt/src/sp_c32.c @@ -20958,8 +20958,6 @@ static int sp_256_point_to_ecc_point_9(const sp_point_256* p, ecc_point* pm) return err; } -#define sp_256_mont_reduce_order_9 sp_256_mont_reduce_9 - /* Compare a with b in constant time. * * a A single precision integer. @@ -21169,40 +21167,89 @@ static void sp_256_mont_shift_9(sp_digit* r, const sp_digit* a) * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static void sp_256_mont_reduce_9(sp_digit* a, const sp_digit* m, sp_digit mp) +static void sp_256_mont_reduce_order_9(sp_digit* a, const sp_digit* m, sp_digit mp) { int i; sp_digit mu; - if (mp != 1) { - for (i=0; i<8; i++) { - mu = (a[i] * mp) & 0x1fffffff; - sp_256_mul_add_9(a+i, m, mu); - a[i+1] += a[i] >> 29; - } - mu = (a[i] * mp) & 0xffffffL; + sp_256_norm_9(a + 9); + + for (i=0; i<8; i++) { + mu = (a[i] * mp) & 0x1fffffff; sp_256_mul_add_9(a+i, m, mu); a[i+1] += a[i] >> 29; - a[i] &= 0x1fffffff; } - else { - for (i=0; i<8; i++) { - mu = a[i] & 0x1fffffff; - sp_256_mul_add_9(a+i, p256_mod, mu); - a[i+1] += a[i] >> 29; - } - mu = a[i] & 0xffffffL; - sp_256_mul_add_9(a+i, p256_mod, mu); - a[i+1] += a[i] >> 29; - a[i] &= 0x1fffffff; - } - + mu = (a[i] * mp) & 0xffffffL; + sp_256_mul_add_9(a+i, m, mu); + a[i+1] += a[i] >> 29; + a[i] &= 0x1fffffff; sp_256_mont_shift_9(a, a); sp_256_cond_sub_9(a, a, m, 0 - (((a[8] >> 24) > 0) ? (sp_digit)1 : (sp_digit)0)); sp_256_norm_9(a); } +/* Reduce the number back to 256 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +static void sp_256_mont_reduce_9(sp_digit* a, const sp_digit* m, sp_digit mp) +{ + int i; + sp_digit am; + + (void)m; + (void)mp; + + for (i = 0; i < 8; i++) { + am = a[i] & 0x1fffffff; + a[i + 3] += (am << 9) & 0x1fffffff; + a[i + 4] += am >> 20; + a[i + 6] += (am << 18) & 0x1fffffff; + a[i + 7] += (am >> 11) - ((am << 21) & 0x1fffffff); + a[i + 8] += -(am >> 8) + ((am << 24) & 0x1fffffff); + a[i + 9] += am >> 5; + + a[i+1] += a[i] >> 29; + } + am = a[8] & 0xffffff; + a[8 + 3] += (am << 9) & 0x1fffffff; + a[8 + 4] += am >> 20; + a[8 + 6] += (am << 18) & 0x1fffffff; + a[8 + 7] += (am >> 11) - ((am << 21) & 0x1fffffff); + a[8 + 8] += -(am >> 8) + ((am << 24) & 0x1fffffff); + a[8 + 9] += am >> 5; + + a[0] = (a[ 8] >> 24) + ((a[ 9] << 5) & 0x1fffffff); + a[1] = (a[ 9] >> 24) + ((a[10] << 5) & 0x1fffffff); + a[2] = (a[10] >> 24) + ((a[11] << 5) & 0x1fffffff); + a[3] = (a[11] >> 24) + ((a[12] << 5) & 0x1fffffff); + a[4] = (a[12] >> 24) + ((a[13] << 5) & 0x1fffffff); + a[5] = (a[13] >> 24) + ((a[14] << 5) & 0x1fffffff); + a[6] = (a[14] >> 24) + ((a[15] << 5) & 0x1fffffff); + a[7] = (a[15] >> 24) + ((a[16] << 5) & 0x1fffffff); + a[8] = (a[16] >> 24) + (a[17] << 5); + + /* Get the bit over, if any. */ + am = a[8] >> 24; + /* Create mask. */ + am = 0 - am; + + a[0] -= 0x1fffffff & am; + a[1] -= 0x1fffffff & am; + a[2] -= 0x1fffffff & am; + a[3] -= 0x000001ff & am; + /* p256_mod[4] is zero */ + /* p256_mod[5] is zero */ + a[6] -= 0x00040000 & am; + a[7] -= 0x1fe00000 & am; + a[8] -= 0x00ffffff & am; + + sp_256_norm_9(a); +} + /* Multiply two Montgomery form numbers mod the modulus (prime). * (r = a * b mod m) * @@ -28075,8 +28122,6 @@ static int sp_384_point_to_ecc_point_15(const sp_point_384* p, ecc_point* pm) return err; } -#define sp_384_mont_reduce_order_15 sp_384_mont_reduce_15 - /* Compare a with b in constant time. * * a A single precision integer. @@ -28302,7 +28347,7 @@ static void sp_384_mont_shift_15(sp_digit* r, const sp_digit* a) * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static void sp_384_mont_reduce_15(sp_digit* a, const sp_digit* m, sp_digit mp) +static void sp_384_mont_reduce_order_15(sp_digit* a, const sp_digit* m, sp_digit mp) { int i; sp_digit mu; @@ -28324,6 +28369,83 @@ static void sp_384_mont_reduce_15(sp_digit* a, const sp_digit* m, sp_digit mp) sp_384_norm_15(a); } +/* Reduce the number back to 384 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +static void sp_384_mont_reduce_15(sp_digit* a, const sp_digit* m, sp_digit mp) +{ + int i; + sp_digit am; + + (void)m; + (void)mp; + + for (i = 0; i < 14; i++) { + am = (a[i] * 0x1) & 0x3ffffff; + a[i + 1] += (am << 6) & 0x3ffffff; + a[i + 2] += am >> 20; + a[i + 3] -= (am << 18) & 0x3ffffff; + a[i + 4] -= am >> 8; + a[i + 4] -= (am << 24) & 0x3ffffff; + a[i + 5] -= am >> 2; + a[i + 14] += (am << 20) & 0x3ffffff; + a[i + 15] += am >> 6; + + a[i+1] += a[i] >> 26; + } + am = (a[14] * 0x1) & 0xfffff; + a[14 + 1] += (am << 6) & 0x3ffffff; + a[14 + 2] += am >> 20; + a[14 + 3] -= (am << 18) & 0x3ffffff; + a[14 + 4] -= am >> 8; + a[14 + 4] -= (am << 24) & 0x3ffffff; + a[14 + 5] -= am >> 2; + a[14 + 14] += (am << 20) & 0x3ffffff; + a[14 + 15] += am >> 6; + + a[0] = (a[14] >> 20) + ((a[15] << 6) & 0x3ffffff); + a[1] = (a[15] >> 20) + ((a[16] << 6) & 0x3ffffff); + a[2] = (a[16] >> 20) + ((a[17] << 6) & 0x3ffffff); + a[3] = (a[17] >> 20) + ((a[18] << 6) & 0x3ffffff); + a[4] = (a[18] >> 20) + ((a[19] << 6) & 0x3ffffff); + a[5] = (a[19] >> 20) + ((a[20] << 6) & 0x3ffffff); + a[6] = (a[20] >> 20) + ((a[21] << 6) & 0x3ffffff); + a[7] = (a[21] >> 20) + ((a[22] << 6) & 0x3ffffff); + a[8] = (a[22] >> 20) + ((a[23] << 6) & 0x3ffffff); + a[9] = (a[23] >> 20) + ((a[24] << 6) & 0x3ffffff); + a[10] = (a[24] >> 20) + ((a[25] << 6) & 0x3ffffff); + a[11] = (a[25] >> 20) + ((a[26] << 6) & 0x3ffffff); + a[12] = (a[26] >> 20) + ((a[27] << 6) & 0x3ffffff); + a[13] = (a[27] >> 20) + ((a[28] << 6) & 0x3ffffff); + a[14] = (a[14 + 14] >> 20) + (a[29] << 6); + + /* Get the bit over, if any. */ + am = a[14] >> 20; + /* Create mask. */ + am = 0 - am; + + a[0] -= 0x03ffffff & am; + a[1] -= 0x0000003f & am; + /* p384_mod[2] is zero */ + a[3] -= 0x03fc0000 & am; + a[4] -= 0x02ffffff & am; + a[5] -= 0x03ffffff & am; + a[6] -= 0x03ffffff & am; + a[7] -= 0x03ffffff & am; + a[8] -= 0x03ffffff & am; + a[9] -= 0x03ffffff & am; + a[10] -= 0x03ffffff & am; + a[11] -= 0x03ffffff & am; + a[12] -= 0x03ffffff & am; + a[13] -= 0x03ffffff & am; + a[14] -= 0x000fffff & am; + + sp_384_norm_15(a); +} + /* Multiply two Montgomery form numbers mod the modulus (prime). * (r = a * b mod m) * @@ -35777,7 +35899,6 @@ static void sp_1024_cond_add_42(sp_digit* r, const sp_digit* a, r[i + 7] = a[i + 7] + (b[i + 7] & m); } r[40] = a[40] + (b[40] & m); - r[41] = a[41] + (b[41] & m); #endif /* WOLFSSL_SP_SMALL */ } diff --git a/wolfcrypt/src/sp_c64.c b/wolfcrypt/src/sp_c64.c index 1d8e6f2f4..4517f4536 100644 --- a/wolfcrypt/src/sp_c64.c +++ b/wolfcrypt/src/sp_c64.c @@ -22364,8 +22364,6 @@ static int sp_256_point_to_ecc_point_5(const sp_point_256* p, ecc_point* pm) return err; } -#define sp_256_mont_reduce_order_5 sp_256_mont_reduce_5 - /* Compare a with b in constant time. * * a A single precision integer. @@ -22527,40 +22525,86 @@ static void sp_256_mont_shift_5(sp_digit* r, const sp_digit* a) * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static void sp_256_mont_reduce_5(sp_digit* a, const sp_digit* m, sp_digit mp) +static void sp_256_mont_reduce_order_5(sp_digit* a, const sp_digit* m, sp_digit mp) { int i; sp_digit mu; - if (mp != 1) { - for (i=0; i<4; i++) { - mu = (a[i] * mp) & 0xfffffffffffffL; - sp_256_mul_add_5(a+i, m, mu); - a[i+1] += a[i] >> 52; - } - mu = (a[i] * mp) & 0xffffffffffffL; + sp_256_norm_5(a + 5); + + for (i=0; i<4; i++) { + mu = (a[i] * mp) & 0xfffffffffffffL; sp_256_mul_add_5(a+i, m, mu); a[i+1] += a[i] >> 52; - a[i] &= 0xfffffffffffffL; } - else { - for (i=0; i<4; i++) { - mu = a[i] & 0xfffffffffffffL; - sp_256_mul_add_5(a+i, p256_mod, mu); - a[i+1] += a[i] >> 52; - } - mu = a[i] & 0xffffffffffffL; - sp_256_mul_add_5(a+i, p256_mod, mu); - a[i+1] += a[i] >> 52; - a[i] &= 0xfffffffffffffL; - } - + mu = (a[i] * mp) & 0xffffffffffffL; + sp_256_mul_add_5(a+i, m, mu); + a[i+1] += a[i] >> 52; + a[i] &= 0xfffffffffffffL; sp_256_mont_shift_5(a, a); sp_256_cond_sub_5(a, a, m, 0 - (((a[4] >> 48) > 0) ? (sp_digit)1 : (sp_digit)0)); sp_256_norm_5(a); } +/* Reduce the number back to 256 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +static void sp_256_mont_reduce_5(sp_digit* a, const sp_digit* m, sp_digit mp) +{ + int i; + sp_int128 t; + sp_digit am; + + (void)m; + (void)mp; + + for (i = 0; i < 4; i++) { + am = a[i] & 0xfffffffffffffL; + /* Fifth word of modulus word */ + t = am; t *= 0x0ffffffff0000L; + + a[i+1] += (am << 44) & 0xfffffffffffffL; + a[i+2] += am >> 8; + a[i+3] += (am << 36) & 0xfffffffffffffL; + a[i+4] += (am >> 16) + (t & 0xfffffffffffffL); + a[i+5] += t >> 52; + + a[i+1] += a[i] >> 52; + } + am = a[4] & 0xffffffffffff; + /* Fifth word of modulus word */ + t = am; t *= 0x0ffffffff0000L; + + a[4+1] += (am << 44) & 0xfffffffffffffL; + a[4+2] += am >> 8; + a[4+3] += (am << 36) & 0xfffffffffffffL; + a[4+4] += (am >> 16) + (t & 0xfffffffffffffL); + a[4+5] += t >> 52; + + a[0] = (a[4] >> 48) + ((a[5] << 4) & 0xfffffffffffffL); + a[1] = (a[5] >> 48) + ((a[6] << 4) & 0xfffffffffffffL); + a[2] = (a[6] >> 48) + ((a[7] << 4) & 0xfffffffffffffL); + a[3] = (a[7] >> 48) + ((a[8] << 4) & 0xfffffffffffffL); + a[4] = (a[8] >> 48) + (a[9] << 4); + + /* Get the bit over, if any. */ + am = a[4] >> 48; + /* Create mask. */ + am = 0 - am; + + a[0] -= 0x000fffffffffffffL & am; + a[1] -= 0x00000fffffffffffL & am; + /* p256_mod[2] is zero */ + a[3] -= 0x0000001000000000L & am; + a[4] -= 0x0000ffffffff0000L & am; + + sp_256_norm_5(a); +} + /* Multiply two Montgomery form numbers mod the modulus (prime). * (r = a * b mod m) * @@ -29011,8 +29055,6 @@ static int sp_384_point_to_ecc_point_7(const sp_point_384* p, ecc_point* pm) return err; } -#define sp_384_mont_reduce_order_7 sp_384_mont_reduce_7 - /* Compare a with b in constant time. * * a A single precision integer. @@ -29192,7 +29234,7 @@ static void sp_384_mont_shift_7(sp_digit* r, const sp_digit* a) * m The single precision number representing the modulus. * mp The digit representing the negative inverse of m mod 2^n. */ -static void sp_384_mont_reduce_7(sp_digit* a, const sp_digit* m, sp_digit mp) +static void sp_384_mont_reduce_order_7(sp_digit* a, const sp_digit* m, sp_digit mp) { int i; sp_digit mu; @@ -29214,6 +29256,63 @@ static void sp_384_mont_reduce_7(sp_digit* a, const sp_digit* m, sp_digit mp) sp_384_norm_7(a); } +/* Reduce the number back to 384 bits using Montgomery reduction. + * + * a A single precision number to reduce in place. + * m The single precision number representing the modulus. + * mp The digit representing the negative inverse of m mod 2^n. + */ +static void sp_384_mont_reduce_7(sp_digit* a, const sp_digit* m, sp_digit mp) +{ + int i; + sp_digit am; + + (void)m; + (void)mp; + + for (i = 0; i < 6; i++) { + am = (a[i] * 0x100000001) & 0x7fffffffffffffL; + a[i + 0] += (am << 32) & 0x7fffffffffffffL; + a[i + 1] += (am >> 23) - ((am << 41) & 0x7fffffffffffffL); + a[i + 2] += -(am >> 14) - ((am << 18) & 0x7fffffffffffffL); + a[i + 3] += -(am >> 37); + a[i + 6] += (am << 54) & 0x7fffffffffffffL; + a[i + 7] += am >> 1; + + a[i+1] += a[i] >> 55; + } + am = (a[6] * 0x100000001) & 0x3fffffffffffff; + a[6 + 0] += (am << 32) & 0x7fffffffffffffL; + a[6 + 1] += (am >> 23) - ((am << 41) & 0x7fffffffffffffL); + a[6 + 2] += -(am >> 14) - ((am << 18) & 0x7fffffffffffffL); + a[6 + 3] += -(am >> 37); + a[6 + 6] += (am << 54) & 0x7fffffffffffffL; + a[6 + 7] += am >> 1; + + a[0] = (a[6] >> 54) + ((a[7] << 1) & 0x7fffffffffffffL); + a[1] = (a[7] >> 54) + ((a[8] << 1) & 0x7fffffffffffffL); + a[2] = (a[8] >> 54) + ((a[9] << 1) & 0x7fffffffffffffL); + a[3] = (a[9] >> 54) + ((a[10] << 1) & 0x7fffffffffffffL); + a[4] = (a[10] >> 54) + ((a[11] << 1) & 0x7fffffffffffffL); + a[5] = (a[11] >> 54) + ((a[12] << 1) & 0x7fffffffffffffL); + a[6] = (a[12] >> 54) + (a[13] << 1); + + /* Get the bit over, if any. */ + am = a[6] >> 54; + /* Create mask. */ + am = 0 - am; + + a[0] -= 0x00000000ffffffffL & am; + a[1] -= 0x007ffe0000000000L & am; + a[2] -= 0x007ffffffffbffffL & am; + a[3] -= 0x007fffffffffffffL & am; + a[4] -= 0x007fffffffffffffL & am; + a[5] -= 0x007fffffffffffffL & am; + a[6] -= 0x003fffffffffffffL & am; + + sp_384_norm_7(a); +} + /* Multiply two Montgomery form numbers mod the modulus (prime). * (r = a * b mod m) *