/********************************************************************** * Copyright (c) 2013-2015 Pieter Wuille, Gregory Maxwell * * Distributed under the MIT software license, see the accompanying * * file COPYING or http://www.opensource.org/licenses/mit-license.php.* **********************************************************************/ #ifndef _SECP256K1_TESTRAND_IMPL_H_ #define _SECP256K1_TESTRAND_IMPL_H_ #include #include #include "testrand.h" #include "hash.h" static secp256k1_rfc6979_hmac_sha256_t secp256k1_test_rng; static uint32_t secp256k1_test_rng_precomputed[8]; static int secp256k1_test_rng_precomputed_used = 8; SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16) { secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, seed16, 16); } SECP256K1_INLINE static uint32_t secp256k1_rand32(void) { 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_test_rng_precomputed_used = 0; } return secp256k1_test_rng_precomputed[secp256k1_test_rng_precomputed_used++]; } static void secp256k1_rand256(unsigned char *b32) { secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, b32, 32); } static void secp256k1_rand256_test(unsigned char *b32) { int bits=0; uint64_t ent = 0; int entleft = 0; memset(b32, 0, 32); while (bits < 256) { int now; uint32_t val; if (entleft < 12) { ent |= ((uint64_t)secp256k1_rand32()) << entleft; entleft += 32; } now = 1 + ((ent % 64)*((ent >> 6) % 32)+16)/31; val = 1 & (ent >> 11); ent >>= 12; entleft -= 12; while (now > 0 && bits < 256) { b32[bits / 8] |= val << (bits % 8); now--; bits++; } } } SECP256K1_INLINE static int64_t secp256k1_rands64(uint64_t min, uint64_t max) { uint64_t range; uint64_t r; uint64_t clz; VERIFY_CHECK(max >= min); if (max == min) { return min; } range = max - min; clz = secp256k1_clz64_var(range); do { r = ((uint64_t)secp256k1_rand32() << 32) | secp256k1_rand32(); r >>= clz; } while (r > range); return min + (int64_t)r; } #endif