Codebase list libcryptx-perl / ea91786
ECC support for curve y^2 = x^3 + a*x + b (part 2); ECDSA handling hashes longer then curve bitsize Karel Miko 10 years ago
29 changed file(s) with 290 addition(s) and 160 deletion(s). Raw diff Collapse all Expand all
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
340348 @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only)
341349 @return CRYPT_OK on success
342350 */
343 int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
351 int (*ecc_ptmul)(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
344352
345353 /** ECC GF(p) point addition
346354 @param P The first point
347355 @param Q The second point
348356 @param R The destination of P + Q
357 @param a ECC curve parameter a (if NULL we assume a == -3)
349358 @param modulus The modulus
350359 @param mp The "b" value from montgomery_setup()
351360 @return CRYPT_OK on success
352361 */
353 int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
362 int (*ecc_ptadd)(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp);
354363
355364 /** ECC GF(p) point double
356365 @param P The first point
357366 @param R The destination of 2P
358 @param modulus The modulus
367 @param a ECC curve parameter a (if NULL we assume a == -3)
368 @param modulus The modulus of the field the ECC curve is in
359369 @param mp The "b" value from montgomery_setup()
360370 @return CRYPT_OK on success
361371 */
362 int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *modulus, void *mp);
372 int (*ecc_ptdbl)(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp);
363373
364374 /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1)
365375 @param P The point to map
383393 int (*ecc_mul2add)(ecc_point *A, void *kA,
384394 ecc_point *B, void *kB,
385395 ecc_point *C,
396 void *a,
386397 void *modulus);
387398
388399 /* ---- (optional) rsa optimized math (for internal CRT) ---- */
496507 #define mp_mul(a, b, c) ltc_mp.mul(a, b, c)
497508 #define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c)
498509 #define mp_sqr(a, b) ltc_mp.sqr(a, b)
510 #define mp_sqrtmod_prime(a, b, c) ltc_mp.sqrtmod_prime(a, b, c)
499511 #define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d)
500512 #define mp_div_2(a, b) ltc_mp.div_2(a, b)
501513 #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 int rand_prime(void *N, long len, prng_state *prng, int wprng);
89
910 enum {
1011 PKA_RSA,
11 PKA_DSA
12 PKA_DSA,
13 PKA_EC,
14 EC_PRIME_FIELD
1215 };
1316
1417 typedef struct Oid {
232235
233236 /** The y co-ordinate of the base point on the curve (hex) */
234237 char *Gy;
238
239 /** The co-factor */
240 int cofactor;
235241 } ltc_ecc_set_type;
236242
237243 /** 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 */
271277 void ecc_sizes(int *low, int *high);
272278 int ecc_get_size(ecc_key *key);
273279
280 int ecc_dp_init(ltc_ecc_set_type *dp);
281 int ecc_dp_set(ltc_ecc_set_type *dp, char *ch_prime, char *ch_A, char *ch_B, char *ch_order, char *ch_Gx, char *ch_Gy, int cofactor, char *ch_name);
282 int ecc_dp_clear(ltc_ecc_set_type *dp);
283
274284 int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key);
275285 int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp);
276286 void ecc_free(ecc_key *key);
282292 int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen);
283293 int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key);
284294 int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
295
296 int ecc_export_full(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
297 int ecc_import_full(const unsigned char *in, unsigned long inlen, ecc_key *key);
298
299 int ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed);
300 int ecc_export_raw(unsigned char *out, unsigned long *outlen, int type, ecc_key *key);
301 int ecc_import_raw(const unsigned char *in, unsigned long inlen, ecc_key *key, ltc_ecc_set_type *dp);
285302
286303 int ecc_shared_secret(ecc_key *private_key, ecc_key *public_key,
287304 unsigned char *out, unsigned long *outlen);
303320 const unsigned char *hash, unsigned long hashlen,
304321 int *stat, ecc_key *key);
305322
323 int ecc_verify_key(ecc_key *key);
324
306325 /* low level functions */
307326 ecc_point *ltc_ecc_new_point(void);
308327 void ltc_ecc_del_point(ecc_point *p);
309328 int ltc_ecc_is_valid_idx(int n);
329 int ltc_ecc_is_point(const ltc_ecc_set_type *dp, void *x, void *y);
310330
311331 /* point ops (mp == montgomery digit) */
312332 #if !defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC) || defined(GMP_LTC_DESC)
313333 /* R = 2P */
314 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp);
334 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp);
315335
316336 /* R = P + Q */
317 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp);
337 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp);
318338 #endif
319339
320340 #if defined(LTC_MECC_FP)
321341 /* optimized point multiplication using fixed point cache (HAC algorithm 14.117) */
322 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
342 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
323343
324344 /* functions for saving/loading/freeing/adding to fixed point cache */
325345 int ltc_ecc_fp_save_state(unsigned char **out, unsigned long *outlen);
332352 #endif
333353
334354 /* R = kG */
335 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map);
355 int ltc_ecc_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map);
336356
337357 #ifdef LTC_ECC_SHAMIR
338358 /* kA*A + kB*B = C */
339359 int ltc_ecc_mul2add(ecc_point *A, void *kA,
340360 ecc_point *B, void *kB,
341 ecc_point *C,
342 void *modulus);
361 ecc_point *C, void *a, void *modulus);
343362
344363 #ifdef LTC_MECC_FP
345364 /* Shamir's trick with optimized point multiplication using fixed point cache */
346365 int ltc_ecc_fp_mul2add(ecc_point *A, void *kA,
347366 ecc_point *B, void *kB,
348 ecc_point *C, void *modulus);
367 ecc_point *C, void *a, void *modulus);
349368 #endif
350369
351370 #endif
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, void *a, void *modulus)
11151115 {
11161116 int idx1, idx2, err;
11171117 void *mp, *mu;
11671167 }
11681168
11691169 /* build the LUT */
1170 if ((err = build_lut(idx1, modulus, mp, mu)) != CRYPT_OK) {
1170 if ((err = build_lut(idx1, a, modulus, mp, mu)) != CRYPT_OK) {
11711171 goto LBL_ERR;;
11721172 }
11731173 }
11881188 }
11891189
11901190 /* build the LUT */
1191 if ((err = build_lut(idx2, modulus, mp, mu)) != CRYPT_OK) {
1191 if ((err = build_lut(idx2, a, modulus, mp, mu)) != CRYPT_OK) {
11921192 goto LBL_ERR;;
11931193 }
11941194 }
11991199 /* compute mp */
12001200 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
12011201 }
1202 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, modulus, mp);
1202 err = accel_fp_mul2add(idx1, idx2, kA, kB, C, a, modulus, mp);
12031203 } else {
1204 err = ltc_ecc_mul2add(A, kA, B, kB, C, modulus);
1204 err = ltc_ecc_mul2add(A, kA, B, kB, C, a, modulus);
12051205 }
12061206 LBL_ERR:
12071207 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
12191219 @param k The multiplicand
12201220 @param G Base point to multiply
12211221 @param R [out] Destination of product
1222 @param a ECC curve parameter a
12221223 @param modulus The modulus for the curve
12231224 @param map [boolean] If non-zero maps the point back to affine co-ordinates, otherwise it's left in jacobian-montgomery form
12241225 @return CRYPT_OK if successful
1225 */
1226 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *modulus, int map)
1226 */
1227 int ltc_ecc_fp_mulmod(void *k, ecc_point *G, ecc_point *R, void *a, void *modulus, int map)
12271228 {
12281229 int idx, err;
12291230 void *mp, *mu;
12651266 }
12661267
12671268 /* build the LUT */
1268 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) {
1269 if ((err = build_lut(idx, a, modulus, mp, mu)) != CRYPT_OK) {
12691270 goto LBL_ERR;;
12701271 }
12711272 }
12751276 /* compute mp */
12761277 if ((err = mp_montgomery_setup(modulus, &mp)) != CRYPT_OK) { goto LBL_ERR; }
12771278 }
1278 err = accel_fp_mul(idx, k, R, modulus, mp, map);
1279 err = accel_fp_mul(idx, k, R, a, modulus, mp, map);
12791280 } else {
1280 err = ltc_ecc_mulmod(k, G, R, modulus, map);
1281 err = ltc_ecc_mulmod(k, G, R, a, modulus, map);
12811282 }
12821283 LBL_ERR:
12831284 LTC_MUTEX_UNLOCK(&ltc_ecc_fp_lock);
13641365 }
13651366
13661367 /* build the LUT */
1367 if ((err = build_lut(idx, modulus, mp, mu)) != CRYPT_OK) {
1368 if ((err = build_lut(idx, a, modulus, mp, mu)) != CRYPT_OK) {
13681369 goto LBL_ERR;
13691370 }
13701371 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 {
450459 &mul,
451460 &muli,
452461 &sqr,
462 &sqrtmod_prime,
453463 &divide,
454464 &div_2,
455465 &modi,
1818 6,
1919 };
2020
21 static const oid_st ec_oid = {
22 { 1, 2, 840, 10045, 2, 1 },
23 6,
24 };
25
26 static const oid_st ec_primef = {
27 { 1, 2, 840, 10045, 1, 1 },
28 6,
29 };
30
2131 /*
2232 Returns the OID of the public key algorithm.
2333 @return CRYPT_OK if valid
3141 case PKA_DSA:
3242 memcpy(st, &dsa_oid, sizeof(*st));
3343 break;
44 case PKA_EC:
45 memcpy(st, &ec_oid, sizeof(*st));
46 break;
47 case EC_PRIME_FIELD:
48 memcpy(st, &ec_primef, sizeof(*st));
49 break;
3450 default:
3551 return CRYPT_INVALID_ARG;
3652 }
1010
1111 /* 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
3331 "659EF8BA043916EEDE8911702B22",
3432 "DB7C2ABF62E35E7628DFAC6561C5",
3533 "09487239995A5EE76B55F9C2F098",
36 "A89CE5AF8724C0A23E0E0FF77500"
34 "A89CE5AF8724C0A23E0E0FF77500",
35 1
3736 },
3837 #endif
3938 #ifdef ECC128
4645 "FFFFFFFE0000000075A30D1B9038A115",
4746 "161FF7528B899B2D0C28607CA52C5B86",
4847 "CF5AC8395BAFEB13C02DA292DDED7A83",
48 1
4949 },
5050 #endif
5151 #ifdef ECC160
5858 "0100000000000000000001F4C8F927AED3CA752257",
5959 "4A96B5688EF573284664698968C38BB913CBFC82",
6060 "23A628553168947D59DCC912042351377AC5FB32",
61 1
6162 },
6263 #endif
6364 #ifdef ECC192
7071 "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831",
7172 "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
7273 "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
74 1
7375 },
7476 #endif
7577 #ifdef ECC224
8284 "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D",
8385 "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21",
8486 "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34",
87 1
8588 },
8689 #endif
8790 #ifdef ECC256
9497 "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
9598 "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296",
9699 "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
100 1
97101 },
98102 #endif
99103 #ifdef ECC384
106110 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973",
107111 "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B9859F741E082542A385502F25DBF55296C3A545E3872760AB7",
108112 "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F",
113 1,
109114 },
110115 #endif
111116 #ifdef ECC521
118123 "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409",
119124 "C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B3C1856A429BF97E7E31C2E5BD66",
120125 "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650",
126 1,
121127 },
122128 #endif
123129 {
1010
1111 /* 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
1010
1111 /* 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
1010
1111 /* 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
1010
1111 /* 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
1010
1111 /* 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
1010
1111 /* 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
1010
1111 /* 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
1010
1111 /* 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
1010
1111 /* 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
5048 {
5149 int err;
5250 ecc_point *base;
53 void *prime, *order;
51 void *prime, *order, *a;
5452 unsigned char *buf;
5553 int keysize;
5654
8179 }
8280
8381 /* setup the key variables */
84 if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, NULL)) != CRYPT_OK) {
82 if ((err = mp_init_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, &prime, &order, &a, NULL)) != CRYPT_OK) {
8583 goto ERR_BUF;
8684 }
8785 base = ltc_ecc_new_point();
103101 if((err = mp_mod(key->k, order, key->k)) != CRYPT_OK) { goto errkey; }
104102 }
105103 /* make the public key */
106 if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, prime, 1)) != CRYPT_OK) { goto errkey; }
104 if ((err = mp_read_radix(a, (char *)key->dp->A, 16)) != CRYPT_OK) { goto errkey; }
105 if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, a, prime, 1)) != CRYPT_OK) { goto errkey; }
107106 key->type = PK_PRIVATE;
108107
109108 /* free up ram */
113112 mp_clear_multi(key->pubkey.x, key->pubkey.y, key->pubkey.z, key->k, NULL);
114113 cleanup:
115114 ltc_ecc_del_point(base);
116 mp_clear_multi(prime, order, NULL);
115 mp_clear_multi(prime, order, a, NULL);
117116 ERR_BUF:
118117 #ifdef LTC_CLEAN_STACK
119118 zeromem(buf, ECC_MAXSIZE);
1010
1111 /* 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 }
1010
1111 /* 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 int 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, (int)inlen)) != CRYPT_OK) { goto errnokey; }
74 }
75 else if (pbits % 8 == 0) {
76 if ((err = mp_read_unsigned_bin(e, (unsigned char *)in, pbytes)) != CRYPT_OK) { goto errnokey; }
77 }
78 else {
79 shift_right = 8 - pbits % 8;
80 for (i=0, ch=0; i<pbytes; i++) {
81 buf[i] = ch;
82 ch = (in[i] << (8-shift_right));
83 buf[i] = buf[i] ^ (in[i] >> shift_right);
84 }
85 if ((err = mp_read_unsigned_bin(e, (unsigned char *)buf, pbytes)) != CRYPT_OK) { goto errnokey; }
86 }
7087
7188 /* make up a key and export the public copy */
7289 for (;;) {
1010
1111 /* 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
1010
1111 /* 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
1816 /**
1917 @file ecc_verify_hash.c
2018 ECC Crypto, Tom St Denis
21 */
19 */
2220
2321 #ifdef LTC_MECC
2422
25 /* verify
23 /* verify
2624 *
2725 * w = s^-1 mod n
28 * u1 = xw
26 * u1 = xw
2927 * u2 = rw
3028 * X = u1*G + u2*Q
3129 * v = X_x1 mod n
4341 @return CRYPT_OK if successful (even if the signature is not valid)
4442 */
4543 int ecc_verify_hash(const unsigned char *sig, unsigned long siglen,
46 const unsigned char *hash, unsigned long hashlen,
44 const unsigned char *hash, unsigned long hashlen,
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 int 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, (int)hashlen)) != CRYPT_OK) { goto error; }
109 }
110 else if (pbits % 8 == 0) {
111 if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, pbytes)) != CRYPT_OK) { goto error; }
112 }
113 else {
114 shift_right = 8 - pbits % 8;
115 for (i=0, ch=0; i<pbytes; i++) {
116 buf[i] = ch;
117 ch = (hash[i] << (8-shift_right));
118 buf[i] = buf[i] ^ (hash[i] >> shift_right);
119 }
120 if ((err = mp_read_unsigned_bin(e, (unsigned char *)buf, pbytes)) != CRYPT_OK) { goto error; }
121 }
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;
1010
1111 /* 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
1010
1111 /* 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
1010
1111 /* 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
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 }
1010
1111 /* 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 @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 }
1010
1111 /* 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;
118117
119118 if (mode == 0 && i == 0) {
120119 /* dummy operations */
121 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
122 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
120 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; }
121 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; }
123122 continue;
124123 }
125124
126125 if (mode == 0 && i == 1) {
127126 mode = 1;
128127 /* dummy operations */
129 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
130 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], modulus, mp)) != CRYPT_OK) { goto done; }
128 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; }
129 if ((err = ltc_mp.ecc_ptdbl(M[1], M[2], a, modulus, mp)) != CRYPT_OK) { goto done; }
131130 continue;
132131 }
133132
134 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], modulus, mp)) != CRYPT_OK) { goto done; }
135 if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], modulus, mp)) != CRYPT_OK) { goto done; }
133 if ((err = ltc_mp.ecc_ptadd(M[0], M[1], M[i^1], a, modulus, mp)) != CRYPT_OK) { goto done; }
134 if ((err = ltc_mp.ecc_ptdbl(M[i], M[i], a, modulus, mp)) != CRYPT_OK) { goto done; }
136135 }
137136
138137 /* copy result out */
1010
1111 /* 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
1010
1111 /* 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 */
14
1615 #include "tomcrypt.h"
1716
1817 /**
3130 @param mp The "b" value from montgomery_setup()
3231 @return CRYPT_OK on success
3332 */
34 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp)
33 int ltc_ecc_projective_add_point(ecc_point *P, ecc_point *Q, ecc_point *R, void *a, void *modulus, void *mp)
3534 {
3635 void *t1, *t2, *x, *y, *z;
3736 int err;
5352 (Q->z != NULL && mp_cmp(P->z, Q->z) == LTC_MP_EQ) &&
5453 (mp_cmp(P->y, Q->y) == LTC_MP_EQ || mp_cmp(P->y, t1) == LTC_MP_EQ)) {
5554 mp_clear_multi(t1, t2, x, y, z, NULL);
56 return ltc_ecc_projective_dbl_point(P, R, modulus, mp);
55 return ltc_ecc_projective_dbl_point(P, R, a, modulus, mp);
5756 }
5857
5958 if ((err = mp_copy(P->x, x)) != CRYPT_OK) { goto done; }
1010
1111 /* 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 */
14
1615 #include "tomcrypt.h"
16
17 /* ### Point doubling in Jacobian coordinate system ###
18 *
19 * let us have a curve: y^2 = x^3 + a*x + b
20 * in Jacobian coordinates it becomes: y^2 = x^3 + a*x*z^4 + b*z^6
21 *
22 * The doubling of P = (Xp, Yp, Zp) is given by R = (Xr, Yr, Zr) where:
23 * Xr = M^2 - 2*S
24 * Yr = M * (S - Xr) - 8*T
25 * Zr = 2 * Yp * Zp
26 *
27 * M = 3 * Xp^2 + a*Zp^4
28 * T = Yp^4
29 * S = 4 * Xp * Yp^2
30 *
31 * SPECIAL CASE - when a == -3 we can compute M as:
32 * M = 3 * (Xp^2 - Zp^4) = 3 * (Xp + Zp^2) * (Xp - Zp^2)
33 */
1734
1835 /**
1936 @file ltc_ecc_projective_dbl_point.c
2037 ECC Crypto, Tom St Denis
21 */
38 */
2239
2340 #if defined(LTC_MECC) && (!defined(LTC_MECC_ACCEL) || defined(LTM_LTC_DESC))
2441
2643 Double an ECC point
2744 @param P The point to double
2845 @param R [out] The destination of the double
46 @param a ECC curve parameter a (if NULL we assume a == -3)
2947 @param modulus The modulus of the field the ECC curve is in
3048 @param mp The "b" value from montgomery_setup()
3149 @return CRYPT_OK on success
3250 */
33 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *modulus, void *mp)
51 int ltc_ecc_projective_dbl_point(ecc_point *P, ecc_point *R, void *a, void *modulus, void *mp)
3452 {
3553 void *t1, *t2;
3654 int err;
6179 if (mp_cmp(R->z, modulus) != LTC_MP_LT) {
6280 if ((err = mp_sub(R->z, modulus, R->z)) != CRYPT_OK) { goto done; }
6381 }
64
65 /* T2 = X - T1 */
66 if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; }
67 if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
68 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
82
83 if (a == NULL) { /* special case for a == -3 (slightly faster than general case) */
84 /* T2 = X - T1 */
85 if ((err = mp_sub(R->x, t1, t2)) != CRYPT_OK) { goto done; }
86 if (mp_cmp_d(t2, 0) == LTC_MP_LT) {
87 if ((err = mp_add(t2, modulus, t2)) != CRYPT_OK) { goto done; }
88 }
89 /* T1 = X + T1 */
90 if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; }
91 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
92 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
93 }
94 /* T2 = T1 * T2 */
95 if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; }
96 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
97 /* T1 = 2T2 */
98 if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; }
99 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
100 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
101 }
102 /* T1 = T1 + T2 */
103 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
104 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
105 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
106 }
69107 }
70 /* T1 = X + T1 */
71 if ((err = mp_add(t1, R->x, t1)) != CRYPT_OK) { goto done; }
72 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
73 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
74 }
75 /* T2 = T1 * T2 */
76 if ((err = mp_mul(t1, t2, t2)) != CRYPT_OK) { goto done; }
77 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
78 /* T1 = 2T2 */
79 if ((err = mp_add(t2, t2, t1)) != CRYPT_OK) { goto done; }
80 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
81 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
82 }
83 /* T1 = T1 + T2 */
84 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
85 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
86 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
108 else {
109 /* T2 = T1 * T1 */
110 if ((err = mp_sqr(t1, t2)) != CRYPT_OK) { goto done; }
111 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
112 /* T1 = T2 * a */
113 if ((err = mp_mulmod(t2, a, modulus, t1)) != CRYPT_OK) { goto done; }
114 /* T2 = X * X */
115 if ((err = mp_sqr(R->x, t2)) != CRYPT_OK) { goto done; }
116 if ((err = mp_montgomery_reduce(t2, modulus, mp)) != CRYPT_OK) { goto done; }
117 /* T1 = T2 + T1 */
118 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
119 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
120 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
121 }
122 /* T1 = T2 + T1 */
123 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
124 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
125 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
126 }
127 /* T1 = T2 + T1 */
128 if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto done; }
129 if (mp_cmp(t1, modulus) != LTC_MP_LT) {
130 if ((err = mp_sub(t1, modulus, t1)) != CRYPT_OK) { goto done; }
131 }
87132 }
88133
89134 /* Y = 2Y */
120165 if ((err = mp_add(R->x, modulus, R->x)) != CRYPT_OK) { goto done; }
121166 }
122167
123 /* Y = Y - X */
168 /* Y = Y - X */
124169 if ((err = mp_sub(R->y, R->x, R->y)) != CRYPT_OK) { goto done; }
125170 if (mp_cmp_d(R->y, 0) == LTC_MP_LT) {
126171 if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
133178 if (mp_cmp_d(R->y, 0) == LTC_MP_LT) {
134179 if ((err = mp_add(R->y, modulus, R->y)) != CRYPT_OK) { goto done; }
135180 }
136
181
137182 err = CRYPT_OK;
138183 done:
139184 mp_clear_multi(t1, t2, NULL);
392392
393393 /* special sqrt algo */
394394 int mp_sqrt(mp_int *arg, mp_int *ret);
395
396 /* special sqrt (mod prime) */
397 int mp_sqrtmod_prime(mp_int *arg, mp_int *prime, mp_int *ret);
395398
396399 /* is number a square? */
397400 int mp_is_square(mp_int *arg, int *ret);
103103 #define BN_MP_SQR_C
104104 #define BN_MP_SQRMOD_C
105105 #define BN_MP_SQRT_C
106 #define BN_MP_SQRTMOD_PRIME_C
106107 #define BN_MP_SUB_C
107108 #define BN_MP_SUB_D_C
108109 #define BN_MP_SUBMOD_C
822823 #define BN_MP_CLEAR_C
823824 #endif
824825
826 #if defined(BN_MP_SQRTMOD_PRIME_C)
827 #define BN_MP_JACOBI_C
828 #define BN_MP_ZERO_C
829 #define BN_MP_SET_INT_C
830 #define BN_MP_COPY_C
831 #define BN_MP_SUB_C
832 #define BN_MP_SUB_D_C
833 #define BN_MP_DIV_2_C
834 #define BN_MP_ADD_D_C
835 #define BN_MP_EXPTMOD_C
836 #endif
837
825838 #if defined(BN_MP_SUB_C)
826839 #define BN_S_MP_ADD_C
827840 #define BN_MP_CMP_MAG_C