1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 
4 #include "tomcrypt_private.h"
5 
6 #ifdef LTC_MDH
7 
8 /**
9   Check DH public key (INTERNAL ONLY, not part of public API)
10   @param key    The key you wish to test
11   @return CRYPT_OK if successful
12 */
dh_check_pubkey(const dh_key * key)13 int dh_check_pubkey(const dh_key *key)
14 {
15    void *p_minus1;
16    ltc_mp_digit digit;
17    int i, digit_count, bits_set = 0, err;
18 
19    LTC_ARGCHK(key != NULL);
20 
21    if ((err = mp_init(&p_minus1)) != CRYPT_OK) {
22       return err;
23    }
24 
25    /* avoid: y <= 1 OR y >= p-1 */
26    if ((err = mp_sub_d(key->prime, 1, p_minus1)) != CRYPT_OK) {
27       goto error;
28    }
29    if (mp_cmp(key->y, p_minus1) != LTC_MP_LT || mp_cmp_d(key->y, 1) != LTC_MP_GT) {
30       err = CRYPT_INVALID_ARG;
31       goto error;
32    }
33 
34    /* public key must have more than one bit set */
35    digit_count = mp_get_digit_count(key->y);
36    for (i = 0; i < digit_count && bits_set < 2; i++) {
37       digit = mp_get_digit(key->y, i);
38       while (digit > 0) {
39          if (digit & 1) bits_set++;
40          digit >>= 1;
41       }
42    }
43    if (bits_set > 1) {
44       err = CRYPT_OK;
45    }
46    else {
47       err = CRYPT_INVALID_ARG;
48    }
49 
50 error:
51    mp_clear(p_minus1);
52    return err;
53 }
54 
55 #endif /* LTC_MDH */
56