Bitcoin ABC
0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
src
secp256k1
src
testrand_impl.h
Go to the documentation of this file.
1
/***********************************************************************
2
* Copyright (c) 2013-2015 Pieter Wuille *
3
* Distributed under the MIT software license, see the accompanying *
4
* file COPYING or https://www.opensource.org/licenses/mit-license.php.*
5
***********************************************************************/
6
7
#ifndef SECP256K1_TESTRAND_IMPL_H
8
#define SECP256K1_TESTRAND_IMPL_H
9
10
#include <stdint.h>
11
#include <stdio.h>
12
#include <
string.h
>
13
14
#include "
testrand.h
"
15
#include "
hash.h
"
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;
20
static
uint64_t
secp256k1_test_rng_integer
;
21
static
int
secp256k1_test_rng_integer_bits_left
= 0;
22
23
SECP256K1_INLINE
static
void
secp256k1_testrand_seed
(
const
unsigned
char
*
seed16
) {
24
secp256k1_rfc6979_hmac_sha256_initialize
(&
secp256k1_test_rng
,
seed16
, 16);
25
}
26
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
++];
33
}
34
35
static
uint32_t
secp256k1_testrand_bits
(
int
bits) {
36
uint32_t
ret
;
37
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;
40
}
41
ret
=
secp256k1_test_rng_integer
;
42
secp256k1_test_rng_integer
>>= bits;
43
secp256k1_test_rng_integer_bits_left
-= bits;
44
ret
&= ((~((
uint32_t
)0)) >> (32 - bits));
45
return
ret
;
46
}
47
48
static
uint32_t
secp256k1_testrand_int
(
uint32_t
range
) {
49
/* We want a uniform integer between 0 and range-1, inclusive.
50
* B is the smallest number such that range <= 2**B.
51
* two mechanisms implemented here:
52
* - generate B bits numbers until one below range is found, and return it
53
* - find the largest multiple M of range that is <= 2**(B+A), generate B+A
54
* bits numbers until one below M is found, and return it modulo range
55
* The second mechanism consumes A more bits of entropy in every iteration,
56
* but may need fewer iterations due to M being closer to 2**(B+A) then
57
* range is to 2**B. The array below (indexed by B) contains a 0 when the
58
* first mechanism is to be used, and the number A otherwise.
59
*/
60
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};
61
uint32_t
trange
,
mult
;
62
int
bits = 0;
63
if
(
range
<= 1) {
64
return
0;
65
}
66
trange
=
range
- 1;
67
while
(
trange
> 0) {
68
trange
>>= 1;
69
bits++;
70
}
71
if
(
addbits
[bits]) {
72
bits = bits +
addbits
[bits];
73
mult
= ((~((
uint32_t
)0)) >> (32 - bits)) /
range
;
74
trange
=
range
*
mult
;
75
}
else
{
76
trange
=
range
;
77
mult
= 1;
78
}
79
while
(1) {
80
uint32_t
x =
secp256k1_testrand_bits
(bits);
81
if
(x <
trange
) {
82
return
(
mult
== 1) ? x : (x %
range
);
83
}
84
}
85
}
86
87
static
void
secp256k1_testrand256
(
unsigned
char
*
b32
) {
88
secp256k1_rfc6979_hmac_sha256_generate
(&
secp256k1_test_rng
,
b32
, 32);
89
}
90
91
static
void
secp256k1_testrand_bytes_test
(
unsigned
char
*bytes,
size_t
len
) {
92
size_t
bits = 0;
93
memset
(bytes, 0,
len
);
94
while
(bits <
len
* 8) {
95
int
now;
96
uint32_t
val;
97
now = 1 + (
secp256k1_testrand_bits
(6) *
secp256k1_testrand_bits
(5) + 16) / 31;
98
val =
secp256k1_testrand_bits
(1);
99
while
(now > 0 && bits <
len
* 8) {
100
bytes[bits / 8] |= val << (bits % 8);
101
now--;
102
bits++;
103
}
104
}
105
}
106
107
static
void
secp256k1_testrand256_test
(
unsigned
char
*
b32
) {
108
secp256k1_testrand_bytes_test
(
b32
, 32);
109
}
110
111
static
void
secp256k1_testrand_flip
(
unsigned
char
*
b
,
size_t
len
) {
112
b
[
secp256k1_testrand_int
(
len
)] ^= (1 <<
secp256k1_testrand_int
(8));
113
}
114
115
static
void
secp256k1_testrand_init
(
const
char
*
hexseed
) {
116
unsigned
char
seed16
[16] = {0};
117
if
(
hexseed
&&
strlen
(
hexseed
) != 0) {
118
int
pos = 0;
119
while
(pos < 16 &&
hexseed
[0] != 0 &&
hexseed
[1] != 0) {
120
unsigned
short
sh
;
121
if
((
sscanf
(
hexseed
,
"%2hx"
, &
sh
)) == 1) {
122
seed16
[pos] =
sh
;
123
}
else
{
124
break
;
125
}
126
hexseed
+= 2;
127
pos++;
128
}
129
}
else
{
130
FILE
*
frand
= fopen(
"/dev/urandom"
,
"r"
);
131
if
((
frand
==
NULL
) ||
fread
(&
seed16
, 1,
sizeof
(
seed16
),
frand
) !=
sizeof
(
seed16
)) {
132
uint64_t
t
= time(
NULL
) * (
uint64_t
)1337;
133
fprintf
(
stderr
,
"WARNING: could not read 16 bytes from /dev/urandom; falling back to insecure PRNG\n"
);
134
seed16
[0] ^=
t
;
135
seed16
[1] ^=
t
>> 8;
136
seed16
[2] ^=
t
>> 16;
137
seed16
[3] ^=
t
>> 24;
138
seed16
[4] ^=
t
>> 32;
139
seed16
[5] ^=
t
>> 40;
140
seed16
[6] ^=
t
>> 48;
141
seed16
[7] ^=
t
>> 56;
142
}
143
if
(
frand
) {
144
fclose(
frand
);
145
}
146
}
147
148
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]);
149
secp256k1_testrand_seed
(
seed16
);
150
}
151
152
static
void
secp256k1_testrand_finish
(
void
) {
153
unsigned
char
run32
[32];
154
secp256k1_testrand256
(
run32
);
155
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]);
156
}
157
158
#endif
/* SECP256K1_TESTRAND_IMPL_H */
GetRand
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition
random.h:85
hash.h
secp256k1_rfc6979_hmac_sha256_generate
static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen)
secp256k1_rfc6979_hmac_sha256_initialize
static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen)
SECP256K1_INLINE
#define SECP256K1_INLINE
Definition
secp256k1.h:127
string.h
secp256k1_rfc6979_hmac_sha256
Definition
hash.h:31
testrand.h
secp256k1_test_rng_precomputed
static uint32_t secp256k1_test_rng_precomputed[8]
Definition
testrand_impl.h:18
secp256k1_test_rng_integer_bits_left
static int secp256k1_test_rng_integer_bits_left
Definition
testrand_impl.h:21
secp256k1_testrand_int
static uint32_t secp256k1_testrand_int(uint32_t range)
Definition
testrand_impl.h:48
secp256k1_testrand_flip
static void secp256k1_testrand_flip(unsigned char *b, size_t len)
Definition
testrand_impl.h:111
secp256k1_testrand_bytes_test
static void secp256k1_testrand_bytes_test(unsigned char *bytes, size_t len)
Definition
testrand_impl.h:91
secp256k1_testrand256
static void secp256k1_testrand256(unsigned char *b32)
Definition
testrand_impl.h:87
secp256k1_test_rng_precomputed_used
static int secp256k1_test_rng_precomputed_used
Definition
testrand_impl.h:19
secp256k1_testrand_seed
static SECP256K1_INLINE void secp256k1_testrand_seed(const unsigned char *seed16)
Definition
testrand_impl.h:23
secp256k1_testrand_init
static void secp256k1_testrand_init(const char *hexseed)
Definition
testrand_impl.h:115
secp256k1_test_rng
static secp256k1_rfc6979_hmac_sha256 secp256k1_test_rng
Definition
testrand_impl.h:17
secp256k1_testrand_finish
static void secp256k1_testrand_finish(void)
Definition
testrand_impl.h:152
secp256k1_testrand32
static SECP256K1_INLINE uint32_t secp256k1_testrand32(void)
Definition
testrand_impl.h:27
secp256k1_test_rng_integer
static uint64_t secp256k1_test_rng_integer
Definition
testrand_impl.h:20
secp256k1_testrand256_test
static void secp256k1_testrand256_test(unsigned char *b32)
Definition
testrand_impl.h:107
secp256k1_testrand_bits
static uint32_t secp256k1_testrand_bits(int bits)
Definition
testrand_impl.h:35
Generated on Fri Dec 27 2024 02:38:18 for Bitcoin ABC by
1.9.8