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