1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3
4 #include "tomcrypt_private.h"
5
6 #ifdef LTC_MECC
7
s_ecc_cmp_hex_bn(const char * left_hex,void * right_bn,void * tmp_bn)8 static int s_ecc_cmp_hex_bn(const char *left_hex, void *right_bn, void *tmp_bn)
9 {
10 if (mp_read_radix(tmp_bn, left_hex, 16) != CRYPT_OK) return 0;
11 if (mp_cmp(tmp_bn, right_bn) != LTC_MP_EQ) return 0;
12 return 1;
13 }
14
s_ecc_oid_lookup(ecc_key * key)15 static void s_ecc_oid_lookup(ecc_key *key)
16 {
17 void *bn;
18 const ltc_ecc_curve *curve;
19
20 key->dp.oidlen = 0;
21 if (mp_init(&bn) != CRYPT_OK) return;
22 for (curve = ltc_ecc_curves; curve->prime != NULL; curve++) {
23 if (s_ecc_cmp_hex_bn(curve->prime, key->dp.prime, bn) != 1) continue;
24 if (s_ecc_cmp_hex_bn(curve->order, key->dp.order, bn) != 1) continue;
25 if (s_ecc_cmp_hex_bn(curve->A, key->dp.A, bn) != 1) continue;
26 if (s_ecc_cmp_hex_bn(curve->B, key->dp.B, bn) != 1) continue;
27 if (s_ecc_cmp_hex_bn(curve->Gx, key->dp.base.x, bn) != 1) continue;
28 if (s_ecc_cmp_hex_bn(curve->Gy, key->dp.base.y, bn) != 1) continue;
29 if (key->dp.cofactor != curve->cofactor) continue;
30 break; /* found */
31 }
32 mp_clear(bn);
33 if (curve->prime && curve->OID) {
34 key->dp.oidlen = 16; /* size of key->dp.oid */
35 pk_oid_str_to_num(curve->OID, key->dp.oid, &key->dp.oidlen);
36 }
37 }
38
ecc_copy_curve(const ecc_key * srckey,ecc_key * key)39 int ecc_copy_curve(const ecc_key *srckey, ecc_key *key)
40 {
41 unsigned long i;
42 int err;
43
44 LTC_ARGCHK(key != NULL);
45 LTC_ARGCHK(srckey != NULL);
46
47 if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B,
48 &key->dp.base.x, &key->dp.base.y, &key->dp.base.z,
49 &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k,
50 NULL)) != CRYPT_OK) {
51 return err;
52 }
53
54 /* A, B, order, prime, Gx, Gy */
55 if ((err = mp_copy(srckey->dp.prime, key->dp.prime )) != CRYPT_OK) { goto error; }
56 if ((err = mp_copy(srckey->dp.order, key->dp.order )) != CRYPT_OK) { goto error; }
57 if ((err = mp_copy(srckey->dp.A, key->dp.A )) != CRYPT_OK) { goto error; }
58 if ((err = mp_copy(srckey->dp.B, key->dp.B )) != CRYPT_OK) { goto error; }
59 if ((err = ltc_ecc_copy_point(&srckey->dp.base, &key->dp.base)) != CRYPT_OK) { goto error; }
60 /* cofactor & size */
61 key->dp.cofactor = srckey->dp.cofactor;
62 key->dp.size = srckey->dp.size;
63 /* OID */
64 if (srckey->dp.oidlen > 0) {
65 key->dp.oidlen = srckey->dp.oidlen;
66 for (i = 0; i < key->dp.oidlen; i++) key->dp.oid[i] = srckey->dp.oid[i];
67 }
68 else {
69 s_ecc_oid_lookup(key); /* try to find OID in ltc_ecc_curves */
70 }
71 /* success */
72 return CRYPT_OK;
73
74 error:
75 ecc_free(key);
76 return err;
77 }
78
ecc_set_curve_from_mpis(void * a,void * b,void * prime,void * order,void * gx,void * gy,unsigned long cofactor,ecc_key * key)79 int ecc_set_curve_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key)
80 {
81 int err;
82
83 LTC_ARGCHK(key != NULL);
84 LTC_ARGCHK(a != NULL);
85 LTC_ARGCHK(b != NULL);
86 LTC_ARGCHK(prime != NULL);
87 LTC_ARGCHK(order != NULL);
88 LTC_ARGCHK(gx != NULL);
89 LTC_ARGCHK(gy != NULL);
90
91 if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B,
92 &key->dp.base.x, &key->dp.base.y, &key->dp.base.z,
93 &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k,
94 NULL)) != CRYPT_OK) {
95 return err;
96 }
97
98 /* A, B, order, prime, Gx, Gy */
99 if ((err = mp_copy(prime, key->dp.prime )) != CRYPT_OK) { goto error; }
100 if ((err = mp_copy(order, key->dp.order )) != CRYPT_OK) { goto error; }
101 if ((err = mp_copy(a, key->dp.A )) != CRYPT_OK) { goto error; }
102 if ((err = mp_copy(b, key->dp.B )) != CRYPT_OK) { goto error; }
103 if ((err = mp_copy(gx, key->dp.base.x)) != CRYPT_OK) { goto error; }
104 if ((err = mp_copy(gy, key->dp.base.y)) != CRYPT_OK) { goto error; }
105 if ((err = mp_set(key->dp.base.z, 1)) != CRYPT_OK) { goto error; }
106 /* cofactor & size */
107 key->dp.cofactor = cofactor;
108 key->dp.size = mp_unsigned_bin_size(prime);
109 /* try to find OID in ltc_ecc_curves */
110 s_ecc_oid_lookup(key);
111 /* success */
112 return CRYPT_OK;
113
114 error:
115 ecc_free(key);
116 return err;
117 }
118
119 #endif
120