Codebase list libcryptx-perl / 49e54a8
libtomcrypt ecc enhancements Karel Miko 9 years ago
40 changed file(s) with 1816 addition(s) and 331 deletion(s). Raw diff Collapse all Expand all
436436 #ifdef LTC_MECC
437437 /* Supported ECC Key Sizes */
438438 #ifndef LTC_NO_CURVES
439 #define LTC_ECC_SECP112R1
440 #define LTC_ECC_SECP112R2
441 #define LTC_ECC_SECP128R1
442 #define LTC_ECC_SECP128R2
443 #define LTC_ECC_SECP160R1
444 #define LTC_ECC_SECP160R2
445 #define LTC_ECC_SECP160K1
446 #define LTC_ECC_BRAINPOOLP160R1
447 #define LTC_ECC_SECP192R1
448 #define LTC_ECC_PRIME192V2
449 #define LTC_ECC_PRIME192V3
450 #define LTC_ECC_SECP192K1
451 #define LTC_ECC_BRAINPOOLP192R1
452 #define LTC_ECC_SECP224R1
453 #define LTC_ECC_SECP224K1
454 #define LTC_ECC_BRAINPOOLP224R1
455 #define LTC_ECC_PRIME239V1
456 #define LTC_ECC_PRIME239V2
457 #define LTC_ECC_PRIME239V3
458 #define LTC_ECC_SECP256R1
459 #define LTC_ECC_SECP256K1
460 #define LTC_ECC_BRAINPOOLP256R1
461 #define LTC_ECC_BRAINPOOLP320R1
462 #define LTC_ECC_SECP384R1
463 #define LTC_ECC_BRAINPOOLP384R1
464 #define LTC_ECC_BRAINPOOLP512R1
465 #define LTC_ECC_SECP521R1
466 /* OLD deprecated (but still working) defines */
439467 #define LTC_ECC112
440468 #define LTC_ECC128
441469 #define LTC_ECC160
216216 @return CRYPT_OK on success
217217 */
218218 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);
219227
220228 /** Divide an integer
221229 @param a The dividend
337345 @param k The integer to multiply the point by
338346 @param G The point to multiply
339347 @param R The destination for kG
348 @param a ECC curve parameter a (if NULL we assume a == -3)
340349 @param modulus The modulus for the field
341350 @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only)
342351 @return CRYPT_OK on success
343352 */
344 int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
353 int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
345354
346355 /** ECC GF(p) point addition
347356 @param P The first point
348357 @param Q The second point
349358 @param R The destination of P + Q
359 @param a ECC curve parameter a (if NULL we assume a == -3)
350360 @param modulus The modulus
351361 @param mp The "b" value from montgomery_setup()
352362 @return CRYPT_OK on success
353363 */
354 int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
364 int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp);
355365
356366 /** ECC GF(p) point double
357367 @param P The first point
358368 @param R The destination of 2P
369 @param a ECC curve parameter a (if NULL we assume a == -3)
359370 @param modulus The modulus
360371 @param mp The "b" value from montgomery_setup()
361372 @return CRYPT_OK on success
362373 */
363 int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp);
374 int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp);
364375
365376 /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1)
366377 @param P The point to map
384395 int (*ecc_mul2add)(ecc_point *A, void *kA,
385396 ecc_point *B, void *kB,
386397 ecc_point *C,
398 void *a,
387399 void *modulus);
388400
389401 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
497509 #define mp_mul(a, b, c) ltc_mp.mul(a, b, c)
498510 #define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c)
499511 #define mp_sqr(a, b) ltc_mp.sqr(a, b)
512 #define mp_sqrtmod_prime(a, b, c) ltc_mp.sqrtmod_prime(a, b, c)
500513 #define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d)
501514 #define mp_div_2(a, b) ltc_mp.div_2(a, b)
502515 #define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c)
11
22 enum {
33 PK_PUBLIC=0,
4 PK_PRIVATE=1
4 PK_PRIVATE=1,
5 PK_PUBLIC_COMPRESSED=2 /* used only when exporting public ECC key */
56 };
67
78 /* Indicates standard output formats that can be read e.g. by OpenSSL or GnuTLS */
1314
1415 enum {
1516 PKA_RSA,
16 PKA_DSA
17 PKA_DSA,
18 PKA_EC,
19 EC_PRIME_FIELD
1720 };
1821
1922 typedef struct Oid {
226229 /** The prime that defines the field the curve is in (encoded in hex) */
227230 char *prime;
228231
232 /** The fields A param (hex) */
233 char *A;
234
229235 /** The fields B param (hex) */
230236 char *B;
231237
237243
238244 /** The y co-ordinate of the base point on the curve (hex) */
239245 char *Gy;
246
247 /** The co-factor */
248 unsigned long cofactor;
249
250 /** The OID stucture */
251 oid_st oid;
240252 } ltc_ecc_set_type;
241253
242254 /** 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 */
276288 void ecc_sizes(int *low, int *high);
277289 int ecc_get_size(ecc_key *key);
278290
291 int ecc_dp_init(ltc_ecc_set_type *dp);
292 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, unsigned long cofactor, char *ch_name);
293 int ecc_dp_clear(ltc_ecc_set_type *dp);
294
279295 int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key);
280296 int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp);
281297 void ecc_free(ecc_key *key);
287303 int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen);
288304 int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
289305 int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
306
307 int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
308 int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
309
310 int ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed);
311 int ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y);
312 int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
313 int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
290314
291315 int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
292316 unsigned char *out, unsigned long *outlen);
308332 const unsigned char *hash, unsigned long hashlen,
309333 int *stat, ecc_key *key);
310334
335 int ecc_verify_key(ecc_key *key);
336
311337 /* low level functions */
312338 ecc_point *ltc_ecc_new_point(void);
313339 void ltc_ecc_del_point(ecc_point *p);
314340 int ltc_ecc_is_valid_idx(int n);
341 int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y);
315342
316343 /* point ops (mp == montgomery digit) */
317344 #if !defined(LTC_MECC_ACCEL) || defined(LTM_DESC) || defined(GMP_DESC)
318345 /* R = 2P */
319 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
346 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp);
320347
321348 /* R = P + Q */
322 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
349 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp);
323350 #endif
324351
325352 #if defined(LTC_MECC_FP)
326353 /* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */
327 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
354 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
328355
329356 /* functions for saving/loading/freeing/adding to fixed point cache */
330357 int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen);
337364 #endif
338365
339366 /* R = kG */
340 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
367 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
341368
342369 #ifdef LTC_ECC_SHAMIR
343370 /* kA*A + kB*B = C */
344371 int ltc_ecc_mul2add(ecc_point *A, void *kA,
345372 ecc_point *B, void *kB,
346373 ecc_point *C,
374 void *a,
347375 void *modulus);
348376
349377 #ifdef LTC_MECC_FP
350378 /* Shamir's trick with optimized point multiplication using fixed point cache */
351379 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
352380 ecc_point *B, void *kB,
353 ecc_point *C, void *modulus);
381 ecc_point *C,
382 void *a,
383 void *modulus);
354384 #endif
355385
356386 #endif
470500 unsigned long size;
471501 /** The used flag, this is used by the CHOICE ASN.1 type to indicate which choice was made */
472502 int used;
503 /** Flag used to indicate optional items in ASN.1 sequences */
504 int optional;
505 /** Flag used to indicate context specific tags on ASN.1 sequence items */
506 unsigned char tag;
473507 /** prev/next entry in the list */
474508 struct ltc_asn1_list_ *prev, *next, *child, *parent;
475509 } ltc_asn1_list;
482516 LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \
483517 LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
484518 LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
519 LTC_MACRO_list[LTC_MACRO_temp].tag = 0; \
520 LTC_MACRO_list[LTC_MACRO_temp].optional = 0; \
485521 } while (0)
486522
487523 /* SEQUENCE */
506542 int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
507543 unsigned int algorithm, void* public_key, unsigned long* public_key_len,
508544 unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len);
545
546 int der_decode_subject_public_key_info_ex(const unsigned char *in, unsigned long inlen,
547 unsigned int algorithm, void* public_key, unsigned long* public_key_len,
548 unsigned long parameters_type, void* parameters, unsigned long parameters_len,
549 unsigned long *parameters_outsize);
509550
510551 /* SET */
511552 #define der_decode_set(in, inlen, list, outlen) der_decode_sequence_ex(in, inlen, list, outlen, 0)
669669 * The algorithm builds patterns in increasing bit order by first making all
670670 * single bit input patterns, then all two bit input patterns and so on
671671 */
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)
673673 {
674674 unsigned x, y, err, bitlen, lut_gap;
675675 void *tmp;
708708
709709 /* now double it bitlen/FP_LUT times */
710710 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) {
712712 goto ERR;
713713 }
714714 }
721721
722722 /* perform the add */
723723 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) {
725725 goto ERR;
726726 }
727727 }
776776 }
777777
778778 /* 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)
780780 {
781781 unsigned char kb[128];
782782 int x;
869869
870870 /* double if not first */
871871 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) {
873873 return err;
874874 }
875875 }
876876
877877 /* add if not first, otherwise copy */
878878 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) {
880880 return err;
881881 }
882882 } else if (z) {
901901 /* perform a fixed point ECC mulmod */
902902 static int accel_fp_mul2add(int idx1, int idx2,
903903 void *kA, void *kB,
904 ecc_point *R, void *modulus, void *mp)
904 ecc_point *R, void *a, void *modulus, void *mp)
905905 {
906906 unsigned char kb[2][128];
907907 int x;
10571057
10581058 /* double if not first */
10591059 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) {
10611061 return err;
10621062 }
10631063 }
10651065 /* add if not first, otherwise copy */
10661066 if (!first) {
10671067 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) {
10691069 return err;
10701070 }
10711071 }
10721072 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) {
10741074 return err;
10751075 }
10761076 }
10831083 }
10841084 if (zB && first == 0) {
10851085 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) {
10871087 return err;
10881088 }
10891089 }
11111111 */
11121112 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
11131113 ecc_point *B, void *kB,
1114 ecc_point *C, void *modulus)
1114 ecc_point *C,
1115 void *a,
1116 void *modulus)
11151117 {
11161118 int idx1, idx2, err;
11171119 void *mp, *mu;
11671169 }
11681170
11691171 /* build the LUT */
1170 if ((err = build_lut(idx1, modulus, mp, mu)) != CRYPT_OK) {
1172 if ((err = build_lut(idx1, a, modulus, mp, mu)) != CRYPT_OK) {
11711173 goto LBL_ERR;;
11721174 }
11731175 }
11881190 }
11891191
11901192 /* build the LUT */
1191 if ((err = build_lut(idx2, modulus, mp, mu)) != CRYPT_OK) {
1193 if ((err = build_lut(idx2, a, modulus, mp, mu)) != CRYPT_OK) {
11921194 goto LBL_ERR;;
11931195 }
11941196 }
11991201 /* compute mp */
12001202 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
12011203 }
1202 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp);
1204 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
12031205 } else {
1204 err = ltc_ecc_mul2add(A, kA, B, kB, C, modulus);
1206 err = ltc_ecc_mul2add(A, kA, B, kB, C, a, modulus);
12051207 }
12061208 LBL_ERR:
12071209 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
12191221 @param k The multiplicand
12201222 @param G Base point to multiply
12211223 @param R [out] Destination of product
1224 @param a ECC curve parameter a
12221225 @param modulus The modulus for the curve
12231226 @param map [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form
12241227 @return CRYPT_OK if successful
12251228 */
1226 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
1229 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map)
12271230 {
12281231 int idx, err;
12291232 void *mp, *mu;
12651268 }
12661269
12671270 /* build the LUT */
1268 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) {
1271 if ((err = build_lut(idx, a, modulus, mp, mu)) != CRYPT_OK) {
12691272 goto LBL_ERR;;
12701273 }
12711274 }
12751278 /* compute mp */
12761279 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
12771280 }
1278 err = accel_fp_mul(idx, k, R, modulus, mp, map);
1281 err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
12791282 } else {
1280 err = ltc_ecc_mulmod(k, G, R, modulus, map);
1283 err = ltc_ecc_mulmod(k, G, R, a, modulus, map);
12811284 }
12821285 LBL_ERR:
12831286 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
13641367 }
13651368
13661369 /* build the LUT */
1367 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) {
1370 if ((err = build_lut(idx, a, modulus, mp, mu)) != CRYPT_OK) {
13681371 goto LBL_ERR;
13691372 }
13701373 fp_cache[idx].lru_count = 2;
258258 return mpi_to_ltc_error(mp_sqr(a, b));
259259 }
260260
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
261270 /* div */
262271 static int divide(void *a, void *b, void *c, void *d)
263272 {
453462 &mul,
454463 &muli,
455464 &sqr,
465 &sqrtmod_prime,
456466 &divide,
457467 &div_2,
458468 &modi,
1919 6,
2020 };
2121
22 static const oid_st ec_oid = {
23 { 1, 2, 840, 10045, 2, 1 },
24 6,
25 };
26
27 static const oid_st ec_primef = {
28 { 1, 2, 840, 10045, 1, 1 },
29 6,
30 };
31
2232 /*
2333 Returns the OID of the public key algorithm.
2434 @return CRYPT_OK if valid
3242 case PKA_DSA:
3343 XMEMCPY(st, &dsa_oid, sizeof(*st));
3444 break;
45 case PKA_EC:
46 XMEMCPY(st, &ec_oid, sizeof(*st));
47 break;
48 case EC_PRIME_FIELD:
49 XMEMCPY(st, &ec_primef, sizeof(*st));
50 break;
3551 default:
3652 return CRYPT_INVALID_ARG;
3753 }
9696 break;
9797 }
9898
99 /* handle context specific tags - just skip the tag + len bytes */
100 z = 0;
101 if (list[i].tag > 0 && list[i].tag == in[x + z++]) {
102 if (in[x+z] & 0x80) {
103 y = in[x + z++] & 0x7F;
104 if (y == 0 || y > 2) { return CRYPT_INVALID_PACKET; }
105 z += y;
106 } else {
107 z++;
108 }
109 x += z;
110 inlen -= z;
111 }
112
99113 switch (type) {
100114 case LTC_ASN1_BOOLEAN:
101115 z = inlen;
102116 if ((err = der_decode_boolean(in + x, z, ((int *)data))) != CRYPT_OK) {
117 if (!ordered || list[i].optional) { continue; }
103118 goto LBL_ERR;
104119 }
105120 if ((err = der_length_boolean(&z)) != CRYPT_OK) {
110125 case LTC_ASN1_INTEGER:
111126 z = inlen;
112127 if ((err = der_decode_integer(in + x, z, data)) != CRYPT_OK) {
113 if (!ordered) { continue; }
128 if (!ordered || list[i].optional) { continue; }
114129 goto LBL_ERR;
115130 }
116131 if ((err = der_length_integer(data, &z)) != CRYPT_OK) {
121136 case LTC_ASN1_SHORT_INTEGER:
122137 z = inlen;
123138 if ((err = der_decode_short_integer(in + x, z, data)) != CRYPT_OK) {
124 if (!ordered) { continue; }
139 if (!ordered || list[i].optional) { continue; }
125140 goto LBL_ERR;
126141 }
127142 if ((err = der_length_short_integer(((unsigned long*)data)[0], &z)) != CRYPT_OK) {
133148 case LTC_ASN1_BIT_STRING:
134149 z = inlen;
135150 if ((err = der_decode_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
136 if (!ordered) { continue; }
151 if (!ordered || list[i].optional) { continue; }
137152 goto LBL_ERR;
138153 }
139154 list[i].size = size;
145160 case LTC_ASN1_RAW_BIT_STRING:
146161 z = inlen;
147162 if ((err = der_decode_raw_bit_string(in + x, z, data, &size)) != CRYPT_OK) {
148 if (!ordered) { continue; }
163 if (!ordered || list[i].optional) { continue; }
149164 goto LBL_ERR;
150165 }
151166 list[i].size = size;
157172 case LTC_ASN1_OCTET_STRING:
158173 z = inlen;
159174 if ((err = der_decode_octet_string(in + x, z, data, &size)) != CRYPT_OK) {
160 if (!ordered) { continue; }
175 if (!ordered || list[i].optional) { continue; }
161176 goto LBL_ERR;
162177 }
163178 list[i].size = size;
168183
169184 case LTC_ASN1_NULL:
170185 if (inlen < 2 || in[x] != 0x05 || in[x+1] != 0x00) {
171 if (!ordered) { continue; }
186 if (!ordered || list[i].optional) { continue; }
172187 err = CRYPT_INVALID_PACKET;
173188 goto LBL_ERR;
174189 }
178193 case LTC_ASN1_OBJECT_IDENTIFIER:
179194 z = inlen;
180195 if ((err = der_decode_object_identifier(in + x, z, data, &size)) != CRYPT_OK) {
181 if (!ordered) { continue; }
196 if (!ordered || list[i].optional) { continue; }
182197 goto LBL_ERR;
183198 }
184199 list[i].size = size;
190205 case LTC_ASN1_TELETEX_STRING:
191206 z = inlen;
192207 if ((err = der_decode_teletex_string(in + x, z, data, &size)) != CRYPT_OK) {
193 if (!ordered) { continue; }
208 if (!ordered || list[i].optional) { continue; }
194209 goto LBL_ERR;
195210 }
196211 list[i].size = size;
202217 case LTC_ASN1_IA5_STRING:
203218 z = inlen;
204219 if ((err = der_decode_ia5_string(in + x, z, data, &size)) != CRYPT_OK) {
205 if (!ordered) { continue; }
220 if (!ordered || list[i].optional) { continue; }
206221 goto LBL_ERR;
207222 }
208223 list[i].size = size;
215230 case LTC_ASN1_PRINTABLE_STRING:
216231 z = inlen;
217232 if ((err = der_decode_printable_string(in + x, z, data, &size)) != CRYPT_OK) {
218 if (!ordered) { continue; }
233 if (!ordered || list[i].optional) { continue; }
219234 goto LBL_ERR;
220235 }
221236 list[i].size = size;
227242 case LTC_ASN1_UTF8_STRING:
228243 z = inlen;
229244 if ((err = der_decode_utf8_string(in + x, z, data, &size)) != CRYPT_OK) {
230 if (!ordered) { continue; }
245 if (!ordered || list[i].optional) { continue; }
231246 goto LBL_ERR;
232247 }
233248 list[i].size = size;
239254 case LTC_ASN1_UTCTIME:
240255 z = inlen;
241256 if ((err = der_decode_utctime(in + x, &z, data)) != CRYPT_OK) {
242 if (!ordered) { continue; }
257 if (!ordered || list[i].optional) { continue; }
243258 goto LBL_ERR;
244259 }
245260 break;
247262 case LTC_ASN1_SET:
248263 z = inlen;
249264 if ((err = der_decode_set(in + x, z, data, size)) != CRYPT_OK) {
250 if (!ordered) { continue; }
265 if (!ordered || list[i].optional) { continue; }
251266 goto LBL_ERR;
252267 }
253268 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
265280
266281 z = inlen;
267282 if ((err = der_decode_sequence(in + x, z, data, size)) != CRYPT_OK) {
268 if (!ordered) { continue; }
283 if (!ordered || list[i].optional) { continue; }
269284 goto LBL_ERR;
270285 }
271286 if ((err = der_length_sequence(data, size, &z)) != CRYPT_OK) {
277292 case LTC_ASN1_CHOICE:
278293 z = inlen;
279294 if ((err = der_decode_choice(in + x, &z, data, size)) != CRYPT_OK) {
280 if (!ordered) { continue; }
295 if (!ordered || list[i].optional) { continue; }
281296 goto LBL_ERR;
282297 }
283298 break;
298313 }
299314
300315 for (i = 0; i < (int)outlen; i++) {
301 if (list[i].used == 0) {
316 if (list[i].used == 0 && list[i].optional == 0) {
302317 err = CRYPT_INVALID_PACKET;
303318 goto LBL_ERR;
304319 }
3434 int der_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen,
3535 unsigned int algorithm, void* public_key, unsigned long* public_key_len,
3636 unsigned long parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len)
37 {
38 return der_decode_subject_public_key_info_ex(in, inlen, algorithm, public_key, public_key_len,
39 parameters_type, parameters, parameters_len, NULL);
40 }
41
42 int der_decode_subject_public_key_info_ex(const unsigned char *in, unsigned long inlen,
43 unsigned int algorithm, void* public_key, unsigned long* public_key_len,
44 unsigned long parameters_type, void* parameters, unsigned long parameters_len,
45 unsigned long *parameters_outsize)
3746 {
3847 int err;
3948 unsigned long len;
7483 goto LBL_ERR;
7584 }
7685
86 if (parameters_outsize) *parameters_outsize = alg_id[1].size;
87
7788 if ((alg_id[0].size != oid.OIDlen) ||
7889 XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0]))) {
7990 /* OID mismatch */
2626 int der_length_sequence(ltc_asn1_list *list, unsigned long inlen,
2727 unsigned long *outlen)
2828 {
29 return der_length_sequence_ex(list, inlen, outlen, NULL);
30 }
31
32 int der_length_sequence_ex(ltc_asn1_list *list, unsigned long inlen,
33 unsigned long *outlen, unsigned long *payloadlen)
34 {
2935 int err;
3036 ltc_asn1_type type;
31 unsigned long size, x, y, i;
37 unsigned long size, x, y, i, z;
3238 void *data;
3339
3440 LTC_ARGCHK(list != NULL);
4450 if (type == LTC_ASN1_EOL) {
4551 break;
4652 }
53
54 /* some items may be optional during import */
55 if (!list[i].used && list[i].optional) continue;
4756
4857 switch (type) {
4958 case LTC_ASN1_BOOLEAN:
145154 err = CRYPT_INVALID_ARG;
146155 goto LBL_ERR;
147156 }
157
158 /* handle context specific tags size */
159 if (list[i].tag > 0) {
160 if (x < 128) {
161 y += 2;
162 } else if (x < 256) {
163 y += 3;
164 } else if (x < 65536UL) {
165 y += 4;
166 } else if (x < 16777216UL) {
167 y += 5;
168 } else {
169 err = CRYPT_INVALID_ARG;
170 goto LBL_ERR;
171 }
172 }
148173 }
149174
150175 /* calc header size */
176 z = y;
151177 if (y < 128) {
152178 y += 2;
153179 } else if (y < 256) {
165191 }
166192
167193 /* store size */
194 if (payloadlen) *payloadlen = z;
168195 *outlen = y;
169196 err = CRYPT_OK;
170197
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
2220
2321 #ifdef LTC_MECC
2422
25 /* This holds the key settings. ***MUST*** be organized by size from smallest to largest. */
23 /* This array holds the curve parameters:
24 * - it ***MUST*** be organized by size from smallest to largest
25 * - due to curve lookup by keysize the ordering is very important
26 * - be careful when adding/removing items to/from this list
27 * Curves (prime field only) are taken from:
28 * - http://www.secg.org/collateral/sec2_final.pdf (named: SECP*)
29 * - http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf (named: NISTP*)
30 * - ANS X9.62 (named: PRIMEP*)
31 * - http://www.ecc-brainpool.org/download/Domain-parameters.pdf (named: BRAINPOOLP*)
32 */
2633 const ltc_ecc_set_type ltc_ecc_sets[] = {
27 #ifdef LTC_ECC112
28 {
29 14,
30 "SECP112R1",
31 "DB7C2ABF62E35E668076BEAD208B",
32 "659EF8BA043916EEDE8911702B22",
33 "DB7C2ABF62E35E7628DFAC6561C5",
34 "09487239995A5EE76B55F9C2F098",
35 "A89CE5AF8724C0A23E0E0FF77500"
36 },
37 #endif
38 #ifdef LTC_ECC128
39 {
40 16,
41 "SECP128R1",
42 "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
43 "E87579C11079F43DD824993C2CEE5ED3",
44 "FFFFFFFE0000000075A30D1B9038A115",
45 "161FF7528B899B2D0C28607CA52C5B86",
46 "CF5AC8395BAFEB13C02DA292DDED7A83",
47 },
48 #endif
49 #ifdef LTC_ECC160
50 {
51 20,
52 "SECP160R1",
53 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
54 "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
55 "0100000000000000000001F4C8F927AED3CA752257",
56 "4A96B5688EF573284664698968C38BB913CBFC82",
57 "23A628553168947D59DCC912042351377AC5FB32",
58 },
59 #endif
60 #ifdef LTC_ECC192
61 {
62 24,
63 "ECC-192",
64 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
65 "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
66 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
67 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
68 "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
69 },
70 #endif
71 #ifdef LTC_ECC224
72 {
73 28,
74 "ECC-224",
75 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
76 "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
77 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
78 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
79 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
80 },
81 #endif
82 #ifdef LTC_ECC256
83 {
84 32,
85 "ECC-256",
86 "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
87 "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
88 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
89 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
90 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
91 },
92 #endif
93 #ifdef LTC_ECC384
94 {
95 48,
96 "ECC-384",
97 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
98 "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
99 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
100 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
101 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
102 },
103 #endif
104 #ifdef LTC_ECC521
105 {
106 66,
107 "ECC-521",
108 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
109 "51953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
110 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
111 "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
112 "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
34 #if defined(LTC_ECC_SECP112R1) || defined(LTC_ECC112)
35 { /* this curve ***MUST*** be the first from all with size 14 (backward compatibility reasons) */
36 /* size/bytes */ 14,
37 /* curve name */ "SECP112R1",
38 /* prime */ "DB7C2ABF62E35E668076BEAD208B",
39 /* A */ "DB7C2ABF62E35E668076BEAD2088",
40 /* B */ "659EF8BA043916EEDE8911702B22",
41 /* order */ "DB7C2ABF62E35E7628DFAC6561C5",
42 /* Gx */ "09487239995A5EE76B55F9C2F098",
43 /* Gy */ "A89CE5AF8724C0A23E0E0FF77500",
44 /* cofactor */ 1,
45 /* OID struct */ { {1,3,132,0,6}, 5 }
46 },
47 #endif
48 #ifdef LTC_ECC_SECP112R2
49 {
50 /* size/bytes */ 14,
51 /* curve name */ "SECP112R2",
52 /* prime */ "DB7C2ABF62E35E668076BEAD208B",
53 /* A */ "6127C24C05F38A0AAAF65C0EF02C",
54 /* B */ "51DEF1815DB5ED74FCC34C85D709",
55 /* order */ "36DF0AAFD8B8D7597CA10520D04B",
56 /* Gx */ "4BA30AB5E892B4E1649DD0928643",
57 /* Gy */ "ADCD46F5882E3747DEF36E956E97",
58 /* cofactor */ 4,
59 /* OID struct */ { {1,3,132,0,7}, 5 }
60 },
61 #endif
62 #if defined(LTC_ECC_SECP128R1) || defined(LTC_ECC128)
63 { /* this curve ***MUST*** be the first from all with size 16 (backward compatibility reasons) */
64 /* size/bytes */ 16,
65 /* curve name */ "SECP128R1",
66 /* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
67 /* A */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC",
68 /* B */ "E87579C11079F43DD824993C2CEE5ED3",
69 /* order */ "FFFFFFFE0000000075A30D1B9038A115",
70 /* Gx */ "161FF7528B899B2D0C28607CA52C5B86",
71 /* Gy */ "CF5AC8395BAFEB13C02DA292DDED7A83",
72 /* cofactor */ 1,
73 /* OID struct */ { {1,3,132,0,28}, 5 }
74 },
75 #endif
76 #ifdef LTC_ECC_SECP128R2
77 {
78 /* size/bytes */ 16,
79 /* curve name */ "SECP128R2",
80 /* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF",
81 /* A */ "D6031998D1B3BBFEBF59CC9BBFF9AEE1",
82 /* B */ "5EEEFCA380D02919DC2C6558BB6D8A5D",
83 /* order */ "3FFFFFFF7FFFFFFFBE0024720613B5A3",
84 /* Gx */ "7B6AA5D85E572983E6FB32A7CDEBC140",
85 /* Gy */ "27B6916A894D3AEE7106FE805FC34B44",
86 /* cofactor */ 4,
87 /* OID struct */ { {1,3,132,0,29}, 5 }
88 },
89 #endif
90 #if defined(LTC_ECC_SECP160R1) || defined(LTC_ECC160)
91 { /* this curve ***MUST*** be the first from all with size 20 (backward compatibility reasons) */
92 /* size/bytes */ 20,
93 /* curve name */ "SECP160R1",
94 /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF",
95 /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC",
96 /* B */ "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45",
97 /* order */ "0100000000000000000001F4C8F927AED3CA752257",
98 /* Gx */ "4A96B5688EF573284664698968C38BB913CBFC82",
99 /* Gy */ "23A628553168947D59DCC912042351377AC5FB32",
100 /* cofactor */ 1,
101 /* OID struct */ { {1,3,132,0,8}, 5 }
102 },
103 #endif
104 #ifdef LTC_ECC_SECP160R2
105 {
106 /* size/bytes */ 20,
107 /* curve name */ "SECP160R2",
108 /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
109 /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70",
110 /* B */ "B4E134D3FB59EB8BAB57274904664D5AF50388BA",
111 /* order */ "0100000000000000000000351EE786A818F3A1A16B",
112 /* Gx */ "52DCB034293A117E1F4FF11B30F7199D3144CE6D",
113 /* Gy */ "FEAFFEF2E331F296E071FA0DF9982CFEA7D43F2E",
114 /* cofactor */ 1,
115 /* OID struct */ { {1,3,132,0,30}, 5 }
116 },
117 #endif
118 #ifdef LTC_ECC_SECP160K1
119 {
120 /* size/bytes */ 20,
121 /* curve name */ "SECP160K1",
122 /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73",
123 /* A */ "0000000000000000000000000000000000000000",
124 /* B */ "0000000000000000000000000000000000000007",
125 /* order */ "0100000000000000000001B8FA16DFAB9ACA16B6B3",
126 /* Gx */ "3B4C382CE37AA192A4019E763036F4F5DD4D7EBB",
127 /* Gy */ "938CF935318FDCED6BC28286531733C3F03C4FEE",
128 /* cofactor */ 1,
129 /* OID struct */ { {1,3,132,0,9}, 5 }
130 },
131 #endif
132 #ifdef LTC_ECC_BRAINPOOLP160R1
133 {
134 /* size/bytes */ 20,
135 /* curve name */ "BRAINPOOLP160R1",
136 /* prime */ "E95E4A5F737059DC60DFC7AD95B3D8139515620F",
137 /* A */ "340E7BE2A280EB74E2BE61BADA745D97E8F7C300",
138 /* B */ "1E589A8595423412134FAA2DBDEC95C8D8675E58",
139 /* order */ "E95E4A5F737059DC60DF5991D45029409E60FC09",
140 /* Gx */ "BED5AF16EA3F6A4F62938C4631EB5AF7BDBCDBC3",
141 /* Gy */ "1667CB477A1A8EC338F94741669C976316DA6321",
142 /* cofactor */ 1,
143 /* OID struct */ { {1,3,36,3,3,2,8,1,1,1}, 10 }
144 },
145 #endif
146 #if defined(LTC_ECC_SECP192R1) || defined(LTC_ECC192)
147 { /* this curve ***MUST*** be the first from all with size 24 (backward compatibility reasons) */
148 /* size/bytes */ 24,
149 /* curve name */ "SECP192R1", /* same as: NISTP192 PRIME192V1, old libtomcrypt name: ECC-192 */
150 /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
151 /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
152 /* B */ "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1",
153 /* order */ "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
154 /* Gx */ "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
155 /* Gy */ "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
156 /* cofactor */ 1,
157 /* OID struct */ { {1,2,840,10045,3,1,1}, 7 }
158 },
159 #endif
160 #ifdef LTC_ECC_PRIME192V2
161 {
162 /* size/bytes */ 24,
163 /* curve name */ "PRIME192V2",
164 /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
165 /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
166 /* B */ "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953",
167 /* order */ "FFFFFFFFFFFFFFFFFFFFFFFE5FB1A724DC80418648D8DD31",
168 /* Gx */ "EEA2BAE7E1497842F2DE7769CFE9C989C072AD696F48034A",
169 /* Gy */ "6574D11D69B6EC7A672BB82A083DF2F2B0847DE970B2DE15",
170 /* cofactor */ 1,
171 /* OID struct */ { {1,2,840,10045,3,1,2}, 7 }
172 },
173 #endif
174 #ifdef LTC_ECC_PRIME192V3
175 {
176 /* size/bytes */ 24,
177 /* curve name */ "PRIME192V3",
178 /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF",
179 /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC",
180 /* B */ "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916",
181 /* order */ "FFFFFFFFFFFFFFFFFFFFFFFF7A62D031C83F4294F640EC13",
182 /* Gx */ "7D29778100C65A1DA1783716588DCE2B8B4AEE8E228F1896",
183 /* Gy */ "38A90F22637337334B49DCB66A6DC8F9978ACA7648A943B0",
184 /* cofactor */ 1,
185 /* OID struct */ { {1,2,840,10045,3,1,3}, 7 }
186 },
187 #endif
188 #ifdef LTC_ECC_SECP192K1
189 {
190 /* size/bytes */ 24,
191 /* curve name */ "SECP192K1",
192 /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37",
193 /* A */ "000000000000000000000000000000000000000000000000",
194 /* B */ "000000000000000000000000000000000000000000000003",
195 /* order */ "FFFFFFFFFFFFFFFFFFFFFFFE26F2FC170F69466A74DEFD8D",
196 /* Gx */ "DB4FF10EC057E9AE26B07D0280B7F4341DA5D1B1EAE06C7D",
197 /* Gy */ "9B2F2F6D9C5628A7844163D015BE86344082AA88D95E2F9D",
198 /* cofactor */ 1,
199 /* OID struct */ { {1,3,132,0,31}, 5 }
200 },
201 #endif
202 #ifdef LTC_ECC_BRAINPOOLP192R1
203 {
204 /* size/bytes */ 24,
205 /* curve name */ "BRAINPOOLP192R1",
206 /* prime */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297",
207 /* A */ "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF",
208 /* B */ "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9",
209 /* order */ "C302F41D932A36CDA7A3462F9E9E916B5BE8F1029AC4ACC1",
210 /* Gx */ "C0A0647EAAB6A48753B033C56CB0F0900A2F5C4853375FD6",
211 /* Gy */ "14B690866ABD5BB88B5F4828C1490002E6773FA2FA299B8F",
212 /* cofactor */ 1,
213 /* OID struct */ { {1,3,36,3,3,2,8,1,1,3}, 10 }
214 },
215 #endif
216 #if defined(LTC_ECC_SECP224R1) || defined(LTC_ECC224)
217 { /* this curve ***MUST*** be the first from all with size 28 (backward compatibility reasons) */
218 /* size/bytes */ 28,
219 /* curve name */ "SECP224R1", /* same as: NISTP224, old libtomcrypt name: ECC-224 */
220 /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001",
221 /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE",
222 /* B */ "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4",
223 /* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
224 /* Gx */ "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
225 /* Gy */ "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
226 /* cofactor */ 1,
227 /* OID struct */ { {1,3,132,0,33}, 5 }
228 },
229 #endif
230 #ifdef LTC_ECC_SECP224K1
231 {
232 /* size/bytes */ 28,
233 /* curve name */ "SECP224K1",
234 /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D",
235 /* A */ "00000000000000000000000000000000000000000000000000000000",
236 /* B */ "00000000000000000000000000000000000000000000000000000005",
237 /* order */ "010000000000000000000000000001DCE8D2EC6184CAF0A971769FB1F7",
238 /* Gx */ "A1455B334DF099DF30FC28A169A467E9E47075A90F7E650EB6B7A45C",
239 /* Gy */ "7E089FED7FBA344282CAFBD6F7E319F7C0B0BD59E2CA4BDB556D61A5",
240 /* cofactor */ 1,
241 /* OID struct */ { {1,3,132,0,32}, 5 }
242 },
243 #endif
244 #ifdef LTC_ECC_BRAINPOOLP224R1
245 {
246 /* size/bytes */ 28,
247 /* curve name */ "BRAINPOOLP224R1",
248 /* prime */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF",
249 /* A */ "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43",
250 /* B */ "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B",
251 /* order */ "D7C134AA264366862A18302575D0FB98D116BC4B6DDEBCA3A5A7939F",
252 /* Gx */ "0D9029AD2C7E5CF4340823B2A87DC68C9E4CE3174C1E6EFDEE12C07D",
253 /* Gy */ "58AA56F772C0726F24C6B89E4ECDAC24354B9E99CAA3F6D3761402CD",
254 /* cofactor */ 1,
255 /* OID struct */ { {1,3,36,3,3,2,8,1,1,5}, 10 }
256 },
257 #endif
258 #ifdef LTC_ECC_PRIME239V1
259 {
260 /* size/bytes */ 30,
261 /* curve name */ "PRIME239V1",
262 /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
263 /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
264 /* B */ "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A",
265 /* order */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF9E5E9A9F5D9071FBD1522688909D0B",
266 /* Gx */ "0FFA963CDCA8816CCC33B8642BEDF905C3D358573D3F27FBBD3B3CB9AAAF",
267 /* Gy */ "7DEBE8E4E90A5DAE6E4054CA530BA04654B36818CE226B39FCCB7B02F1AE",
268 /* cofactor */ 1,
269 /* OID struct */ { {1,2,840,10045,3,1,4}, 7 }
270 },
271 #endif
272 #ifdef LTC_ECC_PRIME239V2
273 {
274 /* size/bytes */ 30,
275 /* curve name */ "PRIME239V2",
276 /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
277 /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
278 /* B */ "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C",
279 /* order */ "7FFFFFFFFFFFFFFFFFFFFFFF800000CFA7E8594377D414C03821BC582063",
280 /* Gx */ "38AF09D98727705120C921BB5E9E26296A3CDCF2F35757A0EAFD87B830E7",
281 /* Gy */ "5B0125E4DBEA0EC7206DA0FC01D9B081329FB555DE6EF460237DFF8BE4BA",
282 /* cofactor */ 1,
283 /* OID struct */ { {1,2,840,10045,3,1,5}, 7 }
284 },
285 #endif
286 #ifdef LTC_ECC_PRIME239V3
287 {
288 /* size/bytes */ 30,
289 /* curve name */ "PRIME239V3",
290 /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF",
291 /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC",
292 /* B */ "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E",
293 /* order */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFF975DEB41B3A6057C3C432146526551",
294 /* Gx */ "6768AE8E18BB92CFCF005C949AA2C6D94853D0E660BBF854B1C9505FE95A",
295 /* Gy */ "1607E6898F390C06BC1D552BAD226F3B6FCFE48B6E818499AF18E3ED6CF3",
296 /* cofactor */ 1,
297 /* OID struct */ { {1,2,840,10045,3,1,6}, 7 }
298 },
299 #endif
300 #if defined(LTC_ECC_SECP256R1) || defined(LTC_ECC256)
301 { /* this curve ***MUST*** be the first from all with size 32 (backward compatibility reasons) */
302 /* size/bytes */ 32,
303 /* curve name */ "SECP256R1", /* same as: NISTP256 PRIME256V1, old libtomcrypt name: ECC-256 */
304 /* prime */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
305 /* A */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
306 /* B */ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
307 /* order */ "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
308 /* Gx */ "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
309 /* Gy */ "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
310 /* cofactor */ 1,
311 /* OID struct */ { {1,2,840,10045,3,1,7}, 7 }
312 },
313 #endif
314 #ifdef LTC_ECC_SECP256K1
315 {
316 /* size/bytes */ 32,
317 /* curve name */ "SECP256K1",
318 /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F",
319 /* A */ "0000000000000000000000000000000000000000000000000000000000000000",
320 /* B */ "0000000000000000000000000000000000000000000000000000000000000007",
321 /* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141",
322 /* Gx */ "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798",
323 /* Gy */ "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8",
324 /* cofactor */ 1,
325 /* OID struct */ { {1,3,132,0,10}, 5 }
326 },
327 #endif
328 #ifdef LTC_ECC_BRAINPOOLP256R1
329 {
330 /* size/bytes */ 32,
331 /* curve name */ "BRAINPOOLP256R1",
332 /* prime */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377",
333 /* A */ "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9",
334 /* B */ "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6",
335 /* order */ "A9FB57DBA1EEA9BC3E660A909D838D718C397AA3B561A6F7901E0E82974856A7",
336 /* Gx */ "8BD2AEB9CB7E57CB2C4B482FFC81B7AFB9DE27E1E3BD23C23A4453BD9ACE3262",
337 /* Gy */ "547EF835C3DAC4FD97F8461A14611DC9C27745132DED8E545C1D54C72F046997",
338 /* cofactor */ 1,
339 /* OID struct */ { {1,3,36,3,3,2,8,1,1,7}, 10 }
340 },
341 #endif
342 #ifdef LTC_ECC_BRAINPOOLP320R1
343 {
344 /* size/bytes */ 40,
345 /* curve name */ "BRAINPOOLP320R1",
346 /* prime */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27",
347 /* A */ "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4",
348 /* B */ "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6",
349 /* order */ "D35E472036BC4FB7E13C785ED201E065F98FCFA5B68F12A32D482EC7EE8658E98691555B44C59311",
350 /* Gx */ "43BD7E9AFB53D8B85289BCC48EE5BFE6F20137D10A087EB6E7871E2A10A599C710AF8D0D39E20611",
351 /* Gy */ "14FDD05545EC1CC8AB4093247F77275E0743FFED117182EAA9C77877AAAC6AC7D35245D1692E8EE1",
352 /* cofactor */ 1,
353 /* OID struct */ { {1,3,36,3,3,2,8,1,1,9}, 10 }
354 },
355 #endif
356 #if defined(LTC_ECC_SECP384R1) || defined(LTC_ECC384)
357 { /* this curve ***MUST*** be the first from all with size 48 (backward compatibility reasons) */
358 /* size/bytes */ 48,
359 /* curve name */ "SECP384R1", /* same as: NISTP384, old libtomcrypt name: ECC-384 */
360 /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF",
361 /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC",
362 /* B */ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF",
363 /* order */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
364 /* Gx */ "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
365 /* Gy */ "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
366 /* cofactor */ 1,
367 /* OID struct */ { {1,3,132,0,34}, 5 }
368 },
369 #endif
370 #ifdef LTC_ECC_BRAINPOOLP384R1
371 {
372 /* size/bytes */ 48,
373 /* curve name */ "BRAINPOOLP384R1",
374 /* prime */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53",
375 /* A */ "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826",
376 /* B */ "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11",
377 /* order */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B31F166E6CAC0425A7CF3AB6AF6B7FC3103B883202E9046565",
378 /* Gx */ "1D1C64F068CF45FFA2A63A81B7C13F6B8847A3E77EF14FE3DB7FCAFE0CBD10E8E826E03436D646AAEF87B2E247D4AF1E",
379 /* Gy */ "8ABE1D7520F9C2A45CB1EB8E95CFD55262B70B29FEEC5864E19C054FF99129280E4646217791811142820341263C5315",
380 /* cofactor */ 1,
381 /* OID struct */ { {1,3,36,3,3,2,8,1,1,11}, 10 }
382 },
383 #endif
384 #ifdef LTC_ECC_BRAINPOOLP512R1
385 {
386 /* size/bytes */ 64,
387 /* curve name */ "BRAINPOOLP512R1",
388 /* prime */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3",
389 /* A */ "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA",
390 /* B */ "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723",
391 /* order */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA70330870553E5C414CA92619418661197FAC10471DB1D381085DDADDB58796829CA90069",
392 /* Gx */ "81AEE4BDD82ED9645A21322E9C4C6A9385ED9F70B5D916C1B43B62EEF4D0098EFF3B1F78E2D0D48D50D1687B93B97D5F7C6D5047406A5E688B352209BCB9F822",
393 /* Gy */ "7DDE385D566332ECC0EABFA9CF7822FDF209F70024A57B1AA000C55B881F8111B2DCDE494A5F485E5BCA4BD88A2763AED1CA2B2FA8F0540678CD1E0F3AD80892",
394 /* cofactor */ 1,
395 /* OID struct */ { {1,3,36,3,3,2,8,1,1,13}, 10 }
396 },
397 #endif
398 #if defined(LTC_ECC_SECP521R1) || defined(LTC_ECC521)
399 { /* this curve ***MUST*** be the first from all with size 66 (backward compatibility reasons) */
400 /* size/bytes */ 66,
401 /* curve name */ "SECP521R1", /* same as: NISTP521, old libtomcrypt name: ECC-521 */
402 /* prime */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
403 /* A */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC",
404 /* B */ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00",
405 /* order */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
406 /* Gx */ "00C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
407 /* Gy */ "011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
408 /* cofactor */ 1,
409 /* OID struct */ { {1,3,132,0,35}, 5 }
113410 },
114411 #endif
115412 {
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
6664 if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto error; }
6765
6866 if (dp == NULL) {
67 /* BEWARE: Here we are looking up the curve params by keysize (neither curve name nor curve oid),
68 * which might be ambiguous (there can more than one curve for given keysize).
69 * Thus the chosen curve depends on order of items in ltc_ecc_sets[] - see ecc.c file.
70 */
6971 /* determine the idx */
7072 for (x = 0; ltc_ecc_sets[x].size != 0; x++) {
7173 if ((unsigned)ltc_ecc_sets[x].size >= ((inlen-1)>>1)) {
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
9088 }
9189
9290 /* import ECC key from packet */
93 if ((err = ecc_import(decode[1].data, decode[1].size, &pubkey)) != CRYPT_OK) {
91 if ((err = ecc_import_raw(decode[1].data, decode[1].size, &pubkey, (ltc_ecc_set_type *)key->dp)) != CRYPT_OK) {
9492 goto LBL_ERR;
9593 }
9694
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 int ecc_dp_clear(ltc_ecc_set_type *dp)
19 {
20 if (dp == NULL) return CRYPT_INVALID_ARG;
21
22 if (dp->name != NULL) { XFREE(dp->name ); dp->name = NULL; }
23 if (dp->prime != NULL) { XFREE(dp->prime); dp->prime = NULL; }
24 if (dp->A != NULL) { XFREE(dp->A ); dp->A = NULL; }
25 if (dp->B != NULL) { XFREE(dp->B ); dp->B = NULL; }
26 if (dp->order != NULL) { XFREE(dp->order); dp->order = NULL; }
27 if (dp->Gx != NULL) { XFREE(dp->Gx ); dp->Gx = NULL; }
28 if (dp->Gy != NULL) { XFREE(dp->Gy ); dp->Gy = NULL; }
29 dp->cofactor = 0;
30
31 return CRYPT_OK;
32 }
33
34 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 int ecc_dp_init(ltc_ecc_set_type *dp)
19 {
20 if (dp == NULL) return CRYPT_INVALID_ARG;
21
22 dp->name = NULL;
23 dp->prime = NULL;
24 dp->A = NULL;
25 dp->B = NULL;
26 dp->order = NULL;
27 dp->Gx = NULL;
28 dp->Gy = NULL;
29 dp->oid.OIDlen = 0;
30 dp->cofactor = 0;
31
32 return CRYPT_OK;
33 }
34
35 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 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, unsigned long cofactor, char *ch_name)
19 {
20 unsigned long l_name, l_prime, l_A, l_B, l_order, l_Gx, l_Gy;
21
22 if (!dp || !ch_prime || !ch_A || !ch_B || !ch_order || !ch_Gx || !ch_Gy || cofactor==0) return CRYPT_INVALID_ARG;
23
24 l_name = (unsigned long)strlen(ch_name);
25 l_prime = (unsigned long)strlen(ch_prime);
26 l_A = (unsigned long)strlen(ch_A);
27 l_B = (unsigned long)strlen(ch_B);
28 l_order = (unsigned long)strlen(ch_order);
29 l_Gx = (unsigned long)strlen(ch_Gx);
30 l_Gy = (unsigned long)strlen(ch_Gy);
31
32 dp->cofactor = cofactor;
33
34 { /* calculate size */
35 void *p_num;
36 mp_init(&p_num);
37 mp_read_radix(p_num, ch_prime, 16);
38 dp->size = mp_unsigned_bin_size(p_num);
39 mp_clear(p_num);
40 }
41
42 if (dp->name != NULL) { XFREE(dp->name ); dp->name = NULL; }
43 if (dp->prime != NULL) { XFREE(dp->prime); dp->prime = NULL; }
44 if (dp->A != NULL) { XFREE(dp->A ); dp->A = NULL; }
45 if (dp->B != NULL) { XFREE(dp->B ); dp->B = NULL; }
46 if (dp->order != NULL) { XFREE(dp->order); dp->order = NULL; }
47 if (dp->Gx != NULL) { XFREE(dp->Gx ); dp->Gx = NULL; }
48 if (dp->Gy != NULL) { XFREE(dp->Gy ); dp->Gy = NULL; }
49
50 dp->name = XMALLOC(1+l_name); strncpy(dp->name, ch_name, 1+l_name);
51 dp->prime = XMALLOC(1+l_prime); strncpy(dp->prime, ch_prime, 1+l_prime);
52 dp->A = XMALLOC(1+l_A); strncpy(dp->A, ch_A, 1+l_A);
53 dp->B = XMALLOC(1+l_B); strncpy(dp->B, ch_B, 1+l_B);
54 dp->order = XMALLOC(1+l_order); strncpy(dp->order, ch_order, 1+l_order);
55 dp->Gx = XMALLOC(1+l_Gx); strncpy(dp->Gx, ch_Gx, 1+l_Gx);
56 dp->Gy = XMALLOC(1+l_Gy); strncpy(dp->Gy, ch_Gy, 1+l_Gy);
57
58 return CRYPT_OK;
59 }
60
61 #endif
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
8583 }
8684
8785 pubkeysize = ECC_BUF_SIZE;
88 if ((err = ecc_export(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) {
86 if ((err = ecc_export_raw(pub_expt, &pubkeysize, PK_PUBLIC_COMPRESSED, &pubkey)) != CRYPT_OK) {
8987 ecc_free(&pubkey);
9088 goto LBL_ERR;
9189 }
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 /**
19 Export an ECC key as a binary packet
20 @param out [out] Destination for the key
21 @param outlen [in/out] Max size and resulting size of the exported key
22 @param type The type of key you want to export (PK_PRIVATE or PK_PUBLIC)
23 @param key The key to export
24 @return CRYPT_OK if successful
25 */
26
27 int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
28 {
29 int err;
30 void *prime, *order, *a, *b, *gx, *gy;
31 unsigned char bin_a[256], bin_b[256], bin_k[256], bin_g[512], bin_xy[512];
32 unsigned long len_a, len_b, len_k, len_g, len_xy;
33 unsigned long cofactor, one = 1;
34 oid_st oid;
35 ltc_asn1_list seq_fieldid[2], seq_curve[2], seq_ecparams[6], seq_priv[4];
36
37 LTC_ARGCHK(out != NULL);
38 LTC_ARGCHK(outlen != NULL);
39 LTC_ARGCHK(key != NULL);
40
41 if (key->type != PK_PRIVATE && type == PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH;
42 if (ltc_ecc_is_valid_idx(key->idx) == 0) return CRYPT_INVALID_ARG;
43
44 if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) return err;
45
46 if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) goto error;
47 if ((err = mp_read_radix(order, key->dp->order, 16)) != CRYPT_OK) goto error;
48 if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) goto error;
49 if ((err = mp_read_radix(a, key->dp->A, 16)) != CRYPT_OK) goto error;
50 if ((err = mp_read_radix(gx, key->dp->Gx, 16)) != CRYPT_OK) goto error;
51 if ((err = mp_read_radix(gy, key->dp->Gy, 16)) != CRYPT_OK) goto error;
52
53 /* curve param a */
54 len_a = mp_unsigned_bin_size(a);
55 if (len_a > sizeof(bin_a)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
56 if ((err = mp_to_unsigned_bin(a, bin_a)) != CRYPT_OK) goto error;
57 if (len_a == 0) { len_a = 1; bin_a[0] = 0; } /* XXX-TODO hack to handle case a == 0 */
58
59 /* curve param b */
60 len_b = mp_unsigned_bin_size(b);
61 if (len_b > sizeof(bin_b)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
62 if ((err = mp_to_unsigned_bin(b, bin_b)) != CRYPT_OK) goto error;
63 if (len_b == 0) { len_b = 1; bin_b[0] = 0; } /* XXX-TODO hack to handle case b == 0 */
64
65 /* base point - we export uncompressed form */
66 len_g = sizeof(bin_g);
67 if ((err = ecc_export_point(bin_g, &len_g, gx, gy, key->dp->size, 0)) != CRYPT_OK) goto error;
68
69 /* public key */
70 len_xy = sizeof(bin_xy);
71 if ((err = ecc_export_point(bin_xy, &len_xy, key->pubkey.x, key->pubkey.y, key->dp->size, 0)) != CRYPT_OK) goto error;
72
73 /* co-factor */
74 cofactor = key->dp->cofactor;
75
76 /* we support only prime-field EC */
77 if ((err = pk_get_oid(EC_PRIME_FIELD, &oid)) != CRYPT_OK) goto error;
78
79 /* FieldID SEQUENCE */
80 LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen);
81 LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
82
83 /* Curve SEQUENCE */
84 LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, len_a);
85 LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, len_b);
86
87 /* ECParameters SEQUENCE */
88 LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &one, 1UL);
89 LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
90 LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 2UL);
91 LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, len_g);
92 LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
93 LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
94
95 if (type == PK_PRIVATE) {
96 /* private key format: http://tools.ietf.org/html/rfc5915
97
98 ECPrivateKey ::= SEQUENCE { # SEQUENCE
99 version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), # INTEGER :01
100 privateKey OCTET STRING, # OCTET STRING
101 [0] ECParameters ::= SEQUENCE { # SEQUENCE
102 version INTEGER { ecpVer1(1) } (ecpVer1), # INTEGER :01
103 FieldID ::= SEQUENCE { # SEQUENCE
104 fieldType FIELD-ID.&id({IOSet}), # OBJECT :prime-field
105 parameters FIELD-ID.&Type({IOSet}{@fieldType}) # INTEGER
106 }
107 Curve ::= SEQUENCE { # SEQUENCE
108 a FieldElement ::= OCTET STRING # OCTET STRING
109 b FieldElement ::= OCTET STRING # OCTET STRING
110 seed BIT STRING OPTIONAL
111 }
112 base ECPoint ::= OCTET STRING # OCTET STRING
113 order INTEGER, # INTEGER
114 cofactor INTEGER OPTIONAL # INTEGER
115 }
116 [1] publicKey # BIT STRING
117 }
118 */
119
120 /* private key */
121 len_k = mp_unsigned_bin_size(key->k);
122 if (len_k > sizeof(bin_k)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
123 if ((err = mp_to_unsigned_bin(key->k, bin_k)) != CRYPT_OK) goto error;
124
125 LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &one, 1UL);
126 LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, len_k);
127 LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL);
128 LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, 8*len_xy);
129 seq_priv[2].tag = 0xA0;
130 seq_priv[3].tag = 0xA1;
131
132 err = der_encode_sequence(seq_priv, 4, out, outlen);
133 }
134 else {
135 /* public key format: http://tools.ietf.org/html/rfc5480
136
137 SubjectPublicKeyInfo ::= SEQUENCE { # SEQUENCE
138 AlgorithmIdentifier ::= SEQUENCE { # SEQUENCE
139 algorithm OBJECT IDENTIFIER # OBJECT :id-ecPublicKey
140 ECParameters ::= SEQUENCE { # SEQUENCE
141 version INTEGER { ecpVer1(1) } (ecpVer1), # INTEGER :01
142 FieldID ::= SEQUENCE { # SEQUENCE
143 fieldType FIELD-ID.&id({IOSet}), # OBJECT :prime-field
144 parameters FIELD-ID.&Type({IOSet}{@fieldType}) # INTEGER
145 }
146 Curve ::= SEQUENCE { # SEQUENCE
147 a FieldElement ::= OCTET STRING # OCTET STRING
148 b FieldElement ::= OCTET STRING # OCTET STRING
149 seed BIT STRING OPTIONAL
150 }
151 base ECPoint ::= OCTET STRING # OCTET STRING
152 order INTEGER, # INTEGER
153 cofactor INTEGER OPTIONAL # INTEGER
154 }
155 }
156 subjectPublicKey BIT STRING # BIT STRING
157 }
158 */
159
160 err = der_encode_subject_public_key_info( out, outlen,
161 PKA_EC, bin_xy, len_xy,
162 LTC_ASN1_SEQUENCE, seq_ecparams, 6 );
163 }
164
165 error:
166 mp_clear_multi(prime, order, a, b, gx, gy, NULL);
167 return err;
168 }
169
170 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 int ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed)
19 {
20 int err;
21 unsigned char buf[ECC_BUF_SIZE];
22 unsigned long xsize, ysize;
23
24 if (size > sizeof(buf)) return CRYPT_BUFFER_OVERFLOW;
25 if ((xsize = mp_unsigned_bin_size(x)) > size) return CRYPT_BUFFER_OVERFLOW;
26 if ((ysize = mp_unsigned_bin_size(y)) > size) return CRYPT_BUFFER_OVERFLOW;
27
28 if(compressed) {
29 if (*outlen < (1 + size)) {
30 *outlen = 1 + size;
31 return CRYPT_BUFFER_OVERFLOW;
32 }
33 /* store first byte */
34 out[0] = mp_isodd(y) ? 0x03 : 0x02;
35 /* pad and store x */
36 zeromem(buf, sizeof(buf));
37 if ((err = mp_to_unsigned_bin(x, buf + (size - xsize))) != CRYPT_OK) return err;
38 XMEMCPY(out+1, buf, size);
39 /* adjust outlen */
40 *outlen = 1 + size;
41 }
42 else {
43 if (*outlen < (1 + 2*size)) {
44 *outlen = 1 + 2*size;
45 return CRYPT_BUFFER_OVERFLOW;
46 }
47 /* store byte 0x04 */
48 out[0] = 0x04;
49 /* pad and store x */
50 zeromem(buf, sizeof(buf));
51 if ((err = mp_to_unsigned_bin(x, buf + (size - xsize))) != CRYPT_OK) return err;
52 XMEMCPY(out+1, buf, size);
53 /* pad and store y */
54 zeromem(buf, sizeof(buf));
55 if ((err = mp_to_unsigned_bin(y, buf + (size - ysize))) != CRYPT_OK) return err;
56 XMEMCPY(out+1+size, buf, size);
57 /* adjust outlen */
58 *outlen = 1 + 2*size;
59 }
60 return CRYPT_OK;
61 }
62
63 /** Export raw public or private key (public keys = ANS X9.63 compressed or uncompressed; private keys = raw bytes)
64 @param out [out] destination of export
65 @param outlen [in/out] Length of destination and final output size
66 @param type PK_PRIVATE, PK_PUBLIC or PK_PUBLIC_COMPRESSED
67 @param key Key to export
68 Return CRYPT_OK on success
69 */
70
71 int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key *key)
72 {
73 unsigned long size, ksize;
74 int err;
75
76 LTC_ARGCHK(key != NULL);
77 LTC_ARGCHK(out != NULL);
78 LTC_ARGCHK(outlen != NULL);
79
80 if (ltc_ecc_is_valid_idx(key->idx) == 0) {
81 return CRYPT_INVALID_ARG;
82 }
83 size = key->dp->size;
84
85 if (type == PK_PUBLIC_COMPRESSED) {
86 if ((err = ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, 1)) != CRYPT_OK) return err;
87 }
88 else if (type == PK_PUBLIC) {
89 if ((err = ecc_export_point(out, outlen, key->pubkey.x, key->pubkey.y, size, 0)) != CRYPT_OK) return err;
90 }
91 else if (type == PK_PRIVATE) {
92 if (key->type != PK_PRIVATE) return CRYPT_PK_TYPE_MISMATCH;
93 *outlen = size;
94 if (size > *outlen) return CRYPT_BUFFER_OVERFLOW;
95 if ((ksize = mp_unsigned_bin_size(key->k)) > size) return CRYPT_BUFFER_OVERFLOW;
96 /* pad and store k */
97 if ((err = mp_to_unsigned_bin(key->k, out + (size - ksize))) != CRYPT_OK) return err;
98 zeromem(out, size - ksize);
99 }
100 else {
101 return CRYPT_INVALID_ARG;
102 }
103
104 return CRYPT_OK;
105 }
106
107 #endif
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
2119 */
2220
2321 #ifdef LTC_MECC
24
25 static int is_point(ecc_key *key)
26 {
27 void *prime, *b, *t1, *t2;
28 int err;
29
30 if ((err = mp_init_multi(&prime, &b, &t1, &t2, NULL)) != CRYPT_OK) {
31 return err;
32 }
33
34 /* load prime and b */
35 if ((err = mp_read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error; }
36 if ((err = mp_read_radix(b, key->dp->B, 16)) != CRYPT_OK) { goto error; }
37
38 /* compute y^2 */
39 if ((err = mp_sqr(key->pubkey.y, t1)) != CRYPT_OK) { goto error; }
40
41 /* compute x^3 */
42 if ((err = mp_sqr(key->pubkey.x, t2)) != CRYPT_OK) { goto error; }
43 if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) { goto error; }
44 if ((err = mp_mul(key->pubkey.x, t2, t2)) != CRYPT_OK) { goto error; }
45
46 /* compute y^2 - x^3 */
47 if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) { goto error; }
48
49 /* compute y^2 - x^3 + 3x */
50 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
51 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
52 if ((err = mp_add(t1, key->pubkey.x, t1)) != CRYPT_OK) { goto error; }
53 if ((err = mp_mod(t1, prime, t1)) != CRYPT_OK) { goto error; }
54 while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
55 if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) { goto error; }
56 }
57 while (mp_cmp(t1, prime) != LTC_MP_LT) {
58 if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) { goto error; }
59 }
60
61 /* compare to b */
62 if (mp_cmp(t1, b) != LTC_MP_EQ) {
63 err = CRYPT_INVALID_PACKET;
64 } else {
65 err = CRYPT_OK;
66 }
67
68 error:
69 mp_clear_multi(prime, b, t1, t2, NULL);
70 return err;
71 }
7222
7323 /**
7424 Import an ECC key from a binary packet
13989 }
14090
14191 if (dp == NULL) {
92 /* BEWARE: Here we are looking up the curve params by keysize (neither curve name nor curve oid),
93 * which might be ambiguous (there can more than one curve for given keysize).
94 * Thus the chosen curve depends on order of items in ltc_ecc_sets[] - see ecc.c file.
95 */
14296 /* find the idx */
14397 for (key->idx = 0; ltc_ecc_sets[key->idx].size && (unsigned long)ltc_ecc_sets[key->idx].size != key_size; ++key->idx);
14498 if (ltc_ecc_sets[key->idx].size == 0) {
154108 if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto done; }
155109
156110 /* is it a point on the curve? */
157 if ((err = is_point(key)) != CRYPT_OK) {
111 if ((err = ltc_ecc_is_point(key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) {
158112 goto done;
159113 }
160114
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
9 */
10
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
12 *
13 */
14
15 #include "tomcrypt.h"
16
17 #ifdef LTC_MECC
18
19 static int _populate_dp_from_oid(unsigned long *oid, unsigned long size, ltc_ecc_set_type *dp)
20 {
21 int i;
22 unsigned long len;
23
24 for(i=0; ltc_ecc_sets[i].size != 0; i++) {
25 if ((size == ltc_ecc_sets[i].oid.OIDlen) &&
26 (XMEM_NEQ(oid, ltc_ecc_sets[i].oid.OID, sizeof(unsigned long) * ltc_ecc_sets[i].oid.OIDlen) == 0)) {
27 break;
28 }
29 }
30 if (ltc_ecc_sets[i].size == 0) return CRYPT_INVALID_ARG; /* not found */
31
32 /* a */
33 len = (unsigned long)strlen(ltc_ecc_sets[i].A);
34 if ((dp->A = XMALLOC(1+len)) == NULL) goto cleanup1;
35 strncpy(dp->A, ltc_ecc_sets[i].A, 1+len);
36 /* b */
37 len = (unsigned long)strlen(ltc_ecc_sets[i].B);
38 if ((dp->B = XMALLOC(1+len)) == NULL) goto cleanup2;
39 strncpy(dp->B, ltc_ecc_sets[i].B, 1+len);
40 /* order */
41 len = (unsigned long)strlen(ltc_ecc_sets[i].order);
42 if ((dp->order = XMALLOC(1+len)) == NULL) goto cleanup3;
43 strncpy(dp->order, ltc_ecc_sets[i].order, 1+len);
44 /* prime */
45 len = (unsigned long)strlen(ltc_ecc_sets[i].prime);
46 if ((dp->prime = XMALLOC(1+len)) == NULL) goto cleanup4;
47 strncpy(dp->prime, ltc_ecc_sets[i].prime, 1+len);
48 /* gx */
49 len = (unsigned long)strlen(ltc_ecc_sets[i].Gx);
50 if ((dp->Gx = XMALLOC(1+len)) == NULL) goto cleanup5;
51 strncpy(dp->Gx, ltc_ecc_sets[i].Gx, 1+len);
52 /* gy */
53 len = (unsigned long)strlen(ltc_ecc_sets[i].Gy);
54 if ((dp->Gy = XMALLOC(1+len)) == NULL) goto cleanup6;
55 strncpy(dp->Gy, ltc_ecc_sets[i].Gy, 1+len);
56 /* cofactor & size */
57 dp->cofactor = ltc_ecc_sets[i].cofactor;
58 dp->size = ltc_ecc_sets[i].size;
59 /* name */
60 len = (unsigned long)strlen(ltc_ecc_sets[i].name);
61 if ((dp->name = XMALLOC(1+len)) == NULL) goto cleanup6;
62 strncpy(dp->name, ltc_ecc_sets[i].name, 1+len);
63 /* done - success */
64 return CRYPT_OK;
65
66 cleanup7:
67 XFREE(dp->Gy);
68 cleanup6:
69 XFREE(dp->Gx);
70 cleanup5:
71 XFREE(dp->prime);
72 cleanup4:
73 XFREE(dp->order);
74 cleanup3:
75 XFREE(dp->B);
76 cleanup2:
77 XFREE(dp->A);
78 cleanup1:
79 return CRYPT_MEM;
80 }
81
82 static int _populate_dp(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ltc_ecc_set_type *dp)
83 {
84 unsigned char buf[ECC_BUF_SIZE];
85 unsigned long len;
86
87 /* a */
88 mp_tohex(a, (char *)buf);
89 len = (unsigned long)strlen((char *)buf);
90 if ((dp->A = XMALLOC(1+len)) == NULL) goto cleanup1;
91 strncpy(dp->A, (char*)buf, 1+len);
92 /* b */
93 mp_tohex(b, (char *)buf);
94 len = (unsigned long)strlen((char *)buf);
95 if ((dp->B = XMALLOC(1+len)) == NULL) goto cleanup2;
96 strncpy(dp->B, (char*)buf, 1+len);
97 /* order */
98 mp_tohex(order, (char *)buf);
99 len = (unsigned long)strlen((char *)buf);
100 if ((dp->order = XMALLOC(1+len)) == NULL) goto cleanup3;
101 strncpy(dp->order, (char*)buf, 1+len);
102 /* prime */
103 mp_tohex(prime, (char *)buf);
104 len = (unsigned long)strlen((char *)buf);
105 if ((dp->prime = XMALLOC(1+len)) == NULL) goto cleanup4;
106 strncpy(dp->prime, (char*)buf, 1+len);
107 /* gx */
108 mp_tohex(gx, (char *)buf);
109 len = (unsigned long)strlen((char *)buf);
110 if ((dp->Gx = XMALLOC(1+len)) == NULL) goto cleanup5;
111 strncpy(dp->Gx, (char*)buf, 1+len);
112 /* gy */
113 mp_tohex(gy, (char *)buf);
114 len = (unsigned long)strlen((char *)buf);
115 if ((dp->Gy = XMALLOC(1+len)) == NULL) goto cleanup6;
116 strncpy(dp->Gy, (char*)buf, 1+len);
117 /* cofactor & size */
118 dp->cofactor = cofactor;
119 dp->size = mp_unsigned_bin_size(prime);
120 /* name */
121 if ((dp->name = XMALLOC(7)) == NULL) goto cleanup7;
122 strcpy(dp->name, "custom"); /* XXX-TODO check this */
123 /* done - success */
124 return CRYPT_OK;
125
126 /* XFREE(dp->name); **** warning: statement not reached *** */
127 cleanup7:
128 XFREE(dp->Gy);
129 cleanup6:
130 XFREE(dp->Gx);
131 cleanup5:
132 XFREE(dp->prime);
133 cleanup4:
134 XFREE(dp->order);
135 cleanup3:
136 XFREE(dp->B);
137 cleanup2:
138 XFREE(dp->A);
139 cleanup1:
140 return CRYPT_MEM;
141 }
142
143 int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp)
144 {
145 void *prime, *order, *a, *b, *gx, *gy;
146 ltc_asn1_list seq_fieldid[2], seq_curve[3], seq_ecparams[6], seq_priv[4], seq_pub[2];
147 unsigned char bin_a[ECC_MAXSIZE], bin_b[ECC_MAXSIZE], bin_k[ECC_MAXSIZE], bin_g[2*ECC_MAXSIZE+1], bin_xy[2*ECC_MAXSIZE+2], bin_seed[128];
148 unsigned long len_a, len_b, len_k, len_g, len_xy, len_oid;
149 unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16], curveoid[16];
150 /*oid_st oid;*/
151 int err;
152
153 if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) return err;
154
155 /* ### 1. try to load public key - no curve parameters just curve OID */
156
157 len_xy = sizeof(bin_xy);
158 err = der_decode_subject_public_key_info_ex(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL, &len_oid);
159 if (err == CRYPT_OK) {
160 /* load curve parameters for given curve OID */
161 if ((err = _populate_dp_from_oid(curveoid, len_oid, dp)) != CRYPT_OK) { goto error; }
162 /* load public key */
163 if ((err = ecc_import_raw(bin_xy, len_xy, key, dp)) != CRYPT_OK) { goto error; }
164 goto success;
165 }
166
167 /* ### 2. try to load public key - curve parameters included */
168
169 /* ECParameters SEQUENCE */
170 LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
171 LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
172 LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL);
173 LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1);
174 LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
175 LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
176 seq_ecparams[5].optional = 1;
177 /* FieldID SEQUENCE */
178 LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL);
179 LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
180 /* Curve SEQUENCE */
181 LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE);
182 LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE);
183 LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128);
184 seq_curve[2].optional = 1;
185 /* try to load public key */
186 len_xy = sizeof(bin_xy);
187 err = der_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, 6);
188 if (err == CRYPT_OK) {
189 len_a = seq_curve[0].size;
190 len_b = seq_curve[1].size;
191 len_g = seq_ecparams[3].size;
192 /* create bignums */
193 if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; }
194 if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; }
195 if ((err = ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; }
196 /* load curve parameters */
197 if ((err = _populate_dp(a, b, prime, order, gx, gy, cofactor, dp)) != CRYPT_OK) { goto error; }
198 /* load public key */
199 if ((err = ecc_import_raw(bin_xy, len_xy, key, dp)) != CRYPT_OK) { goto error; }
200 goto success;
201 }
202
203 /* ### 3. try to load private key - no curve parameters just curve OID */
204
205 /* ECPrivateKey SEQUENCE */
206 LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL);
207 LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE);
208 LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, 16UL);
209 LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2));
210 seq_priv[2].tag = 0xA0; /* context specific 0 */
211 seq_priv[3].tag = 0xA1; /* context specific 1 */
212 /* try to load private key */
213 err = der_decode_sequence(in, inlen, seq_priv, 4);
214 if (err == CRYPT_OK) {
215 /* load curve parameters for given curve OID */
216 if ((err = _populate_dp_from_oid(curveoid, seq_priv[2].size, dp)) != CRYPT_OK) { goto error; }
217 /* load private+public key */
218 if ((err = ecc_import_raw(bin_k, seq_priv[1].size, key, dp)) != CRYPT_OK) { goto error; }
219 goto success;
220 }
221
222 /* ### 4. try to load private key - curve parameters included */
223
224 /* ECPrivateKey SEQUENCE */
225 LTC_SET_ASN1(seq_priv, 0, LTC_ASN1_SHORT_INTEGER, &pkver, 1UL);
226 LTC_SET_ASN1(seq_priv, 1, LTC_ASN1_OCTET_STRING, bin_k, (unsigned long)ECC_MAXSIZE);
227 LTC_SET_ASN1(seq_priv, 2, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL);
228 LTC_SET_ASN1(seq_priv, 3, LTC_ASN1_RAW_BIT_STRING, bin_xy, (unsigned long)8*(2*ECC_MAXSIZE+2));
229 seq_priv[2].tag = 0xA0; /* context specific 0 */
230 seq_priv[3].tag = 0xA1; /* context specific 1 */
231 /* ECParameters SEQUENCE */
232 LTC_SET_ASN1(seq_ecparams, 0, LTC_ASN1_SHORT_INTEGER, &ecver, 1UL);
233 LTC_SET_ASN1(seq_ecparams, 1, LTC_ASN1_SEQUENCE, seq_fieldid, 2UL);
234 LTC_SET_ASN1(seq_ecparams, 2, LTC_ASN1_SEQUENCE, seq_curve, 3UL);
235 LTC_SET_ASN1(seq_ecparams, 3, LTC_ASN1_OCTET_STRING, bin_g, (unsigned long)2*ECC_MAXSIZE+1);
236 LTC_SET_ASN1(seq_ecparams, 4, LTC_ASN1_INTEGER, order, 1UL);
237 LTC_SET_ASN1(seq_ecparams, 5, LTC_ASN1_SHORT_INTEGER, &cofactor, 1UL);
238 seq_ecparams[5].optional = 1;
239 /* FieldID SEQUENCE */
240 LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, 16UL);
241 LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL);
242 /* Curve SEQUENCE */
243 LTC_SET_ASN1(seq_curve, 0, LTC_ASN1_OCTET_STRING, bin_a, (unsigned long)ECC_MAXSIZE);
244 LTC_SET_ASN1(seq_curve, 1, LTC_ASN1_OCTET_STRING, bin_b, (unsigned long)ECC_MAXSIZE);
245 LTC_SET_ASN1(seq_curve, 2, LTC_ASN1_RAW_BIT_STRING, bin_seed, (unsigned long)8*128);
246 seq_curve[2].optional = 1;
247 /* try to load private key */
248 err = der_decode_sequence(in, inlen, seq_priv, 4);
249 if (err == CRYPT_OK) {
250 len_k = seq_priv[1].size;
251 len_xy = seq_priv[3].size;
252 len_a = seq_curve[0].size;
253 len_b = seq_curve[1].size;
254 len_g = seq_ecparams[3].size;
255 /* create bignums */
256 if ((err = mp_read_unsigned_bin(a, bin_a, len_a)) != CRYPT_OK) { goto error; }
257 if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; }
258 if ((err = ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; }
259 /* load curve parameters */
260 if ((err = _populate_dp(a, b, prime, order, gx, gy, cofactor, dp)) != CRYPT_OK) { goto error; }
261 /* load private+public key */
262 if ((err = ecc_import_raw(bin_k, len_k, key, dp)) != CRYPT_OK) { goto error; }
263 goto success;
264 }
265
266 /* ### 5. backward compatibility - try to load old-DER format */
267 if ((err = ecc_import(in, inlen, key)) != CRYPT_OK) { goto error; }
268
269 success:
270 err = CRYPT_OK;
271 error:
272 mp_clear_multi(prime, order, a, b, gx, gy, NULL);
273 return err;
274 }
275
276 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 #ifdef LTC_MECC
17
18 int ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y)
19 {
20 int err;
21 unsigned long size;
22 void *t1, *t2;
23
24 /* init key + temporary numbers */
25 if (mp_init_multi(&t1, &t2, NULL) != CRYPT_OK) {
26 return CRYPT_MEM;
27 }
28
29 size = mp_unsigned_bin_size(prime);
30
31 if (in[0] == 0x04 && (inlen&1) && ((inlen-1)>>1) == size) {
32 /* read uncompressed point */
33 /* load x */
34 if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) {
35 goto cleanup;
36 }
37 /* load y */
38 if ((err = mp_read_unsigned_bin(y, (unsigned char *)in+1+size, size)) != CRYPT_OK) {
39 goto cleanup;
40 }
41 }
42 else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == size) {
43 /* read compressed point */
44 /* load x */
45 if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) {
46 goto cleanup;
47 }
48 /* compute x^3 */
49 if ((err = mp_sqr(x, t1)) != CRYPT_OK) { goto cleanup; }
50 if ((err = mp_mulmod(t1, x, prime, t1)) != CRYPT_OK) { goto cleanup; }
51 /* compute x^3 + a*x */
52 if ((err = mp_mulmod(a, x, prime, t2)) != CRYPT_OK) { goto cleanup; }
53 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto cleanup; }
54 /* compute x^3 + a*x + b */
55 if ((err = mp_add(t1, b, t1)) != CRYPT_OK) { goto cleanup; }
56 /* compute sqrt(x^3 + a*x + b) */
57 if ((err = mp_sqrtmod_prime(t1, prime, t2)) != CRYPT_OK) { goto cleanup; }
58 /* adjust y */
59 if ((mp_isodd(t2) && in[0] == 0x03) || (!mp_isodd(t2) && in[0] == 0x02)) {
60 if ((err = mp_mod(t2, prime, y)) != CRYPT_OK) { goto cleanup; }
61 }
62 else {
63 if ((err = mp_submod(prime, t2, prime, y)) != CRYPT_OK) { goto cleanup; }
64 }
65 }
66 else {
67 err = CRYPT_INVALID_PACKET;
68 goto cleanup;
69 }
70
71 err = CRYPT_OK;
72 cleanup:
73 mp_clear_multi(t1, t2, NULL);
74 return err;
75 }
76
77 /** Import raw public or private key (public keys = ANSI X9.63 compressed or uncompressed; private keys = raw bytes)
78 @param in The input data to read
79 @param inlen The length of the input data
80 @param key [out] destination to store imported key
81 @param dp Curve parameters
82 Return CRYPT_OK on success
83 */
84
85 int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp)
86 {
87 int err, type = -1;
88 unsigned long size = 0;
89 void *prime, *a, *b;
90 ecc_point *base;
91
92 LTC_ARGCHK(in != NULL);
93 LTC_ARGCHK(key != NULL);
94 LTC_ARGCHK(dp != NULL);
95
96 /* init key + temporary numbers */
97 if (mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &a, &b, NULL) != CRYPT_OK) {
98 return CRYPT_MEM;
99 }
100
101 if (inlen == (unsigned long)dp->size) {
102 /* read PRIVATE key */
103 type = PK_PRIVATE;
104 size = inlen;
105 /* load private k */
106 if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)in, size)) != CRYPT_OK) {
107 goto cleanup;
108 }
109 if (mp_iszero(key->k)) {
110 err = CRYPT_INVALID_PACKET;
111 goto cleanup;
112 }
113 /* init base point */
114 if ((base = ltc_ecc_new_point()) == NULL) {
115 err = CRYPT_MEM;
116 goto cleanup;
117 }
118 /* load prime + base point */
119 if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) { goto cleanup; }
120 if ((err = mp_read_radix(base->x, dp->Gx, 16)) != CRYPT_OK) { goto cleanup; }
121 if ((err = mp_read_radix(base->y, dp->Gy, 16)) != CRYPT_OK) { goto cleanup; }
122 if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto cleanup; }
123 /* make the public key */
124 if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) { goto cleanup; }
125 if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, a, prime, 1)) != CRYPT_OK) {
126 goto cleanup;
127 }
128 /* cleanup */
129 ltc_ecc_del_point(base);
130 }
131 else {
132 /* read PUBLIC key */
133 type = PK_PUBLIC;
134 /* load prime + A + B */
135 if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) { goto cleanup; }
136 if ((err = mp_read_radix(b, dp->B, 16)) != CRYPT_OK) { goto cleanup; }
137 if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) { goto cleanup; }
138 err = ecc_import_point(in, inlen, prime, a, b, key->pubkey.x, key->pubkey.y);
139 if (err != CRYPT_OK) { goto cleanup; }
140 if ((err = mp_set(key->pubkey.z, 1)) != CRYPT_OK) { goto cleanup; }
141 }
142
143 if ((err = ltc_ecc_is_point(dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) {
144 err = CRYPT_INVALID_PACKET;
145 goto cleanup;
146 }
147
148 key->type = type;
149 key->idx = -1;
150 key->dp = dp;
151
152 /* we're done */
153 mp_clear_multi(prime, a, b, NULL);
154 return CRYPT_OK;
155 cleanup:
156 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, prime, a, b, NULL);
157 return err;
158 }
159
160 #endif
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
3230 */
3331 int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key)
3432 {
33 /* BEWARE: Here we are looking up the curve params by keysize (neither curve name nor curve oid),
34 * which might be ambiguous (there can more than one curve for given keysize).
35 * Thus the chosen curve depends on order of items in ltc_ecc_sets[] - see ecc.c file.
36 */
3537 int x, err;
3638
3739 /* find key size */
5052 {
5153 int err;
5254 ecc_point *base;
53 void *prime, *order;
55 void *prime, *order, *a;
5456 unsigned char *buf;
55 int keysize;
57 int keysize, orderbits;
5658
5759 LTC_ARGCHK(key != NULL);
5860 LTC_ARGCHK(ltc_mp.name != NULL);
8183 }
8284
8385 /* 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) {
86 if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, &a, NULL)) != CRYPT_OK) {
8587 goto ERR_BUF;
8688 }
8789 base = ltc_ecc_new_point();
98100 if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto errkey; }
99101 if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK) { goto errkey; }
100102
101 /* the key should be smaller than the order of base point */
102 if (mp_cmp(key->k, order) != LTC_MP_LT) {
103 if((err = mp_mod(key->k, order, key->k)) != CRYPT_OK) { goto errkey; }
104 }
103 /* ECC key pair generation according to FIPS-186-4 (B.4.2 Key Pair Generation by Testing Candidates):
104 * the generated private key k should be the range [1, order–1]
105 * a/ N = bitlen(order)
106 * b/ generate N random bits and convert them into big integer k
107 * c/ if k not in [1, order-1] go to b/
108 * e/ Q = k*G
109 */
110 orderbits = mp_count_bits(order);
111 do {
112 if ((err = rand_bn_bits(key->k, orderbits, prng, wprng)) != CRYPT_OK) { goto errkey; }
113 } while (mp_iszero(key->k) || mp_cmp(key->k, order) != LTC_MP_LT);
114
105115 /* make the public key */
106 if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK) { goto errkey; }
116 if ((err = mp_read_radix(a, (char *)key->dp->A, 16)) != CRYPT_OK) { goto errkey; }
117 if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, a, prime, 1)) != CRYPT_OK) { goto errkey; }
107118 key->type = PK_PRIVATE;
108119
109120 /* free up ram */
113124 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
114125 cleanup:
115126 ltc_ecc_del_point(base);
116 mp_clear_multi(prime, order, NULL);
127 mp_clear_multi(prime, order, a, NULL);
117128 ERR_BUF:
118129 #ifdef LTC_CLEAN_STACK
119130 zeromem(buf, ECC_MAXSIZE);
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
3533 {
3634 unsigned long x;
3735 ecc_point *result;
38 void *prime;
36 void *prime, *a;
3937 int err;
4038
4139 LTC_ARGCHK(private_key != NULL);
6260 return CRYPT_MEM;
6361 }
6462
65 if ((err = mp_init(&prime)) != CRYPT_OK) {
63 if ((err = mp_init_multi(&prime, &a, NULL)) != CRYPT_OK) {
6664 ltc_ecc_del_point(result);
6765 return err;
6866 }
6967
7068 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; }
7271
7372 x = (unsigned long)mp_unsigned_bin_size(prime);
7473 if (*outlen < x) {
8281 err = CRYPT_OK;
8382 *outlen = x;
8483 done:
85 mp_clear(prime);
84 mp_clear_multi(prime, a, NULL);
8685 ltc_ecc_del_point(result);
8786 return err;
8887 }
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
4038 ecc_key pubkey;
4139 void *r, *s, *e, *p;
4240 int err;
41 unsigned long pbits, pbytes, i, shift_right;
42 unsigned char ch, buf[MAXBLOCKSIZE];
4343
4444 LTC_ARGCHK(in != NULL);
4545 LTC_ARGCHK(out != NULL);
6060 return err;
6161 }
6262
63 /* get the hash and load it as a bignum into 'e' */
6463 /* init the bignums */
6564 if ((err = mp_init_multi(&r, &s, &p, &e, NULL)) != CRYPT_OK) {
6665 return err;
6766 }
6867 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, 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 }
7087
7188 /* make up a key and export the public copy */
7289 for (;;) {
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
4745 int *stat, ecc_key *key)
4846 {
4947 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;
5149 void *mp;
5250 int err;
51 unsigned long pbits, pbytes, i, shift_right;
52 unsigned char ch, buf[MAXBLOCKSIZE];
5353
5454 LTC_ARGCHK(sig != NULL);
5555 LTC_ARGCHK(hash != NULL);
6666 }
6767
6868 /* 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) {
7070 return CRYPT_MEM;
7171 }
7272
9292 /* get the modulus */
9393 if ((err = mp_read_radix(m, (char *)key->dp->prime, 16)) != CRYPT_OK) { goto error; }
9494
95 /* get the a */
96 if ((err = mp_read_radix(a, (char *)key->dp->A, 16)) != CRYPT_OK) { goto error; }
97
9598 /* check for zero */
9699 if (mp_iszero(r) || mp_iszero(s) || mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) {
97100 err = CRYPT_INVALID_PACKET;
98101 goto error;
99102 }
100103
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, 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 }
103122
104123 /* w = s^-1 mod n */
105124 if ((err = mp_invmod(s, p, w)) != CRYPT_OK) { goto error; }
121140
122141 /* compute u1*mG + u2*mQ = mG */
123142 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
127146 /* find the montgomery mp */
128147 if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; }
129148
130149 /* 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
133152 /* reduce */
134153 if ((err = ltc_mp.ecc_map(mG, m, mp)) != CRYPT_OK) { goto error; }
135154 } else {
136155 /* 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; }
138157 }
139158
140159 /* v = X_x1 mod n */
150169 error:
151170 ltc_ecc_del_point(mG);
152171 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) {
155174 mp_montgomery_free(mp);
156175 }
157176 return err;
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 *
12 */
13
14 #include "tomcrypt.h"
15
16 /* origin of this code - OLPC */
17
18 #ifdef LTC_MECC
19
20 /**
21 Verify a key according to ANSI spec
22 @param key The key to validate
23 @return CRYPT_OK if successful
24 */
25
26 int ecc_verify_key(ecc_key *key)
27 {
28 int err;
29 void *prime = NULL;
30 void *order = NULL;
31 void *a = NULL;
32 ecc_point *test_output = NULL;
33 test_output = malloc(sizeof(ecc_point));
34
35 /* XXX test_output->infinity = 0; */
36 if (mp_init_multi(&(test_output->x), &(test_output->y), &(test_output->z), &order, &prime, NULL) != CRYPT_OK) {
37 return CRYPT_MEM;
38 }
39
40 /* Test 1: Are the x amd y points of the public key in the field? */
41 if((err = ltc_mp.read_radix(prime, key->dp->prime, 16)) != CRYPT_OK) { goto error;}
42
43 if(ltc_mp.compare_d(key->pubkey.z, 1) == LTC_MP_EQ) {
44 if(
45 (ltc_mp.compare(key->pubkey.x, prime) != LTC_MP_LT)
46 || (ltc_mp.compare(key->pubkey.y, prime) != LTC_MP_LT)
47 || (ltc_mp.compare_d(key->pubkey.x, 0) != LTC_MP_GT)
48 || (ltc_mp.compare_d(key->pubkey.y, 0) != LTC_MP_GT) )
49 {
50 err = CRYPT_INVALID_PACKET;
51 goto error;
52 }
53 }
54
55 /* Test 2: is the public key on the curve? */
56 if((err = ltc_ecc_is_point(key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { goto error;}
57
58 /* Test 3: does nG = O? (n = order, 0 = point at infinity, G = public key) */
59 if((err = ltc_mp.read_radix(order, key->dp->order, 16)) != CRYPT_OK) { goto error;}
60 if((err = ltc_mp.read_radix(a, key->dp->A, 16)) != CRYPT_OK) { goto error;}
61 if((err = ltc_ecc_mulmod(order, &(key->pubkey), test_output, a, prime, 1)) != CRYPT_OK) {
62 goto error;
63 }
64
65 /* XXX
66 if(!test_output->infinity){
67 err = CRYPT_INVALID_PACKET;
68 goto error;
69 }
70 */
71
72 err = CRYPT_OK;
73 error:
74 mp_clear_multi(prime, order, test_output->z, test_output->y, test_output->x, NULL);
75 return err;
76 }
77
78 #endif
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9
10 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
11 */
12
13 #include "tomcrypt.h"
14
15 #ifdef LTC_MECC
16
17 /** Returns whether [x,y] is a point on curve defined by dp
18 @param dp curve parameters
19 @param x x point coordinate
20 @param y y point coordinate
21 @return CRYPT_OK if valid
22 */
23
24 int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y)
25 {
26 void *prime, *a, *b, *t1, *t2;
27 int err;
28
29 if ((err = mp_init_multi(&prime, &a, &b, &t1, &t2, NULL)) != CRYPT_OK) {
30 return err;
31 }
32
33 /* load prime, a and b */
34 if ((err = mp_read_radix(prime, dp->prime, 16)) != CRYPT_OK) goto cleanup;
35 if ((err = mp_read_radix(b, dp->B, 16)) != CRYPT_OK) goto cleanup;
36 if ((err = mp_read_radix(a, dp->A, 16)) != CRYPT_OK) goto cleanup;
37
38 /* compute y^2 */
39 if ((err = mp_sqr(y, t1)) != CRYPT_OK) goto cleanup;
40
41 /* compute x^3 */
42 if ((err = mp_sqr(x, t2)) != CRYPT_OK) goto cleanup;
43 if ((err = mp_mod(t2, prime, t2)) != CRYPT_OK) goto cleanup;
44 if ((err = mp_mul(x, t2, t2)) != CRYPT_OK) goto cleanup;
45
46 /* compute y^2 - x^3 */
47 if ((err = mp_sub(t1, t2, t1)) != CRYPT_OK) goto cleanup;
48
49 /* compute y^2 - x^3 - a*x */
50 if ((err = mp_submod(prime, a, prime, t2)) != CRYPT_OK) goto cleanup;
51 if ((err = mp_mulmod(t2, x, prime, t2)) != CRYPT_OK) goto cleanup;
52 if ((err = mp_addmod(t1, t2, prime, t1)) != CRYPT_OK) goto cleanup;
53
54 /* adjust range (0, prime) */
55 while (mp_cmp_d(t1, 0) == LTC_MP_LT) {
56 if ((err = mp_add(t1, prime, t1)) != CRYPT_OK) goto cleanup;
57 }
58 while (mp_cmp(t1, prime) != LTC_MP_LT) {
59 if ((err = mp_sub(t1, prime, t1)) != CRYPT_OK) goto cleanup;
60 }
61
62 /* compare to b */
63 if (mp_cmp(t1, b) != LTC_MP_EQ) {
64 err = CRYPT_INVALID_PACKET;
65 } else {
66 err = CRYPT_OK;
67 }
68
69 cleanup:
70 mp_clear_multi(prime, b, t1, t2, NULL);
71 return err;
72 }
73
74 #endif
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
12 *
1513 */
1614 #include "tomcrypt.h"
1715
3634 int ltc_ecc_mul2add(ecc_point *A, void *kA,
3735 ecc_point *B, void *kB,
3836 ecc_point *C,
37 void *a,
3938 void *modulus)
4039 {
4140 ecc_point *precomp[16];
113112 if ((err = mp_mulmod(B->z, mu, modulus, precomp[1<<2]->z)) != CRYPT_OK) { goto ERR_MU; }
114113
115114 /* 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; }
118117
119118 /* 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; }
122121
123122 /* precomp [i,j](A + B) table (i != 0, j != 0) */
124123 for (x = 1; x < 4; x++) {
125124 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; }
127126 }
128127 }
129128
156155 /* double twice, only if this isn't the first */
157156 if (first == 0) {
158157 /* 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; }
161160 }
162161
163162 /* if not both zero */
170169 if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; }
171170 } else {
172171 /* 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; }
174173 }
175174 }
176175 }
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
12 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
12 *
1513 */
1614 #include "tomcrypt.h"
1715
3533 @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
3634 @return CRYPT_OK on success
3735 */
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)
3937 {
4038 ecc_point *tG, *M[8];
4139 int i, j, err;
9492
9593 /* calc the M tab, which holds kG for k==8..15 */
9694 /* 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; }
10098
10199 /* now find (8+k)G for k=1..7 */
102100 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; }
104102 }
105103
106104 /* setup sliding window */
134132
135133 /* if the bit is zero and mode == 1 then we double */
136134 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; }
138136 continue;
139137 }
140138
155153 /* ok window is filled so double as required and add */
156154 /* double first */
157155 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; }
159157 }
160158
161159 /* 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; }
163161 }
164162 /* empty window and reset */
165163 bitcpy = bitbuf = 0;
173171 for (j = 0; j < bitcpy; j++) {
174172 /* only double if we have had at least one add first */
175173 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; }
177175 }
178176
179177 bitbuf <<= 1;
186184 first = 0;
187185 } else {
188186 /* 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; }
190188 }
191189 }
192190 }
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
2927 @param k The scalar to multiply by
3028 @param G The base point
3129 @param R [out] Destination for kG
30 @param a ECC curve parameter a
3231 @param modulus The modulus of the field the ECC curve is in
3332 @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective)
3433 @return CRYPT_OK on success
3534 */
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)
3736 {
3837 ecc_point *tG, *M[3];
3938 int i, j, err;
9089 if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK) { goto done; }
9190 if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK) { goto done; }
9291 /* 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; }
9493
9594 /* setup sliding window */
9695 mode = 0;
116115
117116 if (mode == 0 && i == 0) {
118117 /* dummy operations */
119 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
120 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
118 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; }
119 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; }
121120 continue;
122121 }
123122
124123 if (mode == 0 && i == 1) {
125124 mode = 1;
126125 /* dummy operations */
127 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
128 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
126 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; }
127 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; }
129128 continue;
130129 }
131130
132 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], modulus, mp)) != CRYPT_OK) { goto done; }
133 if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], modulus, mp)) != CRYPT_OK) { goto done; }
131 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], a, modulus, mp)) != CRYPT_OK) { goto done; }
132 if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], a, modulus, mp)) != CRYPT_OK) { goto done; }
134133 }
135134
136135 /* copy result out */
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
1715
3129 @param mp The "b" value from montgomery_setup()
3230 @return CRYPT_OK on success
3331 */
34 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp)
32 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp)
3533 {
3634 void *t1, *t2, *x, *y, *z;
3735 int err;
5351 (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) &&
5452 (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) {
5553 mp_clear_multi(t1, t2, x, y, z, NULL);
56 return ltc_ecc_projective_dbl_point(P, R, modulus, mp);
54 return ltc_ecc_projective_dbl_point(P, R, a, modulus, mp);
5755 }
5856
5957 if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; }
88 * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
99 */
1010
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 - 3x + b
11 /* Implements ECC over Z/pZ for curve y^2 = x^3 + a*x + b
1212 *
13 * All curves taken from NIST recommendation paper of July 1999
14 * Available at http://csrc.nist.gov/cryptval/dss.htm
1513 */
1614 #include "tomcrypt.h"
15
16 /* ### Point doubling in Jacobian coordinate system ###
17 *
18 * let us have a curve: y^2 = x^3 + a*x + b
19 * in Jacobian coordinates it becomes: y^2 = x^3 + a*x*z^4 + b*z^6
20 *
21 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
22 * Xr = M^2 - 2*S
23 * Yr = M * (S - Xr) - 8*T
24 * Zr = 2 * Yp * Zp
25 *
26 * M = 3 * Xp^2 + a*Zp^4
27 * T = Yp^4
28 * S = 4 * Xp * Yp^2
29 *
30 * SPECIAL CASE: when a == -3 we can compute M as
31 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
32 */
1733
1834 /**
1935 @file ltc_ecc_projective_dbl_point.c
2642 Double an ECC point
2743 @param P The point to double
2844 @param R [out] The destination of the double
45 @param a ECC curve parameter a (if NULL we assume a == -3)
2946 @param modulus The modulus of the field the ECC curve is in
3047 @param mp The "b" value from montgomery_setup()
3148 @return CRYPT_OK on success
3249 */
33 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp)
50 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp)
3451 {
3552 void *t1, *t2;
3653 int err;
6279 if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; }
6380 }
6481
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 if (a == NULL) { /* special case for a == -3 (slightly faster than general case) */
83 /* T2 = X - T1 */
84 if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; }
85 if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
86 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
87 }
88 /* T1 = X + T1 */
89 if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; }
90 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
91 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
92 }
93 /* T2 = T1 * T2 */
94 if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; }
95 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
96 /* T1 = 2T2 */
97 if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; }
98 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
99 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
100 }
101 /* T1 = T1 + T2 */
102 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
103 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
104 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
105 }
69106 }
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; }
107 else {
108 /* T2 = T1 * T1 */
109 if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; }
110 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
111 /* T1 = T2 * a */
112 if ((err = mp_mulmod(t2, a, modulus, t1)) != CRYPT_OK) { goto done; }
113 /* T2 = X * X */
114 if ((err = mp_sqr(R->x, t2)) != CRYPT_OK) { goto done; }
115 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
116 /* T1 = T2 + T1 */
117 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
118 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
119 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
120 }
121 /* T1 = T2 + T1 */
122 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
123 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
124 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
125 }
126 /* T1 = T2 + T1 */
127 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
128 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
129 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
130 }
87131 }
88132
89133 /* Y = 2Y */