Loading system/stack/smp/p_256_curvepara.cc +39 −43 Original line number Diff line number Diff line Loading @@ -25,11 +25,8 @@ #include <string.h> #include "p_256_ecc_pp.h" void p_256_init_curve(uint32_t keyLength) { elliptic_curve_t* ec; if (keyLength == KEY_LENGTH_DWORDS_P256) { ec = &curve_p256; void p_256_init_curve() { elliptic_curve_t* ec = &curve_p256; ec->p[7] = 0xFFFFFFFF; ec->p[6] = 0x00000001; Loading Loading @@ -74,4 +71,3 @@ void p_256_init_curve(uint32_t keyLength) { ec->G.y[1] = 0xcbb64068; ec->G.y[0] = 0x37bf51f5; } } system/stack/smp/p_256_ecc_pp.cc +79 −86 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ static void p_256_copy_point(Point* q, Point* p) { } // q=2q static void ECC_Double(Point* q, Point* p, uint32_t keyLength) { static void ECC_Double(Point* q, Point* p) { uint32_t t1[KEY_LENGTH_DWORDS_P256]; uint32_t t2[KEY_LENGTH_DWORDS_P256]; uint32_t t3[KEY_LENGTH_DWORDS_P256]; Loading @@ -49,8 +49,8 @@ static void ECC_Double(Point* q, Point* p, uint32_t keyLength) { uint32_t* z1; uint32_t* z3; if (multiprecision_iszero(p->z, keyLength)) { multiprecision_init(q->z, keyLength); if (multiprecision_iszero(p->z)) { multiprecision_init(q->z); return; // return infinity } Loading @@ -61,33 +61,33 @@ static void ECC_Double(Point* q, Point* p, uint32_t keyLength) { y3 = q->y; z3 = q->z; multiprecision_mersenns_squa_mod(t1, z1, keyLength); // t1=z1^2 multiprecision_sub_mod(t2, x1, t1, keyLength); // t2=x1-t1 multiprecision_add_mod(t1, x1, t1, keyLength); // t1=x1+t1 multiprecision_mersenns_mult_mod(t2, t1, t2, keyLength); // t2=t2*t1 multiprecision_lshift_mod(t3, t2, keyLength); multiprecision_add_mod(t2, t3, t2, keyLength); // t2=3t2 multiprecision_mersenns_mult_mod(z3, y1, z1, keyLength); // z3=y1*z1 multiprecision_lshift_mod(z3, z3, keyLength); multiprecision_mersenns_squa_mod(y3, y1, keyLength); // y3=y1^2 multiprecision_lshift_mod(y3, y3, keyLength); multiprecision_mersenns_mult_mod(t3, y3, x1, keyLength); // t3=y3*x1=x1*y1^2 multiprecision_lshift_mod(t3, t3, keyLength); multiprecision_mersenns_squa_mod(y3, y3, keyLength); // y3=y3^2=y1^4 multiprecision_lshift_mod(y3, y3, keyLength); multiprecision_mersenns_squa_mod(x3, t2, keyLength); // x3=t2^2 multiprecision_lshift_mod(t1, t3, keyLength); // t1=2t3 multiprecision_sub_mod(x3, x3, t1, keyLength); // x3=x3-t1 multiprecision_sub_mod(t1, t3, x3, keyLength); // t1=t3-x3 multiprecision_mersenns_mult_mod(t1, t1, t2, keyLength); // t1=t1*t2 multiprecision_sub_mod(y3, t1, y3, keyLength); // y3=t1-y3 multiprecision_mersenns_squa_mod(t1, z1); // t1=z1^2 multiprecision_sub_mod(t2, x1, t1); // t2=x1-t1 multiprecision_add_mod(t1, x1, t1); // t1=x1+t1 multiprecision_mersenns_mult_mod(t2, t1, t2); // t2=t2*t1 multiprecision_lshift_mod(t3, t2); multiprecision_add_mod(t2, t3, t2); // t2=3t2 multiprecision_mersenns_mult_mod(z3, y1, z1); // z3=y1*z1 multiprecision_lshift_mod(z3, z3); multiprecision_mersenns_squa_mod(y3, y1); // y3=y1^2 multiprecision_lshift_mod(y3, y3); multiprecision_mersenns_mult_mod(t3, y3, x1); // t3=y3*x1=x1*y1^2 multiprecision_lshift_mod(t3, t3); multiprecision_mersenns_squa_mod(y3, y3); // y3=y3^2=y1^4 multiprecision_lshift_mod(y3, y3); multiprecision_mersenns_squa_mod(x3, t2); // x3=t2^2 multiprecision_lshift_mod(t1, t3); // t1=2t3 multiprecision_sub_mod(x3, x3, t1); // x3=x3-t1 multiprecision_sub_mod(t1, t3, x3); // t1=t3-x3 multiprecision_mersenns_mult_mod(t1, t1, t2); // t1=t1*t2 multiprecision_sub_mod(y3, t1, y3); // y3=t1-y3 } // q=q+p, zp must be 1 static void ECC_Add(Point* r, Point* p, Point* q, uint32_t keyLength) { static void ECC_Add(Point* r, Point* p, Point* q) { uint32_t t1[KEY_LENGTH_DWORDS_P256]; uint32_t t2[KEY_LENGTH_DWORDS_P256]; uint32_t* x1; Loading @@ -111,58 +111,57 @@ static void ECC_Add(Point* r, Point* p, Point* q, uint32_t keyLength) { z3 = r->z; // if Q=infinity, return p if (multiprecision_iszero(z2, keyLength)) { if (multiprecision_iszero(z2)) { p_256_copy_point(r, p); return; } // if P=infinity, return q if (multiprecision_iszero(z1, keyLength)) { if (multiprecision_iszero(z1)) { p_256_copy_point(r, q); return; } multiprecision_mersenns_squa_mod(t1, z1, keyLength); // t1=z1^2 multiprecision_mersenns_mult_mod(t2, z1, t1, keyLength); // t2=t1*z1 multiprecision_mersenns_mult_mod(t1, x2, t1, keyLength); // t1=t1*x2 multiprecision_mersenns_mult_mod(t2, y2, t2, keyLength); // t2=t2*y2 multiprecision_mersenns_squa_mod(t1, z1); // t1=z1^2 multiprecision_mersenns_mult_mod(t2, z1, t1); // t2=t1*z1 multiprecision_mersenns_mult_mod(t1, x2, t1); // t1=t1*x2 multiprecision_mersenns_mult_mod(t2, y2, t2); // t2=t2*y2 multiprecision_sub_mod(t1, t1, x1, keyLength); // t1=t1-x1 multiprecision_sub_mod(t2, t2, y1, keyLength); // t2=t2-y1 multiprecision_sub_mod(t1, t1, x1); // t1=t1-x1 multiprecision_sub_mod(t2, t2, y1); // t2=t2-y1 if (multiprecision_iszero(t1, keyLength)) { if (multiprecision_iszero(t2, keyLength)) { ECC_Double(r, q, keyLength); if (multiprecision_iszero(t1)) { if (multiprecision_iszero(t2)) { ECC_Double(r, q); return; } else { multiprecision_init(z3, keyLength); multiprecision_init(z3); return; // return infinity } } multiprecision_mersenns_mult_mod(z3, z1, t1, keyLength); // z3=z1*t1 multiprecision_mersenns_squa_mod(y3, t1, keyLength); // t3=t1^2 multiprecision_mersenns_mult_mod(z1, y3, t1, keyLength); // t4=t3*t1 multiprecision_mersenns_mult_mod(y3, y3, x1, keyLength); // t3=t3*x1 multiprecision_lshift_mod(t1, y3, keyLength); // t1=2*t3 multiprecision_mersenns_squa_mod(x3, t2, keyLength); // x3=t2^2 multiprecision_sub_mod(x3, x3, t1, keyLength); // x3=x3-t1 multiprecision_sub_mod(x3, x3, z1, keyLength); // x3=x3-t4 multiprecision_sub_mod(y3, y3, x3, keyLength); // t3=t3-x3 multiprecision_mersenns_mult_mod(y3, y3, t2, keyLength); // t3=t3*t2 multiprecision_mersenns_mult_mod(z1, z1, y1, keyLength); // t4=t4*t1 multiprecision_sub_mod(y3, y3, z1, keyLength); multiprecision_mersenns_mult_mod(z3, z1, t1); // z3=z1*t1 multiprecision_mersenns_squa_mod(y3, t1); // t3=t1^2 multiprecision_mersenns_mult_mod(z1, y3, t1); // t4=t3*t1 multiprecision_mersenns_mult_mod(y3, y3, x1); // t3=t3*x1 multiprecision_lshift_mod(t1, y3); // t1=2*t3 multiprecision_mersenns_squa_mod(x3, t2); // x3=t2^2 multiprecision_sub_mod(x3, x3, t1); // x3=x3-t1 multiprecision_sub_mod(x3, x3, z1); // x3=x3-t4 multiprecision_sub_mod(y3, y3, x3); // t3=t3-x3 multiprecision_mersenns_mult_mod(y3, y3, t2); // t3=t3*t2 multiprecision_mersenns_mult_mod(z1, z1, y1); // t4=t4*t1 multiprecision_sub_mod(y3, y3, z1); } // Computing the Non-Adjacent Form of a positive integer static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k, uint32_t keyLength) { static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k) { uint32_t sign; int i = 0; int j; uint32_t var; while ((var = multiprecision_most_signbits(k, keyLength)) >= 1) { while ((var = multiprecision_most_signbits(k)) >= 1) { if (k[0] & 0x01) // k is odd { sign = (k[0] & 0x03); // 1 or 3 Loading @@ -183,7 +182,7 @@ static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k, } else sign = 0; multiprecision_rshift(k, k, keyLength); multiprecision_rshift(k, k); naf[i / 4] |= (sign) << ((i % 4) * 2); i++; } Loading @@ -192,8 +191,7 @@ static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k, } // Binary Non-Adjacent Form for point multiplication void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n, uint32_t keyLength) { void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n) { uint32_t sign; uint8_t naf[256 / 4 + 1]; uint32_t NumNaf; Loading @@ -201,69 +199,64 @@ void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n, Point r; uint32_t* modp; if (keyLength == KEY_LENGTH_DWORDS_P256) { modp = curve_p256.p; } else { modp = curve.p; } p_256_init_point(&r); multiprecision_init(p->z, keyLength); multiprecision_init(p->z); p->z[0] = 1; // initialization p_256_init_point(q); // -p multiprecision_copy(minus_p.x, p->x, keyLength); multiprecision_sub(minus_p.y, modp, p->y, keyLength); multiprecision_copy(minus_p.x, p->x); multiprecision_sub(minus_p.y, modp, p->y); multiprecision_init(minus_p.z, keyLength); multiprecision_init(minus_p.z); minus_p.z[0] = 1; // NAF memset(naf, 0, sizeof(naf)); ECC_NAF(naf, &NumNaf, n, keyLength); ECC_NAF(naf, &NumNaf, n); for (int i = NumNaf - 1; i >= 0; i--) { p_256_copy_point(&r, q); ECC_Double(q, &r, keyLength); ECC_Double(q, &r); sign = (naf[i / 4] >> ((i % 4) * 2)) & 0x03; if (sign == 1) { p_256_copy_point(&r, q); ECC_Add(q, &r, p, keyLength); ECC_Add(q, &r, p); } else if (sign == 3) { p_256_copy_point(&r, q); ECC_Add(q, &r, &minus_p, keyLength); ECC_Add(q, &r, &minus_p); } } multiprecision_inv_mod(minus_p.x, q->z, keyLength); multiprecision_mersenns_squa_mod(q->z, minus_p.x, keyLength); multiprecision_mersenns_mult_mod(q->x, q->x, q->z, keyLength); multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x, keyLength); multiprecision_mersenns_mult_mod(q->y, q->y, q->z, keyLength); multiprecision_inv_mod(minus_p.x, q->z); multiprecision_mersenns_squa_mod(q->z, minus_p.x); multiprecision_mersenns_mult_mod(q->x, q->x, q->z); multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x); multiprecision_mersenns_mult_mod(q->y, q->y, q->z); } bool ECC_ValidatePoint(const Point& pt) { const size_t kl = KEY_LENGTH_DWORDS_P256; p_256_init_curve(kl); p_256_init_curve(); // Ensure y^2 = x^3 + a*x + b (mod p); a = -3 // y^2 mod p uint32_t y2_mod[kl] = {0}; multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y, kl); uint32_t y2_mod[KEY_LENGTH_DWORDS_P256] = {0}; multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y); // Right hand side calculation uint32_t rhs[kl] = {0}; multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x, kl); uint32_t three[kl] = {0}; uint32_t rhs[KEY_LENGTH_DWORDS_P256] = {0}; multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x); uint32_t three[KEY_LENGTH_DWORDS_P256] = {0}; three[0] = 3; multiprecision_sub_mod(rhs, rhs, three, kl); multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x, kl); multiprecision_add_mod(rhs, rhs, curve_p256.b, kl); multiprecision_sub_mod(rhs, rhs, three); multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x); multiprecision_add_mod(rhs, rhs, curve_p256.b); return multiprecision_compare(rhs, y2_mod, kl) == 0; return multiprecision_compare(rhs, y2_mod) == 0; } system/stack/smp/p_256_ecc_pp.h +3 −4 Original line number Diff line number Diff line Loading @@ -58,9 +58,8 @@ extern elliptic_curve_t curve_p256; bool ECC_ValidatePoint(const Point& p); void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n, uint32_t keyLength); void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n); #define ECC_PointMult(q, p, n, keyLength) \ ECC_PointMult_Bin_NAF(q, p, n, keyLength) #define ECC_PointMult(q, p, n) ECC_PointMult_Bin_NAF(q, p, n) void p_256_init_curve(uint32_t keyLength); void p_256_init_curve(); system/stack/smp/p_256_multprecision.cc +73 −183 Original line number Diff line number Diff line Loading @@ -27,24 +27,24 @@ #include "bt_target.h" #include "p_256_ecc_pp.h" void multiprecision_init(uint32_t* c, uint32_t keyLength) { for (uint32_t i = 0; i < keyLength; i++) c[i] = 0; void multiprecision_init(uint32_t* c) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) c[i] = 0; } void multiprecision_copy(uint32_t* c, uint32_t* a, uint32_t keyLength) { for (uint32_t i = 0; i < keyLength; i++) c[i] = a[i]; void multiprecision_copy(uint32_t* c, uint32_t* a) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) c[i] = a[i]; } int multiprecision_compare(uint32_t* a, uint32_t* b, uint32_t keyLength) { for (int i = keyLength - 1; i >= 0; i--) { int multiprecision_compare(uint32_t* a, uint32_t* b) { for (int i = KEY_LENGTH_DWORDS_P256 - 1; i >= 0; i--) { if (a[i] > b[i]) return 1; if (a[i] < b[i]) return -1; } return 0; } int multiprecision_iszero(uint32_t* a, uint32_t keyLength) { for (uint32_t i = 0; i < keyLength; i++) int multiprecision_iszero(uint32_t* a) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) if (a[i]) return 0; return 1; Loading @@ -58,30 +58,29 @@ uint32_t multiprecision_dword_bits(uint32_t a) { return i; } uint32_t multiprecision_most_signdwords(uint32_t* a, uint32_t keyLength) { uint32_t multiprecision_most_signdwords(uint32_t* a) { int i; for (i = keyLength - 1; i >= 0; i--) for (i = KEY_LENGTH_DWORDS_P256 - 1; i >= 0; i--) if (a[i]) break; return (i + 1); } uint32_t multiprecision_most_signbits(uint32_t* a, uint32_t keyLength) { uint32_t multiprecision_most_signbits(uint32_t* a) { int aMostSignDWORDs; aMostSignDWORDs = multiprecision_most_signdwords(a, keyLength); aMostSignDWORDs = multiprecision_most_signdwords(a); if (aMostSignDWORDs == 0) return 0; return (((aMostSignDWORDs - 1) << DWORD_BITS_SHIFT) + multiprecision_dword_bits(a[aMostSignDWORDs - 1])); } uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b, uint32_t keyLength) { uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t carrier; uint32_t temp; carrier = 0; for (uint32_t i = 0; i < keyLength; i++) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) { temp = a[i] + carrier; carrier = (temp < carrier); temp += b[i]; Loading @@ -93,13 +92,12 @@ uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b, } // c=a-b uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b, uint32_t keyLength) { uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t borrow; uint32_t temp; borrow = 0; for (uint32_t i = 0; i < keyLength; i++) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) { temp = a[i] - borrow; borrow = (temp > a[i]); c[i] = temp - b[i]; Loading @@ -110,27 +108,20 @@ uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b, } // c = a << 1 void multiprecision_lshift_mod(uint32_t* c, uint32_t* a, uint32_t keyLength) { void multiprecision_lshift_mod(uint32_t* c, uint32_t* a) { uint32_t carrier; uint32_t* modp; if (keyLength == KEY_LENGTH_DWORDS_P192) { modp = curve.p; } else if (keyLength == KEY_LENGTH_DWORDS_P256) { modp = curve_p256.p; } else return; uint32_t* modp = curve_p256.p; carrier = multiprecision_lshift(c, a, keyLength); carrier = multiprecision_lshift(c, a); if (carrier) { multiprecision_sub(c, c, modp, keyLength); } else if (multiprecision_compare(c, modp, keyLength) >= 0) { multiprecision_sub(c, c, modp, keyLength); multiprecision_sub(c, c, modp); } else if (multiprecision_compare(c, modp) >= 0) { multiprecision_sub(c, c, modp); } } // c=a>>1 void multiprecision_rshift(uint32_t* c, uint32_t* a, uint32_t keyLength) { void multiprecision_rshift(uint32_t* c, uint32_t* a) { int j; uint32_t b = 1; Loading @@ -138,7 +129,7 @@ void multiprecision_rshift(uint32_t* c, uint32_t* a, uint32_t keyLength) { uint32_t carrier = 0; uint32_t temp; for (int i = keyLength - 1; i >= 0; i--) { for (int i = KEY_LENGTH_DWORDS_P256 - 1; i >= 0; i--) { temp = a[i]; // in case of c==a c[i] = (temp >> b) | carrier; carrier = temp << j; Loading @@ -147,64 +138,42 @@ void multiprecision_rshift(uint32_t* c, uint32_t* a, uint32_t keyLength) { // Curve specific optimization when p is a pseudo-Mersenns prime, // p=2^(KEY_LENGTH_BITS)-omega void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b, uint32_t keyLength) { void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t cc[2 * KEY_LENGTH_DWORDS_P256]; multiprecision_mult(cc, a, b, keyLength); if (keyLength == 6) { multiprecision_fast_mod(c, cc); } else if (keyLength == 8) { multiprecision_mult(cc, a, b); multiprecision_fast_mod_P256(c, cc); } } // Curve specific optimization when p is a pseudo-Mersenns prime void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a, uint32_t keyLength) { multiprecision_mersenns_mult_mod(c, a, a, keyLength); void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a) { multiprecision_mersenns_mult_mod(c, a, a); } // c=(a+b) mod p, b<p, a<p void multiprecision_add_mod(uint32_t* c, uint32_t* a, uint32_t* b, uint32_t keyLength) { void multiprecision_add_mod(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t carrier; uint32_t* modp; if (keyLength == KEY_LENGTH_DWORDS_P192) { modp = curve.p; } else if (keyLength == KEY_LENGTH_DWORDS_P256) { modp = curve_p256.p; } else return; uint32_t* modp = curve_p256.p; carrier = multiprecision_add(c, a, b, keyLength); carrier = multiprecision_add(c, a, b); if (carrier) { multiprecision_sub(c, c, modp, keyLength); } else if (multiprecision_compare(c, modp, keyLength) >= 0) { multiprecision_sub(c, c, modp, keyLength); multiprecision_sub(c, c, modp); } else if (multiprecision_compare(c, modp) >= 0) { multiprecision_sub(c, c, modp); } } // c=(a-b) mod p, a<p, b<p void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b, uint32_t keyLength) { void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t borrow; uint32_t* modp; if (keyLength == KEY_LENGTH_DWORDS_P192) { modp = curve.p; } else if (keyLength == KEY_LENGTH_DWORDS_P256) { modp = curve_p256.p; } else return; uint32_t* modp = curve_p256.p; borrow = multiprecision_sub(c, a, b, keyLength); if (borrow) multiprecision_add(c, c, modp, keyLength); borrow = multiprecision_sub(c, a, b); if (borrow) multiprecision_add(c, c, modp); } // c=a<<b, b<DWORD_BITS, c has a buffer size of Numuint32_ts+1 uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a, uint32_t keyLength) { uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a) { int j; uint32_t b = 1; j = DWORD_BITS - b; Loading @@ -212,7 +181,7 @@ uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a, uint32_t keyLength) { uint32_t carrier = 0; uint32_t temp; for (uint32_t i = 0; i < keyLength; i++) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) { temp = a[i]; // in case c==a c[i] = (temp << b) | carrier; carrier = temp >> j; Loading @@ -222,19 +191,18 @@ uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a, uint32_t keyLength) { } // c=a*b; c must have a buffer of 2*Key_LENGTH_uint32_tS, c != a != b void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b, uint32_t keyLength) { void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t W; uint32_t U; uint32_t V; U = V = W = 0; multiprecision_init(c, keyLength); multiprecision_init(c); // assume little endian right now for (uint32_t i = 0; i < keyLength; i++) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) { U = 0; for (uint32_t j = 0; j < keyLength; j++) { for (uint32_t j = 0; j < KEY_LENGTH_DWORDS_P256; j++) { uint64_t result; result = ((uint64_t)a[i]) * ((uint64_t)b[j]); W = result >> 32; Loading @@ -246,78 +214,7 @@ void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b, U += (V < c[i + j]); c[i + j] = V; } c[i + keyLength] = U; } } void multiprecision_fast_mod(uint32_t* c, uint32_t* a) { uint32_t U; uint32_t V; uint32_t* modp = curve.p; c[0] = a[0] + a[6]; U = c[0] < a[0]; c[0] += a[10]; U += c[0] < a[10]; c[1] = a[1] + U; U = c[1] < a[1]; c[1] += a[7]; U += c[1] < a[7]; c[1] += a[11]; U += c[1] < a[11]; c[2] = a[2] + U; U = c[2] < a[2]; c[2] += a[6]; U += c[2] < a[6]; c[2] += a[8]; U += c[2] < a[8]; c[2] += a[10]; U += c[2] < a[10]; c[3] = a[3] + U; U = c[3] < a[3]; c[3] += a[7]; U += c[3] < a[7]; c[3] += a[9]; U += c[3] < a[9]; c[3] += a[11]; U += c[3] < a[11]; c[4] = a[4] + U; U = c[4] < a[4]; c[4] += a[8]; U += c[4] < a[8]; c[4] += a[10]; U += c[4] < a[10]; c[5] = a[5] + U; U = c[5] < a[5]; c[5] += a[9]; U += c[5] < a[9]; c[5] += a[11]; U += c[5] < a[11]; c[0] += U; V = c[0] < U; c[1] += V; V = c[1] < V; c[2] += V; V = c[2] < V; c[2] += U; V = c[2] < U; c[3] += V; V = c[3] < V; c[4] += V; V = c[4] < V; c[5] += V; V = c[5] < V; if (V) { multiprecision_sub(c, c, modp, KEY_LENGTH_DWORDS_P192); } else if (multiprecision_compare(c, modp, KEY_LENGTH_DWORDS_P192) >= 0) { multiprecision_sub(c, c, modp, KEY_LENGTH_DWORDS_P192); c[i + KEY_LENGTH_DWORDS_P256] = U; } } Loading Loading @@ -541,74 +438,67 @@ void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a) { if (U & 0x80000000) { while (U) { multiprecision_add(c, c, modp, KEY_LENGTH_DWORDS_P256); multiprecision_add(c, c, modp); U++; } } else if (U) { while (U) { multiprecision_sub(c, c, modp, KEY_LENGTH_DWORDS_P256); multiprecision_sub(c, c, modp); U--; } } if (multiprecision_compare(c, modp, KEY_LENGTH_DWORDS_P256) >= 0) multiprecision_sub(c, c, modp, KEY_LENGTH_DWORDS_P256); if (multiprecision_compare(c, modp) >= 0) multiprecision_sub(c, c, modp); } void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u, uint32_t keyLength) { void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u) { uint32_t v[KEY_LENGTH_DWORDS_P256]; uint32_t A[KEY_LENGTH_DWORDS_P256 + 1]; uint32_t C[KEY_LENGTH_DWORDS_P256 + 1]; uint32_t* modp; if (keyLength == KEY_LENGTH_DWORDS_P256) { modp = curve_p256.p; } else { modp = curve.p; } uint32_t* modp = curve_p256.p; multiprecision_copy(v, modp, keyLength); multiprecision_init(A, keyLength); multiprecision_init(C, keyLength); multiprecision_copy(v, modp); multiprecision_init(A); multiprecision_init(C); A[0] = 1; while (!multiprecision_iszero(u, keyLength)) { while (!multiprecision_iszero(u)) { while (!(u[0] & 0x01)) // u is even { multiprecision_rshift(u, u, keyLength); multiprecision_rshift(u, u); if (!(A[0] & 0x01)) // A is even multiprecision_rshift(A, A, keyLength); multiprecision_rshift(A, A); else { A[keyLength] = multiprecision_add(A, A, modp, keyLength); // A =A+p multiprecision_rshift(A, A, keyLength); A[keyLength - 1] |= (A[keyLength] << 31); A[KEY_LENGTH_DWORDS_P256] = multiprecision_add(A, A, modp); // A =A+p multiprecision_rshift(A, A); A[KEY_LENGTH_DWORDS_P256 - 1] |= (A[KEY_LENGTH_DWORDS_P256] << 31); } } while (!(v[0] & 0x01)) // v is even { multiprecision_rshift(v, v, keyLength); multiprecision_rshift(v, v); if (!(C[0] & 0x01)) // C is even { multiprecision_rshift(C, C, keyLength); multiprecision_rshift(C, C); } else { C[keyLength] = multiprecision_add(C, C, modp, keyLength); // C =C+p multiprecision_rshift(C, C, keyLength); C[keyLength - 1] |= (C[keyLength] << 31); C[KEY_LENGTH_DWORDS_P256] = multiprecision_add(C, C, modp); // C =C+p multiprecision_rshift(C, C); C[KEY_LENGTH_DWORDS_P256 - 1] |= (C[KEY_LENGTH_DWORDS_P256] << 31); } } if (multiprecision_compare(u, v, keyLength) >= 0) { multiprecision_sub(u, u, v, keyLength); multiprecision_sub_mod(A, A, C, keyLength); if (multiprecision_compare(u, v) >= 0) { multiprecision_sub(u, u, v); multiprecision_sub_mod(A, A, C); } else { multiprecision_sub(v, v, u, keyLength); multiprecision_sub_mod(C, C, A, keyLength); multiprecision_sub(v, v, u); multiprecision_sub_mod(C, C, A); } } if (multiprecision_compare(C, modp, keyLength) >= 0) multiprecision_sub(aminus, C, modp, keyLength); if (multiprecision_compare(C, modp) >= 0) multiprecision_sub(aminus, C, modp); else multiprecision_copy(aminus, C, keyLength); multiprecision_copy(aminus, C); } system/stack/smp/p_256_multprecision.h +22 −33 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
system/stack/smp/p_256_curvepara.cc +39 −43 Original line number Diff line number Diff line Loading @@ -25,11 +25,8 @@ #include <string.h> #include "p_256_ecc_pp.h" void p_256_init_curve(uint32_t keyLength) { elliptic_curve_t* ec; if (keyLength == KEY_LENGTH_DWORDS_P256) { ec = &curve_p256; void p_256_init_curve() { elliptic_curve_t* ec = &curve_p256; ec->p[7] = 0xFFFFFFFF; ec->p[6] = 0x00000001; Loading Loading @@ -74,4 +71,3 @@ void p_256_init_curve(uint32_t keyLength) { ec->G.y[1] = 0xcbb64068; ec->G.y[0] = 0x37bf51f5; } }
system/stack/smp/p_256_ecc_pp.cc +79 −86 Original line number Diff line number Diff line Loading @@ -38,7 +38,7 @@ static void p_256_copy_point(Point* q, Point* p) { } // q=2q static void ECC_Double(Point* q, Point* p, uint32_t keyLength) { static void ECC_Double(Point* q, Point* p) { uint32_t t1[KEY_LENGTH_DWORDS_P256]; uint32_t t2[KEY_LENGTH_DWORDS_P256]; uint32_t t3[KEY_LENGTH_DWORDS_P256]; Loading @@ -49,8 +49,8 @@ static void ECC_Double(Point* q, Point* p, uint32_t keyLength) { uint32_t* z1; uint32_t* z3; if (multiprecision_iszero(p->z, keyLength)) { multiprecision_init(q->z, keyLength); if (multiprecision_iszero(p->z)) { multiprecision_init(q->z); return; // return infinity } Loading @@ -61,33 +61,33 @@ static void ECC_Double(Point* q, Point* p, uint32_t keyLength) { y3 = q->y; z3 = q->z; multiprecision_mersenns_squa_mod(t1, z1, keyLength); // t1=z1^2 multiprecision_sub_mod(t2, x1, t1, keyLength); // t2=x1-t1 multiprecision_add_mod(t1, x1, t1, keyLength); // t1=x1+t1 multiprecision_mersenns_mult_mod(t2, t1, t2, keyLength); // t2=t2*t1 multiprecision_lshift_mod(t3, t2, keyLength); multiprecision_add_mod(t2, t3, t2, keyLength); // t2=3t2 multiprecision_mersenns_mult_mod(z3, y1, z1, keyLength); // z3=y1*z1 multiprecision_lshift_mod(z3, z3, keyLength); multiprecision_mersenns_squa_mod(y3, y1, keyLength); // y3=y1^2 multiprecision_lshift_mod(y3, y3, keyLength); multiprecision_mersenns_mult_mod(t3, y3, x1, keyLength); // t3=y3*x1=x1*y1^2 multiprecision_lshift_mod(t3, t3, keyLength); multiprecision_mersenns_squa_mod(y3, y3, keyLength); // y3=y3^2=y1^4 multiprecision_lshift_mod(y3, y3, keyLength); multiprecision_mersenns_squa_mod(x3, t2, keyLength); // x3=t2^2 multiprecision_lshift_mod(t1, t3, keyLength); // t1=2t3 multiprecision_sub_mod(x3, x3, t1, keyLength); // x3=x3-t1 multiprecision_sub_mod(t1, t3, x3, keyLength); // t1=t3-x3 multiprecision_mersenns_mult_mod(t1, t1, t2, keyLength); // t1=t1*t2 multiprecision_sub_mod(y3, t1, y3, keyLength); // y3=t1-y3 multiprecision_mersenns_squa_mod(t1, z1); // t1=z1^2 multiprecision_sub_mod(t2, x1, t1); // t2=x1-t1 multiprecision_add_mod(t1, x1, t1); // t1=x1+t1 multiprecision_mersenns_mult_mod(t2, t1, t2); // t2=t2*t1 multiprecision_lshift_mod(t3, t2); multiprecision_add_mod(t2, t3, t2); // t2=3t2 multiprecision_mersenns_mult_mod(z3, y1, z1); // z3=y1*z1 multiprecision_lshift_mod(z3, z3); multiprecision_mersenns_squa_mod(y3, y1); // y3=y1^2 multiprecision_lshift_mod(y3, y3); multiprecision_mersenns_mult_mod(t3, y3, x1); // t3=y3*x1=x1*y1^2 multiprecision_lshift_mod(t3, t3); multiprecision_mersenns_squa_mod(y3, y3); // y3=y3^2=y1^4 multiprecision_lshift_mod(y3, y3); multiprecision_mersenns_squa_mod(x3, t2); // x3=t2^2 multiprecision_lshift_mod(t1, t3); // t1=2t3 multiprecision_sub_mod(x3, x3, t1); // x3=x3-t1 multiprecision_sub_mod(t1, t3, x3); // t1=t3-x3 multiprecision_mersenns_mult_mod(t1, t1, t2); // t1=t1*t2 multiprecision_sub_mod(y3, t1, y3); // y3=t1-y3 } // q=q+p, zp must be 1 static void ECC_Add(Point* r, Point* p, Point* q, uint32_t keyLength) { static void ECC_Add(Point* r, Point* p, Point* q) { uint32_t t1[KEY_LENGTH_DWORDS_P256]; uint32_t t2[KEY_LENGTH_DWORDS_P256]; uint32_t* x1; Loading @@ -111,58 +111,57 @@ static void ECC_Add(Point* r, Point* p, Point* q, uint32_t keyLength) { z3 = r->z; // if Q=infinity, return p if (multiprecision_iszero(z2, keyLength)) { if (multiprecision_iszero(z2)) { p_256_copy_point(r, p); return; } // if P=infinity, return q if (multiprecision_iszero(z1, keyLength)) { if (multiprecision_iszero(z1)) { p_256_copy_point(r, q); return; } multiprecision_mersenns_squa_mod(t1, z1, keyLength); // t1=z1^2 multiprecision_mersenns_mult_mod(t2, z1, t1, keyLength); // t2=t1*z1 multiprecision_mersenns_mult_mod(t1, x2, t1, keyLength); // t1=t1*x2 multiprecision_mersenns_mult_mod(t2, y2, t2, keyLength); // t2=t2*y2 multiprecision_mersenns_squa_mod(t1, z1); // t1=z1^2 multiprecision_mersenns_mult_mod(t2, z1, t1); // t2=t1*z1 multiprecision_mersenns_mult_mod(t1, x2, t1); // t1=t1*x2 multiprecision_mersenns_mult_mod(t2, y2, t2); // t2=t2*y2 multiprecision_sub_mod(t1, t1, x1, keyLength); // t1=t1-x1 multiprecision_sub_mod(t2, t2, y1, keyLength); // t2=t2-y1 multiprecision_sub_mod(t1, t1, x1); // t1=t1-x1 multiprecision_sub_mod(t2, t2, y1); // t2=t2-y1 if (multiprecision_iszero(t1, keyLength)) { if (multiprecision_iszero(t2, keyLength)) { ECC_Double(r, q, keyLength); if (multiprecision_iszero(t1)) { if (multiprecision_iszero(t2)) { ECC_Double(r, q); return; } else { multiprecision_init(z3, keyLength); multiprecision_init(z3); return; // return infinity } } multiprecision_mersenns_mult_mod(z3, z1, t1, keyLength); // z3=z1*t1 multiprecision_mersenns_squa_mod(y3, t1, keyLength); // t3=t1^2 multiprecision_mersenns_mult_mod(z1, y3, t1, keyLength); // t4=t3*t1 multiprecision_mersenns_mult_mod(y3, y3, x1, keyLength); // t3=t3*x1 multiprecision_lshift_mod(t1, y3, keyLength); // t1=2*t3 multiprecision_mersenns_squa_mod(x3, t2, keyLength); // x3=t2^2 multiprecision_sub_mod(x3, x3, t1, keyLength); // x3=x3-t1 multiprecision_sub_mod(x3, x3, z1, keyLength); // x3=x3-t4 multiprecision_sub_mod(y3, y3, x3, keyLength); // t3=t3-x3 multiprecision_mersenns_mult_mod(y3, y3, t2, keyLength); // t3=t3*t2 multiprecision_mersenns_mult_mod(z1, z1, y1, keyLength); // t4=t4*t1 multiprecision_sub_mod(y3, y3, z1, keyLength); multiprecision_mersenns_mult_mod(z3, z1, t1); // z3=z1*t1 multiprecision_mersenns_squa_mod(y3, t1); // t3=t1^2 multiprecision_mersenns_mult_mod(z1, y3, t1); // t4=t3*t1 multiprecision_mersenns_mult_mod(y3, y3, x1); // t3=t3*x1 multiprecision_lshift_mod(t1, y3); // t1=2*t3 multiprecision_mersenns_squa_mod(x3, t2); // x3=t2^2 multiprecision_sub_mod(x3, x3, t1); // x3=x3-t1 multiprecision_sub_mod(x3, x3, z1); // x3=x3-t4 multiprecision_sub_mod(y3, y3, x3); // t3=t3-x3 multiprecision_mersenns_mult_mod(y3, y3, t2); // t3=t3*t2 multiprecision_mersenns_mult_mod(z1, z1, y1); // t4=t4*t1 multiprecision_sub_mod(y3, y3, z1); } // Computing the Non-Adjacent Form of a positive integer static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k, uint32_t keyLength) { static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k) { uint32_t sign; int i = 0; int j; uint32_t var; while ((var = multiprecision_most_signbits(k, keyLength)) >= 1) { while ((var = multiprecision_most_signbits(k)) >= 1) { if (k[0] & 0x01) // k is odd { sign = (k[0] & 0x03); // 1 or 3 Loading @@ -183,7 +182,7 @@ static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k, } else sign = 0; multiprecision_rshift(k, k, keyLength); multiprecision_rshift(k, k); naf[i / 4] |= (sign) << ((i % 4) * 2); i++; } Loading @@ -192,8 +191,7 @@ static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k, } // Binary Non-Adjacent Form for point multiplication void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n, uint32_t keyLength) { void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n) { uint32_t sign; uint8_t naf[256 / 4 + 1]; uint32_t NumNaf; Loading @@ -201,69 +199,64 @@ void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n, Point r; uint32_t* modp; if (keyLength == KEY_LENGTH_DWORDS_P256) { modp = curve_p256.p; } else { modp = curve.p; } p_256_init_point(&r); multiprecision_init(p->z, keyLength); multiprecision_init(p->z); p->z[0] = 1; // initialization p_256_init_point(q); // -p multiprecision_copy(minus_p.x, p->x, keyLength); multiprecision_sub(minus_p.y, modp, p->y, keyLength); multiprecision_copy(minus_p.x, p->x); multiprecision_sub(minus_p.y, modp, p->y); multiprecision_init(minus_p.z, keyLength); multiprecision_init(minus_p.z); minus_p.z[0] = 1; // NAF memset(naf, 0, sizeof(naf)); ECC_NAF(naf, &NumNaf, n, keyLength); ECC_NAF(naf, &NumNaf, n); for (int i = NumNaf - 1; i >= 0; i--) { p_256_copy_point(&r, q); ECC_Double(q, &r, keyLength); ECC_Double(q, &r); sign = (naf[i / 4] >> ((i % 4) * 2)) & 0x03; if (sign == 1) { p_256_copy_point(&r, q); ECC_Add(q, &r, p, keyLength); ECC_Add(q, &r, p); } else if (sign == 3) { p_256_copy_point(&r, q); ECC_Add(q, &r, &minus_p, keyLength); ECC_Add(q, &r, &minus_p); } } multiprecision_inv_mod(minus_p.x, q->z, keyLength); multiprecision_mersenns_squa_mod(q->z, minus_p.x, keyLength); multiprecision_mersenns_mult_mod(q->x, q->x, q->z, keyLength); multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x, keyLength); multiprecision_mersenns_mult_mod(q->y, q->y, q->z, keyLength); multiprecision_inv_mod(minus_p.x, q->z); multiprecision_mersenns_squa_mod(q->z, minus_p.x); multiprecision_mersenns_mult_mod(q->x, q->x, q->z); multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x); multiprecision_mersenns_mult_mod(q->y, q->y, q->z); } bool ECC_ValidatePoint(const Point& pt) { const size_t kl = KEY_LENGTH_DWORDS_P256; p_256_init_curve(kl); p_256_init_curve(); // Ensure y^2 = x^3 + a*x + b (mod p); a = -3 // y^2 mod p uint32_t y2_mod[kl] = {0}; multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y, kl); uint32_t y2_mod[KEY_LENGTH_DWORDS_P256] = {0}; multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y); // Right hand side calculation uint32_t rhs[kl] = {0}; multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x, kl); uint32_t three[kl] = {0}; uint32_t rhs[KEY_LENGTH_DWORDS_P256] = {0}; multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x); uint32_t three[KEY_LENGTH_DWORDS_P256] = {0}; three[0] = 3; multiprecision_sub_mod(rhs, rhs, three, kl); multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x, kl); multiprecision_add_mod(rhs, rhs, curve_p256.b, kl); multiprecision_sub_mod(rhs, rhs, three); multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x); multiprecision_add_mod(rhs, rhs, curve_p256.b); return multiprecision_compare(rhs, y2_mod, kl) == 0; return multiprecision_compare(rhs, y2_mod) == 0; }
system/stack/smp/p_256_ecc_pp.h +3 −4 Original line number Diff line number Diff line Loading @@ -58,9 +58,8 @@ extern elliptic_curve_t curve_p256; bool ECC_ValidatePoint(const Point& p); void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n, uint32_t keyLength); void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n); #define ECC_PointMult(q, p, n, keyLength) \ ECC_PointMult_Bin_NAF(q, p, n, keyLength) #define ECC_PointMult(q, p, n) ECC_PointMult_Bin_NAF(q, p, n) void p_256_init_curve(uint32_t keyLength); void p_256_init_curve();
system/stack/smp/p_256_multprecision.cc +73 −183 Original line number Diff line number Diff line Loading @@ -27,24 +27,24 @@ #include "bt_target.h" #include "p_256_ecc_pp.h" void multiprecision_init(uint32_t* c, uint32_t keyLength) { for (uint32_t i = 0; i < keyLength; i++) c[i] = 0; void multiprecision_init(uint32_t* c) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) c[i] = 0; } void multiprecision_copy(uint32_t* c, uint32_t* a, uint32_t keyLength) { for (uint32_t i = 0; i < keyLength; i++) c[i] = a[i]; void multiprecision_copy(uint32_t* c, uint32_t* a) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) c[i] = a[i]; } int multiprecision_compare(uint32_t* a, uint32_t* b, uint32_t keyLength) { for (int i = keyLength - 1; i >= 0; i--) { int multiprecision_compare(uint32_t* a, uint32_t* b) { for (int i = KEY_LENGTH_DWORDS_P256 - 1; i >= 0; i--) { if (a[i] > b[i]) return 1; if (a[i] < b[i]) return -1; } return 0; } int multiprecision_iszero(uint32_t* a, uint32_t keyLength) { for (uint32_t i = 0; i < keyLength; i++) int multiprecision_iszero(uint32_t* a) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) if (a[i]) return 0; return 1; Loading @@ -58,30 +58,29 @@ uint32_t multiprecision_dword_bits(uint32_t a) { return i; } uint32_t multiprecision_most_signdwords(uint32_t* a, uint32_t keyLength) { uint32_t multiprecision_most_signdwords(uint32_t* a) { int i; for (i = keyLength - 1; i >= 0; i--) for (i = KEY_LENGTH_DWORDS_P256 - 1; i >= 0; i--) if (a[i]) break; return (i + 1); } uint32_t multiprecision_most_signbits(uint32_t* a, uint32_t keyLength) { uint32_t multiprecision_most_signbits(uint32_t* a) { int aMostSignDWORDs; aMostSignDWORDs = multiprecision_most_signdwords(a, keyLength); aMostSignDWORDs = multiprecision_most_signdwords(a); if (aMostSignDWORDs == 0) return 0; return (((aMostSignDWORDs - 1) << DWORD_BITS_SHIFT) + multiprecision_dword_bits(a[aMostSignDWORDs - 1])); } uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b, uint32_t keyLength) { uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t carrier; uint32_t temp; carrier = 0; for (uint32_t i = 0; i < keyLength; i++) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) { temp = a[i] + carrier; carrier = (temp < carrier); temp += b[i]; Loading @@ -93,13 +92,12 @@ uint32_t multiprecision_add(uint32_t* c, uint32_t* a, uint32_t* b, } // c=a-b uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b, uint32_t keyLength) { uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t borrow; uint32_t temp; borrow = 0; for (uint32_t i = 0; i < keyLength; i++) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) { temp = a[i] - borrow; borrow = (temp > a[i]); c[i] = temp - b[i]; Loading @@ -110,27 +108,20 @@ uint32_t multiprecision_sub(uint32_t* c, uint32_t* a, uint32_t* b, } // c = a << 1 void multiprecision_lshift_mod(uint32_t* c, uint32_t* a, uint32_t keyLength) { void multiprecision_lshift_mod(uint32_t* c, uint32_t* a) { uint32_t carrier; uint32_t* modp; if (keyLength == KEY_LENGTH_DWORDS_P192) { modp = curve.p; } else if (keyLength == KEY_LENGTH_DWORDS_P256) { modp = curve_p256.p; } else return; uint32_t* modp = curve_p256.p; carrier = multiprecision_lshift(c, a, keyLength); carrier = multiprecision_lshift(c, a); if (carrier) { multiprecision_sub(c, c, modp, keyLength); } else if (multiprecision_compare(c, modp, keyLength) >= 0) { multiprecision_sub(c, c, modp, keyLength); multiprecision_sub(c, c, modp); } else if (multiprecision_compare(c, modp) >= 0) { multiprecision_sub(c, c, modp); } } // c=a>>1 void multiprecision_rshift(uint32_t* c, uint32_t* a, uint32_t keyLength) { void multiprecision_rshift(uint32_t* c, uint32_t* a) { int j; uint32_t b = 1; Loading @@ -138,7 +129,7 @@ void multiprecision_rshift(uint32_t* c, uint32_t* a, uint32_t keyLength) { uint32_t carrier = 0; uint32_t temp; for (int i = keyLength - 1; i >= 0; i--) { for (int i = KEY_LENGTH_DWORDS_P256 - 1; i >= 0; i--) { temp = a[i]; // in case of c==a c[i] = (temp >> b) | carrier; carrier = temp << j; Loading @@ -147,64 +138,42 @@ void multiprecision_rshift(uint32_t* c, uint32_t* a, uint32_t keyLength) { // Curve specific optimization when p is a pseudo-Mersenns prime, // p=2^(KEY_LENGTH_BITS)-omega void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b, uint32_t keyLength) { void multiprecision_mersenns_mult_mod(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t cc[2 * KEY_LENGTH_DWORDS_P256]; multiprecision_mult(cc, a, b, keyLength); if (keyLength == 6) { multiprecision_fast_mod(c, cc); } else if (keyLength == 8) { multiprecision_mult(cc, a, b); multiprecision_fast_mod_P256(c, cc); } } // Curve specific optimization when p is a pseudo-Mersenns prime void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a, uint32_t keyLength) { multiprecision_mersenns_mult_mod(c, a, a, keyLength); void multiprecision_mersenns_squa_mod(uint32_t* c, uint32_t* a) { multiprecision_mersenns_mult_mod(c, a, a); } // c=(a+b) mod p, b<p, a<p void multiprecision_add_mod(uint32_t* c, uint32_t* a, uint32_t* b, uint32_t keyLength) { void multiprecision_add_mod(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t carrier; uint32_t* modp; if (keyLength == KEY_LENGTH_DWORDS_P192) { modp = curve.p; } else if (keyLength == KEY_LENGTH_DWORDS_P256) { modp = curve_p256.p; } else return; uint32_t* modp = curve_p256.p; carrier = multiprecision_add(c, a, b, keyLength); carrier = multiprecision_add(c, a, b); if (carrier) { multiprecision_sub(c, c, modp, keyLength); } else if (multiprecision_compare(c, modp, keyLength) >= 0) { multiprecision_sub(c, c, modp, keyLength); multiprecision_sub(c, c, modp); } else if (multiprecision_compare(c, modp) >= 0) { multiprecision_sub(c, c, modp); } } // c=(a-b) mod p, a<p, b<p void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b, uint32_t keyLength) { void multiprecision_sub_mod(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t borrow; uint32_t* modp; if (keyLength == KEY_LENGTH_DWORDS_P192) { modp = curve.p; } else if (keyLength == KEY_LENGTH_DWORDS_P256) { modp = curve_p256.p; } else return; uint32_t* modp = curve_p256.p; borrow = multiprecision_sub(c, a, b, keyLength); if (borrow) multiprecision_add(c, c, modp, keyLength); borrow = multiprecision_sub(c, a, b); if (borrow) multiprecision_add(c, c, modp); } // c=a<<b, b<DWORD_BITS, c has a buffer size of Numuint32_ts+1 uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a, uint32_t keyLength) { uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a) { int j; uint32_t b = 1; j = DWORD_BITS - b; Loading @@ -212,7 +181,7 @@ uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a, uint32_t keyLength) { uint32_t carrier = 0; uint32_t temp; for (uint32_t i = 0; i < keyLength; i++) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) { temp = a[i]; // in case c==a c[i] = (temp << b) | carrier; carrier = temp >> j; Loading @@ -222,19 +191,18 @@ uint32_t multiprecision_lshift(uint32_t* c, uint32_t* a, uint32_t keyLength) { } // c=a*b; c must have a buffer of 2*Key_LENGTH_uint32_tS, c != a != b void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b, uint32_t keyLength) { void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b) { uint32_t W; uint32_t U; uint32_t V; U = V = W = 0; multiprecision_init(c, keyLength); multiprecision_init(c); // assume little endian right now for (uint32_t i = 0; i < keyLength; i++) { for (uint32_t i = 0; i < KEY_LENGTH_DWORDS_P256; i++) { U = 0; for (uint32_t j = 0; j < keyLength; j++) { for (uint32_t j = 0; j < KEY_LENGTH_DWORDS_P256; j++) { uint64_t result; result = ((uint64_t)a[i]) * ((uint64_t)b[j]); W = result >> 32; Loading @@ -246,78 +214,7 @@ void multiprecision_mult(uint32_t* c, uint32_t* a, uint32_t* b, U += (V < c[i + j]); c[i + j] = V; } c[i + keyLength] = U; } } void multiprecision_fast_mod(uint32_t* c, uint32_t* a) { uint32_t U; uint32_t V; uint32_t* modp = curve.p; c[0] = a[0] + a[6]; U = c[0] < a[0]; c[0] += a[10]; U += c[0] < a[10]; c[1] = a[1] + U; U = c[1] < a[1]; c[1] += a[7]; U += c[1] < a[7]; c[1] += a[11]; U += c[1] < a[11]; c[2] = a[2] + U; U = c[2] < a[2]; c[2] += a[6]; U += c[2] < a[6]; c[2] += a[8]; U += c[2] < a[8]; c[2] += a[10]; U += c[2] < a[10]; c[3] = a[3] + U; U = c[3] < a[3]; c[3] += a[7]; U += c[3] < a[7]; c[3] += a[9]; U += c[3] < a[9]; c[3] += a[11]; U += c[3] < a[11]; c[4] = a[4] + U; U = c[4] < a[4]; c[4] += a[8]; U += c[4] < a[8]; c[4] += a[10]; U += c[4] < a[10]; c[5] = a[5] + U; U = c[5] < a[5]; c[5] += a[9]; U += c[5] < a[9]; c[5] += a[11]; U += c[5] < a[11]; c[0] += U; V = c[0] < U; c[1] += V; V = c[1] < V; c[2] += V; V = c[2] < V; c[2] += U; V = c[2] < U; c[3] += V; V = c[3] < V; c[4] += V; V = c[4] < V; c[5] += V; V = c[5] < V; if (V) { multiprecision_sub(c, c, modp, KEY_LENGTH_DWORDS_P192); } else if (multiprecision_compare(c, modp, KEY_LENGTH_DWORDS_P192) >= 0) { multiprecision_sub(c, c, modp, KEY_LENGTH_DWORDS_P192); c[i + KEY_LENGTH_DWORDS_P256] = U; } } Loading Loading @@ -541,74 +438,67 @@ void multiprecision_fast_mod_P256(uint32_t* c, uint32_t* a) { if (U & 0x80000000) { while (U) { multiprecision_add(c, c, modp, KEY_LENGTH_DWORDS_P256); multiprecision_add(c, c, modp); U++; } } else if (U) { while (U) { multiprecision_sub(c, c, modp, KEY_LENGTH_DWORDS_P256); multiprecision_sub(c, c, modp); U--; } } if (multiprecision_compare(c, modp, KEY_LENGTH_DWORDS_P256) >= 0) multiprecision_sub(c, c, modp, KEY_LENGTH_DWORDS_P256); if (multiprecision_compare(c, modp) >= 0) multiprecision_sub(c, c, modp); } void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u, uint32_t keyLength) { void multiprecision_inv_mod(uint32_t* aminus, uint32_t* u) { uint32_t v[KEY_LENGTH_DWORDS_P256]; uint32_t A[KEY_LENGTH_DWORDS_P256 + 1]; uint32_t C[KEY_LENGTH_DWORDS_P256 + 1]; uint32_t* modp; if (keyLength == KEY_LENGTH_DWORDS_P256) { modp = curve_p256.p; } else { modp = curve.p; } uint32_t* modp = curve_p256.p; multiprecision_copy(v, modp, keyLength); multiprecision_init(A, keyLength); multiprecision_init(C, keyLength); multiprecision_copy(v, modp); multiprecision_init(A); multiprecision_init(C); A[0] = 1; while (!multiprecision_iszero(u, keyLength)) { while (!multiprecision_iszero(u)) { while (!(u[0] & 0x01)) // u is even { multiprecision_rshift(u, u, keyLength); multiprecision_rshift(u, u); if (!(A[0] & 0x01)) // A is even multiprecision_rshift(A, A, keyLength); multiprecision_rshift(A, A); else { A[keyLength] = multiprecision_add(A, A, modp, keyLength); // A =A+p multiprecision_rshift(A, A, keyLength); A[keyLength - 1] |= (A[keyLength] << 31); A[KEY_LENGTH_DWORDS_P256] = multiprecision_add(A, A, modp); // A =A+p multiprecision_rshift(A, A); A[KEY_LENGTH_DWORDS_P256 - 1] |= (A[KEY_LENGTH_DWORDS_P256] << 31); } } while (!(v[0] & 0x01)) // v is even { multiprecision_rshift(v, v, keyLength); multiprecision_rshift(v, v); if (!(C[0] & 0x01)) // C is even { multiprecision_rshift(C, C, keyLength); multiprecision_rshift(C, C); } else { C[keyLength] = multiprecision_add(C, C, modp, keyLength); // C =C+p multiprecision_rshift(C, C, keyLength); C[keyLength - 1] |= (C[keyLength] << 31); C[KEY_LENGTH_DWORDS_P256] = multiprecision_add(C, C, modp); // C =C+p multiprecision_rshift(C, C); C[KEY_LENGTH_DWORDS_P256 - 1] |= (C[KEY_LENGTH_DWORDS_P256] << 31); } } if (multiprecision_compare(u, v, keyLength) >= 0) { multiprecision_sub(u, u, v, keyLength); multiprecision_sub_mod(A, A, C, keyLength); if (multiprecision_compare(u, v) >= 0) { multiprecision_sub(u, u, v); multiprecision_sub_mod(A, A, C); } else { multiprecision_sub(v, v, u, keyLength); multiprecision_sub_mod(C, C, A, keyLength); multiprecision_sub(v, v, u); multiprecision_sub_mod(C, C, A); } } if (multiprecision_compare(C, modp, keyLength) >= 0) multiprecision_sub(aminus, C, modp, keyLength); if (multiprecision_compare(C, modp) >= 0) multiprecision_sub(aminus, C, modp); else multiprecision_copy(aminus, C, keyLength); multiprecision_copy(aminus, C); }
system/stack/smp/p_256_multprecision.h +22 −33 File changed.Preview size limit exceeded, changes collapsed. Show changes