ECC support for curve y^2 = x^3 + a*x + b (part 2); ECDSA handling hashes longer then curve bitsize
Karel Miko
10 years ago
216 | 216 | @return CRYPT_OK on success |
217 | 217 | */ |
218 | 218 | int (*sqr)(void *a, void *b); |
219 | ||
220 | /** Square root (mod prime) | |
221 | @param a The integer to compute square root mod prime from | |
222 | @param b The prime | |
223 | @param c The destination | |
224 | @return CRYPT_OK on success | |
225 | */ | |
226 | int (*sqrtmod_prime)(void *a, void *b, void *c); | |
219 | 227 | |
220 | 228 | /** Divide an integer |
221 | 229 | @param a The dividend |
340 | 348 | @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only) |
341 | 349 | @return CRYPT_OK on success |
342 | 350 | */ |
343 | int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); | |
351 | int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map); | |
344 | 352 | |
345 | 353 | /** ECC GF(p) point addition |
346 | 354 | @param P The first point |
347 | 355 | @param Q The second point |
348 | 356 | @param R The destination of P + Q |
357 | @param a ECC curve parameter a (if NULL we assume a == -3) | |
349 | 358 | @param modulus The modulus |
350 | 359 | @param mp The "b" value from montgomery_setup() |
351 | 360 | @return CRYPT_OK on success |
352 | 361 | */ |
353 | int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); | |
362 | int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp); | |
354 | 363 | |
355 | 364 | /** ECC GF(p) point double |
356 | 365 | @param P The first point |
357 | 366 | @param R The destination of 2P |
358 | @param modulus The modulus | |
367 | @param a ECC curve parameter a (if NULL we assume a == -3) | |
368 | @param modulus The modulus of the field the ECC curve is in | |
359 | 369 | @param mp The "b" value from montgomery_setup() |
360 | 370 | @return CRYPT_OK on success |
361 | 371 | */ |
362 | int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp); | |
372 | int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp); | |
363 | 373 | |
364 | 374 | /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1) |
365 | 375 | @param P The point to map |
383 | 393 | int (*ecc_mul2add)(ecc_point *A, void *kA, |
384 | 394 | ecc_point *B, void *kB, |
385 | 395 | ecc_point *C, |
396 | void *a, | |
386 | 397 | void *modulus); |
387 | 398 | |
388 | 399 | /* ---- (optional) rsa optimized math (for internal CRT) ---- */ |
496 | 507 | #define mp_mul(a, b, c) ltc_mp.mul(a, b, c) |
497 | 508 | #define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c) |
498 | 509 | #define mp_sqr(a, b) ltc_mp.sqr(a, b) |
510 | #define mp_sqrtmod_prime(a, b, c) ltc_mp.sqrtmod_prime(a, b, c) | |
499 | 511 | #define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d) |
500 | 512 | #define mp_div_2(a, b) ltc_mp.div_2(a, b) |
501 | 513 | #define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c) |
1 | 1 | |
2 | 2 | enum { |
3 | 3 | PK_PUBLIC=0, |
4 | PK_PRIVATE=1 | |
4 | PK_PRIVATE=1, | |
5 | PK_PUBLIC_COMPRESSED=2 /* used only when exporting public ECC key */ | |
5 | 6 | }; |
6 | 7 | |
7 | 8 | int rand_prime(void *N, long len, prng_state *prng, int wprng); |
8 | 9 | |
9 | 10 | enum { |
10 | 11 | PKA_RSA, |
11 | PKA_DSA | |
12 | PKA_DSA, | |
13 | PKA_EC, | |
14 | EC_PRIME_FIELD | |
12 | 15 | }; |
13 | 16 | |
14 | 17 | typedef struct Oid { |
232 | 235 | |
233 | 236 | /** The y co-ordinate of the base point on the curve (hex) */ |
234 | 237 | char *Gy; |
238 | ||
239 | /** The co-factor */ | |
240 | int cofactor; | |
235 | 241 | } ltc_ecc_set_type; |
236 | 242 | |
237 | 243 | /** A point on a ECC curve, stored in Jacbobian format such that (x,y,z) => (x/z^2, y/z^3, 1) when interpretted as affine */ |
271 | 277 | void ecc_sizes(int *low, int *high); |
272 | 278 | int ecc_get_size(ecc_key *key); |
273 | 279 | |
280 | int ecc_dp_init(ltc_ecc_set_type *dp); | |
281 | int ecc_dp_set(ltc_ecc_set_type *dp, char *ch_prime, char *ch_A, char *ch_B, char *ch_order, char *ch_Gx, char *ch_Gy, int cofactor, char *ch_name); | |
282 | int ecc_dp_clear(ltc_ecc_set_type *dp); | |
283 | ||
274 | 284 | int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); |
275 | 285 | int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp); |
276 | 286 | void ecc_free(ecc_key *key); |
282 | 292 | int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen); |
283 | 293 | int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key); |
284 | 294 | int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); |
295 | ||
296 | int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); | |
297 | int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key); | |
298 | ||
299 | int ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed); | |
300 | int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); | |
301 | int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp); | |
285 | 302 | |
286 | 303 | int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key, |
287 | 304 | unsigned char *out, unsigned long *outlen); |
303 | 320 | const unsigned char *hash, unsigned long hashlen, |
304 | 321 | int *stat, ecc_key *key); |
305 | 322 | |
323 | int ecc_verify_key(ecc_key *key); | |
324 | ||
306 | 325 | /* low level functions */ |
307 | 326 | ecc_point *ltc_ecc_new_point(void); |
308 | 327 | void ltc_ecc_del_point(ecc_point *p); |
309 | 328 | int ltc_ecc_is_valid_idx(int n); |
329 | int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y); | |
310 | 330 | |
311 | 331 | /* point ops (mp == montgomery digit) */ |
312 | 332 | #if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC) |
313 | 333 | /* R = 2P */ |
314 | int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp); | |
334 | int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp); | |
315 | 335 | |
316 | 336 | /* R = P + Q */ |
317 | int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp); | |
337 | int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp); | |
318 | 338 | #endif |
319 | 339 | |
320 | 340 | #if defined(LTC_MECC_FP) |
321 | 341 | /* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */ |
322 | int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); | |
342 | int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map); | |
323 | 343 | |
324 | 344 | /* functions for saving/loading/freeing/adding to fixed point cache */ |
325 | 345 | int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen); |
332 | 352 | #endif |
333 | 353 | |
334 | 354 | /* R = kG */ |
335 | int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map); | |
355 | int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map); | |
336 | 356 | |
337 | 357 | #ifdef LTC_ECC_SHAMIR |
338 | 358 | /* kA*A + kB*B = C */ |
339 | 359 | int ltc_ecc_mul2add(ecc_point *A, void *kA, |
340 | 360 | ecc_point *B, void *kB, |
341 | ecc_point *C, | |
342 | void *modulus); | |
361 | ecc_point *C, void *a, void *modulus); | |
343 | 362 | |
344 | 363 | #ifdef LTC_MECC_FP |
345 | 364 | /* Shamir's trick with optimized point multiplication using fixed point cache */ |
346 | 365 | int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, |
347 | 366 | ecc_point *B, void *kB, |
348 | ecc_point *C, void *modulus); | |
367 | ecc_point *C, void *a, void *modulus); | |
349 | 368 | #endif |
350 | 369 | |
351 | 370 | #endif |
669 | 669 | * The algorithm builds patterns in increasing bit order by first making all |
670 | 670 | * single bit input patterns, then all two bit input patterns and so on |
671 | 671 | */ |
672 | static int build_lut(int idx, void *modulus, void *mp, void *mu) | |
672 | static int build_lut(int idx, void *a, void *modulus, void *mp, void *mu) | |
673 | 673 | { |
674 | 674 | unsigned x, y, err, bitlen, lut_gap; |
675 | 675 | void *tmp; |
708 | 708 | |
709 | 709 | /* now double it bitlen/FP_LUT times */ |
710 | 710 | for (y = 0; y < lut_gap; y++) { |
711 | if ((err = ltc_mp.ecc_ptdbl(fp_cache[idx].LUT[1<<x], fp_cache[idx].LUT[1<<x], modulus, mp)) != CRYPT_OK) { | |
711 | if ((err = ltc_mp.ecc_ptdbl(fp_cache[idx].LUT[1<<x], fp_cache[idx].LUT[1<<x], a, modulus, mp)) != CRYPT_OK) { | |
712 | 712 | goto ERR; |
713 | 713 | } |
714 | 714 | } |
721 | 721 | |
722 | 722 | /* perform the add */ |
723 | 723 | if ((err = ltc_mp.ecc_ptadd(fp_cache[idx].LUT[lut_orders[y].terma], fp_cache[idx].LUT[lut_orders[y].termb], |
724 | fp_cache[idx].LUT[y], modulus, mp)) != CRYPT_OK) { | |
724 | fp_cache[idx].LUT[y], a, modulus, mp)) != CRYPT_OK) { | |
725 | 725 | goto ERR; |
726 | 726 | } |
727 | 727 | } |
776 | 776 | } |
777 | 777 | |
778 | 778 | /* perform a fixed point ECC mulmod */ |
779 | static int accel_fp_mul(int idx, void *k, ecc_point *R, void *modulus, void *mp, int map) | |
779 | static int accel_fp_mul(int idx, void *k, ecc_point *R, void *a, void *modulus, void *mp, int map) | |
780 | 780 | { |
781 | 781 | unsigned char kb[128]; |
782 | 782 | int x; |
869 | 869 | |
870 | 870 | /* double if not first */ |
871 | 871 | if (!first) { |
872 | if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { | |
872 | if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { | |
873 | 873 | return err; |
874 | 874 | } |
875 | 875 | } |
876 | 876 | |
877 | 877 | /* add if not first, otherwise copy */ |
878 | 878 | if (!first && z) { |
879 | if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx].LUT[z], R, modulus, mp)) != CRYPT_OK) { | |
879 | if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx].LUT[z], R, a, modulus, mp)) != CRYPT_OK) { | |
880 | 880 | return err; |
881 | 881 | } |
882 | 882 | } else if (z) { |
901 | 901 | /* perform a fixed point ECC mulmod */ |
902 | 902 | static int accel_fp_mul2add(int idx1, int idx2, |
903 | 903 | void *kA, void *kB, |
904 | ecc_point *R, void *modulus, void *mp) | |
904 | ecc_point *R, void *a, void *modulus, void *mp) | |
905 | 905 | { |
906 | 906 | unsigned char kb[2][128]; |
907 | 907 | int x; |
1057 | 1057 | |
1058 | 1058 | /* double if not first */ |
1059 | 1059 | if (!first) { |
1060 | if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { | |
1060 | if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { | |
1061 | 1061 | return err; |
1062 | 1062 | } |
1063 | 1063 | } |
1065 | 1065 | /* add if not first, otherwise copy */ |
1066 | 1066 | if (!first) { |
1067 | 1067 | if (zA) { |
1068 | if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx1].LUT[zA], R, modulus, mp)) != CRYPT_OK) { | |
1068 | if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx1].LUT[zA], R, a, modulus, mp)) != CRYPT_OK) { | |
1069 | 1069 | return err; |
1070 | 1070 | } |
1071 | 1071 | } |
1072 | 1072 | if (zB) { |
1073 | if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) { | |
1073 | if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != CRYPT_OK) { | |
1074 | 1074 | return err; |
1075 | 1075 | } |
1076 | 1076 | } |
1083 | 1083 | } |
1084 | 1084 | if (zB && first == 0) { |
1085 | 1085 | if (zB) { |
1086 | if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, modulus, mp)) != CRYPT_OK) { | |
1086 | if ((err = ltc_mp.ecc_ptadd(R, fp_cache[idx2].LUT[zB], R, a, modulus, mp)) != CRYPT_OK) { | |
1087 | 1087 | return err; |
1088 | 1088 | } |
1089 | 1089 | } |
1111 | 1111 | */ |
1112 | 1112 | int ltc_ecc_fp_mul2add(ecc_point *A, void *kA, |
1113 | 1113 | ecc_point *B, void *kB, |
1114 | ecc_point *C, void *modulus) | |
1114 | ecc_point *C, void *a, void *modulus) | |
1115 | 1115 | { |
1116 | 1116 | int idx1, idx2, err; |
1117 | 1117 | void *mp, *mu; |
1167 | 1167 | } |
1168 | 1168 | |
1169 | 1169 | /* build the LUT */ |
1170 | if ((err = build_lut(idx1, modulus, mp, mu)) != CRYPT_OK) { | |
1170 | if ((err = build_lut(idx1, a, modulus, mp, mu)) != CRYPT_OK) { | |
1171 | 1171 | goto LBL_ERR;; |
1172 | 1172 | } |
1173 | 1173 | } |
1188 | 1188 | } |
1189 | 1189 | |
1190 | 1190 | /* build the LUT */ |
1191 | if ((err = build_lut(idx2, modulus, mp, mu)) != CRYPT_OK) { | |
1191 | if ((err = build_lut(idx2, a, modulus, mp, mu)) != CRYPT_OK) { | |
1192 | 1192 | goto LBL_ERR;; |
1193 | 1193 | } |
1194 | 1194 | } |
1199 | 1199 | /* compute mp */ |
1200 | 1200 | if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } |
1201 | 1201 | } |
1202 | err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp); | |
1202 | err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp); | |
1203 | 1203 | } else { |
1204 | err = ltc_ecc_mul2add(A, kA, B, kB, C, modulus); | |
1204 | err = ltc_ecc_mul2add(A, kA, B, kB, C, a, modulus); | |
1205 | 1205 | } |
1206 | 1206 | LBL_ERR: |
1207 | 1207 | LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); |
1219 | 1219 | @param k The multiplicand |
1220 | 1220 | @param G Base point to multiply |
1221 | 1221 | @param R [out] Destination of product |
1222 | @param a ECC curve parameter a | |
1222 | 1223 | @param modulus The modulus for the curve |
1223 | 1224 | @param map [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form |
1224 | 1225 | @return CRYPT_OK if successful |
1225 | */ | |
1226 | int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) | |
1226 | */ | |
1227 | int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map) | |
1227 | 1228 | { |
1228 | 1229 | int idx, err; |
1229 | 1230 | void *mp, *mu; |
1265 | 1266 | } |
1266 | 1267 | |
1267 | 1268 | /* build the LUT */ |
1268 | if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) { | |
1269 | if ((err = build_lut(idx, a, modulus, mp, mu)) != CRYPT_OK) { | |
1269 | 1270 | goto LBL_ERR;; |
1270 | 1271 | } |
1271 | 1272 | } |
1275 | 1276 | /* compute mp */ |
1276 | 1277 | if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; } |
1277 | 1278 | } |
1278 | err = accel_fp_mul(idx, k, R, modulus, mp, map); | |
1279 | err = accel_fp_mul(idx, k, R, a, modulus, mp, map); | |
1279 | 1280 | } else { |
1280 | err = ltc_ecc_mulmod(k, G, R, modulus, map); | |
1281 | err = ltc_ecc_mulmod(k, G, R, a, modulus, map); | |
1281 | 1282 | } |
1282 | 1283 | LBL_ERR: |
1283 | 1284 | LTC_MUTEX_UNLOCK(<c_ecc_fp_lock); |
1364 | 1365 | } |
1365 | 1366 | |
1366 | 1367 | /* build the LUT */ |
1367 | if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) { | |
1368 | if ((err = build_lut(idx, a, modulus, mp, mu)) != CRYPT_OK) { | |
1368 | 1369 | goto LBL_ERR; |
1369 | 1370 | } |
1370 | 1371 | fp_cache[idx].lru_count = 2; |
258 | 258 | return mpi_to_ltc_error(mp_sqr(a, b)); |
259 | 259 | } |
260 | 260 | |
261 | /* sqrtmod_prime */ | |
262 | static int sqrtmod_prime(void *a, void *b, void *c) | |
263 | { | |
264 | LTC_ARGCHK(a != NULL); | |
265 | LTC_ARGCHK(b != NULL); | |
266 | LTC_ARGCHK(c != NULL); | |
267 | return mpi_to_ltc_error(mp_sqrtmod_prime(a, b, c)); | |
268 | } | |
269 | ||
261 | 270 | /* div */ |
262 | 271 | static int divide(void *a, void *b, void *c, void *d) |
263 | 272 | { |
450 | 459 | &mul, |
451 | 460 | &muli, |
452 | 461 | &sqr, |
462 | &sqrtmod_prime, | |
453 | 463 | ÷, |
454 | 464 | &div_2, |
455 | 465 | &modi, |
18 | 18 | 6, |
19 | 19 | }; |
20 | 20 | |
21 | static const oid_st ec_oid = { | |
22 | { 1, 2, 840, 10045, 2, 1 }, | |
23 | 6, | |
24 | }; | |
25 | ||
26 | static const oid_st ec_primef = { | |
27 | { 1, 2, 840, 10045, 1, 1 }, | |
28 | 6, | |
29 | }; | |
30 | ||
21 | 31 | /* |
22 | 32 | Returns the OID of the public key algorithm. |
23 | 33 | @return CRYPT_OK if valid |
31 | 41 | case PKA_DSA: |
32 | 42 | memcpy(st, &dsa_oid, sizeof(*st)); |
33 | 43 | break; |
44 | case PKA_EC: | |
45 | memcpy(st, &ec_oid, sizeof(*st)); | |
46 | break; | |
47 | case EC_PRIME_FIELD: | |
48 | memcpy(st, &ec_primef, sizeof(*st)); | |
49 | break; | |
34 | 50 | default: |
35 | 51 | return CRYPT_INVALID_ARG; |
36 | 52 | } |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 | |
33 | 31 | "659EF8BA043916EEDE8911702B22", |
34 | 32 | "DB7C2ABF62E35E7628DFAC6561C5", |
35 | 33 | "09487239995A5EE76B55F9C2F098", |
36 | "A89CE5AF8724C0A23E0E0FF77500" | |
34 | "A89CE5AF8724C0A23E0E0FF77500", | |
35 | 1 | |
37 | 36 | }, |
38 | 37 | #endif |
39 | 38 | #ifdef ECC128 |
46 | 45 | "FFFFFFFE0000000075A30D1B9038A115", |
47 | 46 | "161FF7528B899B2D0C28607CA52C5B86", |
48 | 47 | "CF5AC8395BAFEB13C02DA292DDED7A83", |
48 | 1 | |
49 | 49 | }, |
50 | 50 | #endif |
51 | 51 | #ifdef ECC160 |
58 | 58 | "0100000000000000000001F4C8F927AED3CA752257", |
59 | 59 | "4A96B5688EF573284664698968C38BB913CBFC82", |
60 | 60 | "23A628553168947D59DCC912042351377AC5FB32", |
61 | 1 | |
61 | 62 | }, |
62 | 63 | #endif |
63 | 64 | #ifdef ECC192 |
70 | 71 | "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", |
71 | 72 | "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", |
72 | 73 | "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", |
74 | 1 | |
73 | 75 | }, |
74 | 76 | #endif |
75 | 77 | #ifdef ECC224 |
82 | 84 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", |
83 | 85 | "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", |
84 | 86 | "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", |
87 | 1 | |
85 | 88 | }, |
86 | 89 | #endif |
87 | 90 | #ifdef ECC256 |
94 | 97 | "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", |
95 | 98 | "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296", |
96 | 99 | "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", |
100 | 1 | |
97 | 101 | }, |
98 | 102 | #endif |
99 | 103 | #ifdef ECC384 |
106 | 110 | "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", |
107 | 111 | "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7", |
108 | 112 | "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", |
113 | 1, | |
109 | 114 | }, |
110 | 115 | #endif |
111 | 116 | #ifdef ECC521 |
118 | 123 | "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", |
119 | 124 | "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66", |
120 | 125 | "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650", |
126 | 1, | |
121 | 127 | }, |
122 | 128 | #endif |
123 | 129 | { |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 | |
50 | 48 | { |
51 | 49 | int err; |
52 | 50 | ecc_point *base; |
53 | void *prime, *order; | |
51 | void *prime, *order, *a; | |
54 | 52 | unsigned char *buf; |
55 | 53 | int keysize; |
56 | 54 | |
81 | 79 | } |
82 | 80 | |
83 | 81 | /* setup the key variables */ |
84 | if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, NULL)) != CRYPT_OK) { | |
82 | if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, &a, NULL)) != CRYPT_OK) { | |
85 | 83 | goto ERR_BUF; |
86 | 84 | } |
87 | 85 | base = ltc_ecc_new_point(); |
103 | 101 | if((err = mp_mod(key->k, order, key->k)) != CRYPT_OK) { goto errkey; } |
104 | 102 | } |
105 | 103 | /* make the public key */ |
106 | if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK) { goto errkey; } | |
104 | if ((err = mp_read_radix(a, (char *)key->dp->A, 16)) != CRYPT_OK) { goto errkey; } | |
105 | if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, a, prime, 1)) != CRYPT_OK) { goto errkey; } | |
107 | 106 | key->type = PK_PRIVATE; |
108 | 107 | |
109 | 108 | /* free up ram */ |
113 | 112 | mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL); |
114 | 113 | cleanup: |
115 | 114 | ltc_ecc_del_point(base); |
116 | mp_clear_multi(prime, order, NULL); | |
115 | mp_clear_multi(prime, order, a, NULL); | |
117 | 116 | ERR_BUF: |
118 | 117 | #ifdef LTC_CLEAN_STACK |
119 | 118 | zeromem(buf, ECC_MAXSIZE); |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 | |
35 | 33 | { |
36 | 34 | unsigned long x; |
37 | 35 | ecc_point *result; |
38 | void *prime; | |
36 | void *prime, *a; | |
39 | 37 | int err; |
40 | 38 | |
41 | 39 | LTC_ARGCHK(private_key != NULL); |
62 | 60 | return CRYPT_MEM; |
63 | 61 | } |
64 | 62 | |
65 | if ((err = mp_init(&prime)) != CRYPT_OK) { | |
63 | if ((err = mp_init_multi(&prime, &a, NULL)) != CRYPT_OK) { | |
66 | 64 | ltc_ecc_del_point(result); |
67 | 65 | return err; |
68 | 66 | } |
69 | 67 | |
70 | 68 | if ((err = mp_read_radix(prime, (char *)private_key->dp->prime, 16)) != CRYPT_OK) { goto done; } |
71 | if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, prime, 1)) != CRYPT_OK) { goto done; } | |
69 | if ((err = mp_read_radix(a, (char *)private_key->dp->A, 16)) != CRYPT_OK) { goto done; } | |
70 | if ((err = ltc_mp.ecc_ptmul(private_key->k, &public_key->pubkey, result, a, prime, 1)) != CRYPT_OK) { goto done; } | |
72 | 71 | |
73 | 72 | x = (unsigned long)mp_unsigned_bin_size(prime); |
74 | 73 | if (*outlen < x) { |
82 | 81 | err = CRYPT_OK; |
83 | 82 | *outlen = x; |
84 | 83 | done: |
85 | mp_clear(prime); | |
84 | mp_clear_multi(prime, a, NULL); | |
86 | 85 | ltc_ecc_del_point(result); |
87 | 86 | return err; |
88 | 87 | } |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 | |
40 | 38 | ecc_key pubkey; |
41 | 39 | void *r, *s, *e, *p; |
42 | 40 | int err; |
41 | int pbits, pbytes, i, shift_right; | |
42 | unsigned char ch, buf[MAXBLOCKSIZE]; | |
43 | 43 | |
44 | 44 | LTC_ARGCHK(in != NULL); |
45 | 45 | LTC_ARGCHK(out != NULL); |
60 | 60 | return err; |
61 | 61 | } |
62 | 62 | |
63 | /* get the hash and load it as a bignum into 'e' */ | |
64 | 63 | /* init the bignums */ |
65 | 64 | if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) { |
66 | 65 | return err; |
67 | 66 | } |
68 | 67 | if ((err = mp_read_radix(p, (char *)key->dp->order, 16)) != CRYPT_OK) { goto errnokey; } |
69 | if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto errnokey; } | |
68 | ||
69 | /* get the hash and load it as a bignum into 'e' */ | |
70 | pbits = mp_count_bits(p); | |
71 | pbytes = (pbits+7) >> 3; | |
72 | if (pbits > inlen*8) { | |
73 | if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, (int)inlen)) != CRYPT_OK) { goto errnokey; } | |
74 | } | |
75 | else if (pbits % 8 == 0) { | |
76 | if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, pbytes)) != CRYPT_OK) { goto errnokey; } | |
77 | } | |
78 | else { | |
79 | shift_right = 8 - pbits % 8; | |
80 | for (i=0, ch=0; i<pbytes; i++) { | |
81 | buf[i] = ch; | |
82 | ch = (in[i] << (8-shift_right)); | |
83 | buf[i] = buf[i] ^ (in[i] >> shift_right); | |
84 | } | |
85 | if ((err = mp_read_unsigned_bin(e, (unsigned char *)buf, pbytes)) != CRYPT_OK) { goto errnokey; } | |
86 | } | |
70 | 87 | |
71 | 88 | /* make up a key and export the public copy */ |
72 | 89 | for (;;) { |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 | |
18 | 16 | /** |
19 | 17 | @file ecc_verify_hash.c |
20 | 18 | ECC Crypto, Tom St Denis |
21 | */ | |
19 | */ | |
22 | 20 | |
23 | 21 | #ifdef LTC_MECC |
24 | 22 | |
25 | /* verify | |
23 | /* verify | |
26 | 24 | * |
27 | 25 | * w = s^-1 mod n |
28 | * u1 = xw | |
26 | * u1 = xw | |
29 | 27 | * u2 = rw |
30 | 28 | * X = u1*G + u2*Q |
31 | 29 | * v = X_x1 mod n |
43 | 41 | @return CRYPT_OK if successful (even if the signature is not valid) |
44 | 42 | */ |
45 | 43 | int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, |
46 | const unsigned char *hash, unsigned long hashlen, | |
44 | const unsigned char *hash, unsigned long hashlen, | |
47 | 45 | int *stat, ecc_key *key) |
48 | 46 | { |
49 | 47 | ecc_point *mG, *mQ; |
50 | void *r, *s, *v, *w, *u1, *u2, *e, *p, *m; | |
48 | void *r, *s, *v, *w, *u1, *u2, *e, *p, *m, *a; | |
51 | 49 | void *mp; |
52 | 50 | int err; |
51 | int pbits, pbytes, i, shift_right; | |
52 | unsigned char ch, buf[MAXBLOCKSIZE]; | |
53 | 53 | |
54 | 54 | LTC_ARGCHK(sig != NULL); |
55 | 55 | LTC_ARGCHK(hash != NULL); |
66 | 66 | } |
67 | 67 | |
68 | 68 | /* allocate ints */ |
69 | if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, NULL)) != CRYPT_OK) { | |
69 | if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &p, &e, &m, &a, NULL)) != CRYPT_OK) { | |
70 | 70 | return CRYPT_MEM; |
71 | 71 | } |
72 | 72 | |
92 | 92 | /* get the modulus */ |
93 | 93 | if ((err = mp_read_radix(m, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto error; } |
94 | 94 | |
95 | /* get the a */ | |
96 | if ((err = mp_read_radix(a, (char *)key->dp->A, 16)) != CRYPT_OK) { goto error; } | |
97 | ||
95 | 98 | /* check for zero */ |
96 | 99 | if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) { |
97 | 100 | err = CRYPT_INVALID_PACKET; |
98 | 101 | goto error; |
99 | 102 | } |
100 | 103 | |
101 | /* read hash */ | |
102 | if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK) { goto error; } | |
104 | /* read hash - truncate if needed */ | |
105 | pbits = mp_count_bits(p); | |
106 | pbytes = (pbits+7) >> 3; | |
107 | if (pbits > hashlen*8) { | |
108 | if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, (int)hashlen)) != CRYPT_OK) { goto error; } | |
109 | } | |
110 | else if (pbits % 8 == 0) { | |
111 | if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, pbytes)) != CRYPT_OK) { goto error; } | |
112 | } | |
113 | else { | |
114 | shift_right = 8 - pbits % 8; | |
115 | for (i=0, ch=0; i<pbytes; i++) { | |
116 | buf[i] = ch; | |
117 | ch = (hash[i] << (8-shift_right)); | |
118 | buf[i] = buf[i] ^ (hash[i] >> shift_right); | |
119 | } | |
120 | if ((err = mp_read_unsigned_bin(e, (unsigned char *)buf, pbytes)) != CRYPT_OK) { goto error; } | |
121 | } | |
103 | 122 | |
104 | 123 | /* w = s^-1 mod n */ |
105 | 124 | if ((err = mp_invmod(s, p, w)) != CRYPT_OK) { goto error; } |
121 | 140 | |
122 | 141 | /* compute u1*mG + u2*mQ = mG */ |
123 | 142 | if (ltc_mp.ecc_mul2add == NULL) { |
124 | if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, m, 0)) != CRYPT_OK) { goto error; } | |
125 | if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, m, 0)) != CRYPT_OK) { goto error; } | |
126 | ||
143 | if ((err = ltc_mp.ecc_ptmul(u1, mG, mG, a, m, 0)) != CRYPT_OK) { goto error; } | |
144 | if ((err = ltc_mp.ecc_ptmul(u2, mQ, mQ, a, m, 0)) != CRYPT_OK) { goto error; } | |
145 | ||
127 | 146 | /* find the montgomery mp */ |
128 | 147 | if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; } |
129 | 148 | |
130 | 149 | /* add them */ |
131 | if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, m, mp)) != CRYPT_OK) { goto error; } | |
132 | ||
150 | if ((err = ltc_mp.ecc_ptadd(mQ, mG, mG, a, m, mp)) != CRYPT_OK) { goto error; } | |
151 | ||
133 | 152 | /* reduce */ |
134 | 153 | if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK) { goto error; } |
135 | 154 | } else { |
136 | 155 | /* use Shamir's trick to compute u1*mG + u2*mQ using half of the doubles */ |
137 | if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, m)) != CRYPT_OK) { goto error; } | |
156 | if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, a, m)) != CRYPT_OK) { goto error; } | |
138 | 157 | } |
139 | 158 | |
140 | 159 | /* v = X_x1 mod n */ |
150 | 169 | error: |
151 | 170 | ltc_ecc_del_point(mG); |
152 | 171 | ltc_ecc_del_point(mQ); |
153 | mp_clear_multi(r, s, v, w, u1, u2, p, e, m, NULL); | |
154 | if (mp != NULL) { | |
172 | mp_clear_multi(r, s, v, w, u1, u2, p, e, m, a, NULL); | |
173 | if (mp != NULL) { | |
155 | 174 | mp_montgomery_free(mp); |
156 | 175 | } |
157 | 176 | return err; |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 | |
36 | 34 | int ltc_ecc_mul2add(ecc_point *A, void *kA, |
37 | 35 | ecc_point *B, void *kB, |
38 | 36 | ecc_point *C, |
37 | void *a, | |
39 | 38 | void *modulus) |
40 | 39 | { |
41 | 40 | ecc_point *precomp[16]; |
113 | 112 | if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; } |
114 | 113 | |
115 | 114 | /* precomp [i,0](A + B) table */ |
116 | if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
117 | if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
115 | if ((err = ltc_mp.ecc_ptdbl(precomp[1], precomp[2], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
116 | if ((err = ltc_mp.ecc_ptadd(precomp[1], precomp[2], precomp[3], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
118 | 117 | |
119 | 118 | /* precomp [0,i](A + B) table */ |
120 | if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
121 | if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
119 | if ((err = ltc_mp.ecc_ptdbl(precomp[1<<2], precomp[2<<2], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
120 | if ((err = ltc_mp.ecc_ptadd(precomp[1<<2], precomp[2<<2], precomp[3<<2], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
122 | 121 | |
123 | 122 | /* precomp [i,j](A + B) table (i != 0, j != 0) */ |
124 | 123 | for (x = 1; x < 4; x++) { |
125 | 124 | for (y = 1; y < 4; y++) { |
126 | if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
125 | if ((err = ltc_mp.ecc_ptadd(precomp[x], precomp[(y<<2)], precomp[x+(y<<2)], a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
127 | 126 | } |
128 | 127 | } |
129 | 128 | |
156 | 155 | /* double twice, only if this isn't the first */ |
157 | 156 | if (first == 0) { |
158 | 157 | /* double twice */ |
159 | if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
160 | if ((err = ltc_mp.ecc_ptdbl(C, C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
158 | if ((err = ltc_mp.ecc_ptdbl(C, C, a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
159 | if ((err = ltc_mp.ecc_ptdbl(C, C, a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
161 | 160 | } |
162 | 161 | |
163 | 162 | /* if not both zero */ |
170 | 169 | if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; } |
171 | 170 | } else { |
172 | 171 | /* if not first, add from table */ |
173 | if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
172 | if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, a, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } | |
174 | 173 | } |
175 | 174 | } |
176 | 175 | } |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 | |
35 | 33 | @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) |
36 | 34 | @return CRYPT_OK on success |
37 | 35 | */ |
38 | int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) | |
36 | int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map) | |
39 | 37 | { |
40 | 38 | ecc_point *tG, *M[8]; |
41 | 39 | int i, j, err; |
94 | 92 | |
95 | 93 | /* calc the M tab, which holds kG for k==8..15 */ |
96 | 94 | /* M[0] == 8G */ |
97 | if ((err = ltc_mp.ecc_ptdbl(tG, M[0], modulus, mp)) != CRYPT_OK) { goto done; } | |
98 | if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; } | |
99 | if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], modulus, mp)) != CRYPT_OK) { goto done; } | |
95 | if ((err = ltc_mp.ecc_ptdbl(tG, M[0], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
96 | if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
97 | if ((err = ltc_mp.ecc_ptdbl(M[0], M[0], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
100 | 98 | |
101 | 99 | /* now find (8+k)G for k=1..7 */ |
102 | 100 | for (j = 9; j < 16; j++) { |
103 | if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], modulus, mp)) != CRYPT_OK) { goto done; } | |
101 | if ((err = ltc_mp.ecc_ptadd(M[j-9], tG, M[j-8], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
104 | 102 | } |
105 | 103 | |
106 | 104 | /* setup sliding window */ |
134 | 132 | |
135 | 133 | /* if the bit is zero and mode == 1 then we double */ |
136 | 134 | if (mode == 1 && i == 0) { |
137 | if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } | |
135 | if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { goto done; } | |
138 | 136 | continue; |
139 | 137 | } |
140 | 138 | |
155 | 153 | /* ok window is filled so double as required and add */ |
156 | 154 | /* double first */ |
157 | 155 | for (j = 0; j < WINSIZE; j++) { |
158 | if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } | |
156 | if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { goto done; } | |
159 | 157 | } |
160 | 158 | |
161 | 159 | /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ |
162 | if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, modulus, mp)) != CRYPT_OK) { goto done; } | |
160 | if ((err = ltc_mp.ecc_ptadd(R, M[bitbuf-8], R, a, modulus, mp)) != CRYPT_OK) { goto done; } | |
163 | 161 | } |
164 | 162 | /* empty window and reset */ |
165 | 163 | bitcpy = bitbuf = 0; |
173 | 171 | for (j = 0; j < bitcpy; j++) { |
174 | 172 | /* only double if we have had at least one add first */ |
175 | 173 | if (first == 0) { |
176 | if ((err = ltc_mp.ecc_ptdbl(R, R, modulus, mp)) != CRYPT_OK) { goto done; } | |
174 | if ((err = ltc_mp.ecc_ptdbl(R, R, a, modulus, mp)) != CRYPT_OK) { goto done; } | |
177 | 175 | } |
178 | 176 | |
179 | 177 | bitbuf <<= 1; |
186 | 184 | first = 0; |
187 | 185 | } else { |
188 | 186 | /* then add */ |
189 | if ((err = ltc_mp.ecc_ptadd(R, tG, R, modulus, mp)) != CRYPT_OK) { goto done; } | |
187 | if ((err = ltc_mp.ecc_ptadd(R, tG, R, a, modulus, mp)) != CRYPT_OK) { goto done; } | |
190 | 188 | } |
191 | 189 | } |
192 | 190 | } |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 | |
29 | 27 | @param k The scalar to multiply by |
30 | 28 | @param G The base point |
31 | 29 | @param R [out] Destination for kG |
30 | @param a ECC curve parameter a | |
32 | 31 | @param modulus The modulus of the field the ECC curve is in |
33 | 32 | @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) |
34 | 33 | @return CRYPT_OK on success |
35 | 34 | */ |
36 | int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) | |
35 | int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map) | |
37 | 36 | { |
38 | 37 | ecc_point *tG, *M[3]; |
39 | 38 | int i, j, err; |
90 | 89 | if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK) { goto done; } |
91 | 90 | if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK) { goto done; } |
92 | 91 | /* M[1] == 2G */ |
93 | if ((err = ltc_mp.ecc_ptdbl(tG, M[1], modulus, mp)) != CRYPT_OK) { goto done; } | |
92 | if ((err = ltc_mp.ecc_ptdbl(tG, M[1], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
94 | 93 | |
95 | 94 | /* setup sliding window */ |
96 | 95 | mode = 0; |
118 | 117 | |
119 | 118 | if (mode == 0 && i == 0) { |
120 | 119 | /* dummy operations */ |
121 | if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; } | |
122 | if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; } | |
120 | if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
121 | if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
123 | 122 | continue; |
124 | 123 | } |
125 | 124 | |
126 | 125 | if (mode == 0 && i == 1) { |
127 | 126 | mode = 1; |
128 | 127 | /* dummy operations */ |
129 | if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; } | |
130 | if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; } | |
128 | if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
129 | if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
131 | 130 | continue; |
132 | 131 | } |
133 | 132 | |
134 | if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], modulus, mp)) != CRYPT_OK) { goto done; } | |
135 | if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], modulus, mp)) != CRYPT_OK) { goto done; } | |
133 | if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
134 | if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], a, modulus, mp)) != CRYPT_OK) { goto done; } | |
136 | 135 | } |
137 | 136 | |
138 | 137 | /* copy result out */ |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
16 | 14 | #include "tomcrypt.h" |
17 | 15 |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
14 | ||
16 | 15 | #include "tomcrypt.h" |
17 | 16 | |
18 | 17 | /** |
31 | 30 | @param mp The "b" value from montgomery_setup() |
32 | 31 | @return CRYPT_OK on success |
33 | 32 | */ |
34 | int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp) | |
33 | int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp) | |
35 | 34 | { |
36 | 35 | void *t1, *t2, *x, *y, *z; |
37 | 36 | int err; |
53 | 52 | (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) && |
54 | 53 | (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) { |
55 | 54 | mp_clear_multi(t1, t2, x, y, z, NULL); |
56 | return ltc_ecc_projective_dbl_point(P, R, modulus, mp); | |
55 | return ltc_ecc_projective_dbl_point(P, R, a, modulus, mp); | |
57 | 56 | } |
58 | 57 | |
59 | 58 | if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; } |
10 | 10 | |
11 | 11 | /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b |
12 | 12 | * |
13 | * All curves taken from NIST recommendation paper of July 1999 | |
14 | * Available at http://csrc.nist.gov/cryptval/dss.htm | |
15 | 13 | */ |
14 | ||
16 | 15 | #include "tomcrypt.h" |
16 | ||
17 | /* ### Point doubling in Jacobian coordinate system ### | |
18 | * | |
19 | * let us have a curve: y^2 = x^3 + a*x + b | |
20 | * in Jacobian coordinates it becomes: y^2 = x^3 + a*x*z^4 + b*z^6 | |
21 | * | |
22 | * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where: | |
23 | * Xr = M^2 - 2*S | |
24 | * Yr = M * (S - Xr) - 8*T | |
25 | * Zr = 2 * Yp * Zp | |
26 | * | |
27 | * M = 3 * Xp^2 + a*Zp^4 | |
28 | * T = Yp^4 | |
29 | * S = 4 * Xp * Yp^2 | |
30 | * | |
31 | * SPECIAL CASE - when a == -3 we can compute M as: | |
32 | * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2) | |
33 | */ | |
17 | 34 | |
18 | 35 | /** |
19 | 36 | @file ltc_ecc_projective_dbl_point.c |
20 | 37 | ECC Crypto, Tom St Denis |
21 | */ | |
38 | */ | |
22 | 39 | |
23 | 40 | #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC)) |
24 | 41 | |
26 | 43 | Double an ECC point |
27 | 44 | @param P The point to double |
28 | 45 | @param R [out] The destination of the double |
46 | @param a ECC curve parameter a (if NULL we assume a == -3) | |
29 | 47 | @param modulus The modulus of the field the ECC curve is in |
30 | 48 | @param mp The "b" value from montgomery_setup() |
31 | 49 | @return CRYPT_OK on success |
32 | 50 | */ |
33 | int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp) | |
51 | int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp) | |
34 | 52 | { |
35 | 53 | void *t1, *t2; |
36 | 54 | int err; |
61 | 79 | if (mp_cmp(R->z, modulus) != LTC_MP_LT) { |
62 | 80 | if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; } |
63 | 81 | } |
64 | ||
65 | /* T2 = X - T1 */ | |
66 | if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; } | |
67 | if (mp_cmp_d(t2, 0) == LTC_MP_LT) { | |
68 | if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } | |
82 | ||
83 | if (a == NULL) { /* special case for a == -3 (slightly faster than general case) */ | |
84 | /* T2 = X - T1 */ | |
85 | if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; } | |
86 | if (mp_cmp_d(t2, 0) == LTC_MP_LT) { | |
87 | if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; } | |
88 | } | |
89 | /* T1 = X + T1 */ | |
90 | if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; } | |
91 | if (mp_cmp(t1, modulus) != LTC_MP_LT) { | |
92 | if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } | |
93 | } | |
94 | /* T2 = T1 * T2 */ | |
95 | if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; } | |
96 | if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } | |
97 | /* T1 = 2T2 */ | |
98 | if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; } | |
99 | if (mp_cmp(t1, modulus) != LTC_MP_LT) { | |
100 | if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } | |
101 | } | |
102 | /* T1 = T1 + T2 */ | |
103 | if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } | |
104 | if (mp_cmp(t1, modulus) != LTC_MP_LT) { | |
105 | if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } | |
106 | } | |
69 | 107 | } |
70 | /* T1 = X + T1 */ | |
71 | if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; } | |
72 | if (mp_cmp(t1, modulus) != LTC_MP_LT) { | |
73 | if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } | |
74 | } | |
75 | /* T2 = T1 * T2 */ | |
76 | if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; } | |
77 | if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } | |
78 | /* T1 = 2T2 */ | |
79 | if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; } | |
80 | if (mp_cmp(t1, modulus) != LTC_MP_LT) { | |
81 | if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } | |
82 | } | |
83 | /* T1 = T1 + T2 */ | |
84 | if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } | |
85 | if (mp_cmp(t1, modulus) != LTC_MP_LT) { | |
86 | if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } | |
108 | else { | |
109 | /* T2 = T1 * T1 */ | |
110 | if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; } | |
111 | if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } | |
112 | /* T1 = T2 * a */ | |
113 | if ((err = mp_mulmod(t2, a, modulus, t1)) != CRYPT_OK) { goto done; } | |
114 | /* T2 = X * X */ | |
115 | if ((err = mp_sqr(R->x, t2)) != CRYPT_OK) { goto done; } | |
116 | if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; } | |
117 | /* T1 = T2 + T1 */ | |
118 | if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } | |
119 | if (mp_cmp(t1, modulus) != LTC_MP_LT) { | |
120 | if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } | |
121 | } | |
122 | /* T1 = T2 + T1 */ | |
123 | if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } | |
124 | if (mp_cmp(t1, modulus) != LTC_MP_LT) { | |
125 | if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } | |
126 | } | |
127 | /* T1 = T2 + T1 */ | |
128 | if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; } | |
129 | if (mp_cmp(t1, modulus) != LTC_MP_LT) { | |
130 | if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; } | |
131 | } | |
87 | 132 | } |
88 | 133 | |
89 | 134 | /* Y = 2Y */ |
120 | 165 | if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; } |
121 | 166 | } |
122 | 167 | |
123 | /* Y = Y - X */ | |
168 | /* Y = Y - X */ | |
124 | 169 | if ((err = mp_sub(R->y, R->x, R->y)) != CRYPT_OK) { goto done; } |
125 | 170 | if (mp_cmp_d(R->y, 0) == LTC_MP_LT) { |
126 | 171 | if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } |
133 | 178 | if (mp_cmp_d(R->y, 0) == LTC_MP_LT) { |
134 | 179 | if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; } |
135 | 180 | } |
136 | ||
181 | ||
137 | 182 | err = CRYPT_OK; |
138 | 183 | done: |
139 | 184 | mp_clear_multi(t1, t2, NULL); |
392 | 392 | |
393 | 393 | /* special sqrt algo */ |
394 | 394 | int mp_sqrt(mp_int *arg, mp_int *ret); |
395 | ||
396 | /* special sqrt (mod prime) */ | |
397 | int mp_sqrtmod_prime(mp_int *arg, mp_int *prime, mp_int *ret); | |
395 | 398 | |
396 | 399 | /* is number a square? */ |
397 | 400 | int mp_is_square(mp_int *arg, int *ret); |
103 | 103 | #define BN_MP_SQR_C |
104 | 104 | #define BN_MP_SQRMOD_C |
105 | 105 | #define BN_MP_SQRT_C |
106 | #define BN_MP_SQRTMOD_PRIME_C | |
106 | 107 | #define BN_MP_SUB_C |
107 | 108 | #define BN_MP_SUB_D_C |
108 | 109 | #define BN_MP_SUBMOD_C |
822 | 823 | #define BN_MP_CLEAR_C |
823 | 824 | #endif |
824 | 825 | |
826 | #if defined(BN_MP_SQRTMOD_PRIME_C) | |
827 | #define BN_MP_JACOBI_C | |
828 | #define BN_MP_ZERO_C | |
829 | #define BN_MP_SET_INT_C | |
830 | #define BN_MP_COPY_C | |
831 | #define BN_MP_SUB_C | |
832 | #define BN_MP_SUB_D_C | |
833 | #define BN_MP_DIV_2_C | |
834 | #define BN_MP_ADD_D_C | |
835 | #define BN_MP_EXPTMOD_C | |
836 | #endif | |
837 | ||
825 | 838 | #if defined(BN_MP_SUB_C) |
826 | 839 | #define BN_S_MP_ADD_C |
827 | 840 | #define BN_MP_CMP_MAG_C |