| 
14 | 14 | #include "testrand.h"  | 
15 | 15 | #include "hash.h"  | 
16 | 16 | 
 
  | 
17 |  | -static secp256k1_rfc6979_hmac_sha256 secp256k1_test_rng;  | 
18 |  | -static uint32_t secp256k1_test_rng_precomputed[8];  | 
19 |  | -static int secp256k1_test_rng_precomputed_used = 8;  | 
 | 17 | +static uint64_t secp256k1_test_state[4];  | 
20 | 18 | static uint64_t secp256k1_test_rng_integer;  | 
21 | 19 | static int secp256k1_test_rng_integer_bits_left = 0;  | 
22 | 20 | 
 
  | 
23 | 21 | SECP256K1_INLINE static void secp256k1_testrand_seed(const unsigned char *seed16) {  | 
24 |  | -    secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, seed16, 16);  | 
 | 22 | +    static const unsigned char PREFIX[19] = "secp256k1 test init";  | 
 | 23 | +    unsigned char out32[32];  | 
 | 24 | +    secp256k1_sha256 hash;  | 
 | 25 | +    int i;  | 
 | 26 | + | 
 | 27 | +    /* Use SHA256(PREFIX || seed16) as initial state. */  | 
 | 28 | +    secp256k1_sha256_initialize(&hash);  | 
 | 29 | +    secp256k1_sha256_write(&hash, PREFIX, sizeof(PREFIX));  | 
 | 30 | +    secp256k1_sha256_write(&hash, seed16, 16);  | 
 | 31 | +    secp256k1_sha256_finalize(&hash, out32);  | 
 | 32 | +    for (i = 0; i < 4; ++i) {  | 
 | 33 | +        uint64_t s = 0;  | 
 | 34 | +        int j;  | 
 | 35 | +        for (j = 0; j < 8; ++j) s = (s << 8) | out32[8*i + j];  | 
 | 36 | +        secp256k1_test_state[i] = s;  | 
 | 37 | +    }  | 
 | 38 | +    secp256k1_test_rng_integer_bits_left = 0;  | 
25 | 39 | }  | 
26 | 40 | 
 
  | 
27 |  | -SECP256K1_INLINE static uint32_t secp256k1_testrand32(void) {  | 
28 |  | -    if (secp256k1_test_rng_precomputed_used == 8) {  | 
29 |  | -        secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, (unsigned char*)(&secp256k1_test_rng_precomputed[0]), sizeof(secp256k1_test_rng_precomputed));  | 
30 |  | -        secp256k1_test_rng_precomputed_used = 0;  | 
31 |  | -    }  | 
32 |  | -    return secp256k1_test_rng_precomputed[secp256k1_test_rng_precomputed_used++];  | 
 | 41 | +SECP256K1_INLINE static uint64_t rotl(const uint64_t x, int k) {  | 
 | 42 | +    return (x << k) | (x >> (64 - k));  | 
 | 43 | +}  | 
 | 44 | + | 
 | 45 | +SECP256K1_INLINE static uint64_t secp256k1_testrand64(void) {  | 
 | 46 | +    /* Test-only Xoshiro256++ RNG. See https://prng.di.unimi.it/ */  | 
 | 47 | +    const uint64_t result = rotl(secp256k1_test_state[0] + secp256k1_test_state[3], 23) + secp256k1_test_state[0];  | 
 | 48 | +    const uint64_t t = secp256k1_test_state[1] << 17;  | 
 | 49 | +    secp256k1_test_state[2] ^= secp256k1_test_state[0];  | 
 | 50 | +    secp256k1_test_state[3] ^= secp256k1_test_state[1];  | 
 | 51 | +    secp256k1_test_state[1] ^= secp256k1_test_state[2];  | 
 | 52 | +    secp256k1_test_state[0] ^= secp256k1_test_state[3];  | 
 | 53 | +    secp256k1_test_state[2] ^= t;  | 
 | 54 | +    secp256k1_test_state[3] = rotl(secp256k1_test_state[3], 45);  | 
 | 55 | +    return result;  | 
33 | 56 | }  | 
34 | 57 | 
 
  | 
35 |  | -static uint32_t secp256k1_testrand_bits(int bits) {  | 
36 |  | -    uint32_t ret;  | 
 | 58 | +SECP256K1_INLINE static uint64_t secp256k1_testrand_bits(int bits) {  | 
 | 59 | +    uint64_t ret;  | 
37 | 60 |     if (secp256k1_test_rng_integer_bits_left < bits) {  | 
38 |  | -        secp256k1_test_rng_integer |= (((uint64_t)secp256k1_testrand32()) << secp256k1_test_rng_integer_bits_left);  | 
39 |  | -        secp256k1_test_rng_integer_bits_left += 32;  | 
 | 61 | +        secp256k1_test_rng_integer = secp256k1_testrand64();  | 
 | 62 | +        secp256k1_test_rng_integer_bits_left = 64;  | 
40 | 63 |     }  | 
41 | 64 |     ret = secp256k1_test_rng_integer;  | 
42 | 65 |     secp256k1_test_rng_integer >>= bits;  | 
43 | 66 |     secp256k1_test_rng_integer_bits_left -= bits;  | 
44 |  | -    ret &= ((~((uint32_t)0)) >> (32 - bits));  | 
 | 67 | +    ret &= ((~((uint64_t)0)) >> (64 - bits));  | 
45 | 68 |     return ret;  | 
46 | 69 | }  | 
47 | 70 | 
 
  | 
 | 71 | +SECP256K1_INLINE static uint32_t secp256k1_testrand32(void) {  | 
 | 72 | +    return secp256k1_testrand_bits(32);  | 
 | 73 | +}  | 
 | 74 | + | 
48 | 75 | static uint32_t secp256k1_testrand_int(uint32_t range) {  | 
49 | 76 |     /* We want a uniform integer between 0 and range-1, inclusive.  | 
50 | 77 |      * B is the smallest number such that range <= 2**B.  | 
@@ -85,7 +112,19 @@ static uint32_t secp256k1_testrand_int(uint32_t range) {  | 
85 | 112 | }  | 
86 | 113 | 
 
  | 
87 | 114 | static void secp256k1_testrand256(unsigned char *b32) {  | 
88 |  | -    secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, b32, 32);  | 
 | 115 | +    int i;  | 
 | 116 | +    for (i = 0; i < 4; ++i) {  | 
 | 117 | +        uint64_t val = secp256k1_testrand64();  | 
 | 118 | +        b32[0] = val;  | 
 | 119 | +        b32[1] = val >> 8;  | 
 | 120 | +        b32[2] = val >> 16;  | 
 | 121 | +        b32[3] = val >> 24;  | 
 | 122 | +        b32[4] = val >> 32;  | 
 | 123 | +        b32[5] = val >> 40;  | 
 | 124 | +        b32[6] = val >> 48;  | 
 | 125 | +        b32[7] = val >> 56;  | 
 | 126 | +        b32 += 8;  | 
 | 127 | +    }  | 
89 | 128 | }  | 
90 | 129 | 
 
  | 
91 | 130 | static void secp256k1_testrand_bytes_test(unsigned char *bytes, size_t len) {  | 
 | 
0 commit comments