Changeset View
Changeset View
Standalone View
Standalone View
src/secp256k1/src/testrand_impl.h
Show All 14 Lines | |||||
#include "hash.h" | #include "hash.h" | ||||
static secp256k1_rfc6979_hmac_sha256 secp256k1_test_rng; | static secp256k1_rfc6979_hmac_sha256 secp256k1_test_rng; | ||||
static uint32_t secp256k1_test_rng_precomputed[8]; | static uint32_t secp256k1_test_rng_precomputed[8]; | ||||
static int secp256k1_test_rng_precomputed_used = 8; | static int secp256k1_test_rng_precomputed_used = 8; | ||||
static uint64_t secp256k1_test_rng_integer; | static uint64_t secp256k1_test_rng_integer; | ||||
static int secp256k1_test_rng_integer_bits_left = 0; | static int secp256k1_test_rng_integer_bits_left = 0; | ||||
SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16) { | SECP256K1_INLINE static void secp256k1_testrand_seed(const unsigned char *seed16) { | ||||
secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, seed16, 16); | secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, seed16, 16); | ||||
} | } | ||||
SECP256K1_INLINE static uint32_t secp256k1_rand32(void) { | SECP256K1_INLINE static uint32_t secp256k1_testrand32(void) { | ||||
if (secp256k1_test_rng_precomputed_used == 8) { | if (secp256k1_test_rng_precomputed_used == 8) { | ||||
secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, (unsigned char*)(&secp256k1_test_rng_precomputed[0]), sizeof(secp256k1_test_rng_precomputed)); | secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, (unsigned char*)(&secp256k1_test_rng_precomputed[0]), sizeof(secp256k1_test_rng_precomputed)); | ||||
secp256k1_test_rng_precomputed_used = 0; | secp256k1_test_rng_precomputed_used = 0; | ||||
} | } | ||||
return secp256k1_test_rng_precomputed[secp256k1_test_rng_precomputed_used++]; | return secp256k1_test_rng_precomputed[secp256k1_test_rng_precomputed_used++]; | ||||
} | } | ||||
static uint32_t secp256k1_rand_bits(int bits) { | static uint32_t secp256k1_testrand_bits(int bits) { | ||||
uint32_t ret; | uint32_t ret; | ||||
if (secp256k1_test_rng_integer_bits_left < bits) { | if (secp256k1_test_rng_integer_bits_left < bits) { | ||||
secp256k1_test_rng_integer |= (((uint64_t)secp256k1_rand32()) << secp256k1_test_rng_integer_bits_left); | secp256k1_test_rng_integer |= (((uint64_t)secp256k1_testrand32()) << secp256k1_test_rng_integer_bits_left); | ||||
secp256k1_test_rng_integer_bits_left += 32; | secp256k1_test_rng_integer_bits_left += 32; | ||||
} | } | ||||
ret = secp256k1_test_rng_integer; | ret = secp256k1_test_rng_integer; | ||||
secp256k1_test_rng_integer >>= bits; | secp256k1_test_rng_integer >>= bits; | ||||
secp256k1_test_rng_integer_bits_left -= bits; | secp256k1_test_rng_integer_bits_left -= bits; | ||||
ret &= ((~((uint32_t)0)) >> (32 - bits)); | ret &= ((~((uint32_t)0)) >> (32 - bits)); | ||||
return ret; | return ret; | ||||
} | } | ||||
static uint32_t secp256k1_rand_int(uint32_t range) { | static uint32_t secp256k1_testrand_int(uint32_t range) { | ||||
/* We want a uniform integer between 0 and range-1, inclusive. | /* We want a uniform integer between 0 and range-1, inclusive. | ||||
* B is the smallest number such that range <= 2**B. | * B is the smallest number such that range <= 2**B. | ||||
* two mechanisms implemented here: | * two mechanisms implemented here: | ||||
* - generate B bits numbers until one below range is found, and return it | * - generate B bits numbers until one below range is found, and return it | ||||
* - find the largest multiple M of range that is <= 2**(B+A), generate B+A | * - find the largest multiple M of range that is <= 2**(B+A), generate B+A | ||||
* bits numbers until one below M is found, and return it modulo range | * bits numbers until one below M is found, and return it modulo range | ||||
* The second mechanism consumes A more bits of entropy in every iteration, | * The second mechanism consumes A more bits of entropy in every iteration, | ||||
* but may need fewer iterations due to M being closer to 2**(B+A) then | * but may need fewer iterations due to M being closer to 2**(B+A) then | ||||
Show All 15 Lines | if (addbits[bits]) { | ||||
bits = bits + addbits[bits]; | bits = bits + addbits[bits]; | ||||
mult = ((~((uint32_t)0)) >> (32 - bits)) / range; | mult = ((~((uint32_t)0)) >> (32 - bits)) / range; | ||||
trange = range * mult; | trange = range * mult; | ||||
} else { | } else { | ||||
trange = range; | trange = range; | ||||
mult = 1; | mult = 1; | ||||
} | } | ||||
while(1) { | while(1) { | ||||
uint32_t x = secp256k1_rand_bits(bits); | uint32_t x = secp256k1_testrand_bits(bits); | ||||
if (x < trange) { | if (x < trange) { | ||||
return (mult == 1) ? x : (x % range); | return (mult == 1) ? x : (x % range); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
static void secp256k1_rand256(unsigned char *b32) { | static void secp256k1_testrand256(unsigned char *b32) { | ||||
secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, b32, 32); | secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, b32, 32); | ||||
} | } | ||||
static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len) { | static void secp256k1_testrand_bytes_test(unsigned char *bytes, size_t len) { | ||||
size_t bits = 0; | size_t bits = 0; | ||||
memset(bytes, 0, len); | memset(bytes, 0, len); | ||||
while (bits < len * 8) { | while (bits < len * 8) { | ||||
int now; | int now; | ||||
uint32_t val; | uint32_t val; | ||||
now = 1 + (secp256k1_rand_bits(6) * secp256k1_rand_bits(5) + 16) / 31; | now = 1 + (secp256k1_testrand_bits(6) * secp256k1_testrand_bits(5) + 16) / 31; | ||||
val = secp256k1_rand_bits(1); | val = secp256k1_testrand_bits(1); | ||||
while (now > 0 && bits < len * 8) { | while (now > 0 && bits < len * 8) { | ||||
bytes[bits / 8] |= val << (bits % 8); | bytes[bits / 8] |= val << (bits % 8); | ||||
now--; | now--; | ||||
bits++; | bits++; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
static void secp256k1_rand256_test(unsigned char *b32) { | static void secp256k1_testrand256_test(unsigned char *b32) { | ||||
secp256k1_rand_bytes_test(b32, 32); | secp256k1_testrand_bytes_test(b32, 32); | ||||
} | } | ||||
static void secp256k1_rand_flip(unsigned char *b, size_t len) { | static void secp256k1_testrand_flip(unsigned char *b, size_t len) { | ||||
b[secp256k1_rand_int(len)] ^= (1 << secp256k1_rand_int(8)); | b[secp256k1_testrand_int(len)] ^= (1 << secp256k1_testrand_int(8)); | ||||
} | } | ||||
static void secp256k1_rand_init(const char* hexseed) { | static void secp256k1_testrand_init(const char* hexseed) { | ||||
unsigned char seed16[16] = {0}; | unsigned char seed16[16] = {0}; | ||||
if (hexseed && strlen(hexseed) != 0) { | if (hexseed && strlen(hexseed) != 0) { | ||||
int pos = 0; | int pos = 0; | ||||
while (pos < 16 && hexseed[0] != 0 && hexseed[1] != 0) { | while (pos < 16 && hexseed[0] != 0 && hexseed[1] != 0) { | ||||
unsigned short sh; | unsigned short sh; | ||||
if ((sscanf(hexseed, "%2hx", &sh)) == 1) { | if ((sscanf(hexseed, "%2hx", &sh)) == 1) { | ||||
seed16[pos] = sh; | seed16[pos] = sh; | ||||
} else { | } else { | ||||
Show All 17 Lines | if (hexseed && strlen(hexseed) != 0) { | ||||
seed16[7] ^= t >> 56; | seed16[7] ^= t >> 56; | ||||
} | } | ||||
if (frand) { | if (frand) { | ||||
fclose(frand); | fclose(frand); | ||||
} | } | ||||
} | } | ||||
printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]); | printf("random seed = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", seed16[0], seed16[1], seed16[2], seed16[3], seed16[4], seed16[5], seed16[6], seed16[7], seed16[8], seed16[9], seed16[10], seed16[11], seed16[12], seed16[13], seed16[14], seed16[15]); | ||||
secp256k1_rand_seed(seed16); | secp256k1_testrand_seed(seed16); | ||||
} | } | ||||
static void secp256k1_rand_finish(void) { | static void secp256k1_testrand_finish(void) { | ||||
unsigned char run32[32]; | unsigned char run32[32]; | ||||
secp256k1_rand256(run32); | secp256k1_testrand256(run32); | ||||
printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]); | printf("random run = %02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", run32[0], run32[1], run32[2], run32[3], run32[4], run32[5], run32[6], run32[7], run32[8], run32[9], run32[10], run32[11], run32[12], run32[13], run32[14], run32[15]); | ||||
} | } | ||||
#endif /* SECP256K1_TESTRAND_IMPL_H */ | #endif /* SECP256K1_TESTRAND_IMPL_H */ |