1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 
4 #include "tomcrypt_private.h"
5 
6 /* origin of this code - OLPC */
7 
8 #ifdef LTC_MECC
9 
10 /**
11   Verify a key according to ANSI spec
12   @param key     The key to validate
13   @return CRYPT_OK if successful
14 */
15 
ltc_ecc_verify_key(const ecc_key * key)16 int ltc_ecc_verify_key(const ecc_key *key)
17 {
18    int err, inf;
19    ecc_point *point;
20    void *prime = key->dp.prime;
21    void *order = key->dp.order;
22    void *a     = key->dp.A;
23 
24    /* Test 1: Are the x and y points of the public key in the field? */
25    if (ltc_mp.compare_d(key->pubkey.z, 1) == LTC_MP_EQ) {
26       if ((ltc_mp.compare(key->pubkey.x, prime) != LTC_MP_LT) ||
27           (ltc_mp.compare(key->pubkey.y, prime) != LTC_MP_LT) ||
28           (ltc_mp.compare_d(key->pubkey.x, 0) == LTC_MP_LT) ||
29           (ltc_mp.compare_d(key->pubkey.y, 0) == LTC_MP_LT) ||
30           (mp_iszero(key->pubkey.x) && mp_iszero(key->pubkey.y))
31          )
32       {
33          err = CRYPT_INVALID_PACKET;
34          goto done2;
35       }
36    }
37 
38    /* Test 2: is the public key on the curve? */
39    if ((err = ltc_ecc_is_point(&key->dp, key->pubkey.x, key->pubkey.y)) != CRYPT_OK)      { goto done2; }
40 
41    /* Test 3: does nG = O? (n = order, O = point at infinity, G = public key) */
42    point = ltc_ecc_new_point();
43    if ((err = ltc_ecc_mulmod(order, &(key->pubkey), point, a, prime, 1)) != CRYPT_OK)     { goto done1; }
44 
45    err = ltc_ecc_is_point_at_infinity(point, prime, &inf);
46    if (err != CRYPT_OK || inf) {
47       err = CRYPT_ERROR;
48    }
49    else {
50       err = CRYPT_OK;
51    }
52 
53 done1:
54    ltc_ecc_del_point(point);
55 done2:
56    return err;
57 }
58 
59 #endif
60