16
16
#include "util.h"
17
17
18
18
static uint64_t secp256k1_test_state [4 ];
19
- static uint64_t secp256k1_test_rng_integer ;
20
- static int secp256k1_test_rng_integer_bits_left = 0 ;
21
19
22
20
SECP256K1_INLINE static void secp256k1_testrand_seed (const unsigned char * seed16 ) {
23
21
static const unsigned char PREFIX [19 ] = "secp256k1 test init" ;
@@ -36,7 +34,6 @@ SECP256K1_INLINE static void secp256k1_testrand_seed(const unsigned char *seed16
36
34
for (j = 0 ; j < 8 ; ++ j ) s = (s << 8 ) | out32 [8 * i + j ];
37
35
secp256k1_test_state [i ] = s ;
38
36
}
39
- secp256k1_test_rng_integer_bits_left = 0 ;
40
37
}
41
38
42
39
SECP256K1_INLINE static uint64_t rotl (const uint64_t x , int k ) {
@@ -57,58 +54,30 @@ SECP256K1_INLINE static uint64_t secp256k1_testrand64(void) {
57
54
}
58
55
59
56
SECP256K1_INLINE static uint64_t secp256k1_testrand_bits (int bits ) {
60
- uint64_t ret ;
61
- if (secp256k1_test_rng_integer_bits_left < bits ) {
62
- secp256k1_test_rng_integer = secp256k1_testrand64 ();
63
- secp256k1_test_rng_integer_bits_left = 64 ;
64
- }
65
- ret = secp256k1_test_rng_integer ;
66
- secp256k1_test_rng_integer >>= bits ;
67
- secp256k1_test_rng_integer_bits_left -= bits ;
68
- ret &= ((~((uint64_t )0 )) >> (64 - bits ));
69
- return ret ;
57
+ if (bits == 0 ) return 0 ;
58
+ return secp256k1_testrand64 () >> (64 - bits );
70
59
}
71
60
72
61
SECP256K1_INLINE static uint32_t secp256k1_testrand32 (void ) {
73
- return secp256k1_testrand_bits ( 32 ) ;
62
+ return secp256k1_testrand64 () >> 32 ;
74
63
}
75
64
76
65
static uint32_t secp256k1_testrand_int (uint32_t range ) {
77
- /* We want a uniform integer between 0 and range-1, inclusive.
78
- * B is the smallest number such that range <= 2**B.
79
- * two mechanisms implemented here:
80
- * - generate B bits numbers until one below range is found, and return it
81
- * - find the largest multiple M of range that is <= 2**(B+A), generate B+A
82
- * bits numbers until one below M is found, and return it modulo range
83
- * The second mechanism consumes A more bits of entropy in every iteration,
84
- * but may need fewer iterations due to M being closer to 2**(B+A) then
85
- * range is to 2**B. The array below (indexed by B) contains a 0 when the
86
- * first mechanism is to be used, and the number A otherwise.
87
- */
88
- static const int addbits [] = {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 3 , 2 , 1 , 0 };
89
- uint32_t trange , mult ;
90
- int bits = 0 ;
91
- if (range <= 1 ) {
92
- return 0 ;
93
- }
94
- trange = range - 1 ;
95
- while (trange > 0 ) {
96
- trange >>= 1 ;
97
- bits ++ ;
66
+ uint32_t mask = 0 ;
67
+ uint32_t range_copy ;
68
+ /* Reduce range by 1, changing its meaning to "maximum value". */
69
+ VERIFY_CHECK (range != 0 );
70
+ range -= 1 ;
71
+ /* Count the number of bits in range. */
72
+ range_copy = range ;
73
+ while (range_copy ) {
74
+ mask = (mask << 1 ) | 1U ;
75
+ range_copy >>= 1 ;
98
76
}
99
- if (addbits [bits ]) {
100
- bits = bits + addbits [bits ];
101
- mult = ((~((uint32_t )0 )) >> (32 - bits )) / range ;
102
- trange = range * mult ;
103
- } else {
104
- trange = range ;
105
- mult = 1 ;
106
- }
107
- while (1 ) {
108
- uint32_t x = secp256k1_testrand_bits (bits );
109
- if (x < trange ) {
110
- return (mult == 1 ) ? x : (x % range );
111
- }
77
+ /* Generation loop. */
78
+ while (1 ) {
79
+ uint32_t val = secp256k1_testrand64 () & mask ;
80
+ if (val <= range ) return val ;
112
81
}
113
82
}
114
83
0 commit comments