-
Notifications
You must be signed in to change notification settings - Fork 68
/
Copy pathfp_rand.c
57 lines (47 loc) · 1.15 KB
/
fp_rand.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/* TomsFastMath, a fast ISO C bignum library. -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
#include <tfm_private.h>
#ifdef FP_GEN_RANDOM
#if FP_GEN_RANDOM_MAX == 0xffffffff
#define FP_GEN_RANDOM_SHIFT 32
#elif FP_GEN_RANDOM_MAX == 32767
/* SHRT_MAX */
#define FP_GEN_RANDOM_SHIFT 15
#elif FP_GEN_RANDOM_MAX == 2147483647
/* INT_MAX */
#define FP_GEN_RANDOM_SHIFT 31
#elif !defined(FP_GEN_RANDOM_SHIFT)
#error Thou shalt define their own valid FP_GEN_RANDOM_SHIFT
#endif
/* makes a pseudo-random int of a given size */
static fp_digit fp_gen_random(void)
{
fp_digit d = 0, msk = 0;
do {
d <<= FP_GEN_RANDOM_SHIFT;
d |= ((fp_digit) FP_GEN_RANDOM());
msk <<= FP_GEN_RANDOM_SHIFT;
msk |= FP_GEN_RANDOM_MAX;
} while ((FP_MASK & msk) != FP_MASK);
d &= FP_MASK;
return d;
}
void fp_rand(fp_int *a, int digits)
{
fp_digit d;
fp_zero(a);
if (digits <= 0) {
return;
}
/* first place a random non-zero digit */
do {
d = fp_gen_random();
} while (d == 0);
fp_add_d (a, d, a);
while (--digits > 0) {
fp_lshd (a, 1);
fp_add_d (a, fp_gen_random(), a);
}
return;
}
#endif