micro-ECC for mbed, ported from GCC version from Github,
Dependents: mbed_microECC Wallet_v1
curve-specific.h@0:b6fdeddc0bc9, 2017-09-07 (annotated)
- Committer:
- allankliu
- Date:
- Thu Sep 07 12:10:11 2017 +0000
- Revision:
- 0:b6fdeddc0bc9
Init version, ported from GCC version of uECC of Github. Assembly optimization for thumb2 is disabled.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
allankliu | 0:b6fdeddc0bc9 | 1 | /* Copyright 2015, Kenneth MacKay. Licensed under the BSD 2-clause license. */ |
allankliu | 0:b6fdeddc0bc9 | 2 | |
allankliu | 0:b6fdeddc0bc9 | 3 | #ifndef _UECC_CURVE_SPECIFIC_H_ |
allankliu | 0:b6fdeddc0bc9 | 4 | #define _UECC_CURVE_SPECIFIC_H_ |
allankliu | 0:b6fdeddc0bc9 | 5 | |
allankliu | 0:b6fdeddc0bc9 | 6 | #define num_bytes_secp160r1 20 |
allankliu | 0:b6fdeddc0bc9 | 7 | #define num_bytes_secp192r1 24 |
allankliu | 0:b6fdeddc0bc9 | 8 | #define num_bytes_secp224r1 28 |
allankliu | 0:b6fdeddc0bc9 | 9 | #define num_bytes_secp256r1 32 |
allankliu | 0:b6fdeddc0bc9 | 10 | #define num_bytes_secp256k1 32 |
allankliu | 0:b6fdeddc0bc9 | 11 | |
allankliu | 0:b6fdeddc0bc9 | 12 | #if (uECC_WORD_SIZE == 1) |
allankliu | 0:b6fdeddc0bc9 | 13 | |
allankliu | 0:b6fdeddc0bc9 | 14 | #define num_words_secp160r1 20 |
allankliu | 0:b6fdeddc0bc9 | 15 | #define num_words_secp192r1 24 |
allankliu | 0:b6fdeddc0bc9 | 16 | #define num_words_secp224r1 28 |
allankliu | 0:b6fdeddc0bc9 | 17 | #define num_words_secp256r1 32 |
allankliu | 0:b6fdeddc0bc9 | 18 | #define num_words_secp256k1 32 |
allankliu | 0:b6fdeddc0bc9 | 19 | |
allankliu | 0:b6fdeddc0bc9 | 20 | #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) \ |
allankliu | 0:b6fdeddc0bc9 | 21 | 0x##a, 0x##b, 0x##c, 0x##d, 0x##e, 0x##f, 0x##g, 0x##h |
allankliu | 0:b6fdeddc0bc9 | 22 | #define BYTES_TO_WORDS_4(a, b, c, d) 0x##a, 0x##b, 0x##c, 0x##d |
allankliu | 0:b6fdeddc0bc9 | 23 | |
allankliu | 0:b6fdeddc0bc9 | 24 | #elif (uECC_WORD_SIZE == 4) |
allankliu | 0:b6fdeddc0bc9 | 25 | |
allankliu | 0:b6fdeddc0bc9 | 26 | #define num_words_secp160r1 5 |
allankliu | 0:b6fdeddc0bc9 | 27 | #define num_words_secp192r1 6 |
allankliu | 0:b6fdeddc0bc9 | 28 | #define num_words_secp224r1 7 |
allankliu | 0:b6fdeddc0bc9 | 29 | #define num_words_secp256r1 8 |
allankliu | 0:b6fdeddc0bc9 | 30 | #define num_words_secp256k1 8 |
allankliu | 0:b6fdeddc0bc9 | 31 | |
allankliu | 0:b6fdeddc0bc9 | 32 | #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##d##c##b##a, 0x##h##g##f##e |
allankliu | 0:b6fdeddc0bc9 | 33 | #define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a |
allankliu | 0:b6fdeddc0bc9 | 34 | |
allankliu | 0:b6fdeddc0bc9 | 35 | #elif (uECC_WORD_SIZE == 8) |
allankliu | 0:b6fdeddc0bc9 | 36 | |
allankliu | 0:b6fdeddc0bc9 | 37 | #define num_words_secp160r1 3 |
allankliu | 0:b6fdeddc0bc9 | 38 | #define num_words_secp192r1 3 |
allankliu | 0:b6fdeddc0bc9 | 39 | #define num_words_secp224r1 4 |
allankliu | 0:b6fdeddc0bc9 | 40 | #define num_words_secp256r1 4 |
allankliu | 0:b6fdeddc0bc9 | 41 | #define num_words_secp256k1 4 |
allankliu | 0:b6fdeddc0bc9 | 42 | |
allankliu | 0:b6fdeddc0bc9 | 43 | #define BYTES_TO_WORDS_8(a, b, c, d, e, f, g, h) 0x##h##g##f##e##d##c##b##a##ull |
allankliu | 0:b6fdeddc0bc9 | 44 | #define BYTES_TO_WORDS_4(a, b, c, d) 0x##d##c##b##a##ull |
allankliu | 0:b6fdeddc0bc9 | 45 | |
allankliu | 0:b6fdeddc0bc9 | 46 | #endif /* uECC_WORD_SIZE */ |
allankliu | 0:b6fdeddc0bc9 | 47 | |
allankliu | 0:b6fdeddc0bc9 | 48 | #if uECC_SUPPORTS_secp160r1 || uECC_SUPPORTS_secp192r1 || \ |
allankliu | 0:b6fdeddc0bc9 | 49 | uECC_SUPPORTS_secp224r1 || uECC_SUPPORTS_secp256r1 |
allankliu | 0:b6fdeddc0bc9 | 50 | static void double_jacobian_default(uECC_word_t * X1, |
allankliu | 0:b6fdeddc0bc9 | 51 | uECC_word_t * Y1, |
allankliu | 0:b6fdeddc0bc9 | 52 | uECC_word_t * Z1, |
allankliu | 0:b6fdeddc0bc9 | 53 | uECC_Curve curve) { |
allankliu | 0:b6fdeddc0bc9 | 54 | /* t1 = X, t2 = Y, t3 = Z */ |
allankliu | 0:b6fdeddc0bc9 | 55 | uECC_word_t t4[uECC_MAX_WORDS]; |
allankliu | 0:b6fdeddc0bc9 | 56 | uECC_word_t t5[uECC_MAX_WORDS]; |
allankliu | 0:b6fdeddc0bc9 | 57 | wordcount_t num_words = curve->num_words; |
allankliu | 0:b6fdeddc0bc9 | 58 | |
allankliu | 0:b6fdeddc0bc9 | 59 | if (uECC_vli_isZero(Z1, num_words)) { |
allankliu | 0:b6fdeddc0bc9 | 60 | return; |
allankliu | 0:b6fdeddc0bc9 | 61 | } |
allankliu | 0:b6fdeddc0bc9 | 62 | |
allankliu | 0:b6fdeddc0bc9 | 63 | uECC_vli_modSquare_fast(t4, Y1, curve); /* t4 = y1^2 */ |
allankliu | 0:b6fdeddc0bc9 | 64 | uECC_vli_modMult_fast(t5, X1, t4, curve); /* t5 = x1*y1^2 = A */ |
allankliu | 0:b6fdeddc0bc9 | 65 | uECC_vli_modSquare_fast(t4, t4, curve); /* t4 = y1^4 */ |
allankliu | 0:b6fdeddc0bc9 | 66 | uECC_vli_modMult_fast(Y1, Y1, Z1, curve); /* t2 = y1*z1 = z3 */ |
allankliu | 0:b6fdeddc0bc9 | 67 | uECC_vli_modSquare_fast(Z1, Z1, curve); /* t3 = z1^2 */ |
allankliu | 0:b6fdeddc0bc9 | 68 | |
allankliu | 0:b6fdeddc0bc9 | 69 | uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = x1 + z1^2 */ |
allankliu | 0:b6fdeddc0bc9 | 70 | uECC_vli_modAdd(Z1, Z1, Z1, curve->p, num_words); /* t3 = 2*z1^2 */ |
allankliu | 0:b6fdeddc0bc9 | 71 | uECC_vli_modSub(Z1, X1, Z1, curve->p, num_words); /* t3 = x1 - z1^2 */ |
allankliu | 0:b6fdeddc0bc9 | 72 | uECC_vli_modMult_fast(X1, X1, Z1, curve); /* t1 = x1^2 - z1^4 */ |
allankliu | 0:b6fdeddc0bc9 | 73 | |
allankliu | 0:b6fdeddc0bc9 | 74 | uECC_vli_modAdd(Z1, X1, X1, curve->p, num_words); /* t3 = 2*(x1^2 - z1^4) */ |
allankliu | 0:b6fdeddc0bc9 | 75 | uECC_vli_modAdd(X1, X1, Z1, curve->p, num_words); /* t1 = 3*(x1^2 - z1^4) */ |
allankliu | 0:b6fdeddc0bc9 | 76 | if (uECC_vli_testBit(X1, 0)) { |
allankliu | 0:b6fdeddc0bc9 | 77 | uECC_word_t l_carry = uECC_vli_add(X1, X1, curve->p, num_words); |
allankliu | 0:b6fdeddc0bc9 | 78 | uECC_vli_rshift1(X1, num_words); |
allankliu | 0:b6fdeddc0bc9 | 79 | X1[num_words - 1] |= l_carry << (uECC_WORD_BITS - 1); |
allankliu | 0:b6fdeddc0bc9 | 80 | } else { |
allankliu | 0:b6fdeddc0bc9 | 81 | uECC_vli_rshift1(X1, num_words); |
allankliu | 0:b6fdeddc0bc9 | 82 | } |
allankliu | 0:b6fdeddc0bc9 | 83 | /* t1 = 3/2*(x1^2 - z1^4) = B */ |
allankliu | 0:b6fdeddc0bc9 | 84 | |
allankliu | 0:b6fdeddc0bc9 | 85 | uECC_vli_modSquare_fast(Z1, X1, curve); /* t3 = B^2 */ |
allankliu | 0:b6fdeddc0bc9 | 86 | uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - A */ |
allankliu | 0:b6fdeddc0bc9 | 87 | uECC_vli_modSub(Z1, Z1, t5, curve->p, num_words); /* t3 = B^2 - 2A = x3 */ |
allankliu | 0:b6fdeddc0bc9 | 88 | uECC_vli_modSub(t5, t5, Z1, curve->p, num_words); /* t5 = A - x3 */ |
allankliu | 0:b6fdeddc0bc9 | 89 | uECC_vli_modMult_fast(X1, X1, t5, curve); /* t1 = B * (A - x3) */ |
allankliu | 0:b6fdeddc0bc9 | 90 | uECC_vli_modSub(t4, X1, t4, curve->p, num_words); /* t4 = B * (A - x3) - y1^4 = y3 */ |
allankliu | 0:b6fdeddc0bc9 | 91 | |
allankliu | 0:b6fdeddc0bc9 | 92 | uECC_vli_set(X1, Z1, num_words); |
allankliu | 0:b6fdeddc0bc9 | 93 | uECC_vli_set(Z1, Y1, num_words); |
allankliu | 0:b6fdeddc0bc9 | 94 | uECC_vli_set(Y1, t4, num_words); |
allankliu | 0:b6fdeddc0bc9 | 95 | } |
allankliu | 0:b6fdeddc0bc9 | 96 | |
allankliu | 0:b6fdeddc0bc9 | 97 | /* Computes result = x^3 + ax + b. result must not overlap x. */ |
allankliu | 0:b6fdeddc0bc9 | 98 | static void x_side_default(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) { |
allankliu | 0:b6fdeddc0bc9 | 99 | uECC_word_t _3[uECC_MAX_WORDS] = {3}; /* -a = 3 */ |
allankliu | 0:b6fdeddc0bc9 | 100 | wordcount_t num_words = curve->num_words; |
allankliu | 0:b6fdeddc0bc9 | 101 | |
allankliu | 0:b6fdeddc0bc9 | 102 | uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ |
allankliu | 0:b6fdeddc0bc9 | 103 | uECC_vli_modSub(result, result, _3, curve->p, num_words); /* r = x^2 - 3 */ |
allankliu | 0:b6fdeddc0bc9 | 104 | uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 - 3x */ |
allankliu | 0:b6fdeddc0bc9 | 105 | uECC_vli_modAdd(result, result, curve->b, curve->p, num_words); /* r = x^3 - 3x + b */ |
allankliu | 0:b6fdeddc0bc9 | 106 | } |
allankliu | 0:b6fdeddc0bc9 | 107 | #endif /* uECC_SUPPORTS_secp... */ |
allankliu | 0:b6fdeddc0bc9 | 108 | |
allankliu | 0:b6fdeddc0bc9 | 109 | #if uECC_SUPPORT_COMPRESSED_POINT |
allankliu | 0:b6fdeddc0bc9 | 110 | #if uECC_SUPPORTS_secp160r1 || uECC_SUPPORTS_secp192r1 || \ |
allankliu | 0:b6fdeddc0bc9 | 111 | uECC_SUPPORTS_secp256r1 || uECC_SUPPORTS_secp256k1 |
allankliu | 0:b6fdeddc0bc9 | 112 | /* Compute a = sqrt(a) (mod curve_p). */ |
allankliu | 0:b6fdeddc0bc9 | 113 | static void mod_sqrt_default(uECC_word_t *a, uECC_Curve curve) { |
allankliu | 0:b6fdeddc0bc9 | 114 | bitcount_t i; |
allankliu | 0:b6fdeddc0bc9 | 115 | uECC_word_t p1[uECC_MAX_WORDS] = {1}; |
allankliu | 0:b6fdeddc0bc9 | 116 | uECC_word_t l_result[uECC_MAX_WORDS] = {1}; |
allankliu | 0:b6fdeddc0bc9 | 117 | wordcount_t num_words = curve->num_words; |
allankliu | 0:b6fdeddc0bc9 | 118 | |
allankliu | 0:b6fdeddc0bc9 | 119 | /* When curve->p == 3 (mod 4), we can compute |
allankliu | 0:b6fdeddc0bc9 | 120 | sqrt(a) = a^((curve->p + 1) / 4) (mod curve->p). */ |
allankliu | 0:b6fdeddc0bc9 | 121 | uECC_vli_add(p1, curve->p, p1, num_words); /* p1 = curve_p + 1 */ |
allankliu | 0:b6fdeddc0bc9 | 122 | for (i = uECC_vli_numBits(p1, num_words) - 1; i > 1; --i) { |
allankliu | 0:b6fdeddc0bc9 | 123 | uECC_vli_modSquare_fast(l_result, l_result, curve); |
allankliu | 0:b6fdeddc0bc9 | 124 | if (uECC_vli_testBit(p1, i)) { |
allankliu | 0:b6fdeddc0bc9 | 125 | uECC_vli_modMult_fast(l_result, l_result, a, curve); |
allankliu | 0:b6fdeddc0bc9 | 126 | } |
allankliu | 0:b6fdeddc0bc9 | 127 | } |
allankliu | 0:b6fdeddc0bc9 | 128 | uECC_vli_set(a, l_result, num_words); |
allankliu | 0:b6fdeddc0bc9 | 129 | } |
allankliu | 0:b6fdeddc0bc9 | 130 | #endif /* uECC_SUPPORTS_secp... */ |
allankliu | 0:b6fdeddc0bc9 | 131 | #endif /* uECC_SUPPORT_COMPRESSED_POINT */ |
allankliu | 0:b6fdeddc0bc9 | 132 | |
allankliu | 0:b6fdeddc0bc9 | 133 | #if uECC_SUPPORTS_secp160r1 |
allankliu | 0:b6fdeddc0bc9 | 134 | |
allankliu | 0:b6fdeddc0bc9 | 135 | #if (uECC_OPTIMIZATION_LEVEL > 0) |
allankliu | 0:b6fdeddc0bc9 | 136 | static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product); |
allankliu | 0:b6fdeddc0bc9 | 137 | #endif |
allankliu | 0:b6fdeddc0bc9 | 138 | |
allankliu | 0:b6fdeddc0bc9 | 139 | static const struct uECC_Curve_t curve_secp160r1 = { |
allankliu | 0:b6fdeddc0bc9 | 140 | num_words_secp160r1, |
allankliu | 0:b6fdeddc0bc9 | 141 | num_bytes_secp160r1, |
allankliu | 0:b6fdeddc0bc9 | 142 | 161, /* num_n_bits */ |
allankliu | 0:b6fdeddc0bc9 | 143 | { BYTES_TO_WORDS_8(FF, FF, FF, 7F, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 144 | BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 145 | BYTES_TO_WORDS_4(FF, FF, FF, FF) }, |
allankliu | 0:b6fdeddc0bc9 | 146 | { BYTES_TO_WORDS_8(57, 22, 75, CA, D3, AE, 27, F9), |
allankliu | 0:b6fdeddc0bc9 | 147 | BYTES_TO_WORDS_8(C8, F4, 01, 00, 00, 00, 00, 00), |
allankliu | 0:b6fdeddc0bc9 | 148 | BYTES_TO_WORDS_8(00, 00, 00, 00, 01, 00, 00, 00) }, |
allankliu | 0:b6fdeddc0bc9 | 149 | { BYTES_TO_WORDS_8(82, FC, CB, 13, B9, 8B, C3, 68), |
allankliu | 0:b6fdeddc0bc9 | 150 | BYTES_TO_WORDS_8(89, 69, 64, 46, 28, 73, F5, 8E), |
allankliu | 0:b6fdeddc0bc9 | 151 | BYTES_TO_WORDS_4(68, B5, 96, 4A), |
allankliu | 0:b6fdeddc0bc9 | 152 | |
allankliu | 0:b6fdeddc0bc9 | 153 | BYTES_TO_WORDS_8(32, FB, C5, 7A, 37, 51, 23, 04), |
allankliu | 0:b6fdeddc0bc9 | 154 | BYTES_TO_WORDS_8(12, C9, DC, 59, 7D, 94, 68, 31), |
allankliu | 0:b6fdeddc0bc9 | 155 | BYTES_TO_WORDS_4(55, 28, A6, 23) }, |
allankliu | 0:b6fdeddc0bc9 | 156 | { BYTES_TO_WORDS_8(45, FA, 65, C5, AD, D4, D4, 81), |
allankliu | 0:b6fdeddc0bc9 | 157 | BYTES_TO_WORDS_8(9F, F8, AC, 65, 8B, 7A, BD, 54), |
allankliu | 0:b6fdeddc0bc9 | 158 | BYTES_TO_WORDS_4(FC, BE, 97, 1C) }, |
allankliu | 0:b6fdeddc0bc9 | 159 | &double_jacobian_default, |
allankliu | 0:b6fdeddc0bc9 | 160 | #if uECC_SUPPORT_COMPRESSED_POINT |
allankliu | 0:b6fdeddc0bc9 | 161 | &mod_sqrt_default, |
allankliu | 0:b6fdeddc0bc9 | 162 | #endif |
allankliu | 0:b6fdeddc0bc9 | 163 | &x_side_default, |
allankliu | 0:b6fdeddc0bc9 | 164 | #if (uECC_OPTIMIZATION_LEVEL > 0) |
allankliu | 0:b6fdeddc0bc9 | 165 | &vli_mmod_fast_secp160r1 |
allankliu | 0:b6fdeddc0bc9 | 166 | #endif |
allankliu | 0:b6fdeddc0bc9 | 167 | }; |
allankliu | 0:b6fdeddc0bc9 | 168 | |
allankliu | 0:b6fdeddc0bc9 | 169 | uECC_Curve uECC_secp160r1(void) { return &curve_secp160r1; } |
allankliu | 0:b6fdeddc0bc9 | 170 | |
allankliu | 0:b6fdeddc0bc9 | 171 | #if (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp160r1) |
allankliu | 0:b6fdeddc0bc9 | 172 | /* Computes result = product % curve_p |
allankliu | 0:b6fdeddc0bc9 | 173 | see http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf page 354 |
allankliu | 0:b6fdeddc0bc9 | 174 | |
allankliu | 0:b6fdeddc0bc9 | 175 | Note that this only works if log2(omega) < log2(p) / 2 */ |
allankliu | 0:b6fdeddc0bc9 | 176 | static void omega_mult_secp160r1(uECC_word_t *result, const uECC_word_t *right); |
allankliu | 0:b6fdeddc0bc9 | 177 | #if uECC_WORD_SIZE == 8 |
allankliu | 0:b6fdeddc0bc9 | 178 | static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product) { |
allankliu | 0:b6fdeddc0bc9 | 179 | uECC_word_t tmp[2 * num_words_secp160r1]; |
allankliu | 0:b6fdeddc0bc9 | 180 | uECC_word_t copy; |
allankliu | 0:b6fdeddc0bc9 | 181 | |
allankliu | 0:b6fdeddc0bc9 | 182 | uECC_vli_clear(tmp, num_words_secp160r1); |
allankliu | 0:b6fdeddc0bc9 | 183 | uECC_vli_clear(tmp + num_words_secp160r1, num_words_secp160r1); |
allankliu | 0:b6fdeddc0bc9 | 184 | |
allankliu | 0:b6fdeddc0bc9 | 185 | omega_mult_secp160r1(tmp, product + num_words_secp160r1 - 1); /* (Rq, q) = q * c */ |
allankliu | 0:b6fdeddc0bc9 | 186 | |
allankliu | 0:b6fdeddc0bc9 | 187 | product[num_words_secp160r1 - 1] &= 0xffffffff; |
allankliu | 0:b6fdeddc0bc9 | 188 | copy = tmp[num_words_secp160r1 - 1]; |
allankliu | 0:b6fdeddc0bc9 | 189 | tmp[num_words_secp160r1 - 1] &= 0xffffffff; |
allankliu | 0:b6fdeddc0bc9 | 190 | uECC_vli_add(result, product, tmp, num_words_secp160r1); /* (C, r) = r + q */ |
allankliu | 0:b6fdeddc0bc9 | 191 | uECC_vli_clear(product, num_words_secp160r1); |
allankliu | 0:b6fdeddc0bc9 | 192 | tmp[num_words_secp160r1 - 1] = copy; |
allankliu | 0:b6fdeddc0bc9 | 193 | omega_mult_secp160r1(product, tmp + num_words_secp160r1 - 1); /* Rq*c */ |
allankliu | 0:b6fdeddc0bc9 | 194 | uECC_vli_add(result, result, product, num_words_secp160r1); /* (C1, r) = r + Rq*c */ |
allankliu | 0:b6fdeddc0bc9 | 195 | |
allankliu | 0:b6fdeddc0bc9 | 196 | while (uECC_vli_cmp_unsafe(result, curve_secp160r1.p, num_words_secp160r1) > 0) { |
allankliu | 0:b6fdeddc0bc9 | 197 | uECC_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); |
allankliu | 0:b6fdeddc0bc9 | 198 | } |
allankliu | 0:b6fdeddc0bc9 | 199 | } |
allankliu | 0:b6fdeddc0bc9 | 200 | |
allankliu | 0:b6fdeddc0bc9 | 201 | static void omega_mult_secp160r1(uint64_t *result, const uint64_t *right) { |
allankliu | 0:b6fdeddc0bc9 | 202 | uint32_t carry; |
allankliu | 0:b6fdeddc0bc9 | 203 | unsigned i; |
allankliu | 0:b6fdeddc0bc9 | 204 | |
allankliu | 0:b6fdeddc0bc9 | 205 | /* Multiply by (2^31 + 1). */ |
allankliu | 0:b6fdeddc0bc9 | 206 | carry = 0; |
allankliu | 0:b6fdeddc0bc9 | 207 | for (i = 0; i < num_words_secp160r1; ++i) { |
allankliu | 0:b6fdeddc0bc9 | 208 | uint64_t tmp = (right[i] >> 32) | (right[i + 1] << 32); |
allankliu | 0:b6fdeddc0bc9 | 209 | result[i] = (tmp << 31) + tmp + carry; |
allankliu | 0:b6fdeddc0bc9 | 210 | carry = (tmp >> 33) + (result[i] < tmp || (carry && result[i] == tmp)); |
allankliu | 0:b6fdeddc0bc9 | 211 | } |
allankliu | 0:b6fdeddc0bc9 | 212 | result[i] = carry; |
allankliu | 0:b6fdeddc0bc9 | 213 | } |
allankliu | 0:b6fdeddc0bc9 | 214 | #else |
allankliu | 0:b6fdeddc0bc9 | 215 | static void vli_mmod_fast_secp160r1(uECC_word_t *result, uECC_word_t *product) { |
allankliu | 0:b6fdeddc0bc9 | 216 | uECC_word_t tmp[2 * num_words_secp160r1]; |
allankliu | 0:b6fdeddc0bc9 | 217 | uECC_word_t carry; |
allankliu | 0:b6fdeddc0bc9 | 218 | |
allankliu | 0:b6fdeddc0bc9 | 219 | uECC_vli_clear(tmp, num_words_secp160r1); |
allankliu | 0:b6fdeddc0bc9 | 220 | uECC_vli_clear(tmp + num_words_secp160r1, num_words_secp160r1); |
allankliu | 0:b6fdeddc0bc9 | 221 | |
allankliu | 0:b6fdeddc0bc9 | 222 | omega_mult_secp160r1(tmp, product + num_words_secp160r1); /* (Rq, q) = q * c */ |
allankliu | 0:b6fdeddc0bc9 | 223 | |
allankliu | 0:b6fdeddc0bc9 | 224 | carry = uECC_vli_add(result, product, tmp, num_words_secp160r1); /* (C, r) = r + q */ |
allankliu | 0:b6fdeddc0bc9 | 225 | uECC_vli_clear(product, num_words_secp160r1); |
allankliu | 0:b6fdeddc0bc9 | 226 | omega_mult_secp160r1(product, tmp + num_words_secp160r1); /* Rq*c */ |
allankliu | 0:b6fdeddc0bc9 | 227 | carry += uECC_vli_add(result, result, product, num_words_secp160r1); /* (C1, r) = r + Rq*c */ |
allankliu | 0:b6fdeddc0bc9 | 228 | |
allankliu | 0:b6fdeddc0bc9 | 229 | while (carry > 0) { |
allankliu | 0:b6fdeddc0bc9 | 230 | --carry; |
allankliu | 0:b6fdeddc0bc9 | 231 | uECC_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); |
allankliu | 0:b6fdeddc0bc9 | 232 | } |
allankliu | 0:b6fdeddc0bc9 | 233 | if (uECC_vli_cmp_unsafe(result, curve_secp160r1.p, num_words_secp160r1) > 0) { |
allankliu | 0:b6fdeddc0bc9 | 234 | uECC_vli_sub(result, result, curve_secp160r1.p, num_words_secp160r1); |
allankliu | 0:b6fdeddc0bc9 | 235 | } |
allankliu | 0:b6fdeddc0bc9 | 236 | } |
allankliu | 0:b6fdeddc0bc9 | 237 | #endif |
allankliu | 0:b6fdeddc0bc9 | 238 | |
allankliu | 0:b6fdeddc0bc9 | 239 | #if uECC_WORD_SIZE == 1 |
allankliu | 0:b6fdeddc0bc9 | 240 | static void omega_mult_secp160r1(uint8_t *result, const uint8_t *right) { |
allankliu | 0:b6fdeddc0bc9 | 241 | uint8_t carry; |
allankliu | 0:b6fdeddc0bc9 | 242 | uint8_t i; |
allankliu | 0:b6fdeddc0bc9 | 243 | |
allankliu | 0:b6fdeddc0bc9 | 244 | /* Multiply by (2^31 + 1). */ |
allankliu | 0:b6fdeddc0bc9 | 245 | uECC_vli_set(result + 4, right, num_words_secp160r1); /* 2^32 */ |
allankliu | 0:b6fdeddc0bc9 | 246 | uECC_vli_rshift1(result + 4, num_words_secp160r1); /* 2^31 */ |
allankliu | 0:b6fdeddc0bc9 | 247 | result[3] = right[0] << 7; /* get last bit from shift */ |
allankliu | 0:b6fdeddc0bc9 | 248 | |
allankliu | 0:b6fdeddc0bc9 | 249 | carry = uECC_vli_add(result, result, right, num_words_secp160r1); /* 2^31 + 1 */ |
allankliu | 0:b6fdeddc0bc9 | 250 | for (i = num_words_secp160r1; carry; ++i) { |
allankliu | 0:b6fdeddc0bc9 | 251 | uint16_t sum = (uint16_t)result[i] + carry; |
allankliu | 0:b6fdeddc0bc9 | 252 | result[i] = (uint8_t)sum; |
allankliu | 0:b6fdeddc0bc9 | 253 | carry = sum >> 8; |
allankliu | 0:b6fdeddc0bc9 | 254 | } |
allankliu | 0:b6fdeddc0bc9 | 255 | } |
allankliu | 0:b6fdeddc0bc9 | 256 | #elif uECC_WORD_SIZE == 4 |
allankliu | 0:b6fdeddc0bc9 | 257 | static void omega_mult_secp160r1(uint32_t *result, const uint32_t *right) { |
allankliu | 0:b6fdeddc0bc9 | 258 | uint32_t carry; |
allankliu | 0:b6fdeddc0bc9 | 259 | unsigned i; |
allankliu | 0:b6fdeddc0bc9 | 260 | |
allankliu | 0:b6fdeddc0bc9 | 261 | /* Multiply by (2^31 + 1). */ |
allankliu | 0:b6fdeddc0bc9 | 262 | uECC_vli_set(result + 1, right, num_words_secp160r1); /* 2^32 */ |
allankliu | 0:b6fdeddc0bc9 | 263 | uECC_vli_rshift1(result + 1, num_words_secp160r1); /* 2^31 */ |
allankliu | 0:b6fdeddc0bc9 | 264 | result[0] = right[0] << 31; /* get last bit from shift */ |
allankliu | 0:b6fdeddc0bc9 | 265 | |
allankliu | 0:b6fdeddc0bc9 | 266 | carry = uECC_vli_add(result, result, right, num_words_secp160r1); /* 2^31 + 1 */ |
allankliu | 0:b6fdeddc0bc9 | 267 | for (i = num_words_secp160r1; carry; ++i) { |
allankliu | 0:b6fdeddc0bc9 | 268 | uint64_t sum = (uint64_t)result[i] + carry; |
allankliu | 0:b6fdeddc0bc9 | 269 | result[i] = (uint32_t)sum; |
allankliu | 0:b6fdeddc0bc9 | 270 | carry = sum >> 32; |
allankliu | 0:b6fdeddc0bc9 | 271 | } |
allankliu | 0:b6fdeddc0bc9 | 272 | } |
allankliu | 0:b6fdeddc0bc9 | 273 | #endif /* uECC_WORD_SIZE */ |
allankliu | 0:b6fdeddc0bc9 | 274 | #endif /* (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp160r1) */ |
allankliu | 0:b6fdeddc0bc9 | 275 | |
allankliu | 0:b6fdeddc0bc9 | 276 | #endif /* uECC_SUPPORTS_secp160r1 */ |
allankliu | 0:b6fdeddc0bc9 | 277 | |
allankliu | 0:b6fdeddc0bc9 | 278 | #if uECC_SUPPORTS_secp192r1 |
allankliu | 0:b6fdeddc0bc9 | 279 | |
allankliu | 0:b6fdeddc0bc9 | 280 | #if (uECC_OPTIMIZATION_LEVEL > 0) |
allankliu | 0:b6fdeddc0bc9 | 281 | static void vli_mmod_fast_secp192r1(uECC_word_t *result, uECC_word_t *product); |
allankliu | 0:b6fdeddc0bc9 | 282 | #endif |
allankliu | 0:b6fdeddc0bc9 | 283 | |
allankliu | 0:b6fdeddc0bc9 | 284 | static const struct uECC_Curve_t curve_secp192r1 = { |
allankliu | 0:b6fdeddc0bc9 | 285 | num_words_secp192r1, |
allankliu | 0:b6fdeddc0bc9 | 286 | num_bytes_secp192r1, |
allankliu | 0:b6fdeddc0bc9 | 287 | 192, /* num_n_bits */ |
allankliu | 0:b6fdeddc0bc9 | 288 | { BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 289 | BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 290 | BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, |
allankliu | 0:b6fdeddc0bc9 | 291 | { BYTES_TO_WORDS_8(31, 28, D2, B4, B1, C9, 6B, 14), |
allankliu | 0:b6fdeddc0bc9 | 292 | BYTES_TO_WORDS_8(36, F8, DE, 99, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 293 | BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, |
allankliu | 0:b6fdeddc0bc9 | 294 | { BYTES_TO_WORDS_8(12, 10, FF, 82, FD, 0A, FF, F4), |
allankliu | 0:b6fdeddc0bc9 | 295 | BYTES_TO_WORDS_8(00, 88, A1, 43, EB, 20, BF, 7C), |
allankliu | 0:b6fdeddc0bc9 | 296 | BYTES_TO_WORDS_8(F6, 90, 30, B0, 0E, A8, 8D, 18), |
allankliu | 0:b6fdeddc0bc9 | 297 | |
allankliu | 0:b6fdeddc0bc9 | 298 | BYTES_TO_WORDS_8(11, 48, 79, 1E, A1, 77, F9, 73), |
allankliu | 0:b6fdeddc0bc9 | 299 | BYTES_TO_WORDS_8(D5, CD, 24, 6B, ED, 11, 10, 63), |
allankliu | 0:b6fdeddc0bc9 | 300 | BYTES_TO_WORDS_8(78, DA, C8, FF, 95, 2B, 19, 07) }, |
allankliu | 0:b6fdeddc0bc9 | 301 | { BYTES_TO_WORDS_8(B1, B9, 46, C1, EC, DE, B8, FE), |
allankliu | 0:b6fdeddc0bc9 | 302 | BYTES_TO_WORDS_8(49, 30, 24, 72, AB, E9, A7, 0F), |
allankliu | 0:b6fdeddc0bc9 | 303 | BYTES_TO_WORDS_8(E7, 80, 9C, E5, 19, 05, 21, 64) }, |
allankliu | 0:b6fdeddc0bc9 | 304 | &double_jacobian_default, |
allankliu | 0:b6fdeddc0bc9 | 305 | #if uECC_SUPPORT_COMPRESSED_POINT |
allankliu | 0:b6fdeddc0bc9 | 306 | &mod_sqrt_default, |
allankliu | 0:b6fdeddc0bc9 | 307 | #endif |
allankliu | 0:b6fdeddc0bc9 | 308 | &x_side_default, |
allankliu | 0:b6fdeddc0bc9 | 309 | #if (uECC_OPTIMIZATION_LEVEL > 0) |
allankliu | 0:b6fdeddc0bc9 | 310 | &vli_mmod_fast_secp192r1 |
allankliu | 0:b6fdeddc0bc9 | 311 | #endif |
allankliu | 0:b6fdeddc0bc9 | 312 | }; |
allankliu | 0:b6fdeddc0bc9 | 313 | |
allankliu | 0:b6fdeddc0bc9 | 314 | uECC_Curve uECC_secp192r1(void) { return &curve_secp192r1; } |
allankliu | 0:b6fdeddc0bc9 | 315 | |
allankliu | 0:b6fdeddc0bc9 | 316 | #if (uECC_OPTIMIZATION_LEVEL > 0) |
allankliu | 0:b6fdeddc0bc9 | 317 | /* Computes result = product % curve_p. |
allankliu | 0:b6fdeddc0bc9 | 318 | See algorithm 5 and 6 from http://www.isys.uni-klu.ac.at/PDF/2001-0126-MT.pdf */ |
allankliu | 0:b6fdeddc0bc9 | 319 | #if uECC_WORD_SIZE == 1 |
allankliu | 0:b6fdeddc0bc9 | 320 | static void vli_mmod_fast_secp192r1(uint8_t *result, uint8_t *product) { |
allankliu | 0:b6fdeddc0bc9 | 321 | uint8_t tmp[num_words_secp192r1]; |
allankliu | 0:b6fdeddc0bc9 | 322 | uint8_t carry; |
allankliu | 0:b6fdeddc0bc9 | 323 | |
allankliu | 0:b6fdeddc0bc9 | 324 | uECC_vli_set(result, product, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 325 | |
allankliu | 0:b6fdeddc0bc9 | 326 | uECC_vli_set(tmp, &product[24], num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 327 | carry = uECC_vli_add(result, result, tmp, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 328 | |
allankliu | 0:b6fdeddc0bc9 | 329 | tmp[0] = tmp[1] = tmp[2] = tmp[3] = tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0; |
allankliu | 0:b6fdeddc0bc9 | 330 | tmp[8] = product[24]; tmp[9] = product[25]; tmp[10] = product[26]; tmp[11] = product[27]; |
allankliu | 0:b6fdeddc0bc9 | 331 | tmp[12] = product[28]; tmp[13] = product[29]; tmp[14] = product[30]; tmp[15] = product[31]; |
allankliu | 0:b6fdeddc0bc9 | 332 | tmp[16] = product[32]; tmp[17] = product[33]; tmp[18] = product[34]; tmp[19] = product[35]; |
allankliu | 0:b6fdeddc0bc9 | 333 | tmp[20] = product[36]; tmp[21] = product[37]; tmp[22] = product[38]; tmp[23] = product[39]; |
allankliu | 0:b6fdeddc0bc9 | 334 | carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 335 | |
allankliu | 0:b6fdeddc0bc9 | 336 | tmp[0] = tmp[8] = product[40]; |
allankliu | 0:b6fdeddc0bc9 | 337 | tmp[1] = tmp[9] = product[41]; |
allankliu | 0:b6fdeddc0bc9 | 338 | tmp[2] = tmp[10] = product[42]; |
allankliu | 0:b6fdeddc0bc9 | 339 | tmp[3] = tmp[11] = product[43]; |
allankliu | 0:b6fdeddc0bc9 | 340 | tmp[4] = tmp[12] = product[44]; |
allankliu | 0:b6fdeddc0bc9 | 341 | tmp[5] = tmp[13] = product[45]; |
allankliu | 0:b6fdeddc0bc9 | 342 | tmp[6] = tmp[14] = product[46]; |
allankliu | 0:b6fdeddc0bc9 | 343 | tmp[7] = tmp[15] = product[47]; |
allankliu | 0:b6fdeddc0bc9 | 344 | tmp[16] = tmp[17] = tmp[18] = tmp[19] = tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; |
allankliu | 0:b6fdeddc0bc9 | 345 | carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 346 | |
allankliu | 0:b6fdeddc0bc9 | 347 | while (carry || uECC_vli_cmp_unsafe(curve_secp192r1.p, result, num_words_secp192r1) != 1) { |
allankliu | 0:b6fdeddc0bc9 | 348 | carry -= uECC_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 349 | } |
allankliu | 0:b6fdeddc0bc9 | 350 | } |
allankliu | 0:b6fdeddc0bc9 | 351 | #elif uECC_WORD_SIZE == 4 |
allankliu | 0:b6fdeddc0bc9 | 352 | static void vli_mmod_fast_secp192r1(uint32_t *result, uint32_t *product) { |
allankliu | 0:b6fdeddc0bc9 | 353 | uint32_t tmp[num_words_secp192r1]; |
allankliu | 0:b6fdeddc0bc9 | 354 | int carry; |
allankliu | 0:b6fdeddc0bc9 | 355 | |
allankliu | 0:b6fdeddc0bc9 | 356 | uECC_vli_set(result, product, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 357 | |
allankliu | 0:b6fdeddc0bc9 | 358 | uECC_vli_set(tmp, &product[6], num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 359 | carry = uECC_vli_add(result, result, tmp, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 360 | |
allankliu | 0:b6fdeddc0bc9 | 361 | tmp[0] = tmp[1] = 0; |
allankliu | 0:b6fdeddc0bc9 | 362 | tmp[2] = product[6]; |
allankliu | 0:b6fdeddc0bc9 | 363 | tmp[3] = product[7]; |
allankliu | 0:b6fdeddc0bc9 | 364 | tmp[4] = product[8]; |
allankliu | 0:b6fdeddc0bc9 | 365 | tmp[5] = product[9]; |
allankliu | 0:b6fdeddc0bc9 | 366 | carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 367 | |
allankliu | 0:b6fdeddc0bc9 | 368 | tmp[0] = tmp[2] = product[10]; |
allankliu | 0:b6fdeddc0bc9 | 369 | tmp[1] = tmp[3] = product[11]; |
allankliu | 0:b6fdeddc0bc9 | 370 | tmp[4] = tmp[5] = 0; |
allankliu | 0:b6fdeddc0bc9 | 371 | carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 372 | |
allankliu | 0:b6fdeddc0bc9 | 373 | while (carry || uECC_vli_cmp_unsafe(curve_secp192r1.p, result, num_words_secp192r1) != 1) { |
allankliu | 0:b6fdeddc0bc9 | 374 | carry -= uECC_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 375 | } |
allankliu | 0:b6fdeddc0bc9 | 376 | } |
allankliu | 0:b6fdeddc0bc9 | 377 | #else |
allankliu | 0:b6fdeddc0bc9 | 378 | static void vli_mmod_fast_secp192r1(uint64_t *result, uint64_t *product) { |
allankliu | 0:b6fdeddc0bc9 | 379 | uint64_t tmp[num_words_secp192r1]; |
allankliu | 0:b6fdeddc0bc9 | 380 | int carry; |
allankliu | 0:b6fdeddc0bc9 | 381 | |
allankliu | 0:b6fdeddc0bc9 | 382 | uECC_vli_set(result, product, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 383 | |
allankliu | 0:b6fdeddc0bc9 | 384 | uECC_vli_set(tmp, &product[3], num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 385 | carry = (int)uECC_vli_add(result, result, tmp, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 386 | |
allankliu | 0:b6fdeddc0bc9 | 387 | tmp[0] = 0; |
allankliu | 0:b6fdeddc0bc9 | 388 | tmp[1] = product[3]; |
allankliu | 0:b6fdeddc0bc9 | 389 | tmp[2] = product[4]; |
allankliu | 0:b6fdeddc0bc9 | 390 | carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 391 | |
allankliu | 0:b6fdeddc0bc9 | 392 | tmp[0] = tmp[1] = product[5]; |
allankliu | 0:b6fdeddc0bc9 | 393 | tmp[2] = 0; |
allankliu | 0:b6fdeddc0bc9 | 394 | carry += uECC_vli_add(result, result, tmp, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 395 | |
allankliu | 0:b6fdeddc0bc9 | 396 | while (carry || uECC_vli_cmp_unsafe(curve_secp192r1.p, result, num_words_secp192r1) != 1) { |
allankliu | 0:b6fdeddc0bc9 | 397 | carry -= uECC_vli_sub(result, result, curve_secp192r1.p, num_words_secp192r1); |
allankliu | 0:b6fdeddc0bc9 | 398 | } |
allankliu | 0:b6fdeddc0bc9 | 399 | } |
allankliu | 0:b6fdeddc0bc9 | 400 | #endif /* uECC_WORD_SIZE */ |
allankliu | 0:b6fdeddc0bc9 | 401 | #endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ |
allankliu | 0:b6fdeddc0bc9 | 402 | |
allankliu | 0:b6fdeddc0bc9 | 403 | #endif /* uECC_SUPPORTS_secp192r1 */ |
allankliu | 0:b6fdeddc0bc9 | 404 | |
allankliu | 0:b6fdeddc0bc9 | 405 | #if uECC_SUPPORTS_secp224r1 |
allankliu | 0:b6fdeddc0bc9 | 406 | |
allankliu | 0:b6fdeddc0bc9 | 407 | #if uECC_SUPPORT_COMPRESSED_POINT |
allankliu | 0:b6fdeddc0bc9 | 408 | static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve); |
allankliu | 0:b6fdeddc0bc9 | 409 | #endif |
allankliu | 0:b6fdeddc0bc9 | 410 | #if (uECC_OPTIMIZATION_LEVEL > 0) |
allankliu | 0:b6fdeddc0bc9 | 411 | static void vli_mmod_fast_secp224r1(uECC_word_t *result, uECC_word_t *product); |
allankliu | 0:b6fdeddc0bc9 | 412 | #endif |
allankliu | 0:b6fdeddc0bc9 | 413 | |
allankliu | 0:b6fdeddc0bc9 | 414 | static const struct uECC_Curve_t curve_secp224r1 = { |
allankliu | 0:b6fdeddc0bc9 | 415 | num_words_secp224r1, |
allankliu | 0:b6fdeddc0bc9 | 416 | num_bytes_secp224r1, |
allankliu | 0:b6fdeddc0bc9 | 417 | 224, /* num_n_bits */ |
allankliu | 0:b6fdeddc0bc9 | 418 | { BYTES_TO_WORDS_8(01, 00, 00, 00, 00, 00, 00, 00), |
allankliu | 0:b6fdeddc0bc9 | 419 | BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 420 | BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 421 | BYTES_TO_WORDS_4(FF, FF, FF, FF) }, |
allankliu | 0:b6fdeddc0bc9 | 422 | { BYTES_TO_WORDS_8(3D, 2A, 5C, 5C, 45, 29, DD, 13), |
allankliu | 0:b6fdeddc0bc9 | 423 | BYTES_TO_WORDS_8(3E, F0, B8, E0, A2, 16, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 424 | BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 425 | BYTES_TO_WORDS_4(FF, FF, FF, FF) }, |
allankliu | 0:b6fdeddc0bc9 | 426 | { BYTES_TO_WORDS_8(21, 1D, 5C, 11, D6, 80, 32, 34), |
allankliu | 0:b6fdeddc0bc9 | 427 | BYTES_TO_WORDS_8(22, 11, C2, 56, D3, C1, 03, 4A), |
allankliu | 0:b6fdeddc0bc9 | 428 | BYTES_TO_WORDS_8(B9, 90, 13, 32, 7F, BF, B4, 6B), |
allankliu | 0:b6fdeddc0bc9 | 429 | BYTES_TO_WORDS_4(BD, 0C, 0E, B7), |
allankliu | 0:b6fdeddc0bc9 | 430 | |
allankliu | 0:b6fdeddc0bc9 | 431 | BYTES_TO_WORDS_8(34, 7E, 00, 85, 99, 81, D5, 44), |
allankliu | 0:b6fdeddc0bc9 | 432 | BYTES_TO_WORDS_8(64, 47, 07, 5A, A0, 75, 43, CD), |
allankliu | 0:b6fdeddc0bc9 | 433 | BYTES_TO_WORDS_8(E6, DF, 22, 4C, FB, 23, F7, B5), |
allankliu | 0:b6fdeddc0bc9 | 434 | BYTES_TO_WORDS_4(88, 63, 37, BD) }, |
allankliu | 0:b6fdeddc0bc9 | 435 | { BYTES_TO_WORDS_8(B4, FF, 55, 23, 43, 39, 0B, 27), |
allankliu | 0:b6fdeddc0bc9 | 436 | BYTES_TO_WORDS_8(BA, D8, BF, D7, B7, B0, 44, 50), |
allankliu | 0:b6fdeddc0bc9 | 437 | BYTES_TO_WORDS_8(56, 32, 41, F5, AB, B3, 04, 0C), |
allankliu | 0:b6fdeddc0bc9 | 438 | BYTES_TO_WORDS_4(85, 0A, 05, B4) }, |
allankliu | 0:b6fdeddc0bc9 | 439 | &double_jacobian_default, |
allankliu | 0:b6fdeddc0bc9 | 440 | #if uECC_SUPPORT_COMPRESSED_POINT |
allankliu | 0:b6fdeddc0bc9 | 441 | &mod_sqrt_secp224r1, |
allankliu | 0:b6fdeddc0bc9 | 442 | #endif |
allankliu | 0:b6fdeddc0bc9 | 443 | &x_side_default, |
allankliu | 0:b6fdeddc0bc9 | 444 | #if (uECC_OPTIMIZATION_LEVEL > 0) |
allankliu | 0:b6fdeddc0bc9 | 445 | &vli_mmod_fast_secp224r1 |
allankliu | 0:b6fdeddc0bc9 | 446 | #endif |
allankliu | 0:b6fdeddc0bc9 | 447 | }; |
allankliu | 0:b6fdeddc0bc9 | 448 | |
allankliu | 0:b6fdeddc0bc9 | 449 | uECC_Curve uECC_secp224r1(void) { return &curve_secp224r1; } |
allankliu | 0:b6fdeddc0bc9 | 450 | |
allankliu | 0:b6fdeddc0bc9 | 451 | |
allankliu | 0:b6fdeddc0bc9 | 452 | #if uECC_SUPPORT_COMPRESSED_POINT |
allankliu | 0:b6fdeddc0bc9 | 453 | /* Routine 3.2.4 RS; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ |
allankliu | 0:b6fdeddc0bc9 | 454 | static void mod_sqrt_secp224r1_rs(uECC_word_t *d1, |
allankliu | 0:b6fdeddc0bc9 | 455 | uECC_word_t *e1, |
allankliu | 0:b6fdeddc0bc9 | 456 | uECC_word_t *f1, |
allankliu | 0:b6fdeddc0bc9 | 457 | const uECC_word_t *d0, |
allankliu | 0:b6fdeddc0bc9 | 458 | const uECC_word_t *e0, |
allankliu | 0:b6fdeddc0bc9 | 459 | const uECC_word_t *f0) { |
allankliu | 0:b6fdeddc0bc9 | 460 | uECC_word_t t[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 461 | |
allankliu | 0:b6fdeddc0bc9 | 462 | uECC_vli_modSquare_fast(t, d0, &curve_secp224r1); /* t <-- d0 ^ 2 */ |
allankliu | 0:b6fdeddc0bc9 | 463 | uECC_vli_modMult_fast(e1, d0, e0, &curve_secp224r1); /* e1 <-- d0 * e0 */ |
allankliu | 0:b6fdeddc0bc9 | 464 | uECC_vli_modAdd(d1, t, f0, curve_secp224r1.p, num_words_secp224r1); /* d1 <-- t + f0 */ |
allankliu | 0:b6fdeddc0bc9 | 465 | uECC_vli_modAdd(e1, e1, e1, curve_secp224r1.p, num_words_secp224r1); /* e1 <-- e1 + e1 */ |
allankliu | 0:b6fdeddc0bc9 | 466 | uECC_vli_modMult_fast(f1, t, f0, &curve_secp224r1); /* f1 <-- t * f0 */ |
allankliu | 0:b6fdeddc0bc9 | 467 | uECC_vli_modAdd(f1, f1, f1, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- f1 + f1 */ |
allankliu | 0:b6fdeddc0bc9 | 468 | uECC_vli_modAdd(f1, f1, f1, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- f1 + f1 */ |
allankliu | 0:b6fdeddc0bc9 | 469 | } |
allankliu | 0:b6fdeddc0bc9 | 470 | |
allankliu | 0:b6fdeddc0bc9 | 471 | /* Routine 3.2.5 RSS; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ |
allankliu | 0:b6fdeddc0bc9 | 472 | static void mod_sqrt_secp224r1_rss(uECC_word_t *d1, |
allankliu | 0:b6fdeddc0bc9 | 473 | uECC_word_t *e1, |
allankliu | 0:b6fdeddc0bc9 | 474 | uECC_word_t *f1, |
allankliu | 0:b6fdeddc0bc9 | 475 | const uECC_word_t *d0, |
allankliu | 0:b6fdeddc0bc9 | 476 | const uECC_word_t *e0, |
allankliu | 0:b6fdeddc0bc9 | 477 | const uECC_word_t *f0, |
allankliu | 0:b6fdeddc0bc9 | 478 | const bitcount_t j) { |
allankliu | 0:b6fdeddc0bc9 | 479 | bitcount_t i; |
allankliu | 0:b6fdeddc0bc9 | 480 | |
allankliu | 0:b6fdeddc0bc9 | 481 | uECC_vli_set(d1, d0, num_words_secp224r1); /* d1 <-- d0 */ |
allankliu | 0:b6fdeddc0bc9 | 482 | uECC_vli_set(e1, e0, num_words_secp224r1); /* e1 <-- e0 */ |
allankliu | 0:b6fdeddc0bc9 | 483 | uECC_vli_set(f1, f0, num_words_secp224r1); /* f1 <-- f0 */ |
allankliu | 0:b6fdeddc0bc9 | 484 | for (i = 1; i <= j; i++) { |
allankliu | 0:b6fdeddc0bc9 | 485 | mod_sqrt_secp224r1_rs(d1, e1, f1, d1, e1, f1); /* RS (d1,e1,f1,d1,e1,f1) */ |
allankliu | 0:b6fdeddc0bc9 | 486 | } |
allankliu | 0:b6fdeddc0bc9 | 487 | } |
allankliu | 0:b6fdeddc0bc9 | 488 | |
allankliu | 0:b6fdeddc0bc9 | 489 | /* Routine 3.2.6 RM; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ |
allankliu | 0:b6fdeddc0bc9 | 490 | static void mod_sqrt_secp224r1_rm(uECC_word_t *d2, |
allankliu | 0:b6fdeddc0bc9 | 491 | uECC_word_t *e2, |
allankliu | 0:b6fdeddc0bc9 | 492 | uECC_word_t *f2, |
allankliu | 0:b6fdeddc0bc9 | 493 | const uECC_word_t *c, |
allankliu | 0:b6fdeddc0bc9 | 494 | const uECC_word_t *d0, |
allankliu | 0:b6fdeddc0bc9 | 495 | const uECC_word_t *e0, |
allankliu | 0:b6fdeddc0bc9 | 496 | const uECC_word_t *d1, |
allankliu | 0:b6fdeddc0bc9 | 497 | const uECC_word_t *e1) { |
allankliu | 0:b6fdeddc0bc9 | 498 | uECC_word_t t1[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 499 | uECC_word_t t2[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 500 | |
allankliu | 0:b6fdeddc0bc9 | 501 | uECC_vli_modMult_fast(t1, e0, e1, &curve_secp224r1); /* t1 <-- e0 * e1 */ |
allankliu | 0:b6fdeddc0bc9 | 502 | uECC_vli_modMult_fast(t1, t1, c, &curve_secp224r1); /* t1 <-- t1 * c */ |
allankliu | 0:b6fdeddc0bc9 | 503 | /* t1 <-- p - t1 */ |
allankliu | 0:b6fdeddc0bc9 | 504 | uECC_vli_modSub(t1, curve_secp224r1.p, t1, curve_secp224r1.p, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 505 | uECC_vli_modMult_fast(t2, d0, d1, &curve_secp224r1); /* t2 <-- d0 * d1 */ |
allankliu | 0:b6fdeddc0bc9 | 506 | uECC_vli_modAdd(t2, t2, t1, curve_secp224r1.p, num_words_secp224r1); /* t2 <-- t2 + t1 */ |
allankliu | 0:b6fdeddc0bc9 | 507 | uECC_vli_modMult_fast(t1, d0, e1, &curve_secp224r1); /* t1 <-- d0 * e1 */ |
allankliu | 0:b6fdeddc0bc9 | 508 | uECC_vli_modMult_fast(e2, d1, e0, &curve_secp224r1); /* e2 <-- d1 * e0 */ |
allankliu | 0:b6fdeddc0bc9 | 509 | uECC_vli_modAdd(e2, e2, t1, curve_secp224r1.p, num_words_secp224r1); /* e2 <-- e2 + t1 */ |
allankliu | 0:b6fdeddc0bc9 | 510 | uECC_vli_modSquare_fast(f2, e2, &curve_secp224r1); /* f2 <-- e2^2 */ |
allankliu | 0:b6fdeddc0bc9 | 511 | uECC_vli_modMult_fast(f2, f2, c, &curve_secp224r1); /* f2 <-- f2 * c */ |
allankliu | 0:b6fdeddc0bc9 | 512 | /* f2 <-- p - f2 */ |
allankliu | 0:b6fdeddc0bc9 | 513 | uECC_vli_modSub(f2, curve_secp224r1.p, f2, curve_secp224r1.p, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 514 | uECC_vli_set(d2, t2, num_words_secp224r1); /* d2 <-- t2 */ |
allankliu | 0:b6fdeddc0bc9 | 515 | } |
allankliu | 0:b6fdeddc0bc9 | 516 | |
allankliu | 0:b6fdeddc0bc9 | 517 | /* Routine 3.2.7 RP; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ |
allankliu | 0:b6fdeddc0bc9 | 518 | static void mod_sqrt_secp224r1_rp(uECC_word_t *d1, |
allankliu | 0:b6fdeddc0bc9 | 519 | uECC_word_t *e1, |
allankliu | 0:b6fdeddc0bc9 | 520 | uECC_word_t *f1, |
allankliu | 0:b6fdeddc0bc9 | 521 | const uECC_word_t *c, |
allankliu | 0:b6fdeddc0bc9 | 522 | const uECC_word_t *r) { |
allankliu | 0:b6fdeddc0bc9 | 523 | wordcount_t i; |
allankliu | 0:b6fdeddc0bc9 | 524 | wordcount_t pow2i = 1; |
allankliu | 0:b6fdeddc0bc9 | 525 | uECC_word_t d0[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 526 | uECC_word_t e0[num_words_secp224r1] = {1}; /* e0 <-- 1 */ |
allankliu | 0:b6fdeddc0bc9 | 527 | uECC_word_t f0[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 528 | |
allankliu | 0:b6fdeddc0bc9 | 529 | uECC_vli_set(d0, r, num_words_secp224r1); /* d0 <-- r */ |
allankliu | 0:b6fdeddc0bc9 | 530 | /* f0 <-- p - c */ |
allankliu | 0:b6fdeddc0bc9 | 531 | uECC_vli_modSub(f0, curve_secp224r1.p, c, curve_secp224r1.p, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 532 | for (i = 0; i <= 6; i++) { |
allankliu | 0:b6fdeddc0bc9 | 533 | mod_sqrt_secp224r1_rss(d1, e1, f1, d0, e0, f0, pow2i); /* RSS (d1,e1,f1,d0,e0,f0,2^i) */ |
allankliu | 0:b6fdeddc0bc9 | 534 | mod_sqrt_secp224r1_rm(d1, e1, f1, c, d1, e1, d0, e0); /* RM (d1,e1,f1,c,d1,e1,d0,e0) */ |
allankliu | 0:b6fdeddc0bc9 | 535 | uECC_vli_set(d0, d1, num_words_secp224r1); /* d0 <-- d1 */ |
allankliu | 0:b6fdeddc0bc9 | 536 | uECC_vli_set(e0, e1, num_words_secp224r1); /* e0 <-- e1 */ |
allankliu | 0:b6fdeddc0bc9 | 537 | uECC_vli_set(f0, f1, num_words_secp224r1); /* f0 <-- f1 */ |
allankliu | 0:b6fdeddc0bc9 | 538 | pow2i *= 2; |
allankliu | 0:b6fdeddc0bc9 | 539 | } |
allankliu | 0:b6fdeddc0bc9 | 540 | } |
allankliu | 0:b6fdeddc0bc9 | 541 | |
allankliu | 0:b6fdeddc0bc9 | 542 | /* Compute a = sqrt(a) (mod curve_p). */ |
allankliu | 0:b6fdeddc0bc9 | 543 | /* Routine 3.2.8 mp_mod_sqrt_224; from http://www.nsa.gov/ia/_files/nist-routines.pdf */ |
allankliu | 0:b6fdeddc0bc9 | 544 | static void mod_sqrt_secp224r1(uECC_word_t *a, uECC_Curve curve) { |
allankliu | 0:b6fdeddc0bc9 | 545 | bitcount_t i; |
allankliu | 0:b6fdeddc0bc9 | 546 | uECC_word_t e1[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 547 | uECC_word_t f1[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 548 | uECC_word_t d0[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 549 | uECC_word_t e0[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 550 | uECC_word_t f0[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 551 | uECC_word_t d1[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 552 | |
allankliu | 0:b6fdeddc0bc9 | 553 | /* s = a; using constant instead of random value */ |
allankliu | 0:b6fdeddc0bc9 | 554 | mod_sqrt_secp224r1_rp(d0, e0, f0, a, a); /* RP (d0, e0, f0, c, s) */ |
allankliu | 0:b6fdeddc0bc9 | 555 | mod_sqrt_secp224r1_rs(d1, e1, f1, d0, e0, f0); /* RS (d1, e1, f1, d0, e0, f0) */ |
allankliu | 0:b6fdeddc0bc9 | 556 | for (i = 1; i <= 95; i++) { |
allankliu | 0:b6fdeddc0bc9 | 557 | uECC_vli_set(d0, d1, num_words_secp224r1); /* d0 <-- d1 */ |
allankliu | 0:b6fdeddc0bc9 | 558 | uECC_vli_set(e0, e1, num_words_secp224r1); /* e0 <-- e1 */ |
allankliu | 0:b6fdeddc0bc9 | 559 | uECC_vli_set(f0, f1, num_words_secp224r1); /* f0 <-- f1 */ |
allankliu | 0:b6fdeddc0bc9 | 560 | mod_sqrt_secp224r1_rs(d1, e1, f1, d0, e0, f0); /* RS (d1, e1, f1, d0, e0, f0) */ |
allankliu | 0:b6fdeddc0bc9 | 561 | if (uECC_vli_isZero(d1, num_words_secp224r1)) { /* if d1 == 0 */ |
allankliu | 0:b6fdeddc0bc9 | 562 | break; |
allankliu | 0:b6fdeddc0bc9 | 563 | } |
allankliu | 0:b6fdeddc0bc9 | 564 | } |
allankliu | 0:b6fdeddc0bc9 | 565 | uECC_vli_modInv(f1, e0, curve_secp224r1.p, num_words_secp224r1); /* f1 <-- 1 / e0 */ |
allankliu | 0:b6fdeddc0bc9 | 566 | uECC_vli_modMult_fast(a, d0, f1, &curve_secp224r1); /* a <-- d0 / e0 */ |
allankliu | 0:b6fdeddc0bc9 | 567 | } |
allankliu | 0:b6fdeddc0bc9 | 568 | #endif /* uECC_SUPPORT_COMPRESSED_POINT */ |
allankliu | 0:b6fdeddc0bc9 | 569 | |
allankliu | 0:b6fdeddc0bc9 | 570 | #if (uECC_OPTIMIZATION_LEVEL > 0) |
allankliu | 0:b6fdeddc0bc9 | 571 | /* Computes result = product % curve_p |
allankliu | 0:b6fdeddc0bc9 | 572 | from http://www.nsa.gov/ia/_files/nist-routines.pdf */ |
allankliu | 0:b6fdeddc0bc9 | 573 | #if uECC_WORD_SIZE == 1 |
allankliu | 0:b6fdeddc0bc9 | 574 | static void vli_mmod_fast_secp224r1(uint8_t *result, uint8_t *product) { |
allankliu | 0:b6fdeddc0bc9 | 575 | uint8_t tmp[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 576 | int8_t carry; |
allankliu | 0:b6fdeddc0bc9 | 577 | |
allankliu | 0:b6fdeddc0bc9 | 578 | /* t */ |
allankliu | 0:b6fdeddc0bc9 | 579 | uECC_vli_set(result, product, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 580 | |
allankliu | 0:b6fdeddc0bc9 | 581 | /* s1 */ |
allankliu | 0:b6fdeddc0bc9 | 582 | tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; |
allankliu | 0:b6fdeddc0bc9 | 583 | tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0; |
allankliu | 0:b6fdeddc0bc9 | 584 | tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0; |
allankliu | 0:b6fdeddc0bc9 | 585 | tmp[12] = product[28]; tmp[13] = product[29]; tmp[14] = product[30]; tmp[15] = product[31]; |
allankliu | 0:b6fdeddc0bc9 | 586 | tmp[16] = product[32]; tmp[17] = product[33]; tmp[18] = product[34]; tmp[19] = product[35]; |
allankliu | 0:b6fdeddc0bc9 | 587 | tmp[20] = product[36]; tmp[21] = product[37]; tmp[22] = product[38]; tmp[23] = product[39]; |
allankliu | 0:b6fdeddc0bc9 | 588 | tmp[24] = product[40]; tmp[25] = product[41]; tmp[26] = product[42]; tmp[27] = product[43]; |
allankliu | 0:b6fdeddc0bc9 | 589 | carry = uECC_vli_add(result, result, tmp, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 590 | |
allankliu | 0:b6fdeddc0bc9 | 591 | /* s2 */ |
allankliu | 0:b6fdeddc0bc9 | 592 | tmp[12] = product[44]; tmp[13] = product[45]; tmp[14] = product[46]; tmp[15] = product[47]; |
allankliu | 0:b6fdeddc0bc9 | 593 | tmp[16] = product[48]; tmp[17] = product[49]; tmp[18] = product[50]; tmp[19] = product[51]; |
allankliu | 0:b6fdeddc0bc9 | 594 | tmp[20] = product[52]; tmp[21] = product[53]; tmp[22] = product[54]; tmp[23] = product[55]; |
allankliu | 0:b6fdeddc0bc9 | 595 | tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; |
allankliu | 0:b6fdeddc0bc9 | 596 | carry += uECC_vli_add(result, result, tmp, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 597 | |
allankliu | 0:b6fdeddc0bc9 | 598 | /* d1 */ |
allankliu | 0:b6fdeddc0bc9 | 599 | tmp[0] = product[28]; tmp[1] = product[29]; tmp[2] = product[30]; tmp[3] = product[31]; |
allankliu | 0:b6fdeddc0bc9 | 600 | tmp[4] = product[32]; tmp[5] = product[33]; tmp[6] = product[34]; tmp[7] = product[35]; |
allankliu | 0:b6fdeddc0bc9 | 601 | tmp[8] = product[36]; tmp[9] = product[37]; tmp[10] = product[38]; tmp[11] = product[39]; |
allankliu | 0:b6fdeddc0bc9 | 602 | tmp[12] = product[40]; tmp[13] = product[41]; tmp[14] = product[42]; tmp[15] = product[43]; |
allankliu | 0:b6fdeddc0bc9 | 603 | tmp[16] = product[44]; tmp[17] = product[45]; tmp[18] = product[46]; tmp[19] = product[47]; |
allankliu | 0:b6fdeddc0bc9 | 604 | tmp[20] = product[48]; tmp[21] = product[49]; tmp[22] = product[50]; tmp[23] = product[51]; |
allankliu | 0:b6fdeddc0bc9 | 605 | tmp[24] = product[52]; tmp[25] = product[53]; tmp[26] = product[54]; tmp[27] = product[55]; |
allankliu | 0:b6fdeddc0bc9 | 606 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 607 | |
allankliu | 0:b6fdeddc0bc9 | 608 | /* d2 */ |
allankliu | 0:b6fdeddc0bc9 | 609 | tmp[0] = product[44]; tmp[1] = product[45]; tmp[2] = product[46]; tmp[3] = product[47]; |
allankliu | 0:b6fdeddc0bc9 | 610 | tmp[4] = product[48]; tmp[5] = product[49]; tmp[6] = product[50]; tmp[7] = product[51]; |
allankliu | 0:b6fdeddc0bc9 | 611 | tmp[8] = product[52]; tmp[9] = product[53]; tmp[10] = product[54]; tmp[11] = product[55]; |
allankliu | 0:b6fdeddc0bc9 | 612 | tmp[12] = tmp[13] = tmp[14] = tmp[15] = 0; |
allankliu | 0:b6fdeddc0bc9 | 613 | tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; |
allankliu | 0:b6fdeddc0bc9 | 614 | tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; |
allankliu | 0:b6fdeddc0bc9 | 615 | tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; |
allankliu | 0:b6fdeddc0bc9 | 616 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 617 | |
allankliu | 0:b6fdeddc0bc9 | 618 | if (carry < 0) { |
allankliu | 0:b6fdeddc0bc9 | 619 | do { |
allankliu | 0:b6fdeddc0bc9 | 620 | carry += uECC_vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 621 | } while (carry < 0); |
allankliu | 0:b6fdeddc0bc9 | 622 | } else { |
allankliu | 0:b6fdeddc0bc9 | 623 | while (carry || uECC_vli_cmp_unsafe(curve_secp224r1.p, result, num_words_secp224r1) != 1) { |
allankliu | 0:b6fdeddc0bc9 | 624 | carry -= uECC_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 625 | } |
allankliu | 0:b6fdeddc0bc9 | 626 | } |
allankliu | 0:b6fdeddc0bc9 | 627 | } |
allankliu | 0:b6fdeddc0bc9 | 628 | #elif uECC_WORD_SIZE == 4 |
allankliu | 0:b6fdeddc0bc9 | 629 | static void vli_mmod_fast_secp224r1(uint32_t *result, uint32_t *product) |
allankliu | 0:b6fdeddc0bc9 | 630 | { |
allankliu | 0:b6fdeddc0bc9 | 631 | uint32_t tmp[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 632 | int carry; |
allankliu | 0:b6fdeddc0bc9 | 633 | |
allankliu | 0:b6fdeddc0bc9 | 634 | /* t */ |
allankliu | 0:b6fdeddc0bc9 | 635 | uECC_vli_set(result, product, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 636 | |
allankliu | 0:b6fdeddc0bc9 | 637 | /* s1 */ |
allankliu | 0:b6fdeddc0bc9 | 638 | tmp[0] = tmp[1] = tmp[2] = 0; |
allankliu | 0:b6fdeddc0bc9 | 639 | tmp[3] = product[7]; |
allankliu | 0:b6fdeddc0bc9 | 640 | tmp[4] = product[8]; |
allankliu | 0:b6fdeddc0bc9 | 641 | tmp[5] = product[9]; |
allankliu | 0:b6fdeddc0bc9 | 642 | tmp[6] = product[10]; |
allankliu | 0:b6fdeddc0bc9 | 643 | carry = uECC_vli_add(result, result, tmp, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 644 | |
allankliu | 0:b6fdeddc0bc9 | 645 | /* s2 */ |
allankliu | 0:b6fdeddc0bc9 | 646 | tmp[3] = product[11]; |
allankliu | 0:b6fdeddc0bc9 | 647 | tmp[4] = product[12]; |
allankliu | 0:b6fdeddc0bc9 | 648 | tmp[5] = product[13]; |
allankliu | 0:b6fdeddc0bc9 | 649 | tmp[6] = 0; |
allankliu | 0:b6fdeddc0bc9 | 650 | carry += uECC_vli_add(result, result, tmp, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 651 | |
allankliu | 0:b6fdeddc0bc9 | 652 | /* d1 */ |
allankliu | 0:b6fdeddc0bc9 | 653 | tmp[0] = product[7]; |
allankliu | 0:b6fdeddc0bc9 | 654 | tmp[1] = product[8]; |
allankliu | 0:b6fdeddc0bc9 | 655 | tmp[2] = product[9]; |
allankliu | 0:b6fdeddc0bc9 | 656 | tmp[3] = product[10]; |
allankliu | 0:b6fdeddc0bc9 | 657 | tmp[4] = product[11]; |
allankliu | 0:b6fdeddc0bc9 | 658 | tmp[5] = product[12]; |
allankliu | 0:b6fdeddc0bc9 | 659 | tmp[6] = product[13]; |
allankliu | 0:b6fdeddc0bc9 | 660 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 661 | |
allankliu | 0:b6fdeddc0bc9 | 662 | /* d2 */ |
allankliu | 0:b6fdeddc0bc9 | 663 | tmp[0] = product[11]; |
allankliu | 0:b6fdeddc0bc9 | 664 | tmp[1] = product[12]; |
allankliu | 0:b6fdeddc0bc9 | 665 | tmp[2] = product[13]; |
allankliu | 0:b6fdeddc0bc9 | 666 | tmp[3] = tmp[4] = tmp[5] = tmp[6] = 0; |
allankliu | 0:b6fdeddc0bc9 | 667 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 668 | |
allankliu | 0:b6fdeddc0bc9 | 669 | if (carry < 0) { |
allankliu | 0:b6fdeddc0bc9 | 670 | do { |
allankliu | 0:b6fdeddc0bc9 | 671 | carry += uECC_vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 672 | } while (carry < 0); |
allankliu | 0:b6fdeddc0bc9 | 673 | } else { |
allankliu | 0:b6fdeddc0bc9 | 674 | while (carry || uECC_vli_cmp_unsafe(curve_secp224r1.p, result, num_words_secp224r1) != 1) { |
allankliu | 0:b6fdeddc0bc9 | 675 | carry -= uECC_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 676 | } |
allankliu | 0:b6fdeddc0bc9 | 677 | } |
allankliu | 0:b6fdeddc0bc9 | 678 | } |
allankliu | 0:b6fdeddc0bc9 | 679 | #else |
allankliu | 0:b6fdeddc0bc9 | 680 | static void vli_mmod_fast_secp224r1(uint64_t *result, uint64_t *product) |
allankliu | 0:b6fdeddc0bc9 | 681 | { |
allankliu | 0:b6fdeddc0bc9 | 682 | uint64_t tmp[num_words_secp224r1]; |
allankliu | 0:b6fdeddc0bc9 | 683 | int carry = 0; |
allankliu | 0:b6fdeddc0bc9 | 684 | |
allankliu | 0:b6fdeddc0bc9 | 685 | /* t */ |
allankliu | 0:b6fdeddc0bc9 | 686 | uECC_vli_set(result, product, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 687 | result[num_words_secp224r1 - 1] &= 0xffffffff; |
allankliu | 0:b6fdeddc0bc9 | 688 | |
allankliu | 0:b6fdeddc0bc9 | 689 | /* s1 */ |
allankliu | 0:b6fdeddc0bc9 | 690 | tmp[0] = 0; |
allankliu | 0:b6fdeddc0bc9 | 691 | tmp[1] = product[3] & 0xffffffff00000000ull; |
allankliu | 0:b6fdeddc0bc9 | 692 | tmp[2] = product[4]; |
allankliu | 0:b6fdeddc0bc9 | 693 | tmp[3] = product[5] & 0xffffffff; |
allankliu | 0:b6fdeddc0bc9 | 694 | uECC_vli_add(result, result, tmp, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 695 | |
allankliu | 0:b6fdeddc0bc9 | 696 | /* s2 */ |
allankliu | 0:b6fdeddc0bc9 | 697 | tmp[1] = product[5] & 0xffffffff00000000ull; |
allankliu | 0:b6fdeddc0bc9 | 698 | tmp[2] = product[6]; |
allankliu | 0:b6fdeddc0bc9 | 699 | tmp[3] = 0; |
allankliu | 0:b6fdeddc0bc9 | 700 | uECC_vli_add(result, result, tmp, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 701 | |
allankliu | 0:b6fdeddc0bc9 | 702 | /* d1 */ |
allankliu | 0:b6fdeddc0bc9 | 703 | tmp[0] = (product[3] >> 32) | (product[4] << 32); |
allankliu | 0:b6fdeddc0bc9 | 704 | tmp[1] = (product[4] >> 32) | (product[5] << 32); |
allankliu | 0:b6fdeddc0bc9 | 705 | tmp[2] = (product[5] >> 32) | (product[6] << 32); |
allankliu | 0:b6fdeddc0bc9 | 706 | tmp[3] = product[6] >> 32; |
allankliu | 0:b6fdeddc0bc9 | 707 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 708 | |
allankliu | 0:b6fdeddc0bc9 | 709 | /* d2 */ |
allankliu | 0:b6fdeddc0bc9 | 710 | tmp[0] = (product[5] >> 32) | (product[6] << 32); |
allankliu | 0:b6fdeddc0bc9 | 711 | tmp[1] = product[6] >> 32; |
allankliu | 0:b6fdeddc0bc9 | 712 | tmp[2] = tmp[3] = 0; |
allankliu | 0:b6fdeddc0bc9 | 713 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 714 | |
allankliu | 0:b6fdeddc0bc9 | 715 | if (carry < 0) { |
allankliu | 0:b6fdeddc0bc9 | 716 | do { |
allankliu | 0:b6fdeddc0bc9 | 717 | carry += uECC_vli_add(result, result, curve_secp224r1.p, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 718 | } while (carry < 0); |
allankliu | 0:b6fdeddc0bc9 | 719 | } else { |
allankliu | 0:b6fdeddc0bc9 | 720 | while (uECC_vli_cmp_unsafe(curve_secp224r1.p, result, num_words_secp224r1) != 1) { |
allankliu | 0:b6fdeddc0bc9 | 721 | uECC_vli_sub(result, result, curve_secp224r1.p, num_words_secp224r1); |
allankliu | 0:b6fdeddc0bc9 | 722 | } |
allankliu | 0:b6fdeddc0bc9 | 723 | } |
allankliu | 0:b6fdeddc0bc9 | 724 | } |
allankliu | 0:b6fdeddc0bc9 | 725 | #endif /* uECC_WORD_SIZE */ |
allankliu | 0:b6fdeddc0bc9 | 726 | #endif /* (uECC_OPTIMIZATION_LEVEL > 0) */ |
allankliu | 0:b6fdeddc0bc9 | 727 | |
allankliu | 0:b6fdeddc0bc9 | 728 | #endif /* uECC_SUPPORTS_secp224r1 */ |
allankliu | 0:b6fdeddc0bc9 | 729 | |
allankliu | 0:b6fdeddc0bc9 | 730 | #if uECC_SUPPORTS_secp256r1 |
allankliu | 0:b6fdeddc0bc9 | 731 | |
allankliu | 0:b6fdeddc0bc9 | 732 | #if (uECC_OPTIMIZATION_LEVEL > 0) |
allankliu | 0:b6fdeddc0bc9 | 733 | static void vli_mmod_fast_secp256r1(uECC_word_t *result, uECC_word_t *product); |
allankliu | 0:b6fdeddc0bc9 | 734 | #endif |
allankliu | 0:b6fdeddc0bc9 | 735 | |
allankliu | 0:b6fdeddc0bc9 | 736 | static const struct uECC_Curve_t curve_secp256r1 = { |
allankliu | 0:b6fdeddc0bc9 | 737 | num_words_secp256r1, |
allankliu | 0:b6fdeddc0bc9 | 738 | num_bytes_secp256r1, |
allankliu | 0:b6fdeddc0bc9 | 739 | 256, /* num_n_bits */ |
allankliu | 0:b6fdeddc0bc9 | 740 | { BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 741 | BYTES_TO_WORDS_8(FF, FF, FF, FF, 00, 00, 00, 00), |
allankliu | 0:b6fdeddc0bc9 | 742 | BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), |
allankliu | 0:b6fdeddc0bc9 | 743 | BYTES_TO_WORDS_8(01, 00, 00, 00, FF, FF, FF, FF) }, |
allankliu | 0:b6fdeddc0bc9 | 744 | { BYTES_TO_WORDS_8(51, 25, 63, FC, C2, CA, B9, F3), |
allankliu | 0:b6fdeddc0bc9 | 745 | BYTES_TO_WORDS_8(84, 9E, 17, A7, AD, FA, E6, BC), |
allankliu | 0:b6fdeddc0bc9 | 746 | BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 747 | BYTES_TO_WORDS_8(00, 00, 00, 00, FF, FF, FF, FF) }, |
allankliu | 0:b6fdeddc0bc9 | 748 | { BYTES_TO_WORDS_8(96, C2, 98, D8, 45, 39, A1, F4), |
allankliu | 0:b6fdeddc0bc9 | 749 | BYTES_TO_WORDS_8(A0, 33, EB, 2D, 81, 7D, 03, 77), |
allankliu | 0:b6fdeddc0bc9 | 750 | BYTES_TO_WORDS_8(F2, 40, A4, 63, E5, E6, BC, F8), |
allankliu | 0:b6fdeddc0bc9 | 751 | BYTES_TO_WORDS_8(47, 42, 2C, E1, F2, D1, 17, 6B), |
allankliu | 0:b6fdeddc0bc9 | 752 | |
allankliu | 0:b6fdeddc0bc9 | 753 | BYTES_TO_WORDS_8(F5, 51, BF, 37, 68, 40, B6, CB), |
allankliu | 0:b6fdeddc0bc9 | 754 | BYTES_TO_WORDS_8(CE, 5E, 31, 6B, 57, 33, CE, 2B), |
allankliu | 0:b6fdeddc0bc9 | 755 | BYTES_TO_WORDS_8(16, 9E, 0F, 7C, 4A, EB, E7, 8E), |
allankliu | 0:b6fdeddc0bc9 | 756 | BYTES_TO_WORDS_8(9B, 7F, 1A, FE, E2, 42, E3, 4F) }, |
allankliu | 0:b6fdeddc0bc9 | 757 | { BYTES_TO_WORDS_8(4B, 60, D2, 27, 3E, 3C, CE, 3B), |
allankliu | 0:b6fdeddc0bc9 | 758 | BYTES_TO_WORDS_8(F6, B0, 53, CC, B0, 06, 1D, 65), |
allankliu | 0:b6fdeddc0bc9 | 759 | BYTES_TO_WORDS_8(BC, 86, 98, 76, 55, BD, EB, B3), |
allankliu | 0:b6fdeddc0bc9 | 760 | BYTES_TO_WORDS_8(E7, 93, 3A, AA, D8, 35, C6, 5A) }, |
allankliu | 0:b6fdeddc0bc9 | 761 | &double_jacobian_default, |
allankliu | 0:b6fdeddc0bc9 | 762 | #if uECC_SUPPORT_COMPRESSED_POINT |
allankliu | 0:b6fdeddc0bc9 | 763 | &mod_sqrt_default, |
allankliu | 0:b6fdeddc0bc9 | 764 | #endif |
allankliu | 0:b6fdeddc0bc9 | 765 | &x_side_default, |
allankliu | 0:b6fdeddc0bc9 | 766 | #if (uECC_OPTIMIZATION_LEVEL > 0) |
allankliu | 0:b6fdeddc0bc9 | 767 | &vli_mmod_fast_secp256r1 |
allankliu | 0:b6fdeddc0bc9 | 768 | #endif |
allankliu | 0:b6fdeddc0bc9 | 769 | }; |
allankliu | 0:b6fdeddc0bc9 | 770 | |
allankliu | 0:b6fdeddc0bc9 | 771 | uECC_Curve uECC_secp256r1(void) { return &curve_secp256r1; } |
allankliu | 0:b6fdeddc0bc9 | 772 | |
allankliu | 0:b6fdeddc0bc9 | 773 | |
allankliu | 0:b6fdeddc0bc9 | 774 | #if (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp256r1) |
allankliu | 0:b6fdeddc0bc9 | 775 | /* Computes result = product % curve_p |
allankliu | 0:b6fdeddc0bc9 | 776 | from http://www.nsa.gov/ia/_files/nist-routines.pdf */ |
allankliu | 0:b6fdeddc0bc9 | 777 | #if uECC_WORD_SIZE == 1 |
allankliu | 0:b6fdeddc0bc9 | 778 | static void vli_mmod_fast_secp256r1(uint8_t *result, uint8_t *product) { |
allankliu | 0:b6fdeddc0bc9 | 779 | uint8_t tmp[num_words_secp256r1]; |
allankliu | 0:b6fdeddc0bc9 | 780 | int8_t carry; |
allankliu | 0:b6fdeddc0bc9 | 781 | |
allankliu | 0:b6fdeddc0bc9 | 782 | /* t */ |
allankliu | 0:b6fdeddc0bc9 | 783 | uECC_vli_set(result, product, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 784 | |
allankliu | 0:b6fdeddc0bc9 | 785 | /* s1 */ |
allankliu | 0:b6fdeddc0bc9 | 786 | tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; |
allankliu | 0:b6fdeddc0bc9 | 787 | tmp[4] = tmp[5] = tmp[6] = tmp[7] = 0; |
allankliu | 0:b6fdeddc0bc9 | 788 | tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0; |
allankliu | 0:b6fdeddc0bc9 | 789 | tmp[12] = product[44]; tmp[13] = product[45]; tmp[14] = product[46]; tmp[15] = product[47]; |
allankliu | 0:b6fdeddc0bc9 | 790 | tmp[16] = product[48]; tmp[17] = product[49]; tmp[18] = product[50]; tmp[19] = product[51]; |
allankliu | 0:b6fdeddc0bc9 | 791 | tmp[20] = product[52]; tmp[21] = product[53]; tmp[22] = product[54]; tmp[23] = product[55]; |
allankliu | 0:b6fdeddc0bc9 | 792 | tmp[24] = product[56]; tmp[25] = product[57]; tmp[26] = product[58]; tmp[27] = product[59]; |
allankliu | 0:b6fdeddc0bc9 | 793 | tmp[28] = product[60]; tmp[29] = product[61]; tmp[30] = product[62]; tmp[31] = product[63]; |
allankliu | 0:b6fdeddc0bc9 | 794 | carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 795 | carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 796 | |
allankliu | 0:b6fdeddc0bc9 | 797 | /* s2 */ |
allankliu | 0:b6fdeddc0bc9 | 798 | tmp[12] = product[48]; tmp[13] = product[49]; tmp[14] = product[50]; tmp[15] = product[51]; |
allankliu | 0:b6fdeddc0bc9 | 799 | tmp[16] = product[52]; tmp[17] = product[53]; tmp[18] = product[54]; tmp[19] = product[55]; |
allankliu | 0:b6fdeddc0bc9 | 800 | tmp[20] = product[56]; tmp[21] = product[57]; tmp[22] = product[58]; tmp[23] = product[59]; |
allankliu | 0:b6fdeddc0bc9 | 801 | tmp[24] = product[60]; tmp[25] = product[61]; tmp[26] = product[62]; tmp[27] = product[63]; |
allankliu | 0:b6fdeddc0bc9 | 802 | tmp[28] = tmp[29] = tmp[30] = tmp[31] = 0; |
allankliu | 0:b6fdeddc0bc9 | 803 | carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 804 | carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 805 | |
allankliu | 0:b6fdeddc0bc9 | 806 | /* s3 */ |
allankliu | 0:b6fdeddc0bc9 | 807 | tmp[0] = product[32]; tmp[1] = product[33]; tmp[2] = product[34]; tmp[3] = product[35]; |
allankliu | 0:b6fdeddc0bc9 | 808 | tmp[4] = product[36]; tmp[5] = product[37]; tmp[6] = product[38]; tmp[7] = product[39]; |
allankliu | 0:b6fdeddc0bc9 | 809 | tmp[8] = product[40]; tmp[9] = product[41]; tmp[10] = product[42]; tmp[11] = product[43]; |
allankliu | 0:b6fdeddc0bc9 | 810 | tmp[12] = tmp[13] = tmp[14] = tmp[15] = 0; |
allankliu | 0:b6fdeddc0bc9 | 811 | tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; |
allankliu | 0:b6fdeddc0bc9 | 812 | tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; |
allankliu | 0:b6fdeddc0bc9 | 813 | tmp[24] = product[56]; tmp[25] = product[57]; tmp[26] = product[58]; tmp[27] = product[59]; |
allankliu | 0:b6fdeddc0bc9 | 814 | tmp[28] = product[60]; tmp[29] = product[61]; tmp[30] = product[62]; tmp[31] = product[63]; |
allankliu | 0:b6fdeddc0bc9 | 815 | carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 816 | |
allankliu | 0:b6fdeddc0bc9 | 817 | /* s4 */ |
allankliu | 0:b6fdeddc0bc9 | 818 | tmp[0] = product[36]; tmp[1] = product[37]; tmp[2] = product[38]; tmp[3] = product[39]; |
allankliu | 0:b6fdeddc0bc9 | 819 | tmp[4] = product[40]; tmp[5] = product[41]; tmp[6] = product[42]; tmp[7] = product[43]; |
allankliu | 0:b6fdeddc0bc9 | 820 | tmp[8] = product[44]; tmp[9] = product[45]; tmp[10] = product[46]; tmp[11] = product[47]; |
allankliu | 0:b6fdeddc0bc9 | 821 | tmp[12] = product[52]; tmp[13] = product[53]; tmp[14] = product[54]; tmp[15] = product[55]; |
allankliu | 0:b6fdeddc0bc9 | 822 | tmp[16] = product[56]; tmp[17] = product[57]; tmp[18] = product[58]; tmp[19] = product[59]; |
allankliu | 0:b6fdeddc0bc9 | 823 | tmp[20] = product[60]; tmp[21] = product[61]; tmp[22] = product[62]; tmp[23] = product[63]; |
allankliu | 0:b6fdeddc0bc9 | 824 | tmp[24] = product[52]; tmp[25] = product[53]; tmp[26] = product[54]; tmp[27] = product[55]; |
allankliu | 0:b6fdeddc0bc9 | 825 | tmp[28] = product[32]; tmp[29] = product[33]; tmp[30] = product[34]; tmp[31] = product[35]; |
allankliu | 0:b6fdeddc0bc9 | 826 | carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 827 | |
allankliu | 0:b6fdeddc0bc9 | 828 | /* d1 */ |
allankliu | 0:b6fdeddc0bc9 | 829 | tmp[0] = product[44]; tmp[1] = product[45]; tmp[2] = product[46]; tmp[3] = product[47]; |
allankliu | 0:b6fdeddc0bc9 | 830 | tmp[4] = product[48]; tmp[5] = product[49]; tmp[6] = product[50]; tmp[7] = product[51]; |
allankliu | 0:b6fdeddc0bc9 | 831 | tmp[8] = product[52]; tmp[9] = product[53]; tmp[10] = product[54]; tmp[11] = product[55]; |
allankliu | 0:b6fdeddc0bc9 | 832 | tmp[12] = tmp[13] = tmp[14] = tmp[15] = 0; |
allankliu | 0:b6fdeddc0bc9 | 833 | tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; |
allankliu | 0:b6fdeddc0bc9 | 834 | tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; |
allankliu | 0:b6fdeddc0bc9 | 835 | tmp[24] = product[32]; tmp[25] = product[33]; tmp[26] = product[34]; tmp[27] = product[35]; |
allankliu | 0:b6fdeddc0bc9 | 836 | tmp[28] = product[40]; tmp[29] = product[41]; tmp[30] = product[42]; tmp[31] = product[43]; |
allankliu | 0:b6fdeddc0bc9 | 837 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 838 | |
allankliu | 0:b6fdeddc0bc9 | 839 | /* d2 */ |
allankliu | 0:b6fdeddc0bc9 | 840 | tmp[0] = product[48]; tmp[1] = product[49]; tmp[2] = product[50]; tmp[3] = product[51]; |
allankliu | 0:b6fdeddc0bc9 | 841 | tmp[4] = product[52]; tmp[5] = product[53]; tmp[6] = product[54]; tmp[7] = product[55]; |
allankliu | 0:b6fdeddc0bc9 | 842 | tmp[8] = product[56]; tmp[9] = product[57]; tmp[10] = product[58]; tmp[11] = product[59]; |
allankliu | 0:b6fdeddc0bc9 | 843 | tmp[12] = product[60]; tmp[13] = product[61]; tmp[14] = product[62]; tmp[15] = product[63]; |
allankliu | 0:b6fdeddc0bc9 | 844 | tmp[16] = tmp[17] = tmp[18] = tmp[19] = 0; |
allankliu | 0:b6fdeddc0bc9 | 845 | tmp[20] = tmp[21] = tmp[22] = tmp[23] = 0; |
allankliu | 0:b6fdeddc0bc9 | 846 | tmp[24] = product[36]; tmp[25] = product[37]; tmp[26] = product[38]; tmp[27] = product[39]; |
allankliu | 0:b6fdeddc0bc9 | 847 | tmp[28] = product[44]; tmp[29] = product[45]; tmp[30] = product[46]; tmp[31] = product[47]; |
allankliu | 0:b6fdeddc0bc9 | 848 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 849 | |
allankliu | 0:b6fdeddc0bc9 | 850 | /* d3 */ |
allankliu | 0:b6fdeddc0bc9 | 851 | tmp[0] = product[52]; tmp[1] = product[53]; tmp[2] = product[54]; tmp[3] = product[55]; |
allankliu | 0:b6fdeddc0bc9 | 852 | tmp[4] = product[56]; tmp[5] = product[57]; tmp[6] = product[58]; tmp[7] = product[59]; |
allankliu | 0:b6fdeddc0bc9 | 853 | tmp[8] = product[60]; tmp[9] = product[61]; tmp[10] = product[62]; tmp[11] = product[63]; |
allankliu | 0:b6fdeddc0bc9 | 854 | tmp[12] = product[32]; tmp[13] = product[33]; tmp[14] = product[34]; tmp[15] = product[35]; |
allankliu | 0:b6fdeddc0bc9 | 855 | tmp[16] = product[36]; tmp[17] = product[37]; tmp[18] = product[38]; tmp[19] = product[39]; |
allankliu | 0:b6fdeddc0bc9 | 856 | tmp[20] = product[40]; tmp[21] = product[41]; tmp[22] = product[42]; tmp[23] = product[43]; |
allankliu | 0:b6fdeddc0bc9 | 857 | tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; |
allankliu | 0:b6fdeddc0bc9 | 858 | tmp[28] = product[48]; tmp[29] = product[49]; tmp[30] = product[50]; tmp[31] = product[51]; |
allankliu | 0:b6fdeddc0bc9 | 859 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 860 | |
allankliu | 0:b6fdeddc0bc9 | 861 | /* d4 */ |
allankliu | 0:b6fdeddc0bc9 | 862 | tmp[0] = product[56]; tmp[1] = product[57]; tmp[2] = product[58]; tmp[3] = product[59]; |
allankliu | 0:b6fdeddc0bc9 | 863 | tmp[4] = product[60]; tmp[5] = product[61]; tmp[6] = product[62]; tmp[7] = product[63]; |
allankliu | 0:b6fdeddc0bc9 | 864 | tmp[8] = tmp[9] = tmp[10] = tmp[11] = 0; |
allankliu | 0:b6fdeddc0bc9 | 865 | tmp[12] = product[36]; tmp[13] = product[37]; tmp[14] = product[38]; tmp[15] = product[39]; |
allankliu | 0:b6fdeddc0bc9 | 866 | tmp[16] = product[40]; tmp[17] = product[41]; tmp[18] = product[42]; tmp[19] = product[43]; |
allankliu | 0:b6fdeddc0bc9 | 867 | tmp[20] = product[44]; tmp[21] = product[45]; tmp[22] = product[46]; tmp[23] = product[47]; |
allankliu | 0:b6fdeddc0bc9 | 868 | tmp[24] = tmp[25] = tmp[26] = tmp[27] = 0; |
allankliu | 0:b6fdeddc0bc9 | 869 | tmp[28] = product[52]; tmp[29] = product[53]; tmp[30] = product[54]; tmp[31] = product[55]; |
allankliu | 0:b6fdeddc0bc9 | 870 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 871 | |
allankliu | 0:b6fdeddc0bc9 | 872 | if (carry < 0) { |
allankliu | 0:b6fdeddc0bc9 | 873 | do { |
allankliu | 0:b6fdeddc0bc9 | 874 | carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 875 | } while (carry < 0); |
allankliu | 0:b6fdeddc0bc9 | 876 | } else { |
allankliu | 0:b6fdeddc0bc9 | 877 | while (carry || uECC_vli_cmp_unsafe(curve_secp256r1.p, result, num_words_secp256r1) != 1) { |
allankliu | 0:b6fdeddc0bc9 | 878 | carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 879 | } |
allankliu | 0:b6fdeddc0bc9 | 880 | } |
allankliu | 0:b6fdeddc0bc9 | 881 | } |
allankliu | 0:b6fdeddc0bc9 | 882 | #elif uECC_WORD_SIZE == 4 |
allankliu | 0:b6fdeddc0bc9 | 883 | static void vli_mmod_fast_secp256r1(uint32_t *result, uint32_t *product) { |
allankliu | 0:b6fdeddc0bc9 | 884 | uint32_t tmp[num_words_secp256r1]; |
allankliu | 0:b6fdeddc0bc9 | 885 | int carry; |
allankliu | 0:b6fdeddc0bc9 | 886 | |
allankliu | 0:b6fdeddc0bc9 | 887 | /* t */ |
allankliu | 0:b6fdeddc0bc9 | 888 | uECC_vli_set(result, product, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 889 | |
allankliu | 0:b6fdeddc0bc9 | 890 | /* s1 */ |
allankliu | 0:b6fdeddc0bc9 | 891 | tmp[0] = tmp[1] = tmp[2] = 0; |
allankliu | 0:b6fdeddc0bc9 | 892 | tmp[3] = product[11]; |
allankliu | 0:b6fdeddc0bc9 | 893 | tmp[4] = product[12]; |
allankliu | 0:b6fdeddc0bc9 | 894 | tmp[5] = product[13]; |
allankliu | 0:b6fdeddc0bc9 | 895 | tmp[6] = product[14]; |
allankliu | 0:b6fdeddc0bc9 | 896 | tmp[7] = product[15]; |
allankliu | 0:b6fdeddc0bc9 | 897 | carry = uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 898 | carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 899 | |
allankliu | 0:b6fdeddc0bc9 | 900 | /* s2 */ |
allankliu | 0:b6fdeddc0bc9 | 901 | tmp[3] = product[12]; |
allankliu | 0:b6fdeddc0bc9 | 902 | tmp[4] = product[13]; |
allankliu | 0:b6fdeddc0bc9 | 903 | tmp[5] = product[14]; |
allankliu | 0:b6fdeddc0bc9 | 904 | tmp[6] = product[15]; |
allankliu | 0:b6fdeddc0bc9 | 905 | tmp[7] = 0; |
allankliu | 0:b6fdeddc0bc9 | 906 | carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 907 | carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 908 | |
allankliu | 0:b6fdeddc0bc9 | 909 | /* s3 */ |
allankliu | 0:b6fdeddc0bc9 | 910 | tmp[0] = product[8]; |
allankliu | 0:b6fdeddc0bc9 | 911 | tmp[1] = product[9]; |
allankliu | 0:b6fdeddc0bc9 | 912 | tmp[2] = product[10]; |
allankliu | 0:b6fdeddc0bc9 | 913 | tmp[3] = tmp[4] = tmp[5] = 0; |
allankliu | 0:b6fdeddc0bc9 | 914 | tmp[6] = product[14]; |
allankliu | 0:b6fdeddc0bc9 | 915 | tmp[7] = product[15]; |
allankliu | 0:b6fdeddc0bc9 | 916 | carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 917 | |
allankliu | 0:b6fdeddc0bc9 | 918 | /* s4 */ |
allankliu | 0:b6fdeddc0bc9 | 919 | tmp[0] = product[9]; |
allankliu | 0:b6fdeddc0bc9 | 920 | tmp[1] = product[10]; |
allankliu | 0:b6fdeddc0bc9 | 921 | tmp[2] = product[11]; |
allankliu | 0:b6fdeddc0bc9 | 922 | tmp[3] = product[13]; |
allankliu | 0:b6fdeddc0bc9 | 923 | tmp[4] = product[14]; |
allankliu | 0:b6fdeddc0bc9 | 924 | tmp[5] = product[15]; |
allankliu | 0:b6fdeddc0bc9 | 925 | tmp[6] = product[13]; |
allankliu | 0:b6fdeddc0bc9 | 926 | tmp[7] = product[8]; |
allankliu | 0:b6fdeddc0bc9 | 927 | carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 928 | |
allankliu | 0:b6fdeddc0bc9 | 929 | /* d1 */ |
allankliu | 0:b6fdeddc0bc9 | 930 | tmp[0] = product[11]; |
allankliu | 0:b6fdeddc0bc9 | 931 | tmp[1] = product[12]; |
allankliu | 0:b6fdeddc0bc9 | 932 | tmp[2] = product[13]; |
allankliu | 0:b6fdeddc0bc9 | 933 | tmp[3] = tmp[4] = tmp[5] = 0; |
allankliu | 0:b6fdeddc0bc9 | 934 | tmp[6] = product[8]; |
allankliu | 0:b6fdeddc0bc9 | 935 | tmp[7] = product[10]; |
allankliu | 0:b6fdeddc0bc9 | 936 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 937 | |
allankliu | 0:b6fdeddc0bc9 | 938 | /* d2 */ |
allankliu | 0:b6fdeddc0bc9 | 939 | tmp[0] = product[12]; |
allankliu | 0:b6fdeddc0bc9 | 940 | tmp[1] = product[13]; |
allankliu | 0:b6fdeddc0bc9 | 941 | tmp[2] = product[14]; |
allankliu | 0:b6fdeddc0bc9 | 942 | tmp[3] = product[15]; |
allankliu | 0:b6fdeddc0bc9 | 943 | tmp[4] = tmp[5] = 0; |
allankliu | 0:b6fdeddc0bc9 | 944 | tmp[6] = product[9]; |
allankliu | 0:b6fdeddc0bc9 | 945 | tmp[7] = product[11]; |
allankliu | 0:b6fdeddc0bc9 | 946 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 947 | |
allankliu | 0:b6fdeddc0bc9 | 948 | /* d3 */ |
allankliu | 0:b6fdeddc0bc9 | 949 | tmp[0] = product[13]; |
allankliu | 0:b6fdeddc0bc9 | 950 | tmp[1] = product[14]; |
allankliu | 0:b6fdeddc0bc9 | 951 | tmp[2] = product[15]; |
allankliu | 0:b6fdeddc0bc9 | 952 | tmp[3] = product[8]; |
allankliu | 0:b6fdeddc0bc9 | 953 | tmp[4] = product[9]; |
allankliu | 0:b6fdeddc0bc9 | 954 | tmp[5] = product[10]; |
allankliu | 0:b6fdeddc0bc9 | 955 | tmp[6] = 0; |
allankliu | 0:b6fdeddc0bc9 | 956 | tmp[7] = product[12]; |
allankliu | 0:b6fdeddc0bc9 | 957 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 958 | |
allankliu | 0:b6fdeddc0bc9 | 959 | /* d4 */ |
allankliu | 0:b6fdeddc0bc9 | 960 | tmp[0] = product[14]; |
allankliu | 0:b6fdeddc0bc9 | 961 | tmp[1] = product[15]; |
allankliu | 0:b6fdeddc0bc9 | 962 | tmp[2] = 0; |
allankliu | 0:b6fdeddc0bc9 | 963 | tmp[3] = product[9]; |
allankliu | 0:b6fdeddc0bc9 | 964 | tmp[4] = product[10]; |
allankliu | 0:b6fdeddc0bc9 | 965 | tmp[5] = product[11]; |
allankliu | 0:b6fdeddc0bc9 | 966 | tmp[6] = 0; |
allankliu | 0:b6fdeddc0bc9 | 967 | tmp[7] = product[13]; |
allankliu | 0:b6fdeddc0bc9 | 968 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 969 | |
allankliu | 0:b6fdeddc0bc9 | 970 | if (carry < 0) { |
allankliu | 0:b6fdeddc0bc9 | 971 | do { |
allankliu | 0:b6fdeddc0bc9 | 972 | carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 973 | } while (carry < 0); |
allankliu | 0:b6fdeddc0bc9 | 974 | } else { |
allankliu | 0:b6fdeddc0bc9 | 975 | while (carry || uECC_vli_cmp_unsafe(curve_secp256r1.p, result, num_words_secp256r1) != 1) { |
allankliu | 0:b6fdeddc0bc9 | 976 | carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 977 | } |
allankliu | 0:b6fdeddc0bc9 | 978 | } |
allankliu | 0:b6fdeddc0bc9 | 979 | } |
allankliu | 0:b6fdeddc0bc9 | 980 | #else |
allankliu | 0:b6fdeddc0bc9 | 981 | static void vli_mmod_fast_secp256r1(uint64_t *result, uint64_t *product) { |
allankliu | 0:b6fdeddc0bc9 | 982 | uint64_t tmp[num_words_secp256r1]; |
allankliu | 0:b6fdeddc0bc9 | 983 | int carry; |
allankliu | 0:b6fdeddc0bc9 | 984 | |
allankliu | 0:b6fdeddc0bc9 | 985 | /* t */ |
allankliu | 0:b6fdeddc0bc9 | 986 | uECC_vli_set(result, product, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 987 | |
allankliu | 0:b6fdeddc0bc9 | 988 | /* s1 */ |
allankliu | 0:b6fdeddc0bc9 | 989 | tmp[0] = 0; |
allankliu | 0:b6fdeddc0bc9 | 990 | tmp[1] = product[5] & 0xffffffff00000000ull; |
allankliu | 0:b6fdeddc0bc9 | 991 | tmp[2] = product[6]; |
allankliu | 0:b6fdeddc0bc9 | 992 | tmp[3] = product[7]; |
allankliu | 0:b6fdeddc0bc9 | 993 | carry = (int)uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 994 | carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 995 | |
allankliu | 0:b6fdeddc0bc9 | 996 | /* s2 */ |
allankliu | 0:b6fdeddc0bc9 | 997 | tmp[1] = product[6] << 32; |
allankliu | 0:b6fdeddc0bc9 | 998 | tmp[2] = (product[6] >> 32) | (product[7] << 32); |
allankliu | 0:b6fdeddc0bc9 | 999 | tmp[3] = product[7] >> 32; |
allankliu | 0:b6fdeddc0bc9 | 1000 | carry += uECC_vli_add(tmp, tmp, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 1001 | carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 1002 | |
allankliu | 0:b6fdeddc0bc9 | 1003 | /* s3 */ |
allankliu | 0:b6fdeddc0bc9 | 1004 | tmp[0] = product[4]; |
allankliu | 0:b6fdeddc0bc9 | 1005 | tmp[1] = product[5] & 0xffffffff; |
allankliu | 0:b6fdeddc0bc9 | 1006 | tmp[2] = 0; |
allankliu | 0:b6fdeddc0bc9 | 1007 | tmp[3] = product[7]; |
allankliu | 0:b6fdeddc0bc9 | 1008 | carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 1009 | |
allankliu | 0:b6fdeddc0bc9 | 1010 | /* s4 */ |
allankliu | 0:b6fdeddc0bc9 | 1011 | tmp[0] = (product[4] >> 32) | (product[5] << 32); |
allankliu | 0:b6fdeddc0bc9 | 1012 | tmp[1] = (product[5] >> 32) | (product[6] & 0xffffffff00000000ull); |
allankliu | 0:b6fdeddc0bc9 | 1013 | tmp[2] = product[7]; |
allankliu | 0:b6fdeddc0bc9 | 1014 | tmp[3] = (product[6] >> 32) | (product[4] << 32); |
allankliu | 0:b6fdeddc0bc9 | 1015 | carry += uECC_vli_add(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 1016 | |
allankliu | 0:b6fdeddc0bc9 | 1017 | /* d1 */ |
allankliu | 0:b6fdeddc0bc9 | 1018 | tmp[0] = (product[5] >> 32) | (product[6] << 32); |
allankliu | 0:b6fdeddc0bc9 | 1019 | tmp[1] = (product[6] >> 32); |
allankliu | 0:b6fdeddc0bc9 | 1020 | tmp[2] = 0; |
allankliu | 0:b6fdeddc0bc9 | 1021 | tmp[3] = (product[4] & 0xffffffff) | (product[5] << 32); |
allankliu | 0:b6fdeddc0bc9 | 1022 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 1023 | |
allankliu | 0:b6fdeddc0bc9 | 1024 | /* d2 */ |
allankliu | 0:b6fdeddc0bc9 | 1025 | tmp[0] = product[6]; |
allankliu | 0:b6fdeddc0bc9 | 1026 | tmp[1] = product[7]; |
allankliu | 0:b6fdeddc0bc9 | 1027 | tmp[2] = 0; |
allankliu | 0:b6fdeddc0bc9 | 1028 | tmp[3] = (product[4] >> 32) | (product[5] & 0xffffffff00000000ull); |
allankliu | 0:b6fdeddc0bc9 | 1029 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 1030 | |
allankliu | 0:b6fdeddc0bc9 | 1031 | /* d3 */ |
allankliu | 0:b6fdeddc0bc9 | 1032 | tmp[0] = (product[6] >> 32) | (product[7] << 32); |
allankliu | 0:b6fdeddc0bc9 | 1033 | tmp[1] = (product[7] >> 32) | (product[4] << 32); |
allankliu | 0:b6fdeddc0bc9 | 1034 | tmp[2] = (product[4] >> 32) | (product[5] << 32); |
allankliu | 0:b6fdeddc0bc9 | 1035 | tmp[3] = (product[6] << 32); |
allankliu | 0:b6fdeddc0bc9 | 1036 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 1037 | |
allankliu | 0:b6fdeddc0bc9 | 1038 | /* d4 */ |
allankliu | 0:b6fdeddc0bc9 | 1039 | tmp[0] = product[7]; |
allankliu | 0:b6fdeddc0bc9 | 1040 | tmp[1] = product[4] & 0xffffffff00000000ull; |
allankliu | 0:b6fdeddc0bc9 | 1041 | tmp[2] = product[5]; |
allankliu | 0:b6fdeddc0bc9 | 1042 | tmp[3] = product[6] & 0xffffffff00000000ull; |
allankliu | 0:b6fdeddc0bc9 | 1043 | carry -= uECC_vli_sub(result, result, tmp, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 1044 | |
allankliu | 0:b6fdeddc0bc9 | 1045 | if (carry < 0) { |
allankliu | 0:b6fdeddc0bc9 | 1046 | do { |
allankliu | 0:b6fdeddc0bc9 | 1047 | carry += uECC_vli_add(result, result, curve_secp256r1.p, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 1048 | } while (carry < 0); |
allankliu | 0:b6fdeddc0bc9 | 1049 | } else { |
allankliu | 0:b6fdeddc0bc9 | 1050 | while (carry || uECC_vli_cmp_unsafe(curve_secp256r1.p, result, num_words_secp256r1) != 1) { |
allankliu | 0:b6fdeddc0bc9 | 1051 | carry -= uECC_vli_sub(result, result, curve_secp256r1.p, num_words_secp256r1); |
allankliu | 0:b6fdeddc0bc9 | 1052 | } |
allankliu | 0:b6fdeddc0bc9 | 1053 | } |
allankliu | 0:b6fdeddc0bc9 | 1054 | } |
allankliu | 0:b6fdeddc0bc9 | 1055 | #endif /* uECC_WORD_SIZE */ |
allankliu | 0:b6fdeddc0bc9 | 1056 | #endif /* (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp256r1) */ |
allankliu | 0:b6fdeddc0bc9 | 1057 | |
allankliu | 0:b6fdeddc0bc9 | 1058 | #endif /* uECC_SUPPORTS_secp256r1 */ |
allankliu | 0:b6fdeddc0bc9 | 1059 | |
allankliu | 0:b6fdeddc0bc9 | 1060 | #if uECC_SUPPORTS_secp256k1 |
allankliu | 0:b6fdeddc0bc9 | 1061 | |
allankliu | 0:b6fdeddc0bc9 | 1062 | static void double_jacobian_secp256k1(uECC_word_t * X1, |
allankliu | 0:b6fdeddc0bc9 | 1063 | uECC_word_t * Y1, |
allankliu | 0:b6fdeddc0bc9 | 1064 | uECC_word_t * Z1, |
allankliu | 0:b6fdeddc0bc9 | 1065 | uECC_Curve curve); |
allankliu | 0:b6fdeddc0bc9 | 1066 | static void x_side_secp256k1(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve); |
allankliu | 0:b6fdeddc0bc9 | 1067 | #if (uECC_OPTIMIZATION_LEVEL > 0) |
allankliu | 0:b6fdeddc0bc9 | 1068 | static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product); |
allankliu | 0:b6fdeddc0bc9 | 1069 | #endif |
allankliu | 0:b6fdeddc0bc9 | 1070 | |
allankliu | 0:b6fdeddc0bc9 | 1071 | static const struct uECC_Curve_t curve_secp256k1 = { |
allankliu | 0:b6fdeddc0bc9 | 1072 | num_words_secp256k1, |
allankliu | 0:b6fdeddc0bc9 | 1073 | num_bytes_secp256k1, |
allankliu | 0:b6fdeddc0bc9 | 1074 | 256, /* num_n_bits */ |
allankliu | 0:b6fdeddc0bc9 | 1075 | { BYTES_TO_WORDS_8(2F, FC, FF, FF, FE, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 1076 | BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 1077 | BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 1078 | BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, |
allankliu | 0:b6fdeddc0bc9 | 1079 | { BYTES_TO_WORDS_8(41, 41, 36, D0, 8C, 5E, D2, BF), |
allankliu | 0:b6fdeddc0bc9 | 1080 | BYTES_TO_WORDS_8(3B, A0, 48, AF, E6, DC, AE, BA), |
allankliu | 0:b6fdeddc0bc9 | 1081 | BYTES_TO_WORDS_8(FE, FF, FF, FF, FF, FF, FF, FF), |
allankliu | 0:b6fdeddc0bc9 | 1082 | BYTES_TO_WORDS_8(FF, FF, FF, FF, FF, FF, FF, FF) }, |
allankliu | 0:b6fdeddc0bc9 | 1083 | { BYTES_TO_WORDS_8(98, 17, F8, 16, 5B, 81, F2, 59), |
allankliu | 0:b6fdeddc0bc9 | 1084 | BYTES_TO_WORDS_8(D9, 28, CE, 2D, DB, FC, 9B, 02), |
allankliu | 0:b6fdeddc0bc9 | 1085 | BYTES_TO_WORDS_8(07, 0B, 87, CE, 95, 62, A0, 55), |
allankliu | 0:b6fdeddc0bc9 | 1086 | BYTES_TO_WORDS_8(AC, BB, DC, F9, 7E, 66, BE, 79), |
allankliu | 0:b6fdeddc0bc9 | 1087 | |
allankliu | 0:b6fdeddc0bc9 | 1088 | BYTES_TO_WORDS_8(B8, D4, 10, FB, 8F, D0, 47, 9C), |
allankliu | 0:b6fdeddc0bc9 | 1089 | BYTES_TO_WORDS_8(19, 54, 85, A6, 48, B4, 17, FD), |
allankliu | 0:b6fdeddc0bc9 | 1090 | BYTES_TO_WORDS_8(A8, 08, 11, 0E, FC, FB, A4, 5D), |
allankliu | 0:b6fdeddc0bc9 | 1091 | BYTES_TO_WORDS_8(65, C4, A3, 26, 77, DA, 3A, 48) }, |
allankliu | 0:b6fdeddc0bc9 | 1092 | { BYTES_TO_WORDS_8(07, 00, 00, 00, 00, 00, 00, 00), |
allankliu | 0:b6fdeddc0bc9 | 1093 | BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), |
allankliu | 0:b6fdeddc0bc9 | 1094 | BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00), |
allankliu | 0:b6fdeddc0bc9 | 1095 | BYTES_TO_WORDS_8(00, 00, 00, 00, 00, 00, 00, 00) }, |
allankliu | 0:b6fdeddc0bc9 | 1096 | &double_jacobian_secp256k1, |
allankliu | 0:b6fdeddc0bc9 | 1097 | #if uECC_SUPPORT_COMPRESSED_POINT |
allankliu | 0:b6fdeddc0bc9 | 1098 | &mod_sqrt_default, |
allankliu | 0:b6fdeddc0bc9 | 1099 | #endif |
allankliu | 0:b6fdeddc0bc9 | 1100 | &x_side_secp256k1, |
allankliu | 0:b6fdeddc0bc9 | 1101 | #if (uECC_OPTIMIZATION_LEVEL > 0) |
allankliu | 0:b6fdeddc0bc9 | 1102 | &vli_mmod_fast_secp256k1 |
allankliu | 0:b6fdeddc0bc9 | 1103 | #endif |
allankliu | 0:b6fdeddc0bc9 | 1104 | }; |
allankliu | 0:b6fdeddc0bc9 | 1105 | |
allankliu | 0:b6fdeddc0bc9 | 1106 | uECC_Curve uECC_secp256k1(void) { return &curve_secp256k1; } |
allankliu | 0:b6fdeddc0bc9 | 1107 | |
allankliu | 0:b6fdeddc0bc9 | 1108 | |
allankliu | 0:b6fdeddc0bc9 | 1109 | /* Double in place */ |
allankliu | 0:b6fdeddc0bc9 | 1110 | static void double_jacobian_secp256k1(uECC_word_t * X1, |
allankliu | 0:b6fdeddc0bc9 | 1111 | uECC_word_t * Y1, |
allankliu | 0:b6fdeddc0bc9 | 1112 | uECC_word_t * Z1, |
allankliu | 0:b6fdeddc0bc9 | 1113 | uECC_Curve curve) { |
allankliu | 0:b6fdeddc0bc9 | 1114 | /* t1 = X, t2 = Y, t3 = Z */ |
allankliu | 0:b6fdeddc0bc9 | 1115 | uECC_word_t t4[num_words_secp256k1]; |
allankliu | 0:b6fdeddc0bc9 | 1116 | uECC_word_t t5[num_words_secp256k1]; |
allankliu | 0:b6fdeddc0bc9 | 1117 | |
allankliu | 0:b6fdeddc0bc9 | 1118 | if (uECC_vli_isZero(Z1, num_words_secp256k1)) { |
allankliu | 0:b6fdeddc0bc9 | 1119 | return; |
allankliu | 0:b6fdeddc0bc9 | 1120 | } |
allankliu | 0:b6fdeddc0bc9 | 1121 | |
allankliu | 0:b6fdeddc0bc9 | 1122 | uECC_vli_modSquare_fast(t5, Y1, curve); /* t5 = y1^2 */ |
allankliu | 0:b6fdeddc0bc9 | 1123 | uECC_vli_modMult_fast(t4, X1, t5, curve); /* t4 = x1*y1^2 = A */ |
allankliu | 0:b6fdeddc0bc9 | 1124 | uECC_vli_modSquare_fast(X1, X1, curve); /* t1 = x1^2 */ |
allankliu | 0:b6fdeddc0bc9 | 1125 | uECC_vli_modSquare_fast(t5, t5, curve); /* t5 = y1^4 */ |
allankliu | 0:b6fdeddc0bc9 | 1126 | uECC_vli_modMult_fast(Z1, Y1, Z1, curve); /* t3 = y1*z1 = z3 */ |
allankliu | 0:b6fdeddc0bc9 | 1127 | |
allankliu | 0:b6fdeddc0bc9 | 1128 | uECC_vli_modAdd(Y1, X1, X1, curve->p, num_words_secp256k1); /* t2 = 2*x1^2 */ |
allankliu | 0:b6fdeddc0bc9 | 1129 | uECC_vli_modAdd(Y1, Y1, X1, curve->p, num_words_secp256k1); /* t2 = 3*x1^2 */ |
allankliu | 0:b6fdeddc0bc9 | 1130 | if (uECC_vli_testBit(Y1, 0)) { |
allankliu | 0:b6fdeddc0bc9 | 1131 | uECC_word_t carry = uECC_vli_add(Y1, Y1, curve->p, num_words_secp256k1); |
allankliu | 0:b6fdeddc0bc9 | 1132 | uECC_vli_rshift1(Y1, num_words_secp256k1); |
allankliu | 0:b6fdeddc0bc9 | 1133 | Y1[num_words_secp256k1 - 1] |= carry << (uECC_WORD_BITS - 1); |
allankliu | 0:b6fdeddc0bc9 | 1134 | } else { |
allankliu | 0:b6fdeddc0bc9 | 1135 | uECC_vli_rshift1(Y1, num_words_secp256k1); |
allankliu | 0:b6fdeddc0bc9 | 1136 | } |
allankliu | 0:b6fdeddc0bc9 | 1137 | /* t2 = 3/2*(x1^2) = B */ |
allankliu | 0:b6fdeddc0bc9 | 1138 | |
allankliu | 0:b6fdeddc0bc9 | 1139 | uECC_vli_modSquare_fast(X1, Y1, curve); /* t1 = B^2 */ |
allankliu | 0:b6fdeddc0bc9 | 1140 | uECC_vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - A */ |
allankliu | 0:b6fdeddc0bc9 | 1141 | uECC_vli_modSub(X1, X1, t4, curve->p, num_words_secp256k1); /* t1 = B^2 - 2A = x3 */ |
allankliu | 0:b6fdeddc0bc9 | 1142 | |
allankliu | 0:b6fdeddc0bc9 | 1143 | uECC_vli_modSub(t4, t4, X1, curve->p, num_words_secp256k1); /* t4 = A - x3 */ |
allankliu | 0:b6fdeddc0bc9 | 1144 | uECC_vli_modMult_fast(Y1, Y1, t4, curve); /* t2 = B * (A - x3) */ |
allankliu | 0:b6fdeddc0bc9 | 1145 | uECC_vli_modSub(Y1, Y1, t5, curve->p, num_words_secp256k1); /* t2 = B * (A - x3) - y1^4 = y3 */ |
allankliu | 0:b6fdeddc0bc9 | 1146 | } |
allankliu | 0:b6fdeddc0bc9 | 1147 | |
allankliu | 0:b6fdeddc0bc9 | 1148 | /* Computes result = x^3 + b. result must not overlap x. */ |
allankliu | 0:b6fdeddc0bc9 | 1149 | static void x_side_secp256k1(uECC_word_t *result, const uECC_word_t *x, uECC_Curve curve) { |
allankliu | 0:b6fdeddc0bc9 | 1150 | uECC_vli_modSquare_fast(result, x, curve); /* r = x^2 */ |
allankliu | 0:b6fdeddc0bc9 | 1151 | uECC_vli_modMult_fast(result, result, x, curve); /* r = x^3 */ |
allankliu | 0:b6fdeddc0bc9 | 1152 | uECC_vli_modAdd(result, result, curve->b, curve->p, num_words_secp256k1); /* r = x^3 + b */ |
allankliu | 0:b6fdeddc0bc9 | 1153 | } |
allankliu | 0:b6fdeddc0bc9 | 1154 | |
allankliu | 0:b6fdeddc0bc9 | 1155 | #if (uECC_OPTIMIZATION_LEVEL > 0 && !asm_mmod_fast_secp256k1) |
allankliu | 0:b6fdeddc0bc9 | 1156 | static void omega_mult_secp256k1(uECC_word_t *result, const uECC_word_t *right); |
allankliu | 0:b6fdeddc0bc9 | 1157 | static void vli_mmod_fast_secp256k1(uECC_word_t *result, uECC_word_t *product) { |
allankliu | 0:b6fdeddc0bc9 | 1158 | uECC_word_t tmp[2 * num_words_secp256k1]; |
allankliu | 0:b6fdeddc0bc9 | 1159 | uECC_word_t carry; |
allankliu | 0:b6fdeddc0bc9 | 1160 | |
allankliu | 0:b6fdeddc0bc9 | 1161 | uECC_vli_clear(tmp, num_words_secp256k1); |
allankliu | 0:b6fdeddc0bc9 | 1162 | uECC_vli_clear(tmp + num_words_secp256k1, num_words_secp256k1); |
allankliu | 0:b6fdeddc0bc9 | 1163 | |
allankliu | 0:b6fdeddc0bc9 | 1164 | omega_mult_secp256k1(tmp, product + num_words_secp256k1); /* (Rq, q) = q * c */ |
allankliu | 0:b6fdeddc0bc9 | 1165 | |
allankliu | 0:b6fdeddc0bc9 | 1166 | carry = uECC_vli_add(result, product, tmp, num_words_secp256k1); /* (C, r) = r + q */ |
allankliu | 0:b6fdeddc0bc9 | 1167 | uECC_vli_clear(product, num_words_secp256k1); |
allankliu | 0:b6fdeddc0bc9 | 1168 | omega_mult_secp256k1(product, tmp + num_words_secp256k1); /* Rq*c */ |
allankliu | 0:b6fdeddc0bc9 | 1169 | carry += uECC_vli_add(result, result, product, num_words_secp256k1); /* (C1, r) = r + Rq*c */ |
allankliu | 0:b6fdeddc0bc9 | 1170 | |
allankliu | 0:b6fdeddc0bc9 | 1171 | while (carry > 0) { |
allankliu | 0:b6fdeddc0bc9 | 1172 | --carry; |
allankliu | 0:b6fdeddc0bc9 | 1173 | uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); |
allankliu | 0:b6fdeddc0bc9 | 1174 | } |
allankliu | 0:b6fdeddc0bc9 | 1175 | if (uECC_vli_cmp_unsafe(result, curve_secp256k1.p, num_words_secp256k1) > 0) { |
allankliu | 0:b6fdeddc0bc9 | 1176 | uECC_vli_sub(result, result, curve_secp256k1.p, num_words_secp256k1); |
allankliu | 0:b6fdeddc0bc9 | 1177 | } |
allankliu | 0:b6fdeddc0bc9 | 1178 | } |
allankliu | 0:b6fdeddc0bc9 | 1179 | |
allankliu | 0:b6fdeddc0bc9 | 1180 | #if uECC_WORD_SIZE == 1 |
allankliu | 0:b6fdeddc0bc9 | 1181 | static void omega_mult_secp256k1(uint8_t * result, const uint8_t * right) { |
allankliu | 0:b6fdeddc0bc9 | 1182 | /* Multiply by (2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ |
allankliu | 0:b6fdeddc0bc9 | 1183 | uECC_word_t r0 = 0; |
allankliu | 0:b6fdeddc0bc9 | 1184 | uECC_word_t r1 = 0; |
allankliu | 0:b6fdeddc0bc9 | 1185 | uECC_word_t r2 = 0; |
allankliu | 0:b6fdeddc0bc9 | 1186 | wordcount_t k; |
allankliu | 0:b6fdeddc0bc9 | 1187 | |
allankliu | 0:b6fdeddc0bc9 | 1188 | /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ |
allankliu | 0:b6fdeddc0bc9 | 1189 | muladd(0xD1, right[0], &r0, &r1, &r2); |
allankliu | 0:b6fdeddc0bc9 | 1190 | result[0] = r0; |
allankliu | 0:b6fdeddc0bc9 | 1191 | r0 = r1; |
allankliu | 0:b6fdeddc0bc9 | 1192 | r1 = r2; |
allankliu | 0:b6fdeddc0bc9 | 1193 | /* r2 is still 0 */ |
allankliu | 0:b6fdeddc0bc9 | 1194 | |
allankliu | 0:b6fdeddc0bc9 | 1195 | for (k = 1; k < num_words_secp256k1; ++k) { |
allankliu | 0:b6fdeddc0bc9 | 1196 | muladd(0x03, right[k - 1], &r0, &r1, &r2); |
allankliu | 0:b6fdeddc0bc9 | 1197 | muladd(0xD1, right[k], &r0, &r1, &r2); |
allankliu | 0:b6fdeddc0bc9 | 1198 | result[k] = r0; |
allankliu | 0:b6fdeddc0bc9 | 1199 | r0 = r1; |
allankliu | 0:b6fdeddc0bc9 | 1200 | r1 = r2; |
allankliu | 0:b6fdeddc0bc9 | 1201 | r2 = 0; |
allankliu | 0:b6fdeddc0bc9 | 1202 | } |
allankliu | 0:b6fdeddc0bc9 | 1203 | muladd(0x03, right[num_words_secp256k1 - 1], &r0, &r1, &r2); |
allankliu | 0:b6fdeddc0bc9 | 1204 | result[num_words_secp256k1] = r0; |
allankliu | 0:b6fdeddc0bc9 | 1205 | result[num_words_secp256k1 + 1] = r1; |
allankliu | 0:b6fdeddc0bc9 | 1206 | /* add the 2^32 multiple */ |
allankliu | 0:b6fdeddc0bc9 | 1207 | result[4 + num_words_secp256k1] = |
allankliu | 0:b6fdeddc0bc9 | 1208 | uECC_vli_add(result + 4, result + 4, right, num_words_secp256k1); |
allankliu | 0:b6fdeddc0bc9 | 1209 | } |
allankliu | 0:b6fdeddc0bc9 | 1210 | #elif uECC_WORD_SIZE == 4 |
allankliu | 0:b6fdeddc0bc9 | 1211 | static void omega_mult_secp256k1(uint32_t * result, const uint32_t * right) { |
allankliu | 0:b6fdeddc0bc9 | 1212 | /* Multiply by (2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ |
allankliu | 0:b6fdeddc0bc9 | 1213 | uint32_t carry = 0; |
allankliu | 0:b6fdeddc0bc9 | 1214 | wordcount_t k; |
allankliu | 0:b6fdeddc0bc9 | 1215 | |
allankliu | 0:b6fdeddc0bc9 | 1216 | for (k = 0; k < num_words_secp256k1; ++k) { |
allankliu | 0:b6fdeddc0bc9 | 1217 | uint64_t p = (uint64_t)0x3D1 * right[k] + carry; |
allankliu | 0:b6fdeddc0bc9 | 1218 | result[k] = (uint32_t) p; |
allankliu | 0:b6fdeddc0bc9 | 1219 | carry = p >> 32; |
allankliu | 0:b6fdeddc0bc9 | 1220 | } |
allankliu | 0:b6fdeddc0bc9 | 1221 | result[num_words_secp256k1] = carry; |
allankliu | 0:b6fdeddc0bc9 | 1222 | /* add the 2^32 multiple */ |
allankliu | 0:b6fdeddc0bc9 | 1223 | result[1 + num_words_secp256k1] = |
allankliu | 0:b6fdeddc0bc9 | 1224 | uECC_vli_add(result + 1, result + 1, right, num_words_secp256k1); |
allankliu | 0:b6fdeddc0bc9 | 1225 | } |
allankliu | 0:b6fdeddc0bc9 | 1226 | #else |
allankliu | 0:b6fdeddc0bc9 | 1227 | static void omega_mult_secp256k1(uint64_t * result, const uint64_t * right) { |
allankliu | 0:b6fdeddc0bc9 | 1228 | uECC_word_t r0 = 0; |
allankliu | 0:b6fdeddc0bc9 | 1229 | uECC_word_t r1 = 0; |
allankliu | 0:b6fdeddc0bc9 | 1230 | uECC_word_t r2 = 0; |
allankliu | 0:b6fdeddc0bc9 | 1231 | wordcount_t k; |
allankliu | 0:b6fdeddc0bc9 | 1232 | |
allankliu | 0:b6fdeddc0bc9 | 1233 | /* Multiply by (2^32 + 2^9 + 2^8 + 2^7 + 2^6 + 2^4 + 1). */ |
allankliu | 0:b6fdeddc0bc9 | 1234 | for (k = 0; k < num_words_secp256k1; ++k) { |
allankliu | 0:b6fdeddc0bc9 | 1235 | muladd(0x1000003D1ull, right[k], &r0, &r1, &r2); |
allankliu | 0:b6fdeddc0bc9 | 1236 | result[k] = r0; |
allankliu | 0:b6fdeddc0bc9 | 1237 | r0 = r1; |
allankliu | 0:b6fdeddc0bc9 | 1238 | r1 = r2; |
allankliu | 0:b6fdeddc0bc9 | 1239 | r2 = 0; |
allankliu | 0:b6fdeddc0bc9 | 1240 | } |
allankliu | 0:b6fdeddc0bc9 | 1241 | result[num_words_secp256k1] = r0; |
allankliu | 0:b6fdeddc0bc9 | 1242 | } |
allankliu | 0:b6fdeddc0bc9 | 1243 | #endif /* uECC_WORD_SIZE */ |
allankliu | 0:b6fdeddc0bc9 | 1244 | #endif /* (uECC_OPTIMIZATION_LEVEL > 0 && && !asm_mmod_fast_secp256k1) */ |
allankliu | 0:b6fdeddc0bc9 | 1245 | |
allankliu | 0:b6fdeddc0bc9 | 1246 | #endif /* uECC_SUPPORTS_secp256k1 */ |
allankliu | 0:b6fdeddc0bc9 | 1247 | |
allankliu | 0:b6fdeddc0bc9 | 1248 | #endif /* _UECC_CURVE_SPECIFIC_H_ */ |