ltc update
Karel Miko
6 years ago
261 | 261 | int err; |
262 | 262 | unsigned i; |
263 | 263 | void *tmp; |
264 | const ltc_ecc_set_type *set; | |
264 | const ltc_ecc_curve *cu; | |
265 | 265 | |
266 | 266 | key->dp.oidlen = 0; |
267 | 267 | if ((err = ltc_mp.init(&tmp)) != CRYPT_OK) return; |
268 | for (set = ltc_ecc_sets; set->name != NULL; set++) { | |
269 | if ((err = mp_read_radix(tmp, set->prime, 16)) != CRYPT_OK) continue; | |
268 | for (cu = ltc_ecc_curves; cu->prime != NULL; cu++) { | |
269 | if ((err = mp_read_radix(tmp, cu->prime, 16)) != CRYPT_OK) continue; | |
270 | 270 | if ((mp_cmp(tmp, key->dp.prime) != LTC_MP_EQ)) continue; |
271 | if ((err = mp_read_radix(tmp, set->order, 16)) != CRYPT_OK) continue; | |
271 | if ((err = mp_read_radix(tmp, cu->order, 16)) != CRYPT_OK) continue; | |
272 | 272 | if ((mp_cmp(tmp, key->dp.order) != LTC_MP_EQ)) continue; |
273 | if ((err = mp_read_radix(tmp, set->A, 16)) != CRYPT_OK) continue; | |
273 | if ((err = mp_read_radix(tmp, cu->A, 16)) != CRYPT_OK) continue; | |
274 | 274 | if ((mp_cmp(tmp, key->dp.A) != LTC_MP_EQ)) continue; |
275 | if ((err = mp_read_radix(tmp, set->B, 16)) != CRYPT_OK) continue; | |
275 | if ((err = mp_read_radix(tmp, cu->B, 16)) != CRYPT_OK) continue; | |
276 | 276 | if ((mp_cmp(tmp, key->dp.B) != LTC_MP_EQ)) continue; |
277 | if ((err = mp_read_radix(tmp, set->Gx, 16)) != CRYPT_OK) continue; | |
277 | if ((err = mp_read_radix(tmp, cu->Gx, 16)) != CRYPT_OK) continue; | |
278 | 278 | if ((mp_cmp(tmp, key->dp.base.x) != LTC_MP_EQ)) continue; |
279 | if ((err = mp_read_radix(tmp, set->Gy, 16)) != CRYPT_OK) continue; | |
279 | if ((err = mp_read_radix(tmp, cu->Gy, 16)) != CRYPT_OK) continue; | |
280 | 280 | if ((mp_cmp(tmp, key->dp.base.y) != LTC_MP_EQ)) continue; |
281 | if (key->dp.cofactor != set->cofactor) continue; | |
281 | if (key->dp.cofactor != cu->cofactor) continue; | |
282 | 282 | break; /* found */ |
283 | 283 | } |
284 | 284 | ltc_mp.deinit(tmp); |
285 | if (set->name != NULL) { | |
286 | key->dp.oidlen = set->oidlen; | |
287 | for(i = 0; i < set->oidlen; i++) key->dp.oid[i] = set->oid[i]; | |
285 | if (cu->prime != NULL) { | |
286 | key->dp.oidlen = cu->oidlen; | |
287 | for(i = 0; i < cu->oidlen; i++) key->dp.oid[i] = cu->oid[i]; | |
288 | 288 | } |
289 | 289 | } |
290 | 290 | |
329 | 329 | |
330 | 330 | if (SvPOK(sv_crv)) { |
331 | 331 | /* string - curve name */ |
332 | const ltc_ecc_set_type *dp; | |
332 | const ltc_ecc_curve *cu; | |
333 | 333 | ch_name = SvPV(sv_crv, l_name); |
334 | if (ecc_get_set_by_name(ch_name, &dp) != CRYPT_OK) croak("FATAL: ecparams: unknown curve '%s'", ch_name); | |
335 | return ecc_set_dp(dp, key); | |
334 | if (ecc_get_curve_by_name(ch_name, &cu) != CRYPT_OK) croak("FATAL: ecparams: unknown curve '%s'", ch_name); | |
335 | return ecc_set_dp(cu, key); | |
336 | 336 | } |
337 | 337 | else { |
338 | 338 | /* hashref */ |
339 | ltc_ecc_set_type set = { 0 }; | |
339 | ltc_ecc_curve cu = { 0 }; | |
340 | 340 | |
341 | 341 | if ((h = (HV*)(SvRV(sv_crv))) == NULL) croak("FATAL: ecparams: param is not valid hashref"); |
342 | 342 | |
356 | 356 | if (!SvOK(*sv_Gy )) croak("FATAL: ecparams: undefined param Gy"); |
357 | 357 | if (!SvOK(*sv_cofactor)) croak("FATAL: ecparams: undefined param cofactor"); |
358 | 358 | |
359 | set.prime = SvPV_nolen(*sv_prime); | |
360 | set.A = SvPV_nolen(*sv_A); | |
361 | set.B = SvPV_nolen(*sv_B); | |
362 | set.order = SvPV_nolen(*sv_order); | |
363 | set.Gx = SvPV_nolen(*sv_Gx); | |
364 | set.Gy = SvPV_nolen(*sv_Gy); | |
365 | set.cofactor = (unsigned long)SvUV(*sv_cofactor), | |
366 | set.name = NULL; | |
367 | set.oidlen = 0; | |
359 | cu.prime = SvPV_nolen(*sv_prime); | |
360 | cu.A = SvPV_nolen(*sv_A); | |
361 | cu.B = SvPV_nolen(*sv_B); | |
362 | cu.order = SvPV_nolen(*sv_order); | |
363 | cu.Gx = SvPV_nolen(*sv_Gx); | |
364 | cu.Gy = SvPV_nolen(*sv_Gy); | |
365 | cu.cofactor = (unsigned long)SvUV(*sv_cofactor), | |
366 | cu.oidlen = 0; | |
368 | 367 | |
369 | 368 | sv_oid = hv_fetchs(h, "oid", 0); |
370 | 369 | if (sv_oid && SvPOK(*sv_oid)) { |
374 | 373 | if (++j >= 16) return CRYPT_ERROR; |
375 | 374 | } |
376 | 375 | else if(ch_name[i] >= '0' && ch_name[i] <= '9') { |
377 | set.oid[j] = set.oid[j] * 10 + (ch_name[i] - '0'); | |
376 | cu.oid[j] = cu.oid[j] * 10 + (ch_name[i] - '0'); | |
378 | 377 | } |
379 | 378 | else { |
380 | 379 | return CRYPT_ERROR; |
381 | 380 | } |
382 | 381 | } |
383 | 382 | if (j == 0) return CRYPT_ERROR; |
384 | set.oidlen = j + 1; | |
385 | } | |
386 | ||
387 | if ((err = ecc_set_dp(&set, key)) != CRYPT_OK) return err; | |
383 | cu.oidlen = j + 1; | |
384 | } | |
385 | ||
386 | if ((err = ecc_set_dp(&cu, key)) != CRYPT_OK) return err; | |
388 | 387 | if (key->dp.oidlen == 0) _ecc_oid_lookup(key); |
389 | 388 | return CRYPT_OK; |
390 | 389 | } |
532 | 531 | SvREFCNT_dec(RETVAL); |
533 | 532 | XSRETURN_UNDEF; |
534 | 533 | } |
535 | SvCUR_set(RETVAL, out_len); | |
534 | SvCUR_set(RETVAL, strlen(out_data)); | |
536 | 535 | } |
537 | 536 | } |
538 | 537 | OUTPUT: |
560 | 559 | SvPOK_only(RETVAL); |
561 | 560 | out_data = (unsigned char *)SvPVX(RETVAL); |
562 | 561 | if (ix == 1) |
563 | rv = base64url_decode(in_data, (unsigned long)in_len, out_data, &out_len); | |
562 | rv = base64url_sane_decode(in_data, (unsigned long)in_len, out_data, &out_len); | |
564 | 563 | else |
565 | rv = base64_decode(in_data, (unsigned long)in_len, out_data, &out_len); | |
564 | rv = base64_sane_decode(in_data, (unsigned long)in_len, out_data, &out_len); | |
566 | 565 | if (rv != CRYPT_OK) { |
567 | 566 | SvREFCNT_dec(RETVAL); |
568 | 567 | XSRETURN_UNDEF; |
585 | 584 | unsigned long out_len; |
586 | 585 | unsigned char *in_data; |
587 | 586 | char *out_data; |
588 | int id = -1; | |
587 | int id = -1, err; | |
589 | 588 | |
590 | 589 | if (!SvPOK(in)) XSRETURN_UNDEF; |
591 | 590 | if (ix == 0) id = BASE32_RFC4648; |
598 | 597 | RETVAL = newSVpvn("", 0); |
599 | 598 | } |
600 | 599 | else { |
601 | out_len = (unsigned long)((8 * in_len + 4) / 5); | |
600 | out_len = (unsigned long)((8 * in_len + 4) / 5 + 1); | |
602 | 601 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ |
603 | 602 | SvPOK_only(RETVAL); |
604 | 603 | out_data = SvPVX(RETVAL); |
605 | if (base32_encode(in_data, (unsigned long)in_len, out_data, &out_len, id) != CRYPT_OK) { | |
604 | err = base32_encode(in_data, (unsigned long)in_len, out_data, &out_len, id); | |
605 | if (err != CRYPT_OK) { | |
606 | 606 | SvREFCNT_dec(RETVAL); |
607 | 607 | XSRETURN_UNDEF; |
608 | 608 | } |
609 | SvCUR_set(RETVAL, out_len); | |
609 | SvCUR_set(RETVAL, strlen(out_data)); | |
610 | 610 | } |
611 | 611 | } |
612 | 612 | OUTPUT: |
624 | 624 | unsigned long out_len; |
625 | 625 | unsigned char *out_data; |
626 | 626 | char *in_data; |
627 | int id = -1; | |
627 | int id = -1, err; | |
628 | 628 | |
629 | 629 | if (!SvPOK(in)) XSRETURN_UNDEF; |
630 | 630 | if (ix == 0) id = BASE32_RFC4648; |
641 | 641 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ |
642 | 642 | SvPOK_only(RETVAL); |
643 | 643 | out_data = (unsigned char *)SvPVX(RETVAL); |
644 | if (base32_decode(in_data, (unsigned long)in_len, out_data, &out_len, id) != CRYPT_OK) { | |
644 | err = base32_decode(in_data, (unsigned long)in_len, out_data, &out_len, id); | |
645 | if (err != CRYPT_OK) { | |
645 | 646 | SvREFCNT_dec(RETVAL); |
646 | 647 | XSRETURN_UNDEF; |
647 | 648 | } |
101 | 101 | ltc/pk/dsa/dsa_set_pqg_dsaparam.o ltc/pk/dsa/dsa_shared_secret.o ltc/pk/dsa/dsa_sign_hash.o \ |
102 | 102 | ltc/pk/dsa/dsa_verify_hash.o ltc/pk/dsa/dsa_verify_key.o ltc/pk/ecc/ecc.o ltc/pk/ecc/ecc_ansi_x963_export.o \ |
103 | 103 | ltc/pk/ecc/ecc_ansi_x963_import.o ltc/pk/ecc/ecc_decrypt_key.o ltc/pk/ecc/ecc_encrypt_key.o \ |
104 | ltc/pk/ecc/ecc_export.o ltc/pk/ecc/ecc_export_openssl.o ltc/pk/ecc/ecc_free.o ltc/pk/ecc/ecc_get_key.o \ | |
105 | ltc/pk/ecc/ecc_get_set.o ltc/pk/ecc/ecc_get_size.o ltc/pk/ecc/ecc_import.o ltc/pk/ecc/ecc_import_openssl.o \ | |
104 | ltc/pk/ecc/ecc_export.o ltc/pk/ecc/ecc_export_openssl.o ltc/pk/ecc/ecc_free.o ltc/pk/ecc/ecc_get_curve_by_name.o \ | |
105 | ltc/pk/ecc/ecc_get_key.o ltc/pk/ecc/ecc_get_size.o ltc/pk/ecc/ecc_import.o ltc/pk/ecc/ecc_import_openssl.o \ | |
106 | 106 | ltc/pk/ecc/ecc_import_pkcs8.o ltc/pk/ecc/ecc_import_x509.o ltc/pk/ecc/ecc_make_key.o \ |
107 | 107 | ltc/pk/ecc/ecc_set_dp.o ltc/pk/ecc/ecc_set_dp_internal.o ltc/pk/ecc/ecc_set_key.o \ |
108 | 108 | ltc/pk/ecc/ecc_shared_secret.o ltc/pk/ecc/ecc_sign_hash.o ltc/pk/ecc/ecc_sizes.o \ |
109 | 109 | ltc/pk/dsa/dsa_verify_key.obj ltc/pk/ecc/ecc.obj ltc/pk/ecc/ecc_ansi_x963_export.obj \ |
110 | 110 | ltc/pk/ecc/ecc_ansi_x963_import.obj ltc/pk/ecc/ecc_decrypt_key.obj ltc/pk/ecc/ecc_encrypt_key.obj \ |
111 | 111 | ltc/pk/ecc/ecc_export.obj ltc/pk/ecc/ecc_export_openssl.obj ltc/pk/ecc/ecc_free.obj \ |
112 | ltc/pk/ecc/ecc_get_key.obj ltc/pk/ecc/ecc_get_set.obj ltc/pk/ecc/ecc_get_size.obj \ | |
112 | ltc/pk/ecc/ecc_get_curve_by_name.obj ltc/pk/ecc/ecc_get_key.obj ltc/pk/ecc/ecc_get_size.obj \ | |
113 | 113 | ltc/pk/ecc/ecc_import.obj ltc/pk/ecc/ecc_import_openssl.obj ltc/pk/ecc/ecc_import_pkcs8.obj \ |
114 | 114 | ltc/pk/ecc/ecc_import_x509.obj ltc/pk/ecc/ecc_make_key.obj ltc/pk/ecc/ecc_set_dp.obj \ |
115 | 115 | ltc/pk/ecc/ecc_set_dp_internal.obj ltc/pk/ecc/ecc_set_key.obj ltc/pk/ecc/ecc_shared_secret.obj \ |
9 | 9 | /* ---- LTC_BASE64 Routines ---- */ |
10 | 10 | #ifdef LTC_BASE64 |
11 | 11 | int base64_encode(const unsigned char *in, unsigned long len, |
12 | char *out, unsigned long *outlen); | |
13 | ||
14 | int base64_decode(const char *in, unsigned long len, | |
12 | 15 | unsigned char *out, unsigned long *outlen); |
13 | ||
14 | int base64_decode(const unsigned char *in, unsigned long len, | |
16 | int base64_strict_decode(const char *in, unsigned long len, | |
15 | 17 | unsigned char *out, unsigned long *outlen); |
16 | int base64_strict_decode(const unsigned char *in, unsigned long len, | |
18 | int base64_sane_decode(const char *in, unsigned long inlen, | |
17 | 19 | unsigned char *out, unsigned long *outlen); |
18 | 20 | #endif |
19 | 21 | |
20 | 22 | #ifdef LTC_BASE64_URL |
21 | 23 | int base64url_encode(const unsigned char *in, unsigned long len, |
24 | char *out, unsigned long *outlen); | |
25 | int base64url_strict_encode(const unsigned char *in, unsigned long inlen, | |
26 | char *out, unsigned long *outlen); | |
27 | ||
28 | int base64url_decode(const char *in, unsigned long len, | |
22 | 29 | unsigned char *out, unsigned long *outlen); |
23 | int base64url_strict_encode(const unsigned char *in, unsigned long inlen, | |
30 | int base64url_strict_decode(const char *in, unsigned long len, | |
24 | 31 | unsigned char *out, unsigned long *outlen); |
25 | ||
26 | int base64url_decode(const unsigned char *in, unsigned long len, | |
27 | unsigned char *out, unsigned long *outlen); | |
28 | int base64url_strict_decode(const unsigned char *in, unsigned long len, | |
32 | int base64url_sane_decode(const char *in, unsigned long inlen, | |
29 | 33 | unsigned char *out, unsigned long *outlen); |
30 | 34 | #endif |
31 | 35 | |
50 | 54 | int base16_encode(const unsigned char *in, unsigned long inlen, |
51 | 55 | char *out, unsigned long *outlen, |
52 | 56 | int caps); |
53 | int base16_decode(const char *in, | |
57 | int base16_decode(const char *in, unsigned long inlen, | |
54 | 58 | unsigned char *out, unsigned long *outlen); |
55 | 59 | #endif |
56 | 60 |
258 | 258 | /** Structure defines a GF(p) curve */ |
259 | 259 | typedef struct { |
260 | 260 | /** name of curve */ |
261 | const char *name; | |
261 | const char *names[6]; | |
262 | 262 | |
263 | 263 | /** The prime that defines the field the curve is in (encoded in hex) */ |
264 | 264 | const char *prime; |
284 | 284 | /** The OID */ |
285 | 285 | unsigned long oid[16]; |
286 | 286 | unsigned long oidlen; |
287 | } ltc_ecc_set_type; | |
287 | } ltc_ecc_curve; | |
288 | 288 | |
289 | 289 | /** 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 */ |
290 | 290 | typedef struct { |
335 | 335 | } ecc_key; |
336 | 336 | |
337 | 337 | /** the ECC params provided */ |
338 | extern const ltc_ecc_set_type ltc_ecc_sets[]; | |
338 | extern const ltc_ecc_curve ltc_ecc_curves[]; | |
339 | 339 | |
340 | 340 | int ecc_test(void); |
341 | 341 | void ecc_sizes(int *low, int *high); |
342 | 342 | int ecc_get_size(ecc_key *key); |
343 | 343 | |
344 | int ecc_get_set_by_name(const char* name, const ltc_ecc_set_type** dp); | |
345 | int ecc_set_dp(const ltc_ecc_set_type *set, ecc_key *key); | |
344 | int ecc_get_curve_by_name(const char* name, const ltc_ecc_curve** cu); | |
345 | int ecc_set_dp(const ltc_ecc_curve *cu, ecc_key *key); | |
346 | 346 | int ecc_generate_key(prng_state *prng, int wprng, ecc_key *key); |
347 | 347 | int ecc_set_key(const unsigned char *in, unsigned long inlen, int type, ecc_key *key); |
348 | 348 | int ecc_get_key(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); |
349 | 349 | |
350 | 350 | int ecc_make_key(prng_state *prng, int wprng, int keysize, ecc_key *key); |
351 | int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp); | |
351 | int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_curve *cu); | |
352 | 352 | void ecc_free(ecc_key *key); |
353 | 353 | |
354 | 354 | int ecc_export(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); |
355 | 355 | int ecc_import(const unsigned char *in, unsigned long inlen, ecc_key *key); |
356 | int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); | |
356 | int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_curve *cu); | |
357 | 357 | |
358 | 358 | int ecc_ansi_x963_export(ecc_key *key, unsigned char *out, unsigned long *outlen); |
359 | 359 | int ecc_ansi_x963_import(const unsigned char *in, unsigned long inlen, ecc_key *key); |
360 | int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp); | |
360 | int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_curve *cu); | |
361 | 361 | |
362 | 362 | int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, ecc_key *key); |
363 | 363 | int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *key); |
396 | 396 | #ifdef LTC_SOURCE |
397 | 397 | /* INTERNAL ONLY - it should be later moved to src/headers/tomcrypt_internal.h */ |
398 | 398 | |
399 | int ecc_set_dp_bn(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key); | |
400 | int ecc_set_dp_oid(unsigned long *oid, unsigned long oidsize, ecc_key *key); | |
401 | int ecc_set_dp_copy(ecc_key *srckey, ecc_key *key); | |
402 | int ecc_set_dp_size(int size, ecc_key *key); | |
399 | int ecc_set_dp_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key); | |
400 | int ecc_set_dp_by_oid(unsigned long *oid, unsigned long oidsize, ecc_key *key); | |
401 | int ecc_copy_dp(const ecc_key *srckey, ecc_key *key); | |
402 | int ecc_set_dp_by_size(int size, ecc_key *key); | |
403 | 403 | |
404 | 404 | /* low level functions */ |
405 | 405 | ecc_point *ltc_ecc_new_point(void); |
406 | 406 | void ltc_ecc_del_point(ecc_point *p); |
407 | int ltc_ecc_set_point_xyz(ltc_mp_digit x, ltc_mp_digit y, ltc_mp_digit z, ecc_point *p); | |
408 | int ltc_ecc_copy_point(const ecc_point *src, ecc_point *dst); | |
407 | 409 | int ltc_ecc_is_point(const ltc_ecc_dp *dp, void *x, void *y); |
408 | int ltc_ecc_is_point_at_infinity(const ecc_point *p, void *modulus); | |
410 | int ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus, int *retval); | |
409 | 411 | int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *prime, void *a, void *b, void *x, void *y); |
410 | 412 | int ltc_ecc_export_point(unsigned char *out, unsigned long *outlen, void *x, void *y, unsigned long size, int compressed); |
411 | 413 | int ltc_ecc_verify_key(ecc_key *key); |
264 | 264 | return CRYPT_OK; |
265 | 265 | } |
266 | 266 | |
267 | /* sqrtmod_prime */ | |
268 | static int sqrtmod_prime(void *a, void *b, void *c) | |
269 | { | |
270 | LTC_ARGCHK(a != NULL); | |
271 | LTC_ARGCHK(b != NULL); | |
272 | LTC_ARGCHK(c != NULL); | |
273 | fprintf(stderr, "TFM does not support sqrtmod_prime\n"); /* XXX-FIXME */ | |
274 | return CRYPT_ERROR; | |
275 | } | |
267 | /* sqrtmod_prime - NOT SUPPORTED */ | |
276 | 268 | |
277 | 269 | /* div */ |
278 | 270 | static int divide(void *a, void *b, void *c, void *d) |
437 | 429 | { |
438 | 430 | fp_int t1, t2; |
439 | 431 | fp_digit mp; |
432 | int err, inf; | |
440 | 433 | |
441 | 434 | LTC_ARGCHK(P != NULL); |
442 | 435 | LTC_ARGCHK(R != NULL); |
454 | 447 | fp_copy(P->z, R->z); |
455 | 448 | } |
456 | 449 | |
457 | if (ltc_ecc_is_point_at_infinity(P, modulus)) { | |
450 | if ((err = ltc_ecc_is_point_at_infinity(P, modulus, &inf)) != CRYPT_OK) return err; | |
451 | if (inf) { | |
458 | 452 | /* if P is point at infinity >> Result = point at infinity */ |
459 | 453 | ltc_mp.set_int(R->x, 1); |
460 | 454 | ltc_mp.set_int(R->y, 1); |
590 | 584 | { |
591 | 585 | fp_int t1, t2, x, y, z; |
592 | 586 | fp_digit mp; |
587 | int err, inf; | |
593 | 588 | |
594 | 589 | LTC_ARGCHK(P != NULL); |
595 | 590 | LTC_ARGCHK(Q != NULL); |
605 | 600 | fp_init(&y); |
606 | 601 | fp_init(&z); |
607 | 602 | |
608 | if (ltc_ecc_is_point_at_infinity(P, modulus)) { | |
603 | if ((err = ltc_ecc_is_point_at_infinity(P, modulus, &inf)) != CRYPT_OK) return err; | |
604 | if (inf) { | |
609 | 605 | /* P is point at infinity >> Result = Q */ |
610 | 606 | ltc_mp.copy(Q->x, R->x); |
611 | 607 | ltc_mp.copy(Q->y, R->y); |
613 | 609 | return CRYPT_OK; |
614 | 610 | } |
615 | 611 | |
616 | if (ltc_ecc_is_point_at_infinity(Q, modulus)) { | |
612 | if ((err = ltc_ecc_is_point_at_infinity(Q, modulus, &inf)) != CRYPT_OK) return err; | |
613 | if (inf) { | |
617 | 614 | /* Q is point at infinity >> Result = P */ |
618 | 615 | ltc_mp.copy(P->x, R->x); |
619 | 616 | ltc_mp.copy(P->y, R->y); |
802 | 799 | &mul, |
803 | 800 | &muli, |
804 | 801 | &sqr, |
805 | &sqrtmod_prime, | |
802 | NULL, /* TODO: &sqrtmod_prime */ | |
806 | 803 | ÷, |
807 | 804 | &div_2, |
808 | 805 | &modi, |
24 | 24 | @param outlen [in/out] The max size and resulting size of the decoded data |
25 | 25 | @return CRYPT_OK if successful |
26 | 26 | */ |
27 | int base16_decode(const char *in, | |
27 | int base16_decode(const char *in, unsigned long inlen, | |
28 | 28 | unsigned char *out, unsigned long *outlen) |
29 | 29 | { |
30 | unsigned long pos, in_len, out_len; | |
31 | unsigned char idx0; | |
32 | unsigned char idx1; | |
30 | unsigned long pos, out_len; | |
31 | unsigned char idx0, idx1; | |
32 | char in0, in1; | |
33 | 33 | |
34 | 34 | const unsigned char hashmap[] = { |
35 | 35 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */ |
36 | 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89:;<=>? */ | |
37 | 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* @ABCDEFG */ | |
38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* HIJKLMNO */ | |
39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* PQRSTUVW */ | |
40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* XYZ[\]^_ */ | |
41 | 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* `abcdefg */ | |
36 | 0x08, 0x09, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* 89:;<=>? */ | |
37 | 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, /* @ABCDEFG */ | |
38 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* HIJKLMNO */ | |
39 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* PQRSTUVW */ | |
40 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* XYZ[\]^_ */ | |
41 | 0xff, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0xff, /* `abcdefg */ | |
42 | 42 | }; |
43 | 43 | |
44 | 44 | LTC_ARGCHK(in != NULL); |
45 | 45 | LTC_ARGCHK(out != NULL); |
46 | 46 | LTC_ARGCHK(outlen != NULL); |
47 | 47 | |
48 | in_len = strlen(in); | |
49 | if ((in_len % 2) == 1) return CRYPT_INVALID_PACKET; | |
48 | if ((inlen % 2) == 1) return CRYPT_INVALID_PACKET; | |
50 | 49 | out_len = *outlen * 2; |
51 | for (pos = 0; ((pos + 1 < out_len) && (pos + 1 < in_len)); pos += 2) { | |
52 | idx0 = (unsigned char) (in[pos + 0] & 0x1F) ^ 0x10; | |
53 | idx1 = (unsigned char) (in[pos + 1] & 0x1F) ^ 0x10; | |
50 | for (pos = 0; ((pos + 1 < out_len) && (pos + 1 < inlen)); pos += 2) { | |
51 | in0 = in[pos + 0]; | |
52 | in1 = in[pos + 1]; | |
53 | ||
54 | if ((in0 < '0') || (in0 > 'g')) return CRYPT_INVALID_PACKET; | |
55 | if ((in1 < '0') || (in1 > 'g')) return CRYPT_INVALID_PACKET; | |
56 | ||
57 | idx0 = (unsigned char) (in0 & 0x1F) ^ 0x10; | |
58 | idx1 = (unsigned char) (in1 & 0x1F) ^ 0x10; | |
59 | ||
60 | if (hashmap[idx0] == 0xff) return CRYPT_INVALID_PACKET; | |
61 | if (hashmap[idx1] == 0xff) return CRYPT_INVALID_PACKET; | |
62 | ||
54 | 63 | out[pos / 2] = (unsigned char) (hashmap[idx0] << 4) | hashmap[idx1]; |
55 | 64 | } |
56 | 65 | *outlen = pos / 2; |
38 | 38 | LTC_ARGCHK(id >= BASE32_RFC4648); |
39 | 39 | LTC_ARGCHK(id <= BASE32_CROCKFORD); |
40 | 40 | |
41 | /* no input, nothing to do */ | |
42 | if (inlen == 0) { | |
43 | *outlen = 0; | |
44 | return CRYPT_OK; | |
45 | } | |
46 | ||
47 | /* check the size of output buffer */ | |
48 | x = (8 * inlen + 4) / 5; | |
41 | /* check the size of output buffer +1 byte for terminating NUL */ | |
42 | x = (8 * inlen + 4) / 5 + 1; | |
49 | 43 | if (*outlen < x) { |
50 | 44 | *outlen = x; |
51 | 45 | return CRYPT_BUFFER_OVERFLOW; |
52 | 46 | } |
53 | 47 | *outlen = x; |
48 | ||
49 | /* no input, nothing to do */ | |
50 | if (inlen == 0) { | |
51 | *out = '\0'; | |
52 | return CRYPT_OK; | |
53 | } | |
54 | 54 | |
55 | 55 | codes = alphabet[id]; |
56 | 56 | x = 5 * (inlen / 5); |
78 | 78 | } |
79 | 79 | if (i+2 < inlen) { |
80 | 80 | *out++ = codes[(((c & 0xF) << 1) + (d >> 7)) & 0x1F]; |
81 | *out++ = codes[(d >> 2) & 0x1F]; | |
82 | 81 | } |
83 | 82 | if (i+3 < inlen) { |
83 | *out++ = codes[(d >> 2) & 0x1F]; | |
84 | 84 | *out++ = codes[((d & 0x3) << 3) & 0x1F]; |
85 | 85 | } |
86 | 86 | } |
87 | *out = '\0'; | |
87 | 88 | return CRYPT_OK; |
88 | 89 | } |
89 | 90 |
16 | 16 | |
17 | 17 | #if defined(LTC_BASE64) || defined (LTC_BASE64_URL) |
18 | 18 | |
19 | /* 253 - ignored in "relaxed" mode: TAB(9), CR(13), LF(10), space(32) | |
19 | /* 253 - ignored in "relaxed" + "insane" mode: TAB(9), CR(13), LF(10), space(32) | |
20 | 20 | * 254 - padding character '=' (allowed only at the end) |
21 | * 255 - invalid character (not allowed even in relaxed mode) | |
21 | * 255 - ignored in "insane" mode, but not allowed in "relaxed" + "strict" mode | |
22 | 22 | */ |
23 | 23 | |
24 | 24 | #if defined(LTC_BASE64) |
75 | 75 | }; |
76 | 76 | |
77 | 77 | enum { |
78 | relaxed = 0, | |
79 | strict = 1 | |
78 | insane = 0, | |
79 | strict = 1, | |
80 | relaxed = 2 | |
80 | 81 | }; |
81 | 82 | |
82 | static int _base64_decode_internal(const unsigned char *in, unsigned long inlen, | |
83 | static int _base64_decode_internal(const char *in, unsigned long inlen, | |
83 | 84 | unsigned char *out, unsigned long *outlen, |
84 | const unsigned char *map, int is_strict) | |
85 | const unsigned char *map, int mode) | |
85 | 86 | { |
86 | 87 | unsigned long t, x, y, z; |
87 | 88 | unsigned char c; |
93 | 94 | |
94 | 95 | g = 0; /* '=' counter */ |
95 | 96 | for (x = y = z = t = 0; x < inlen; x++) { |
96 | if (in[x] == 0 && x == (inlen - 1)) continue; /* allow the last byte to be NUL */ | |
97 | c = map[in[x]&0xFF]; | |
97 | if ((in[x] == 0) && (x == (inlen - 1)) && (mode != strict)) { | |
98 | continue; /* allow the last byte to be NUL (relaxed+insane) */ | |
99 | } | |
100 | c = map[(unsigned char)in[x]&0xFF]; | |
98 | 101 | if (c == 254) { |
99 | 102 | g++; |
100 | 103 | continue; |
101 | 104 | } |
102 | 105 | if (c == 253) { |
103 | if (is_strict) | |
106 | if (mode == strict) | |
104 | 107 | return CRYPT_INVALID_PACKET; |
105 | 108 | else |
106 | continue; | |
109 | continue; /* allow to ignore white-spaces (relaxed+insane) */ | |
107 | 110 | } |
108 | 111 | if (c == 255) { |
109 | return CRYPT_INVALID_PACKET; | |
110 | } | |
111 | if (g > 0) { | |
112 | /* we only allow '=' to be at the end */ | |
112 | if (mode == insane) | |
113 | continue; /* allow to ignore invalid garbage (insane) */ | |
114 | else | |
115 | return CRYPT_INVALID_PACKET; | |
116 | } | |
117 | if ((g > 0) && (mode != insane)) { | |
118 | /* we only allow '=' to be at the end (strict+relaxed) */ | |
113 | 119 | return CRYPT_INVALID_PACKET; |
114 | 120 | } |
115 | 121 | |
126 | 132 | |
127 | 133 | if (y != 0) { |
128 | 134 | if (y == 1) return CRYPT_INVALID_PACKET; |
129 | if ((y + g) != 4 && is_strict && map != map_base64url) return CRYPT_INVALID_PACKET; | |
135 | if (((y + g) != 4) && (mode == strict) && (map != map_base64url)) return CRYPT_INVALID_PACKET; | |
130 | 136 | t = t << (6 * (4 - y)); |
131 | 137 | if (z + y - 1 > *outlen) return CRYPT_BUFFER_OVERFLOW; |
132 | 138 | if (y >= 2) out[z++] = (unsigned char) ((t >> 16) & 255); |
138 | 144 | |
139 | 145 | #if defined(LTC_BASE64) |
140 | 146 | /** |
141 | Relaxed base64 decode a block of memory | |
142 | @param in The base64 data to decode | |
143 | @param inlen The length of the base64 data | |
144 | @param out [out] The destination of the binary decoded data | |
145 | @param outlen [in/out] The max size and resulting size of the decoded data | |
146 | @return CRYPT_OK if successful | |
147 | */ | |
148 | int base64_decode(const unsigned char *in, unsigned long inlen, | |
147 | Dangerously relaxed base64 decode a block of memory | |
148 | @param in The base64 data to decode | |
149 | @param inlen The length of the base64 data | |
150 | @param out [out] The destination of the binary decoded data | |
151 | @param outlen [in/out] The max size and resulting size of the decoded data | |
152 | @return CRYPT_OK if successful | |
153 | */ | |
154 | int base64_decode(const char *in, unsigned long inlen, | |
149 | 155 | unsigned char *out, unsigned long *outlen) |
150 | 156 | { |
151 | return _base64_decode_internal(in, inlen, out, outlen, map_base64, relaxed); | |
157 | return _base64_decode_internal(in, inlen, out, outlen, map_base64, insane); | |
152 | 158 | } |
153 | 159 | |
154 | 160 | /** |
159 | 165 | @param outlen [in/out] The max size and resulting size of the decoded data |
160 | 166 | @return CRYPT_OK if successful |
161 | 167 | */ |
162 | int base64_strict_decode(const unsigned char *in, unsigned long inlen, | |
168 | int base64_strict_decode(const char *in, unsigned long inlen, | |
163 | 169 | unsigned char *out, unsigned long *outlen) |
164 | 170 | { |
165 | 171 | return _base64_decode_internal(in, inlen, out, outlen, map_base64, strict); |
166 | 172 | } |
173 | ||
174 | /** | |
175 | Sane base64 decode a block of memory | |
176 | @param in The base64 data to decode | |
177 | @param inlen The length of the base64 data | |
178 | @param out [out] The destination of the binary decoded data | |
179 | @param outlen [in/out] The max size and resulting size of the decoded data | |
180 | @return CRYPT_OK if successful | |
181 | */ | |
182 | int base64_sane_decode(const char *in, unsigned long inlen, | |
183 | unsigned char *out, unsigned long *outlen) | |
184 | { | |
185 | return _base64_decode_internal(in, inlen, out, outlen, map_base64, relaxed); | |
186 | } | |
167 | 187 | #endif /* LTC_BASE64 */ |
168 | 188 | |
169 | 189 | #if defined(LTC_BASE64_URL) |
170 | 190 | /** |
171 | Relaxed base64 (URL Safe, RFC 4648 section 5) decode a block of memory | |
172 | @param in The base64 data to decode | |
173 | @param inlen The length of the base64 data | |
174 | @param out [out] The destination of the binary decoded data | |
175 | @param outlen [in/out] The max size and resulting size of the decoded data | |
176 | @return CRYPT_OK if successful | |
177 | */ | |
178 | int base64url_decode(const unsigned char *in, unsigned long inlen, | |
191 | Dangerously relaxed base64 (URL Safe, RFC 4648 section 5) decode a block of memory | |
192 | @param in The base64 data to decode | |
193 | @param inlen The length of the base64 data | |
194 | @param out [out] The destination of the binary decoded data | |
195 | @param outlen [in/out] The max size and resulting size of the decoded data | |
196 | @return CRYPT_OK if successful | |
197 | */ | |
198 | int base64url_decode(const char *in, unsigned long inlen, | |
179 | 199 | unsigned char *out, unsigned long *outlen) |
180 | 200 | { |
201 | return _base64_decode_internal(in, inlen, out, outlen, map_base64url, insane); | |
202 | } | |
203 | ||
204 | /** | |
205 | Strict base64 (URL Safe, RFC 4648 section 5) decode a block of memory | |
206 | @param in The base64 data to decode | |
207 | @param inlen The length of the base64 data | |
208 | @param out [out] The destination of the binary decoded data | |
209 | @param outlen [in/out] The max size and resulting size of the decoded data | |
210 | @return CRYPT_OK if successful | |
211 | */ | |
212 | int base64url_strict_decode(const char *in, unsigned long inlen, | |
213 | unsigned char *out, unsigned long *outlen) | |
214 | { | |
215 | return _base64_decode_internal(in, inlen, out, outlen, map_base64url, strict); | |
216 | } | |
217 | ||
218 | /** | |
219 | Sane base64 (URL Safe, RFC 4648 section 5) decode a block of memory | |
220 | @param in The base64 data to decode | |
221 | @param inlen The length of the base64 data | |
222 | @param out [out] The destination of the binary decoded data | |
223 | @param outlen [in/out] The max size and resulting size of the decoded data | |
224 | @return CRYPT_OK if successful | |
225 | */ | |
226 | int base64url_sane_decode(const char *in, unsigned long inlen, | |
227 | unsigned char *out, unsigned long *outlen) | |
228 | { | |
181 | 229 | return _base64_decode_internal(in, inlen, out, outlen, map_base64url, relaxed); |
182 | } | |
183 | ||
184 | /** | |
185 | Strict base64 (URL Safe, RFC 4648 section 5) decode a block of memory | |
186 | @param in The base64 data to decode | |
187 | @param inlen The length of the base64 data | |
188 | @param out [out] The destination of the binary decoded data | |
189 | @param outlen [in/out] The max size and resulting size of the decoded data | |
190 | @return CRYPT_OK if successful | |
191 | */ | |
192 | int base64url_strict_decode(const unsigned char *in, unsigned long inlen, | |
193 | unsigned char *out, unsigned long *outlen) | |
194 | { | |
195 | return _base64_decode_internal(in, inlen, out, outlen, map_base64url, strict); | |
196 | 230 | } |
197 | 231 | #endif /* LTC_BASE64_URL */ |
198 | 232 |
27 | 27 | #endif /* LTC_BASE64_URL */ |
28 | 28 | |
29 | 29 | static int _base64_encode_internal(const unsigned char *in, unsigned long inlen, |
30 | unsigned char *out, unsigned long *outlen, | |
30 | char *out, unsigned long *outlen, | |
31 | 31 | const char *codes, int pad) |
32 | 32 | { |
33 | 33 | unsigned long i, len2, leven; |
34 | unsigned char *p; | |
34 | char *p; | |
35 | 35 | |
36 | 36 | LTC_ARGCHK(in != NULL); |
37 | 37 | LTC_ARGCHK(out != NULL); |
86 | 86 | @return CRYPT_OK if successful |
87 | 87 | */ |
88 | 88 | int base64_encode(const unsigned char *in, unsigned long inlen, |
89 | unsigned char *out, unsigned long *outlen) | |
89 | char *out, unsigned long *outlen) | |
90 | 90 | { |
91 | 91 | return _base64_encode_internal(in, inlen, out, outlen, codes_base64, 1); |
92 | 92 | } |
103 | 103 | @return CRYPT_OK if successful |
104 | 104 | */ |
105 | 105 | int base64url_encode(const unsigned char *in, unsigned long inlen, |
106 | unsigned char *out, unsigned long *outlen) | |
106 | char *out, unsigned long *outlen) | |
107 | 107 | { |
108 | 108 | return _base64_encode_internal(in, inlen, out, outlen, codes_base64url, 0); |
109 | 109 | } |
110 | 110 | |
111 | 111 | int base64url_strict_encode(const unsigned char *in, unsigned long inlen, |
112 | unsigned char *out, unsigned long *outlen) | |
112 | char *out, unsigned long *outlen) | |
113 | 113 | { |
114 | 114 | return _base64_encode_internal(in, inlen, out, outlen, codes_base64url, 1); |
115 | 115 | } |
244 | 244 | _SZ_STRINGIFY_T(dh_key), |
245 | 245 | #endif |
246 | 246 | #ifdef LTC_MECC |
247 | _SZ_STRINGIFY_T(ltc_ecc_set_type), | |
247 | _SZ_STRINGIFY_T(ltc_ecc_curve), | |
248 | 248 | _SZ_STRINGIFY_T(ecc_point), |
249 | 249 | _SZ_STRINGIFY_T(ecc_key), |
250 | 250 | #endif |
16 | 16 | #ifdef LTC_CTR_MODE |
17 | 17 | |
18 | 18 | /** |
19 | CTR encrypt | |
19 | CTR encrypt software implementation | |
20 | 20 | @param pt Plaintext |
21 | 21 | @param ct [out] Ciphertext |
22 | 22 | @param len Length of plaintext (octets) |
23 | 23 | @param ctr CTR state |
24 | 24 | @return CRYPT_OK if successful |
25 | 25 | */ |
26 | int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) | |
26 | static int _ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) | |
27 | 27 | { |
28 | 28 | int x, err; |
29 | ||
30 | LTC_ARGCHK(pt != NULL); | |
31 | LTC_ARGCHK(ct != NULL); | |
32 | LTC_ARGCHK(ctr != NULL); | |
33 | ||
34 | if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { | |
35 | return err; | |
36 | } | |
37 | ||
38 | /* is blocklen/padlen valid? */ | |
39 | if (ctr->blocklen < 1 || ctr->blocklen > (int)sizeof(ctr->ctr) || | |
40 | ctr->padlen < 0 || ctr->padlen > (int)sizeof(ctr->pad)) { | |
41 | return CRYPT_INVALID_ARG; | |
42 | } | |
43 | ||
44 | #ifdef LTC_FAST | |
45 | if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) { | |
46 | return CRYPT_INVALID_ARG; | |
47 | } | |
48 | #endif | |
49 | ||
50 | /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */ | |
51 | if ((ctr->padlen == ctr->blocklen) && cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL && (len >= (unsigned long)ctr->blocklen)) { | |
52 | if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) { | |
53 | return err; | |
54 | } | |
55 | pt += (len / ctr->blocklen) * ctr->blocklen; | |
56 | ct += (len / ctr->blocklen) * ctr->blocklen; | |
57 | len %= ctr->blocklen; | |
58 | } | |
59 | 29 | |
60 | 30 | while (len) { |
61 | 31 | /* is the pad empty? */ |
86 | 56 | ctr->padlen = 0; |
87 | 57 | } |
88 | 58 | #ifdef LTC_FAST |
89 | if (ctr->padlen == 0 && len >= (unsigned long)ctr->blocklen) { | |
59 | if ((ctr->padlen == 0) && (len >= (unsigned long)ctr->blocklen)) { | |
90 | 60 | for (x = 0; x < ctr->blocklen; x += sizeof(LTC_FAST_TYPE)) { |
91 | 61 | *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) ^ |
92 | 62 | *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ctr->pad + x)); |
104 | 74 | return CRYPT_OK; |
105 | 75 | } |
106 | 76 | |
77 | /** | |
78 | CTR encrypt | |
79 | @param pt Plaintext | |
80 | @param ct [out] Ciphertext | |
81 | @param len Length of plaintext (octets) | |
82 | @param ctr CTR state | |
83 | @return CRYPT_OK if successful | |
84 | */ | |
85 | int ctr_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long len, symmetric_CTR *ctr) | |
86 | { | |
87 | int err, fr; | |
88 | ||
89 | LTC_ARGCHK(pt != NULL); | |
90 | LTC_ARGCHK(ct != NULL); | |
91 | LTC_ARGCHK(ctr != NULL); | |
92 | ||
93 | if ((err = cipher_is_valid(ctr->cipher)) != CRYPT_OK) { | |
94 | return err; | |
95 | } | |
96 | ||
97 | /* is blocklen/padlen valid? */ | |
98 | if ((ctr->blocklen < 1) || (ctr->blocklen > (int)sizeof(ctr->ctr)) || | |
99 | (ctr->padlen < 0) || (ctr->padlen > (int)sizeof(ctr->pad))) { | |
100 | return CRYPT_INVALID_ARG; | |
101 | } | |
102 | ||
103 | #ifdef LTC_FAST | |
104 | if (ctr->blocklen % sizeof(LTC_FAST_TYPE)) { | |
105 | return CRYPT_INVALID_ARG; | |
106 | } | |
107 | #endif | |
108 | ||
109 | /* handle acceleration only if pad is empty, accelerator is present and length is >= a block size */ | |
110 | if ((cipher_descriptor[ctr->cipher].accel_ctr_encrypt != NULL) && (len >= (unsigned long)ctr->blocklen)) { | |
111 | if (ctr->padlen < ctr->blocklen) { | |
112 | fr = ctr->blocklen - ctr->padlen; | |
113 | if ((err = _ctr_encrypt(pt, ct, fr, ctr)) != CRYPT_OK) { | |
114 | return err; | |
115 | } | |
116 | pt += fr; | |
117 | ct += fr; | |
118 | len -= fr; | |
119 | } | |
120 | ||
121 | if (len >= (unsigned long)ctr->blocklen) { | |
122 | if ((err = cipher_descriptor[ctr->cipher].accel_ctr_encrypt(pt, ct, len/ctr->blocklen, ctr->ctr, ctr->mode, &ctr->key)) != CRYPT_OK) { | |
123 | return err; | |
124 | } | |
125 | pt += (len / ctr->blocklen) * ctr->blocklen; | |
126 | ct += (len / ctr->blocklen) * ctr->blocklen; | |
127 | len %= ctr->blocklen; | |
128 | } | |
129 | } | |
130 | ||
131 | return _ctr_encrypt(pt, ct, len, ctr); | |
132 | } | |
133 | ||
107 | 134 | #endif |
108 | 135 | |
109 | 136 | /* ref: $Format:%D$ */ |
22 | 22 | * - ANS X9.62 (named: PRIMEP*) |
23 | 23 | * - http://www.ecc-brainpool.org/download/Domain-parameters.pdf (named: BRAINPOOLP*) |
24 | 24 | */ |
25 | const ltc_ecc_set_type ltc_ecc_sets[] = { | |
25 | const ltc_ecc_curve ltc_ecc_curves[] = { | |
26 | 26 | #if defined(LTC_ECC_SECP112R1) || defined(LTC_ECC112) |
27 | 27 | { |
28 | /* curve name */ "SECP112R1", | |
28 | /* curve name */ { "SECP112R1", "ECC-112", NULL }, | |
29 | 29 | /* prime */ "DB7C2ABF62E35E668076BEAD208B", |
30 | 30 | /* A */ "DB7C2ABF62E35E668076BEAD2088", |
31 | 31 | /* B */ "659EF8BA043916EEDE8911702B22", |
38 | 38 | #endif |
39 | 39 | #ifdef LTC_ECC_SECP112R2 |
40 | 40 | { |
41 | /* curve name */ "SECP112R2", | |
41 | /* curve name */ { "SECP112R2", NULL }, | |
42 | 42 | /* prime */ "DB7C2ABF62E35E668076BEAD208B", |
43 | 43 | /* A */ "6127C24C05F38A0AAAF65C0EF02C", |
44 | 44 | /* B */ "51DEF1815DB5ED74FCC34C85D709", |
51 | 51 | #endif |
52 | 52 | #if defined(LTC_ECC_SECP128R1) || defined(LTC_ECC128) |
53 | 53 | { |
54 | /* curve name */ "SECP128R1", | |
54 | /* curve name */ { "SECP128R1", "ECC-128", NULL }, | |
55 | 55 | /* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", |
56 | 56 | /* A */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFC", |
57 | 57 | /* B */ "E87579C11079F43DD824993C2CEE5ED3", |
64 | 64 | #endif |
65 | 65 | #ifdef LTC_ECC_SECP128R2 |
66 | 66 | { |
67 | /* curve name */ "SECP128R2", | |
67 | /* curve name */ { "SECP128R2", NULL }, | |
68 | 68 | /* prime */ "FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF", |
69 | 69 | /* A */ "D6031998D1B3BBFEBF59CC9BBFF9AEE1", |
70 | 70 | /* B */ "5EEEFCA380D02919DC2C6558BB6D8A5D", |
77 | 77 | #endif |
78 | 78 | #if defined(LTC_ECC_SECP160R1) || defined(LTC_ECC160) |
79 | 79 | { |
80 | /* curve name */ "SECP160R1", | |
80 | /* curve name */ { "SECP160R1", "ECC-160", NULL }, | |
81 | 81 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF", |
82 | 82 | /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC", |
83 | 83 | /* B */ "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45", |
90 | 90 | #endif |
91 | 91 | #ifdef LTC_ECC_SECP160R2 |
92 | 92 | { |
93 | /* curve name */ "SECP160R2", | |
93 | /* curve name */ { "SECP160R2", NULL }, | |
94 | 94 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", |
95 | 95 | /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC70", |
96 | 96 | /* B */ "B4E134D3FB59EB8BAB57274904664D5AF50388BA", |
103 | 103 | #endif |
104 | 104 | #ifdef LTC_ECC_SECP160K1 |
105 | 105 | { |
106 | /* curve name */ "SECP160K1", | |
106 | /* curve name */ { "SECP160K1", NULL }, | |
107 | 107 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFAC73", |
108 | 108 | /* A */ "0000000000000000000000000000000000000000", |
109 | 109 | /* B */ "0000000000000000000000000000000000000007", |
116 | 116 | #endif |
117 | 117 | #if defined(LTC_ECC_SECP192R1) || defined(LTC_ECC192) |
118 | 118 | { |
119 | /* curve name */ "SECP192R1", /* same as: NISTP192 PRIME192V1, old libtomcrypt name: ECC-192 */ | |
119 | /* curve name */ { "SECP192R1", "NISTP192", "PRIME192V1", "ECC-192", "P-192", NULL }, | |
120 | 120 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", |
121 | 121 | /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", |
122 | 122 | /* B */ "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1", |
129 | 129 | #endif |
130 | 130 | #ifdef LTC_ECC_PRIME192V2 |
131 | 131 | { |
132 | /* curve name */ "PRIME192V2", | |
132 | /* curve name */ { "PRIME192V2", NULL }, | |
133 | 133 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", |
134 | 134 | /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", |
135 | 135 | /* B */ "CC22D6DFB95C6B25E49C0D6364A4E5980C393AA21668D953", |
142 | 142 | #endif |
143 | 143 | #ifdef LTC_ECC_PRIME192V3 |
144 | 144 | { |
145 | /* curve name */ "PRIME192V3", | |
145 | /* curve name */ { "PRIME192V3", NULL }, | |
146 | 146 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF", |
147 | 147 | /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC", |
148 | 148 | /* B */ "22123DC2395A05CAA7423DAECCC94760A7D462256BD56916", |
155 | 155 | #endif |
156 | 156 | #ifdef LTC_ECC_SECP192K1 |
157 | 157 | { |
158 | /* curve name */ "SECP192K1", | |
158 | /* curve name */ { "SECP192K1", NULL }, | |
159 | 159 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFEE37", |
160 | 160 | /* A */ "000000000000000000000000000000000000000000000000", |
161 | 161 | /* B */ "000000000000000000000000000000000000000000000003", |
168 | 168 | #endif |
169 | 169 | #if defined(LTC_ECC_SECP224R1) || defined(LTC_ECC224) |
170 | 170 | { |
171 | /* curve name */ "SECP224R1", /* same as: NISTP224, old libtomcrypt name: ECC-224 */ | |
171 | /* curve name */ { "SECP224R1", "NISTP224", "ECC-224", "P-224", NULL }, | |
172 | 172 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", |
173 | 173 | /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", |
174 | 174 | /* B */ "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", |
181 | 181 | #endif |
182 | 182 | #ifdef LTC_ECC_SECP224K1 |
183 | 183 | { |
184 | /* curve name */ "SECP224K1", | |
184 | /* curve name */ { "SECP224K1", NULL }, | |
185 | 185 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFE56D", |
186 | 186 | /* A */ "00000000000000000000000000000000000000000000000000000000", |
187 | 187 | /* B */ "00000000000000000000000000000000000000000000000000000005", |
194 | 194 | #endif |
195 | 195 | #if defined(LTC_ECC_SECP256R1) || defined(LTC_ECC256) |
196 | 196 | { |
197 | /* curve name */ "SECP256R1", /* same as: NISTP256 PRIME256V1, old libtomcrypt name: ECC-256 */ | |
197 | /* curve name */ { "SECP256R1", "NISTP256", "PRIME256V1", "ECC-256", "P-256", NULL }, | |
198 | 198 | /* prime */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF", |
199 | 199 | /* A */ "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC", |
200 | 200 | /* B */ "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B", |
207 | 207 | #endif |
208 | 208 | #ifdef LTC_ECC_SECP256K1 |
209 | 209 | { |
210 | /* curve name */ "SECP256K1", | |
210 | /* curve name */ { "SECP256K1", NULL }, | |
211 | 211 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", |
212 | 212 | /* A */ "0000000000000000000000000000000000000000000000000000000000000000", |
213 | 213 | /* B */ "0000000000000000000000000000000000000000000000000000000000000007", |
220 | 220 | #endif |
221 | 221 | #if defined(LTC_ECC_SECP384R1) || defined(LTC_ECC384) |
222 | 222 | { |
223 | /* curve name */ "SECP384R1", /* same as: NISTP384, old libtomcrypt name: ECC-384 */ | |
223 | /* curve name */ { "SECP384R1", "NISTP384", "ECC-384", "P-384", NULL }, | |
224 | 224 | /* prime */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF", |
225 | 225 | /* A */ "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC", |
226 | 226 | /* B */ "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF", |
233 | 233 | #endif |
234 | 234 | #if defined(LTC_ECC_SECP521R1) || defined(LTC_ECC521) |
235 | 235 | { |
236 | /* curve name */ "SECP521R1", /* same as: NISTP521, old libtomcrypt name: ECC-521 */ | |
236 | /* curve name */ { "SECP521R1", "NISTP521", "ECC-521", "P-521", NULL }, | |
237 | 237 | /* prime */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", |
238 | 238 | /* A */ "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC", |
239 | 239 | /* B */ "0051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573DF883D2C34F1EF451FD46B503F00", |
246 | 246 | #endif |
247 | 247 | #ifdef LTC_ECC_PRIME239V1 |
248 | 248 | { |
249 | /* curve name */ "PRIME239V1", | |
249 | /* curve name */ { "PRIME239V1", NULL }, | |
250 | 250 | /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", |
251 | 251 | /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", |
252 | 252 | /* B */ "6B016C3BDCF18941D0D654921475CA71A9DB2FB27D1D37796185C2942C0A", |
259 | 259 | #endif |
260 | 260 | #ifdef LTC_ECC_PRIME239V2 |
261 | 261 | { |
262 | /* curve name */ "PRIME239V2", | |
262 | /* curve name */ { "PRIME239V2", NULL }, | |
263 | 263 | /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", |
264 | 264 | /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", |
265 | 265 | /* B */ "617FAB6832576CBBFED50D99F0249C3FEE58B94BA0038C7AE84C8C832F2C", |
272 | 272 | #endif |
273 | 273 | #ifdef LTC_ECC_PRIME239V3 |
274 | 274 | { |
275 | /* curve name */ "PRIME239V3", | |
275 | /* curve name */ { "PRIME239V3", NULL }, | |
276 | 276 | /* prime */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFF", |
277 | 277 | /* A */ "7FFFFFFFFFFFFFFFFFFFFFFF7FFFFFFFFFFF8000000000007FFFFFFFFFFC", |
278 | 278 | /* B */ "255705FA2A306654B1F4CB03D6A750A30C250102D4988717D9BA15AB6D3E", |
285 | 285 | #endif |
286 | 286 | #ifdef LTC_ECC_BRAINPOOLP160R1 |
287 | 287 | { |
288 | /* curve name */ "BRAINPOOLP160R1", | |
288 | /* curve name */ { "BRAINPOOLP160R1", NULL }, | |
289 | 289 | /* prime */ "E95E4A5F737059DC60DFC7AD95B3D8139515620F", |
290 | 290 | /* A */ "340E7BE2A280EB74E2BE61BADA745D97E8F7C300", |
291 | 291 | /* B */ "1E589A8595423412134FAA2DBDEC95C8D8675E58", |
298 | 298 | #endif |
299 | 299 | #ifdef LTC_ECC_BRAINPOOLP192R1 |
300 | 300 | { |
301 | /* curve name */ "BRAINPOOLP192R1", | |
301 | /* curve name */ { "BRAINPOOLP192R1", NULL }, | |
302 | 302 | /* prime */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", |
303 | 303 | /* A */ "6A91174076B1E0E19C39C031FE8685C1CAE040E5C69A28EF", |
304 | 304 | /* B */ "469A28EF7C28CCA3DC721D044F4496BCCA7EF4146FBF25C9", |
311 | 311 | #endif |
312 | 312 | #ifdef LTC_ECC_BRAINPOOLP224R1 |
313 | 313 | { |
314 | /* curve name */ "BRAINPOOLP224R1", | |
314 | /* curve name */ { "BRAINPOOLP224R1", NULL }, | |
315 | 315 | /* prime */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", |
316 | 316 | /* A */ "68A5E62CA9CE6C1C299803A6C1530B514E182AD8B0042A59CAD29F43", |
317 | 317 | /* B */ "2580F63CCFE44138870713B1A92369E33E2135D266DBB372386C400B", |
324 | 324 | #endif |
325 | 325 | #ifdef LTC_ECC_BRAINPOOLP256R1 |
326 | 326 | { |
327 | /* curve name */ "BRAINPOOLP256R1", | |
327 | /* curve name */ { "BRAINPOOLP256R1", NULL }, | |
328 | 328 | /* prime */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", |
329 | 329 | /* A */ "7D5A0975FC2C3057EEF67530417AFFE7FB8055C126DC5C6CE94A4B44F330B5D9", |
330 | 330 | /* B */ "26DC5C6CE94A4B44F330B5D9BBD77CBF958416295CF7E1CE6BCCDC18FF8C07B6", |
337 | 337 | #endif |
338 | 338 | #ifdef LTC_ECC_BRAINPOOLP320R1 |
339 | 339 | { |
340 | /* curve name */ "BRAINPOOLP320R1", | |
340 | /* curve name */ { "BRAINPOOLP320R1", NULL }, | |
341 | 341 | /* prime */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", |
342 | 342 | /* A */ "3EE30B568FBAB0F883CCEBD46D3F3BB8A2A73513F5EB79DA66190EB085FFA9F492F375A97D860EB4", |
343 | 343 | /* B */ "520883949DFDBC42D3AD198640688A6FE13F41349554B49ACC31DCCD884539816F5EB4AC8FB1F1A6", |
350 | 350 | #endif |
351 | 351 | #ifdef LTC_ECC_BRAINPOOLP384R1 |
352 | 352 | { |
353 | /* curve name */ "BRAINPOOLP384R1", | |
353 | /* curve name */ { "BRAINPOOLP384R1", NULL }, | |
354 | 354 | /* prime */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", |
355 | 355 | /* A */ "7BC382C63D8C150C3C72080ACE05AFA0C2BEA28E4FB22787139165EFBA91F90F8AA5814A503AD4EB04A8C7DD22CE2826", |
356 | 356 | /* B */ "04A8C7DD22CE28268B39B55416F0447C2FB77DE107DCD2A62E880EA53EEB62D57CB4390295DBC9943AB78696FA504C11", |
363 | 363 | #endif |
364 | 364 | #ifdef LTC_ECC_BRAINPOOLP512R1 |
365 | 365 | { |
366 | /* curve name */ "BRAINPOOLP512R1", | |
366 | /* curve name */ { "BRAINPOOLP512R1", NULL }, | |
367 | 367 | /* prime */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", |
368 | 368 | /* A */ "7830A3318B603B89E2327145AC234CC594CBDD8D3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CA", |
369 | 369 | /* B */ "3DF91610A83441CAEA9863BC2DED5D5AA8253AA10A2EF1C98B9AC8B57F1117A72BF2C7B9E7C1AC4D77FC94CADC083E67984050B75EBAE5DD2809BD638016F723", |
376 | 376 | #endif |
377 | 377 | #ifdef LTC_ECC_BRAINPOOLP160T1 |
378 | 378 | { |
379 | /* curve name */ "BRAINPOOLP160T1", | |
379 | /* curve name */ { "BRAINPOOLP160T1", NULL }, | |
380 | 380 | /* prime */ "E95E4A5F737059DC60DFC7AD95B3D8139515620F", |
381 | 381 | /* A */ "E95E4A5F737059DC60DFC7AD95B3D8139515620C", |
382 | 382 | /* B */ "7A556B6DAE535B7B51ED2C4D7DAA7A0B5C55F380", |
389 | 389 | #endif |
390 | 390 | #ifdef LTC_ECC_BRAINPOOLP192T1 |
391 | 391 | { |
392 | /* curve name */ "BRAINPOOLP192T1", | |
392 | /* curve name */ { "BRAINPOOLP192T1", NULL }, | |
393 | 393 | /* prime */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86297", |
394 | 394 | /* A */ "C302F41D932A36CDA7A3463093D18DB78FCE476DE1A86294", |
395 | 395 | /* B */ "13D56FFAEC78681E68F9DEB43B35BEC2FB68542E27897B79", |
402 | 402 | #endif |
403 | 403 | #ifdef LTC_ECC_BRAINPOOLP224T1 |
404 | 404 | { |
405 | /* curve name */ "BRAINPOOLP224T1", | |
405 | /* curve name */ { "BRAINPOOLP224T1", NULL }, | |
406 | 406 | /* prime */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FF", |
407 | 407 | /* A */ "D7C134AA264366862A18302575D1D787B09F075797DA89F57EC8C0FC", |
408 | 408 | /* B */ "4B337D934104CD7BEF271BF60CED1ED20DA14C08B3BB64F18A60888D", |
415 | 415 | #endif |
416 | 416 | #ifdef LTC_ECC_BRAINPOOLP256T1 |
417 | 417 | { |
418 | /* curve name */ "BRAINPOOLP256T1", | |
418 | /* curve name */ { "BRAINPOOLP256T1", NULL }, | |
419 | 419 | /* prime */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5377", |
420 | 420 | /* A */ "A9FB57DBA1EEA9BC3E660A909D838D726E3BF623D52620282013481D1F6E5374", |
421 | 421 | /* B */ "662C61C430D84EA4FE66A7733D0B76B7BF93EBC4AF2F49256AE58101FEE92B04", |
428 | 428 | #endif |
429 | 429 | #ifdef LTC_ECC_BRAINPOOLP320T1 |
430 | 430 | { |
431 | /* curve name */ "BRAINPOOLP320T1", | |
431 | /* curve name */ { "BRAINPOOLP320T1", NULL }, | |
432 | 432 | /* prime */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E27", |
433 | 433 | /* A */ "D35E472036BC4FB7E13C785ED201E065F98FCFA6F6F40DEF4F92B9EC7893EC28FCD412B1F1B32E24", |
434 | 434 | /* B */ "A7F561E038EB1ED560B3D147DB782013064C19F27ED27C6780AAF77FB8A547CEB5B4FEF422340353", |
441 | 441 | #endif |
442 | 442 | #ifdef LTC_ECC_BRAINPOOLP384T1 |
443 | 443 | { |
444 | /* curve name */ "BRAINPOOLP384T1", | |
444 | /* curve name */ { "BRAINPOOLP384T1", NULL }, | |
445 | 445 | /* prime */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC53", |
446 | 446 | /* A */ "8CB91E82A3386D280F5D6F7E50E641DF152F7109ED5456B412B1DA197FB71123ACD3A729901D1A71874700133107EC50", |
447 | 447 | /* B */ "7F519EADA7BDA81BD826DBA647910F8C4B9346ED8CCDC64E4B1ABD11756DCE1D2074AA263B88805CED70355A33B471EE", |
454 | 454 | #endif |
455 | 455 | #ifdef LTC_ECC_BRAINPOOLP512T1 |
456 | 456 | { |
457 | /* curve name */ "BRAINPOOLP512T1", | |
457 | /* curve name */ { "BRAINPOOLP512T1", NULL }, | |
458 | 458 | /* prime */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F3", |
459 | 459 | /* A */ "AADD9DB8DBE9C48B3FD4E6AE33C9FC07CB308DB3B3C9D20ED6639CCA703308717D4D9B009BC66842AECDA12AE6A380E62881FF2F2D82C68528AA6056583A48F0", |
460 | 460 | /* B */ "7CBBBCF9441CFAB76E1890E46884EAE321F70C0BCB4981527897504BEC3E36A62BCDFA2304976540F6450085F2DAE145C22553B465763689180EA2571867423E", |
466 | 466 | }, |
467 | 467 | #endif |
468 | 468 | { |
469 | NULL, NULL, NULL, NULL, NULL, NULL, NULL, | |
469 | { NULL }, | |
470 | NULL, NULL, NULL, NULL, NULL, NULL, | |
470 | 471 | 0, |
471 | 472 | { 0 }, 0 |
472 | 473 | } |
25 | 25 | return ecc_ansi_x963_import_ex(in, inlen, key, NULL); |
26 | 26 | } |
27 | 27 | |
28 | int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp) | |
28 | int ecc_ansi_x963_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_curve *cu) | |
29 | 29 | { |
30 | 30 | int err; |
31 | 31 | |
38 | 38 | } |
39 | 39 | |
40 | 40 | /* initialize key->dp */ |
41 | if (dp == NULL) { | |
41 | if (cu == NULL) { | |
42 | 42 | /* this case works only for uncompressed public keys */ |
43 | if ((err = ecc_set_dp_size((inlen-1)>>1, key)) != CRYPT_OK) { return err; } | |
43 | if ((err = ecc_set_dp_by_size((inlen-1)>>1, key)) != CRYPT_OK) { return err; } | |
44 | 44 | } |
45 | 45 | else { |
46 | 46 | /* this one works for both compressed / uncompressed pubkeys */ |
47 | if ((err = ecc_set_dp(dp, key)) != CRYPT_OK) { return err; } | |
47 | if ((err = ecc_set_dp(cu, key)) != CRYPT_OK) { return err; } | |
48 | 48 | } |
49 | 49 | |
50 | 50 | /* load public key */ |
84 | 84 | } |
85 | 85 | |
86 | 86 | /* import ECC key from packet */ |
87 | if ((err = ecc_set_dp_copy(key, &pubkey)) != CRYPT_OK) { goto LBL_ERR; } | |
87 | if ((err = ecc_copy_dp(key, &pubkey)) != CRYPT_OK) { goto LBL_ERR; } | |
88 | 88 | if ((err = ecc_set_key(decode[1].data, decode[1].size, PK_PUBLIC, &pubkey)) != CRYPT_OK) { goto LBL_ERR; } |
89 | 89 | |
90 | 90 | /* make shared key */ |
56 | 56 | } |
57 | 57 | |
58 | 58 | /* make a random key and export the public copy */ |
59 | if ((err = ecc_set_dp_copy(key, &pubkey)) != CRYPT_OK) { return err; } | |
59 | if ((err = ecc_copy_dp(key, &pubkey)) != CRYPT_OK) { return err; } | |
60 | 60 | if ((err = ecc_generate_key(prng, wprng, &pubkey)) != CRYPT_OK) { return err; } |
61 | 61 | |
62 | 62 | pub_expt = XMALLOC(ECC_BUF_SIZE); |
77 | 77 | } |
78 | 78 | |
79 | 79 | pubkeysize = ECC_BUF_SIZE; |
80 | #ifdef USE_TFM | |
81 | /* XXX-FIXME: TFM does not support sqrtmod_prime */ | |
82 | if ((err = ecc_get_key(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey)) != CRYPT_OK) { | |
83 | #else | |
84 | if ((err = ecc_get_key(pub_expt, &pubkeysize, PK_PUBLIC|PK_COMPRESSED, &pubkey)) != CRYPT_OK) { | |
85 | #endif | |
80 | if (ltc_mp.sqrtmod_prime != NULL) { | |
81 | /* PK_COMPRESSED requires sqrtmod_prime */ | |
82 | err = ecc_get_key(pub_expt, &pubkeysize, PK_PUBLIC|PK_COMPRESSED, &pubkey); | |
83 | } | |
84 | else { | |
85 | err = ecc_get_key(pub_expt, &pubkeysize, PK_PUBLIC, &pubkey); | |
86 | } | |
87 | if (err != CRYPT_OK) { | |
86 | 88 | ecc_free(&pubkey); |
87 | 89 | goto LBL_ERR; |
88 | 90 | } |
22 | 22 | void ecc_free(ecc_key *key) |
23 | 23 | { |
24 | 24 | LTC_ARGCHKVD(key != NULL); |
25 | /* clean dp */ | |
25 | ||
26 | 26 | mp_cleanup_multi(&key->dp.prime, &key->dp.order, |
27 | 27 | &key->dp.A, &key->dp.B, |
28 | 28 | &key->dp.base.x, &key->dp.base.y, &key->dp.base.z, |
29 | NULL); | |
30 | ||
31 | /* clean key */ | |
32 | mp_cleanup_multi(&key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL); | |
29 | &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, | |
30 | &key->k, NULL); | |
33 | 31 | } |
34 | 32 | |
35 | 33 | #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 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_MECC | |
12 | ||
13 | /* case-insensitive match + ignore '-', '_', ' ' */ | |
14 | static int _name_match(const char *left, const char *right) | |
15 | { | |
16 | char lc_r, lc_l; | |
17 | ||
18 | while ((*left != '\0') && (*right != '\0')) { | |
19 | while ((*left == ' ') || (*left == '-') || (*left == '_')) left++; | |
20 | while ((*right == ' ') || (*right == '-') || (*right == '_')) right++; | |
21 | if (*left == '\0' || *right == '\0') break; | |
22 | lc_r = *right; | |
23 | lc_l = *left; | |
24 | if ((lc_r >= 'A') && (lc_r <= 'Z')) lc_r += 32; | |
25 | if ((lc_l >= 'A') && (lc_l <= 'Z')) lc_l += 32; | |
26 | if (lc_l != lc_r) return 0; | |
27 | left++; | |
28 | right++; | |
29 | } | |
30 | ||
31 | if ((*left == '\0') && (*right == '\0')) | |
32 | return 1; | |
33 | else | |
34 | return 0; | |
35 | } | |
36 | ||
37 | int ecc_get_curve_by_name(const char *name, const ltc_ecc_curve **cu) | |
38 | { | |
39 | int i, j; | |
40 | ||
41 | LTC_ARGCHK(cu != NULL); | |
42 | LTC_ARGCHK(name != NULL); | |
43 | ||
44 | *cu = NULL; | |
45 | ||
46 | for (i = 0; ltc_ecc_curves[i].prime != NULL; i++) { | |
47 | for (j = 0; ltc_ecc_curves[i].names[j] != NULL; j++) { | |
48 | if (_name_match(ltc_ecc_curves[i].names[j], name)) { | |
49 | *cu = <c_ecc_curves[i]; | |
50 | return CRYPT_OK; | |
51 | } | |
52 | } | |
53 | } | |
54 | ||
55 | return CRYPT_INVALID_ARG; /* not found */ | |
56 | } | |
57 | ||
58 | #endif | |
59 | ||
60 | /* ref: $Format:%D$ */ | |
61 | /* git commit: $Format:%H$ */ | |
62 | /* commit time: $Format:%ai$ */ |
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 | #include "tomcrypt.h" | |
10 | ||
11 | #ifdef LTC_MECC | |
12 | ||
13 | int ecc_get_set_by_name(const char* name, const ltc_ecc_set_type** dp) | |
14 | { | |
15 | int i; | |
16 | ||
17 | LTC_ARGCHK(dp != NULL); | |
18 | LTC_ARGCHK(name != NULL); | |
19 | ||
20 | *dp = NULL; | |
21 | ||
22 | for (i = 0; ltc_ecc_sets[i].name != NULL; i++) { | |
23 | if (XSTRCMP(ltc_ecc_sets[i].name, name) == 0) break; | |
24 | } | |
25 | ||
26 | if (ltc_ecc_sets[i].name == NULL) { | |
27 | /* not found */ | |
28 | return CRYPT_INVALID_ARG; | |
29 | } | |
30 | ||
31 | *dp = <c_ecc_sets[i]; | |
32 | return CRYPT_OK; | |
33 | } | |
34 | ||
35 | #endif | |
36 | ||
37 | /* ref: $Format:%D$ */ | |
38 | /* git commit: $Format:%H$ */ | |
39 | /* commit time: $Format:%ai$ */ |
32 | 32 | @param in The packet to import |
33 | 33 | @param inlen The length of the packet |
34 | 34 | @param key [out] The destination of the import |
35 | @param dp pointer to user supplied params; must be the same as the params used when exporting | |
35 | @param cu pointer to user supplied params; must be the same as the params used when exporting | |
36 | 36 | @return CRYPT_OK if successful, upon error all allocated memory will be freed |
37 | 37 | */ |
38 | int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_set_type *dp) | |
38 | int ecc_import_ex(const unsigned char *in, unsigned long inlen, ecc_key *key, const ltc_ecc_curve *cu) | |
39 | 39 | { |
40 | 40 | unsigned long key_size; |
41 | 41 | unsigned char flags[1]; |
54 | 54 | } |
55 | 55 | |
56 | 56 | /* allocate & initialize the key */ |
57 | if (dp == NULL) { | |
58 | if ((err = ecc_set_dp_size(key_size, key)) != CRYPT_OK) { goto done; } | |
57 | if (cu == NULL) { | |
58 | if ((err = ecc_set_dp_by_size(key_size, key)) != CRYPT_OK) { goto done; } | |
59 | 59 | } else { |
60 | if ((err = ecc_set_dp(dp, key)) != CRYPT_OK) { goto done; } | |
60 | if ((err = ecc_set_dp(cu, key)) != CRYPT_OK) { goto done; } | |
61 | 61 | } |
62 | 62 | |
63 | 63 | if (flags[0] == 1) { |
30 | 30 | err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_OBJECT_IDENTIFIER, (void *)curveoid, &len_oid); |
31 | 31 | if (err == CRYPT_OK) { |
32 | 32 | /* load curve parameters for given curve OID */ |
33 | if ((err = ecc_set_dp_oid(curveoid, len_oid, key)) != CRYPT_OK) { goto error; } | |
33 | if ((err = ecc_set_dp_by_oid(curveoid, len_oid, key)) != CRYPT_OK) { goto error; } | |
34 | 34 | /* load public key */ |
35 | 35 | if ((err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key)) != CRYPT_OK) { goto error; } |
36 | 36 | goto success; |
68 | 68 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } |
69 | 69 | if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } |
70 | 70 | /* load curve parameters */ |
71 | if ((err = ecc_set_dp_bn(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } | |
71 | if ((err = ecc_set_dp_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } | |
72 | 72 | /* load public key */ |
73 | 73 | if ((err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key)) != CRYPT_OK) { goto error; } |
74 | 74 | goto success; |
88 | 88 | err = der_decode_sequence(in, inlen, seq_priv, 4); |
89 | 89 | if (err == CRYPT_OK) { |
90 | 90 | /* load curve parameters for given curve OID */ |
91 | if ((err = ecc_set_dp_oid(curveoid, custom[0].size, key)) != CRYPT_OK) { goto error; } | |
91 | if ((err = ecc_set_dp_by_oid(curveoid, custom[0].size, key)) != CRYPT_OK) { goto error; } | |
92 | 92 | /* load private+public key */ |
93 | 93 | if ((err = ecc_set_key(bin_k, seq_priv[1].size, PK_PRIVATE, key)) != CRYPT_OK) { goto error; } |
94 | 94 | goto success; |
132 | 132 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } |
133 | 133 | if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } |
134 | 134 | /* load curve parameters */ |
135 | if ((err = ecc_set_dp_bn(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } | |
135 | if ((err = ecc_set_dp_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } | |
136 | 136 | /* load private+public key */ |
137 | 137 | if ((err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key)) != CRYPT_OK) { goto error; } |
138 | 138 | goto success; |
499 | 499 | * 23:d=1 hl=2 l= 77 prim: OCTET STRING :bytes (== privatekey) |
500 | 500 | */ |
501 | 501 | ltc_asn1_list *loid = lseq->child->next; |
502 | if ((err = ecc_set_dp_oid(loid->data, loid->size, key)) != CRYPT_OK) { | |
502 | if ((err = ecc_set_dp_by_oid(loid->data, loid->size, key)) != CRYPT_OK) { | |
503 | 503 | goto LBL_DONE; |
504 | 504 | } |
505 | 505 | } |
552 | 552 | if ((err = ltc_ecc_import_point(lg->data, lg->size, lprime->data, a, b, gx, gy)) != CRYPT_OK) { |
553 | 553 | goto LBL_DONE; |
554 | 554 | } |
555 | if ((err = ecc_set_dp_bn(a, b, lprime->data, lorder->data, gx, gy, cofactor, key)) != CRYPT_OK) { | |
555 | if ((err = ecc_set_dp_from_mpis(a, b, lprime->data, lorder->data, gx, gy, cofactor, key)) != CRYPT_OK) { | |
556 | 556 | goto LBL_DONE; |
557 | 557 | } |
558 | 558 | } |
27 | 27 | { |
28 | 28 | int err; |
29 | 29 | |
30 | if ((err = ecc_set_dp_size(keysize, key)) != CRYPT_OK) { return err; } | |
30 | if ((err = ecc_set_dp_by_size(keysize, key)) != CRYPT_OK) { return err; } | |
31 | 31 | if ((err = ecc_generate_key(prng, wprng, key)) != CRYPT_OK) { return err; } |
32 | 32 | return CRYPT_OK; |
33 | 33 | } |
34 | 34 | |
35 | int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_set_type *dp) | |
35 | int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_curve *cu) | |
36 | 36 | { |
37 | 37 | int err; |
38 | if ((err = ecc_set_dp(dp, key)) != CRYPT_OK) { return err; } | |
38 | if ((err = ecc_set_dp(cu, key)) != CRYPT_OK) { return err; } | |
39 | 39 | if ((err = ecc_generate_key(prng, wprng, key)) != CRYPT_OK) { return err; } |
40 | 40 | return CRYPT_OK; |
41 | 41 | } |
10 | 10 | |
11 | 11 | #ifdef LTC_MECC |
12 | 12 | |
13 | int ecc_set_dp(const ltc_ecc_set_type *set, ecc_key *key) | |
13 | int ecc_set_dp(const ltc_ecc_curve *curve, ecc_key *key) | |
14 | 14 | { |
15 | 15 | unsigned long i; |
16 | 16 | int err; |
17 | 17 | |
18 | 18 | LTC_ARGCHK(key != NULL); |
19 | LTC_ARGCHK(set != NULL); | |
19 | LTC_ARGCHK(curve != NULL); | |
20 | 20 | |
21 | 21 | if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B, |
22 | 22 | &key->dp.base.x, &key->dp.base.y, &key->dp.base.z, |
26 | 26 | } |
27 | 27 | |
28 | 28 | /* A, B, order, prime, Gx, Gy */ |
29 | if ((err = mp_read_radix(key->dp.prime, set->prime, 16)) != CRYPT_OK) { goto error; } | |
30 | if ((err = mp_read_radix(key->dp.order, set->order, 16)) != CRYPT_OK) { goto error; } | |
31 | if ((err = mp_read_radix(key->dp.A, set->A, 16)) != CRYPT_OK) { goto error; } | |
32 | if ((err = mp_read_radix(key->dp.B, set->B, 16)) != CRYPT_OK) { goto error; } | |
33 | if ((err = mp_read_radix(key->dp.base.x, set->Gx, 16)) != CRYPT_OK) { goto error; } | |
34 | if ((err = mp_read_radix(key->dp.base.y, set->Gy, 16)) != CRYPT_OK) { goto error; } | |
35 | if ((err = mp_set(key->dp.base.z, 1)) != CRYPT_OK) { goto error; } | |
29 | if ((err = mp_read_radix(key->dp.prime, curve->prime, 16)) != CRYPT_OK) { goto error; } | |
30 | if ((err = mp_read_radix(key->dp.order, curve->order, 16)) != CRYPT_OK) { goto error; } | |
31 | if ((err = mp_read_radix(key->dp.A, curve->A, 16)) != CRYPT_OK) { goto error; } | |
32 | if ((err = mp_read_radix(key->dp.B, curve->B, 16)) != CRYPT_OK) { goto error; } | |
33 | if ((err = mp_read_radix(key->dp.base.x, curve->Gx, 16)) != CRYPT_OK) { goto error; } | |
34 | if ((err = mp_read_radix(key->dp.base.y, curve->Gy, 16)) != CRYPT_OK) { goto error; } | |
35 | if ((err = mp_set(key->dp.base.z, 1)) != CRYPT_OK) { goto error; } | |
36 | 36 | /* cofactor & size */ |
37 | key->dp.cofactor = set->cofactor; | |
37 | key->dp.cofactor = curve->cofactor; | |
38 | 38 | key->dp.size = mp_unsigned_bin_size(key->dp.prime); |
39 | 39 | /* OID */ |
40 | key->dp.oidlen = set->oidlen; | |
41 | for (i = 0; i < key->dp.oidlen; i++) key->dp.oid[i] = set->oid[i]; | |
40 | key->dp.oidlen = curve->oidlen; | |
41 | for (i = 0; i < key->dp.oidlen; i++) key->dp.oid[i] = curve->oid[i]; | |
42 | 42 | /* success */ |
43 | 43 | return CRYPT_OK; |
44 | 44 | |
47 | 47 | return err; |
48 | 48 | } |
49 | 49 | |
50 | int ecc_set_dp_size(int size, ecc_key *key) | |
50 | int ecc_set_dp_by_size(int size, ecc_key *key) | |
51 | 51 | { |
52 | const ltc_ecc_set_type *dp = NULL; | |
53 | int err; | |
52 | const ltc_ecc_curve *cu = NULL; | |
53 | int err = CRYPT_ERROR; | |
54 | 54 | |
55 | 55 | /* for compatibility with libtomcrypt-1.17 the sizes below must match the specific curves */ |
56 | 56 | if (size <= 14) { |
57 | if ((err = ecc_get_set_by_name("SECP112R1", &dp)) != CRYPT_OK) return err; | |
58 | return ecc_set_dp(dp, key); | |
57 | err = ecc_get_curve_by_name("SECP112R1", &cu); | |
59 | 58 | } |
60 | 59 | else if (size <= 16) { |
61 | if ((err = ecc_get_set_by_name("SECP128R1", &dp)) != CRYPT_OK) return err; | |
62 | return ecc_set_dp(dp, key); | |
60 | err = ecc_get_curve_by_name("SECP128R1", &cu); | |
63 | 61 | } |
64 | 62 | else if (size <= 20) { |
65 | if ((err = ecc_get_set_by_name("SECP160R1", &dp)) != CRYPT_OK) return err; | |
66 | return ecc_set_dp(dp, key); | |
63 | err = ecc_get_curve_by_name("SECP160R1", &cu); | |
67 | 64 | } |
68 | 65 | else if (size <= 24) { |
69 | if ((err = ecc_get_set_by_name("SECP192R1", &dp)) != CRYPT_OK) return err; | |
70 | return ecc_set_dp(dp, key); | |
66 | err = ecc_get_curve_by_name("SECP192R1", &cu); | |
71 | 67 | } |
72 | 68 | else if (size <= 28) { |
73 | if ((err = ecc_get_set_by_name("SECP224R1", &dp)) != CRYPT_OK) return err; | |
74 | return ecc_set_dp(dp, key); | |
69 | err = ecc_get_curve_by_name("SECP224R1", &cu); | |
75 | 70 | } |
76 | 71 | else if (size <= 32) { |
77 | if ((err = ecc_get_set_by_name("SECP256R1", &dp)) != CRYPT_OK) return err; | |
78 | return ecc_set_dp(dp, key); | |
72 | err = ecc_get_curve_by_name("SECP256R1", &cu); | |
79 | 73 | } |
80 | 74 | else if (size <= 48) { |
81 | if ((err = ecc_get_set_by_name("SECP384R1", &dp)) != CRYPT_OK) return err; | |
82 | return ecc_set_dp(dp, key); | |
75 | err = ecc_get_curve_by_name("SECP384R1", &cu); | |
83 | 76 | } |
84 | 77 | else if (size <= 66) { |
85 | if ((err = ecc_get_set_by_name("SECP521R1", &dp)) != CRYPT_OK) return err; | |
86 | return ecc_set_dp(dp, key); | |
78 | err = ecc_get_curve_by_name("SECP521R1", &cu); | |
87 | 79 | } |
80 | ||
81 | if (err == CRYPT_OK && cu != NULL) return ecc_set_dp(cu, key); | |
88 | 82 | |
89 | 83 | return CRYPT_INVALID_ARG; |
90 | 84 | } |
15 | 15 | int err; |
16 | 16 | unsigned i; |
17 | 17 | void *tmp; |
18 | const ltc_ecc_set_type *set; | |
18 | const ltc_ecc_curve *curve; | |
19 | 19 | |
20 | 20 | key->dp.oidlen = 0; |
21 | 21 | if ((err = mp_init(&tmp)) != CRYPT_OK) return; |
22 | for (set = ltc_ecc_sets; set->name != NULL; set++) { | |
23 | if ((err = mp_read_radix(tmp, set->prime, 16)) != CRYPT_OK) continue; | |
22 | for (curve = ltc_ecc_curves; curve->prime != NULL; curve++) { | |
23 | if ((err = mp_read_radix(tmp, curve->prime, 16)) != CRYPT_OK) continue; | |
24 | 24 | if ((mp_cmp(tmp, key->dp.prime) != LTC_MP_EQ)) continue; |
25 | if ((err = mp_read_radix(tmp, set->order, 16)) != CRYPT_OK) continue; | |
25 | if ((err = mp_read_radix(tmp, curve->order, 16)) != CRYPT_OK) continue; | |
26 | 26 | if ((mp_cmp(tmp, key->dp.order) != LTC_MP_EQ)) continue; |
27 | if ((err = mp_read_radix(tmp, set->A, 16)) != CRYPT_OK) continue; | |
27 | if ((err = mp_read_radix(tmp, curve->A, 16)) != CRYPT_OK) continue; | |
28 | 28 | if ((mp_cmp(tmp, key->dp.A) != LTC_MP_EQ)) continue; |
29 | if ((err = mp_read_radix(tmp, set->B, 16)) != CRYPT_OK) continue; | |
29 | if ((err = mp_read_radix(tmp, curve->B, 16)) != CRYPT_OK) continue; | |
30 | 30 | if ((mp_cmp(tmp, key->dp.B) != LTC_MP_EQ)) continue; |
31 | if ((err = mp_read_radix(tmp, set->Gx, 16)) != CRYPT_OK) continue; | |
31 | if ((err = mp_read_radix(tmp, curve->Gx, 16)) != CRYPT_OK) continue; | |
32 | 32 | if ((mp_cmp(tmp, key->dp.base.x) != LTC_MP_EQ)) continue; |
33 | if ((err = mp_read_radix(tmp, set->Gy, 16)) != CRYPT_OK) continue; | |
33 | if ((err = mp_read_radix(tmp, curve->Gy, 16)) != CRYPT_OK) continue; | |
34 | 34 | if ((mp_cmp(tmp, key->dp.base.y) != LTC_MP_EQ)) continue; |
35 | if (key->dp.cofactor != set->cofactor) continue; | |
35 | if (key->dp.cofactor != curve->cofactor) continue; | |
36 | 36 | break; /* found */ |
37 | 37 | } |
38 | 38 | mp_clear(tmp); |
39 | if (set->name != NULL) { | |
39 | if (curve->prime != NULL) { | |
40 | 40 | /* OID found */ |
41 | key->dp.oidlen = set->oidlen; | |
42 | for(i = 0; i < set->oidlen; i++) key->dp.oid[i] = set->oid[i]; | |
41 | key->dp.oidlen = curve->oidlen; | |
42 | for(i = 0; i < curve->oidlen; i++) key->dp.oid[i] = curve->oid[i]; | |
43 | 43 | } |
44 | 44 | } |
45 | 45 | |
46 | int ecc_set_dp_oid(unsigned long *oid, unsigned long oidsize, ecc_key *key) | |
46 | int ecc_set_dp_by_oid(unsigned long *oid, unsigned long oidsize, ecc_key *key) | |
47 | 47 | { |
48 | 48 | int i; |
49 | 49 | |
50 | 50 | LTC_ARGCHK(oid != NULL); |
51 | 51 | LTC_ARGCHK(oidsize > 0); |
52 | 52 | |
53 | for(i = 0; ltc_ecc_sets[i].name != NULL; i++) { | |
54 | if ((oidsize == ltc_ecc_sets[i].oidlen) && | |
55 | (XMEM_NEQ(oid, ltc_ecc_sets[i].oid, sizeof(unsigned long) * ltc_ecc_sets[i].oidlen) == 0)) { | |
53 | for(i = 0; ltc_ecc_curves[i].prime != NULL; i++) { | |
54 | if ((oidsize == ltc_ecc_curves[i].oidlen) && | |
55 | (XMEM_NEQ(oid, ltc_ecc_curves[i].oid, sizeof(unsigned long) * ltc_ecc_curves[i].oidlen) == 0)) { | |
56 | 56 | break; |
57 | 57 | } |
58 | 58 | } |
59 | if (ltc_ecc_sets[i].name == NULL) return CRYPT_ERROR; /* not found */ | |
60 | return ecc_set_dp(<c_ecc_sets[i], key); | |
59 | if (ltc_ecc_curves[i].prime == NULL) return CRYPT_ERROR; /* not found */ | |
60 | return ecc_set_dp(<c_ecc_curves[i], key); | |
61 | 61 | } |
62 | 62 | |
63 | int ecc_set_dp_copy(ecc_key *srckey, ecc_key *key) | |
63 | int ecc_copy_dp(const ecc_key *srckey, ecc_key *key) | |
64 | 64 | { |
65 | 65 | unsigned long i; |
66 | 66 | int err; |
80 | 80 | if ((err = mp_copy(srckey->dp.order, key->dp.order )) != CRYPT_OK) { goto error; } |
81 | 81 | if ((err = mp_copy(srckey->dp.A, key->dp.A )) != CRYPT_OK) { goto error; } |
82 | 82 | if ((err = mp_copy(srckey->dp.B, key->dp.B )) != CRYPT_OK) { goto error; } |
83 | if ((err = mp_copy(srckey->dp.base.x, key->dp.base.x)) != CRYPT_OK) { goto error; } | |
84 | if ((err = mp_copy(srckey->dp.base.y, key->dp.base.y)) != CRYPT_OK) { goto error; } | |
85 | if ((err = mp_copy(srckey->dp.base.z, key->dp.base.z)) != CRYPT_OK) { goto error; } | |
83 | if ((err = ltc_ecc_copy_point(&srckey->dp.base, &key->dp.base)) != CRYPT_OK) { goto error; } | |
86 | 84 | /* cofactor & size */ |
87 | 85 | key->dp.cofactor = srckey->dp.cofactor; |
88 | 86 | key->dp.size = srckey->dp.size; |
92 | 90 | for (i = 0; i < key->dp.oidlen; i++) key->dp.oid[i] = srckey->dp.oid[i]; |
93 | 91 | } |
94 | 92 | else { |
95 | _ecc_oid_lookup(key); /* try to find OID in ltc_ecc_sets */ | |
93 | _ecc_oid_lookup(key); /* try to find OID in ltc_ecc_curves */ | |
96 | 94 | } |
97 | 95 | /* success */ |
98 | 96 | return CRYPT_OK; |
102 | 100 | return err; |
103 | 101 | } |
104 | 102 | |
105 | int ecc_set_dp_bn(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key) | |
103 | int ecc_set_dp_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key) | |
106 | 104 | { |
107 | 105 | int err; |
108 | 106 | |
132 | 130 | /* cofactor & size */ |
133 | 131 | key->dp.cofactor = cofactor; |
134 | 132 | key->dp.size = mp_unsigned_bin_size(prime); |
135 | /* try to find OID in ltc_ecc_sets */ | |
133 | /* try to find OID in ltc_ecc_curves */ | |
136 | 134 | _ecc_oid_lookup(key); |
137 | 135 | /* success */ |
138 | 136 | return CRYPT_OK; |
66 | 66 | |
67 | 67 | /* make up a key and export the public copy */ |
68 | 68 | do { |
69 | if ((err = ecc_set_dp_copy(key, &pubkey)) != CRYPT_OK) { goto errnokey; } | |
69 | if ((err = ecc_copy_dp(key, &pubkey)) != CRYPT_OK) { goto errnokey; } | |
70 | 70 | if ((err = ecc_generate_key(prng, wprng, &pubkey)) != CRYPT_OK) { goto errnokey; } |
71 | 71 | |
72 | 72 | /* find r = x1 mod n */ |
27 | 27 | *high = 0; |
28 | 28 | |
29 | 29 | if (mp_init(&prime) == CRYPT_OK) { |
30 | for (i = 0; ltc_ecc_sets[i].name != NULL; i++) { | |
31 | if (mp_read_radix(prime, ltc_ecc_sets[i].prime, 16) == CRYPT_OK) { | |
30 | for (i = 0; ltc_ecc_curves[i].prime != NULL; i++) { | |
31 | if (mp_read_radix(prime, ltc_ecc_curves[i].prime, 16) == CRYPT_OK) { | |
32 | 32 | size = mp_unsigned_bin_size(prime); |
33 | 33 | if (size < *low) *low = size; |
34 | 34 | if (size > *high) *high = size; |
108 | 108 | if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK) { goto error; } |
109 | 109 | |
110 | 110 | /* find mG and mQ */ |
111 | if ((err = mp_copy(key->dp.base.x, mG->x)) != CRYPT_OK) { goto error; } | |
112 | if ((err = mp_copy(key->dp.base.y, mG->y)) != CRYPT_OK) { goto error; } | |
113 | if ((err = mp_copy(key->dp.base.z, mG->z)) != CRYPT_OK) { goto error; } | |
114 | if ((err = mp_copy(key->pubkey.x, mQ->x)) != CRYPT_OK) { goto error; } | |
115 | if ((err = mp_copy(key->pubkey.y, mQ->y)) != CRYPT_OK) { goto error; } | |
116 | if ((err = mp_copy(key->pubkey.z, mQ->z)) != CRYPT_OK) { goto error; } | |
111 | if ((err = ltc_ecc_copy_point(&key->dp.base, mG)) != CRYPT_OK) { goto error; } | |
112 | if ((err = ltc_ecc_copy_point(&key->pubkey, mQ)) != CRYPT_OK) { goto error; } | |
117 | 113 | |
118 | 114 | /* find the montgomery mp */ |
119 | 115 | if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; } |
30 | 30 | /* load y */ |
31 | 31 | if ((err = mp_read_unsigned_bin(y, (unsigned char *)in+1+size, size)) != CRYPT_OK) { goto cleanup; } |
32 | 32 | } |
33 | else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == size) { | |
34 | /* read compressed point */ | |
33 | else if ((in[0] == 0x02 || in[0] == 0x03) && (inlen-1) == size && ltc_mp.sqrtmod_prime != NULL) { | |
34 | /* read compressed point - BEWARE: requires sqrtmod_prime */ | |
35 | 35 | /* load x */ |
36 | 36 | if ((err = mp_read_unsigned_bin(x, (unsigned char *)in+1, size)) != CRYPT_OK) { goto cleanup; } |
37 | 37 | /* compute x^3 */ |
14 | 14 | * a point at infinity is any point (x,y,0) such that y^2 == x^3, except (0,0,0) |
15 | 15 | */ |
16 | 16 | |
17 | int ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus) | |
17 | int ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus, int *retval) | |
18 | 18 | { |
19 | int err, retval = 0; | |
19 | int err; | |
20 | 20 | void *x3, *y2; |
21 | 21 | |
22 | 22 | /* trivial case */ |
23 | if (!mp_iszero(P->z)) goto done; | |
23 | if (!mp_iszero(P->z)) { | |
24 | *retval = 0; | |
25 | return CRYPT_OK; | |
26 | } | |
24 | 27 | |
25 | 28 | /* point (0,0,0) is not at infinity */ |
26 | if (mp_iszero(P->x) && mp_iszero(P->y)) goto done; | |
29 | if (mp_iszero(P->x) && mp_iszero(P->y)) { | |
30 | *retval = 0; | |
31 | return CRYPT_OK; | |
32 | } | |
27 | 33 | |
28 | 34 | /* initialize */ |
29 | 35 | if ((err = mp_init_multi(&x3, &y2, NULL)) != CRYPT_OK) goto done; |
36 | 42 | if ((err = mp_mulmod(P->x, x3, modulus, x3)) != CRYPT_OK) goto cleanup; |
37 | 43 | |
38 | 44 | /* test y^2 == x^3 */ |
39 | if ((mp_cmp(x3, y2) == LTC_MP_EQ) && !mp_iszero(y2)) retval = 1; | |
45 | err = CRYPT_OK; | |
46 | if ((mp_cmp(x3, y2) == LTC_MP_EQ) && !mp_iszero(y2)) | |
47 | *retval = 1; | |
48 | else | |
49 | *retval = 0; | |
40 | 50 | |
41 | 51 | cleanup: |
42 | 52 | mp_clear_multi(x3, y2, NULL); |
43 | 53 | done: |
44 | return retval; | |
54 | return err; | |
45 | 55 | } |
46 | 56 | |
47 | 57 | #endif |
32 | 32 | LTC_ARGCHK(mp != NULL); |
33 | 33 | |
34 | 34 | if (mp_iszero(P->z)) { |
35 | if ((err = mp_set(P->x, 0)) != CRYPT_OK) { return err; } | |
36 | if ((err = mp_set(P->y, 0)) != CRYPT_OK) { return err; } | |
37 | if ((err = mp_set(P->z, 1)) != CRYPT_OK) { return err; } | |
38 | return CRYPT_OK; | |
35 | return ltc_ecc_set_point_xyz(0, 0, 1, P); | |
39 | 36 | } |
40 | 37 | |
41 | 38 | if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) { |
162 | 162 | if (first == 1) { |
163 | 163 | /* if first, copy from table */ |
164 | 164 | first = 0; |
165 | if ((err = mp_copy(precomp[nA + (nB<<2)]->x, C->x)) != CRYPT_OK) { goto ERR_MU; } | |
166 | if ((err = mp_copy(precomp[nA + (nB<<2)]->y, C->y)) != CRYPT_OK) { goto ERR_MU; } | |
167 | if ((err = mp_copy(precomp[nA + (nB<<2)]->z, C->z)) != CRYPT_OK) { goto ERR_MU; } | |
165 | if ((err = ltc_ecc_copy_point(precomp[nA + (nB<<2)], C)) != CRYPT_OK) { goto ERR_MU; } | |
168 | 166 | } else { |
169 | 167 | /* if not first, add from table */ |
170 | 168 | if ((err = ltc_mp.ecc_ptadd(C, precomp[nA + (nB<<2)], C, ma, modulus, mp)) != CRYPT_OK) { goto ERR_MU; } |
31 | 31 | int ltc_ecc_mulmod(void *k, const ecc_point *G, ecc_point *R, void *a, void *modulus, int map) |
32 | 32 | { |
33 | 33 | ecc_point *tG, *M[8]; |
34 | int i, j, err; | |
34 | int i, j, err, inf; | |
35 | 35 | void *mp = NULL, *mu = NULL, *ma = NULL, *a_plus3 = NULL; |
36 | 36 | ltc_mp_digit buf; |
37 | 37 | int first, bitbuf, bitcpy, bitcnt, mode, digidx; |
41 | 41 | LTC_ARGCHK(R != NULL); |
42 | 42 | LTC_ARGCHK(modulus != NULL); |
43 | 43 | |
44 | if (ltc_ecc_is_point_at_infinity(G, modulus)) { | |
44 | if ((err = ltc_ecc_is_point_at_infinity(G, modulus, &inf)) != CRYPT_OK) return err; | |
45 | if (inf) { | |
45 | 46 | /* return the point at infinity */ |
46 | if ((err = mp_set(R->x, 1)) != CRYPT_OK) { return err; } | |
47 | if ((err = mp_set(R->y, 1)) != CRYPT_OK) { return err; } | |
48 | if ((err = mp_set(R->z, 0)) != CRYPT_OK) { return err; } | |
49 | return CRYPT_OK; | |
47 | return ltc_ecc_set_point_xyz(1, 1, 0, R); | |
50 | 48 | } |
51 | 49 | |
52 | 50 | /* init montgomery reduction */ |
80 | 78 | |
81 | 79 | /* tG = G and convert to montgomery */ |
82 | 80 | if (mp_cmp_d(mu, 1) == LTC_MP_EQ) { |
83 | if ((err = mp_copy(G->x, tG->x)) != CRYPT_OK) { goto done; } | |
84 | if ((err = mp_copy(G->y, tG->y)) != CRYPT_OK) { goto done; } | |
85 | if ((err = mp_copy(G->z, tG->z)) != CRYPT_OK) { goto done; } | |
81 | if ((err = ltc_ecc_copy_point(G, tG)) != CRYPT_OK) { goto done; } | |
86 | 82 | } else { |
87 | 83 | if ((err = mp_mulmod(G->x, mu, modulus, tG->x)) != CRYPT_OK) { goto done; } |
88 | 84 | if ((err = mp_mulmod(G->y, mu, modulus, tG->y)) != CRYPT_OK) { goto done; } |
145 | 141 | /* if this is the first window we do a simple copy */ |
146 | 142 | if (first == 1) { |
147 | 143 | /* R = kG [k = first window] */ |
148 | if ((err = mp_copy(M[bitbuf-8]->x, R->x)) != CRYPT_OK) { goto done; } | |
149 | if ((err = mp_copy(M[bitbuf-8]->y, R->y)) != CRYPT_OK) { goto done; } | |
150 | if ((err = mp_copy(M[bitbuf-8]->z, R->z)) != CRYPT_OK) { goto done; } | |
144 | if ((err = ltc_ecc_copy_point(M[bitbuf-8], R)) != CRYPT_OK) { goto done; } | |
151 | 145 | first = 0; |
152 | 146 | } else { |
153 | 147 | /* normal window */ |
179 | 173 | if ((bitbuf & (1 << WINSIZE)) != 0) { |
180 | 174 | if (first == 1){ |
181 | 175 | /* first add, so copy */ |
182 | if ((err = mp_copy(tG->x, R->x)) != CRYPT_OK) { goto done; } | |
183 | if ((err = mp_copy(tG->y, R->y)) != CRYPT_OK) { goto done; } | |
184 | if ((err = mp_copy(tG->z, R->z)) != CRYPT_OK) { goto done; } | |
176 | if ((err = ltc_ecc_copy_point(tG, R)) != CRYPT_OK) { goto done; } | |
185 | 177 | first = 0; |
186 | 178 | } else { |
187 | 179 | /* then add */ |
30 | 30 | int ltc_ecc_mulmod(void *k, const ecc_point *G, ecc_point *R, void *a, void *modulus, int map) |
31 | 31 | { |
32 | 32 | ecc_point *tG, *M[3]; |
33 | int i, j, err; | |
33 | int i, j, err, inf; | |
34 | 34 | void *mp = NULL, *mu = NULL, *ma = NULL, *a_plus3 = NULL; |
35 | 35 | ltc_mp_digit buf; |
36 | 36 | int bitcnt, mode, digidx; |
40 | 40 | LTC_ARGCHK(R != NULL); |
41 | 41 | LTC_ARGCHK(modulus != NULL); |
42 | 42 | |
43 | if (ltc_ecc_is_point_at_infinity(G, modulus)) { | |
43 | if ((err = ltc_ecc_is_point_at_infinity(G, modulus, &inf)) != CRYPT_OK) return err; | |
44 | if (inf) { | |
44 | 45 | /* return the point at infinity */ |
45 | if ((err = mp_set(R->x, 1)) != CRYPT_OK) { return err; } | |
46 | if ((err = mp_set(R->y, 1)) != CRYPT_OK) { return err; } | |
47 | if ((err = mp_set(R->z, 0)) != CRYPT_OK) { return err; } | |
48 | return CRYPT_OK; | |
46 | return ltc_ecc_set_point_xyz(1, 1, 0, R); | |
49 | 47 | } |
50 | 48 | |
51 | 49 | /* init montgomery reduction */ |
87 | 85 | |
88 | 86 | /* calc the M tab */ |
89 | 87 | /* M[0] == G */ |
90 | if ((err = mp_copy(tG->x, M[0]->x)) != CRYPT_OK) { goto done; } | |
91 | if ((err = mp_copy(tG->y, M[0]->y)) != CRYPT_OK) { goto done; } | |
92 | if ((err = mp_copy(tG->z, M[0]->z)) != CRYPT_OK) { goto done; } | |
88 | if ((err = ltc_ecc_copy_point(tG, M[0])) != CRYPT_OK) { goto done; } | |
93 | 89 | /* M[1] == 2G */ |
94 | 90 | if ((err = ltc_mp.ecc_ptdbl(tG, M[1], ma, modulus, mp)) != CRYPT_OK) { goto done; } |
95 | 91 | |
135 | 131 | } |
136 | 132 | |
137 | 133 | /* copy result out */ |
138 | if ((err = mp_copy(M[0]->x, R->x)) != CRYPT_OK) { goto done; } | |
139 | if ((err = mp_copy(M[0]->y, R->y)) != CRYPT_OK) { goto done; } | |
140 | if ((err = mp_copy(M[0]->z, R->z)) != CRYPT_OK) { goto done; } | |
134 | if ((err = ltc_ecc_copy_point(M[0], R)) != CRYPT_OK) { goto done; } | |
141 | 135 | |
142 | 136 | /* map R back from projective space */ |
143 | 137 | if (map) { |
45 | 45 | } |
46 | 46 | } |
47 | 47 | |
48 | int ltc_ecc_set_point_xyz(ltc_mp_digit x, ltc_mp_digit y, ltc_mp_digit z, ecc_point *p) | |
49 | { | |
50 | int err; | |
51 | if ((err = ltc_mp.set_int(p->x, x)) != CRYPT_OK) return err; | |
52 | if ((err = ltc_mp.set_int(p->y, y)) != CRYPT_OK) return err; | |
53 | if ((err = ltc_mp.set_int(p->z, z)) != CRYPT_OK) return err; | |
54 | return CRYPT_OK; | |
55 | } | |
56 | ||
57 | int ltc_ecc_copy_point(const ecc_point *src, ecc_point *dst) | |
58 | { | |
59 | int err; | |
60 | if ((err = ltc_mp.copy(src->x, dst->x)) != CRYPT_OK) return err; | |
61 | if ((err = ltc_mp.copy(src->y, dst->y)) != CRYPT_OK) return err; | |
62 | if ((err = ltc_mp.copy(src->z, dst->z)) != CRYPT_OK) return err; | |
63 | return CRYPT_OK; | |
64 | } | |
65 | ||
48 | 66 | #endif |
49 | 67 | /* ref: $Format:%D$ */ |
50 | 68 | /* git commit: $Format:%H$ */ |
28 | 28 | int ltc_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_point *R, void *ma, void *modulus, void *mp) |
29 | 29 | { |
30 | 30 | void *t1, *t2, *x, *y, *z; |
31 | int err; | |
31 | int err, inf; | |
32 | 32 | |
33 | 33 | LTC_ARGCHK(P != NULL); |
34 | 34 | LTC_ARGCHK(Q != NULL); |
40 | 40 | return err; |
41 | 41 | } |
42 | 42 | |
43 | if (ltc_ecc_is_point_at_infinity(P, modulus)) { | |
43 | if ((err = ltc_ecc_is_point_at_infinity(P, modulus, &inf)) != CRYPT_OK) return err; | |
44 | if (inf) { | |
44 | 45 | /* P is point at infinity >> Result = Q */ |
45 | if ((err = ltc_mp.copy(Q->x, R->x)) != CRYPT_OK) { goto done; } | |
46 | if ((err = ltc_mp.copy(Q->y, R->y)) != CRYPT_OK) { goto done; } | |
47 | if ((err = ltc_mp.copy(Q->z, R->z)) != CRYPT_OK) { goto done; } | |
48 | goto done; /* CRYPT_OK */ | |
49 | } | |
50 | ||
51 | if (ltc_ecc_is_point_at_infinity(Q, modulus)) { | |
46 | err = ltc_ecc_copy_point(Q, R); | |
47 | goto done; | |
48 | } | |
49 | ||
50 | if ((err = ltc_ecc_is_point_at_infinity(Q, modulus, &inf)) != CRYPT_OK) return err; | |
51 | if (inf) { | |
52 | 52 | /* Q is point at infinity >> Result = P */ |
53 | if ((err = ltc_mp.copy(P->x, R->x)) != CRYPT_OK) { goto done; } | |
54 | if ((err = ltc_mp.copy(P->y, R->y)) != CRYPT_OK) { goto done; } | |
55 | if ((err = ltc_mp.copy(P->z, R->z)) != CRYPT_OK) { goto done; } | |
56 | goto done; /* CRYPT_OK */ | |
53 | err = ltc_ecc_copy_point(P, R); | |
54 | goto done; | |
57 | 55 | } |
58 | 56 | |
59 | 57 | if ((mp_cmp(P->x, Q->x) == LTC_MP_EQ) && (mp_cmp(P->z, Q->z) == LTC_MP_EQ)) { |
65 | 63 | if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; } |
66 | 64 | if (mp_cmp(P->y, t1) == LTC_MP_EQ) { |
67 | 65 | /* here Q = -P >>> Result = the point at infinity */ |
68 | if ((err = ltc_mp.set_int(R->x, 1)) != CRYPT_OK) { goto done; } | |
69 | if ((err = ltc_mp.set_int(R->y, 1)) != CRYPT_OK) { goto done; } | |
70 | if ((err = ltc_mp.set_int(R->z, 0)) != CRYPT_OK) { goto done; } | |
71 | goto done; /* CRYPT_OK */ | |
66 | err = ltc_ecc_set_point_xyz(1, 1, 0, R); | |
67 | goto done; | |
72 | 68 | } |
73 | 69 | } |
74 | 70 |
45 | 45 | int ltc_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, void *modulus, void *mp) |
46 | 46 | { |
47 | 47 | void *t1, *t2; |
48 | int err; | |
48 | int err, inf; | |
49 | 49 | |
50 | 50 | LTC_ARGCHK(P != NULL); |
51 | 51 | LTC_ARGCHK(R != NULL); |
57 | 57 | } |
58 | 58 | |
59 | 59 | if (P != R) { |
60 | if ((err = mp_copy(P->x, R->x)) != CRYPT_OK) { goto done; } | |
61 | if ((err = mp_copy(P->y, R->y)) != CRYPT_OK) { goto done; } | |
62 | if ((err = mp_copy(P->z, R->z)) != CRYPT_OK) { goto done; } | |
60 | if ((err = ltc_ecc_copy_point(P, R)) != CRYPT_OK) { goto done; } | |
63 | 61 | } |
64 | 62 | |
65 | if (ltc_ecc_is_point_at_infinity(P, modulus)) { | |
63 | if ((err = ltc_ecc_is_point_at_infinity(P, modulus, &inf)) != CRYPT_OK) return err; | |
64 | if (inf) { | |
66 | 65 | /* if P is point at infinity >> Result = point at infinity */ |
67 | if ((err = ltc_mp.set_int(R->x, 1)) != CRYPT_OK) { goto done; } | |
68 | if ((err = ltc_mp.set_int(R->y, 1)) != CRYPT_OK) { goto done; } | |
69 | if ((err = ltc_mp.set_int(R->z, 0)) != CRYPT_OK) { goto done; } | |
70 | goto done; /* CRYPT_OK */ | |
66 | err = ltc_ecc_set_point_xyz(1, 1, 0, R); | |
67 | goto done; | |
71 | 68 | } |
72 | 69 | |
73 | 70 | /* t1 = Z * Z */ |
20 | 20 | |
21 | 21 | int ltc_ecc_verify_key(ecc_key *key) |
22 | 22 | { |
23 | int err; | |
23 | int err, inf; | |
24 | 24 | void *prime = NULL; |
25 | 25 | void *order = NULL; |
26 | 26 | void *a = NULL; |
51 | 51 | point = ltc_ecc_new_point(); |
52 | 52 | if ((err = ltc_ecc_mulmod(order, &(key->pubkey), point, a, prime, 1)) != CRYPT_OK) { goto done1; } |
53 | 53 | |
54 | if (ltc_ecc_is_point_at_infinity(point, prime)) { | |
54 | err = ltc_ecc_is_point_at_infinity(point, prime, &inf); | |
55 | if (err != CRYPT_OK || inf) { | |
55 | 56 | err = CRYPT_ERROR; |
56 | 57 | } |
57 | 58 | else { |