Codebase list libcryptx-perl / 4c27d16
ECC key pair generation according to FIPS-186-4 Karel Miko 10 years ago
3 changed file(s) with 83 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
66 };
77
88 int rand_prime(void *N, long len, prng_state *prng, int wprng);
9 int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng);
10 int rand_bn_range(void *N, void *limit, prng_state *prng, int wprng);
911
1012 enum {
1113 PKA_RSA,
0 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
1 *
2 * LibTomCrypt is a library that provides various cryptographic
3 * algorithms in a highly modular and flexible manner.
4 *
5 * The library is free for all purposes without any express
6 * guarantee it works.
7 *
8 */
9 #include "tomcrypt.h"
10
11 /**
12 Generate a random number N with given bitlength (note: MSB can be 0)
13 */
14
15 int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng)
16 {
17 int res, bytes;
18 unsigned char *buf, mask;
19
20 LTC_ARGCHK(N != NULL);
21 LTC_ARGCHK(bits > 1);
22
23 /* check PRNG */
24 if ((res = prng_is_valid(wprng)) != CRYPT_OK) return res;
25
26 bytes = (bits+7) >> 3;
27 mask = 0xff << (8 - bits % 8);
28
29 /* allocate buffer */
30 if ((buf = XCALLOC(1, bytes)) == NULL) return CRYPT_MEM;
31
32 /* generate random bytes */
33 if (prng_descriptor[wprng].read(buf, bytes, prng) != (unsigned long)bytes) {
34 res = CRYPT_ERROR_READPRNG;
35 goto cleanup;
36 }
37 /* mask bits */
38 buf[0] &= ~mask;
39 /* load value */
40 if ((res = mp_read_unsigned_bin(N, buf, bytes)) != CRYPT_OK) goto cleanup;
41
42 res = CRYPT_OK;
43
44 cleanup:
45 #ifdef LTC_CLEAN_STACK
46 zeromem(buf, len);
47 #endif
48 XFREE(buf);
49 return res;
50 }
51
52 /**
53 Generate a random number N in a range: 0 <= N < limit
54 */
55 int rand_bn_range(void *N, void *limit, prng_state *prng, int wprng)
56 {
57 int res;
58
59 LTC_ARGCHK(N != NULL);
60 LTC_ARGCHK(limit != NULL);
61
62 do {
63 res = rand_bn_bits(N, mp_count_bits(limit), prng, wprng);
64 if (res != CRYPT_OK) return res;
65 } while (mp_cmp(N, limit) != LTC_MP_LT);
66
67 return CRYPT_OK;
68 }
9696 if ((err = mp_set(base->z, 1)) != CRYPT_OK) { goto errkey; }
9797 if ((err = mp_read_unsigned_bin(key->k, (unsigned char *)buf, keysize)) != CRYPT_OK) { goto errkey; }
9898
99 /* the key should be smaller than the order of base point */
100 if (mp_cmp(key->k, order) != LTC_MP_LT) {
101 if((err = mp_mod(key->k, order, key->k)) != CRYPT_OK) { goto errkey; }
102 }
99 /* ECC key pair generation according to FIPS-186-4 (B.4.2 Key Pair Generation by Testing Candidates):
100 * the generated private key k should be the range [1, order–1]
101 * a/ N = bitlen(order)
102 * b/ generate N random bits and convert them into big integer k
103 * c/ if k not in [1, order-1] go to b/
104 * e/ Q = k*G
105 */
106 do {
107 /* generate random k: 0 <= k < order */
108 if ((err = rand_bn_range(key->k, order, prng, wprng)) != CRYPT_OK) { goto errkey; }
109 } while (mp_iszero(key->k));
110
103111 /* make the public key */
104112 if ((err = mp_read_radix(a, (char *)key->dp->A, 16)) != CRYPT_OK) { goto errkey; }
105113 if ((err = ltc_mp.ecc_ptmul(key->k, base, &key->pubkey, a, prime, 1)) != CRYPT_OK) { goto errkey; }