1616#include "util.h"
1717
1818static uint64_t secp256k1_test_state [4 ];
19- static uint64_t secp256k1_test_rng_integer ;
20- static int secp256k1_test_rng_integer_bits_left = 0 ;
2119
2220SECP256K1_INLINE static void secp256k1_testrand_seed (const unsigned char * seed16 ) {
2321 static const unsigned char PREFIX [19 ] = "secp256k1 test init" ;
@@ -36,7 +34,6 @@ SECP256K1_INLINE static void secp256k1_testrand_seed(const unsigned char *seed16
3634 for (j = 0 ; j < 8 ; ++ j ) s = (s << 8 ) | out32 [8 * i + j ];
3735 secp256k1_test_state [i ] = s ;
3836 }
39- secp256k1_test_rng_integer_bits_left = 0 ;
4037}
4138
4239SECP256K1_INLINE static uint64_t rotl (const uint64_t x , int k ) {
@@ -57,58 +54,30 @@ SECP256K1_INLINE static uint64_t secp256k1_testrand64(void) {
5754}
5855
5956SECP256K1_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 );
7059}
7160
7261SECP256K1_INLINE static uint32_t secp256k1_testrand32 (void ) {
73- return secp256k1_testrand_bits ( 32 ) ;
62+ return secp256k1_testrand64 () >> 32 ;
7463}
7564
7665static 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 ;
9876 }
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 ;
11281 }
11382}
11483
0 commit comments