// SPDX-License-Identifier: BSD-2-Clause /* LibTomCrypt, modular cryptographic library -- Tom St Denis * * LibTomCrypt is a library that provides various cryptographic * algorithms in a highly modular and flexible manner. * * The library is free for all purposes without any express * guarantee it works. */ #include "tomcrypt_private.h" #ifdef LTC_MECC static int _ecc_cmp_hex_bn(const char *left_hex, void *right_bn, void *tmp_bn) { if (mp_read_radix(tmp_bn, left_hex, 16) != CRYPT_OK) return 0; if (mp_cmp(tmp_bn, right_bn) != LTC_MP_EQ) return 0; return 1; } static void _ecc_oid_lookup(ecc_key *key) { void *bn; const ltc_ecc_curve *curve; key->dp.oidlen = 0; if (mp_init(&bn) != CRYPT_OK) return; for (curve = ltc_ecc_curves; curve->prime != NULL; curve++) { if (_ecc_cmp_hex_bn(curve->prime, key->dp.prime, bn) != 1) continue; if (_ecc_cmp_hex_bn(curve->order, key->dp.order, bn) != 1) continue; if (_ecc_cmp_hex_bn(curve->A, key->dp.A, bn) != 1) continue; if (_ecc_cmp_hex_bn(curve->B, key->dp.B, bn) != 1) continue; if (_ecc_cmp_hex_bn(curve->Gx, key->dp.base.x, bn) != 1) continue; if (_ecc_cmp_hex_bn(curve->Gy, key->dp.base.y, bn) != 1) continue; if (key->dp.cofactor != curve->cofactor) continue; break; /* found */ } mp_clear(bn); if (curve->prime && curve->OID) { key->dp.oidlen = 16; /* size of key->dp.oid */ pk_oid_str_to_num(curve->OID, key->dp.oid, &key->dp.oidlen); } } int ecc_copy_curve(const ecc_key *srckey, ecc_key *key) { unsigned long i; int err; LTC_ARGCHK(key != NULL); LTC_ARGCHK(srckey != NULL); if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B, &key->dp.base.x, &key->dp.base.y, &key->dp.base.z, &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL)) != CRYPT_OK) { return err; } /* A, B, order, prime, Gx, Gy */ if ((err = mp_copy(srckey->dp.prime, key->dp.prime )) != CRYPT_OK) { goto error; } if ((err = mp_copy(srckey->dp.order, key->dp.order )) != CRYPT_OK) { goto error; } if ((err = mp_copy(srckey->dp.A, key->dp.A )) != CRYPT_OK) { goto error; } if ((err = mp_copy(srckey->dp.B, key->dp.B )) != CRYPT_OK) { goto error; } if ((err = ltc_ecc_copy_point(&srckey->dp.base, &key->dp.base)) != CRYPT_OK) { goto error; } /* cofactor & size */ key->dp.cofactor = srckey->dp.cofactor; key->dp.size = srckey->dp.size; /* OID */ if (srckey->dp.oidlen > 0) { key->dp.oidlen = srckey->dp.oidlen; for (i = 0; i < key->dp.oidlen; i++) key->dp.oid[i] = srckey->dp.oid[i]; } else { _ecc_oid_lookup(key); /* try to find OID in ltc_ecc_curves */ } /* success */ return CRYPT_OK; error: ecc_free(key); return err; } int ecc_set_curve_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key) { int err; LTC_ARGCHK(key != NULL); LTC_ARGCHK(a != NULL); LTC_ARGCHK(b != NULL); LTC_ARGCHK(prime != NULL); LTC_ARGCHK(order != NULL); LTC_ARGCHK(gx != NULL); LTC_ARGCHK(gy != NULL); if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B, &key->dp.base.x, &key->dp.base.y, &key->dp.base.z, &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, NULL)) != CRYPT_OK) { return err; } /* A, B, order, prime, Gx, Gy */ if ((err = mp_copy(prime, key->dp.prime )) != CRYPT_OK) { goto error; } if ((err = mp_copy(order, key->dp.order )) != CRYPT_OK) { goto error; } if ((err = mp_copy(a, key->dp.A )) != CRYPT_OK) { goto error; } if ((err = mp_copy(b, key->dp.B )) != CRYPT_OK) { goto error; } if ((err = mp_copy(gx, key->dp.base.x)) != CRYPT_OK) { goto error; } if ((err = mp_copy(gy, key->dp.base.y)) != CRYPT_OK) { goto error; } if ((err = mp_set(key->dp.base.z, 1)) != CRYPT_OK) { goto error; } /* cofactor & size */ key->dp.cofactor = cofactor; key->dp.size = mp_unsigned_bin_size(prime); /* try to find OID in ltc_ecc_curves */ _ecc_oid_lookup(key); /* success */ return CRYPT_OK; error: ecc_free(key); return err; } #endif /* ref: $Format:%D$ */ /* git commit: $Format:%H$ */ /* commit time: $Format:%ai$ */