/* LibTomCrypt, modular cryptographic library -- Tom St Denis */ /* SPDX-License-Identifier: Unlicense */ #include "tomcrypt_private.h" /* origin of this code - OLPC */ #ifdef LTC_MECC /** Verify a key according to ANSI spec @param key The key to validate @return CRYPT_OK if successful */ int ltc_ecc_verify_key(const ecc_key *key) { int err, inf; ecc_point *point; void *prime = key->dp.prime; void *order = key->dp.order; void *a = key->dp.A; /* Test 1: Are the x and y points of the public key in the field? */ if (ltc_mp.compare_d(key->pubkey.z, 1) == LTC_MP_EQ) { if ((ltc_mp.compare(key->pubkey.x, prime) != LTC_MP_LT) || (ltc_mp.compare(key->pubkey.y, prime) != LTC_MP_LT) || (ltc_mp.compare_d(key->pubkey.x, 0) == LTC_MP_LT) || (ltc_mp.compare_d(key->pubkey.y, 0) == LTC_MP_LT) || (ltc_mp_iszero(key->pubkey.x) && ltc_mp_iszero(key->pubkey.y)) ) { err = CRYPT_INVALID_PACKET; goto done2; } } /* Test 2: is the public key on the curve? */ if ((err = ltc_ecc_is_point(&key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK) { goto done2; } /* Test 3: does nG = O? (n = order, O = point at infinity, G = public key) */ point = ltc_ecc_new_point(); if ((err = ltc_ecc_mulmod(order, &(key->pubkey), point, a, prime, 1)) != CRYPT_OK) { goto done1; } err = ltc_ecc_is_point_at_infinity(point, prime, &inf); if (err != CRYPT_OK || inf) { err = CRYPT_ERROR; } else { err = CRYPT_OK; } done1: ltc_ecc_del_point(point); done2: return err; } #endif