|
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