1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis */
2 /* SPDX-License-Identifier: Unlicense */
3 #include "tomcrypt_private.h"
4
5 #if defined(LTC_MDSA) || defined(LTC_MECC)
6 /**
7 Generate a random number N with given bitlength (note: MSB can be 0)
8 */
9
rand_bn_bits(void * N,int bits,prng_state * prng,int wprng)10 int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng)
11 {
12 int res, bytes;
13 unsigned char *buf, mask;
14
15 LTC_ARGCHK(N != NULL);
16 LTC_ARGCHK(bits > 1);
17
18 /* check PRNG */
19 if ((res = prng_is_valid(wprng)) != CRYPT_OK) return res;
20
21 bytes = (bits+7) >> 3;
22 mask = 0xff >> (bits % 8 == 0 ? 0 : 8 - bits % 8);
23
24 /* allocate buffer */
25 if ((buf = XCALLOC(1, bytes)) == NULL) return CRYPT_MEM;
26
27 /* generate random bytes */
28 if (prng_descriptor[wprng]->read(buf, bytes, prng) != (unsigned long)bytes) {
29 res = CRYPT_ERROR_READPRNG;
30 goto cleanup;
31 }
32 /* mask bits */
33 buf[0] &= mask;
34 /* load value */
35 if ((res = mp_read_unsigned_bin(N, buf, bytes)) != CRYPT_OK) goto cleanup;
36
37 res = CRYPT_OK;
38
39 cleanup:
40 #ifdef LTC_CLEAN_STACK
41 zeromem(buf, bytes);
42 #endif
43 XFREE(buf);
44 return res;
45 }
46
47 /**
48 Generate a random number N in a range: 1 <= N < limit
49 */
rand_bn_upto(void * N,void * limit,prng_state * prng,int wprng)50 int rand_bn_upto(void *N, void *limit, prng_state *prng, int wprng)
51 {
52 int res, bits;
53
54 LTC_ARGCHK(N != NULL);
55 LTC_ARGCHK(limit != NULL);
56
57 bits = mp_count_bits(limit);
58 do {
59 res = rand_bn_bits(N, bits, prng, wprng);
60 if (res != CRYPT_OK) return res;
61 } while (mp_cmp_d(N, 0) != LTC_MP_GT || mp_cmp(N, limit) != LTC_MP_LT);
62
63 return CRYPT_OK;
64 }
65 #endif
66