Bitcoin Core
31.1.0
P2P Digital Currency
Toggle main menu visibility
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
#include "
util.h
"
17
18
static
uint64_t
secp256k1_test_state
[4];
19
20
SECP256K1_INLINE
static
void
testrand_seed
(
const
unsigned
char
*seed16) {
21
static
const
unsigned
char
PREFIX[] = {
's'
,
'e'
,
'c'
,
'p'
,
'2'
,
'5'
,
'6'
,
'k'
,
'1'
,
' '
,
't'
,
'e'
,
's'
,
't'
,
' '
,
'i'
,
'n'
,
'i'
,
't'
};
22
unsigned
char
out32[32];
23
secp256k1_sha256
hash;
24
int
i;
25
26
/* Use SHA256(PREFIX || seed16) as initial state. */
27
secp256k1_sha256_initialize
(&hash);
28
secp256k1_sha256_write
(&hash, PREFIX,
sizeof
(PREFIX));
29
secp256k1_sha256_write
(&hash, seed16, 16);
30
secp256k1_sha256_finalize
(&hash, out32);
31
for
(i = 0; i < 4; ++i) {
32
uint64_t s = 0;
33
int
j;
34
for
(j = 0; j < 8; ++j) s = (s << 8) | out32[8*i + j];
35
secp256k1_test_state
[i] = s;
36
}
37
}
38
39
SECP256K1_INLINE
static
uint64_t
rotl
(
const
uint64_t x,
int
k
) {
40
return
(x <<
k
) | (x >> (64 -
k
));
41
}
42
43
SECP256K1_INLINE
static
uint64_t
testrand64
(
void
) {
44
/* Test-only Xoshiro256++ RNG. See https://prng.di.unimi.it/ */
45
const
uint64_t result =
rotl
(
secp256k1_test_state
[0] +
secp256k1_test_state
[3], 23) +
secp256k1_test_state
[0];
46
const
uint64_t
t
=
secp256k1_test_state
[1] << 17;
47
secp256k1_test_state
[2] ^=
secp256k1_test_state
[0];
48
secp256k1_test_state
[3] ^=
secp256k1_test_state
[1];
49
secp256k1_test_state
[1] ^=
secp256k1_test_state
[2];
50
secp256k1_test_state
[0] ^=
secp256k1_test_state
[3];
51
secp256k1_test_state
[2] ^=
t
;
52
secp256k1_test_state
[3] =
rotl
(
secp256k1_test_state
[3], 45);
53
return
result;
54
}
55
56
SECP256K1_INLINE
static
uint64_t
testrand_bits
(
int
bits) {
57
if
(bits == 0)
return
0;
58
return
testrand64
() >> (64 - bits);
59
}
60
61
SECP256K1_INLINE
static
uint32_t
testrand32
(
void
) {
62
return
testrand64
() >> 32;
63
}
64
65
static
uint32_t
testrand_int
(uint32_t range) {
66
uint32_t mask = 0;
67
uint32_t range_copy;
68
/* Reduce range by 1, changing its meaning to "maximum value". */
69
VERIFY_CHECK
(range != 0);
70
range -= 1;
71
/* Count the number of bits in range. */
72
range_copy = range;
73
while
(range_copy) {
74
mask = (mask << 1) | 1U;
75
range_copy >>= 1;
76
}
77
/* Generation loop. */
78
while
(1) {
79
uint32_t val =
testrand64
() & mask;
80
if
(val <= range)
return
val;
81
}
82
}
83
84
static
void
testrand256
(
unsigned
char
*b32) {
85
int
i;
86
for
(i = 0; i < 4; ++i) {
87
uint64_t val =
testrand64
();
88
b32[0] = val;
89
b32[1] = val >> 8;
90
b32[2] = val >> 16;
91
b32[3] = val >> 24;
92
b32[4] = val >> 32;
93
b32[5] = val >> 40;
94
b32[6] = val >> 48;
95
b32[7] = val >> 56;
96
b32 += 8;
97
}
98
}
99
100
static
void
testrand_bytes_test
(
unsigned
char
*bytes,
size_t
len) {
101
size_t
bits = 0;
102
memset(bytes, 0, len);
103
while
(bits < len * 8) {
104
int
now;
105
uint32_t val;
106
now = 1 + (
testrand_bits
(6) *
testrand_bits
(5) + 16) / 31;
107
val =
testrand_bits
(1);
108
while
(now > 0 && bits < len * 8) {
109
bytes[bits / 8] |= val << (bits % 8);
110
now--;
111
bits++;
112
}
113
}
114
}
115
116
static
void
testrand256_test
(
unsigned
char
*b32) {
117
testrand_bytes_test
(b32, 32);
118
}
119
120
static
void
testrand_flip
(
unsigned
char
*b,
size_t
len) {
121
b[
testrand_int
(len)] ^= (1 <<
testrand_bits
(3));
122
}
123
124
static
void
testrand_init
(
const
char
* hexseed) {
125
unsigned
char
seed16[16] = {0};
126
if
(hexseed && strlen(hexseed) != 0) {
127
int
pos = 0;
128
while
(pos < 16 && hexseed[0] != 0 && hexseed[1] != 0) {
129
unsigned
short
sh;
130
if
((sscanf(hexseed,
"%2hx"
, &sh)) == 1) {
131
seed16[pos] = sh;
132
}
else
{
133
break
;
134
}
135
hexseed += 2;
136
pos++;
137
}
138
}
else
{
139
FILE *frand = fopen(
"/dev/urandom"
,
"rb"
);
140
if
((frand == NULL) || fread(&seed16, 1,
sizeof
(seed16), frand) !=
sizeof
(seed16)) {
141
uint64_t
t
= time(NULL) * (uint64_t)1337;
142
fprintf(stderr,
"WARNING: could not read 16 bytes from /dev/urandom; falling back to insecure PRNG\n"
);
143
seed16[0] ^=
t
;
144
seed16[1] ^=
t
>> 8;
145
seed16[2] ^=
t
>> 16;
146
seed16[3] ^=
t
>> 24;
147
seed16[4] ^=
t
>> 32;
148
seed16[5] ^=
t
>> 40;
149
seed16[6] ^=
t
>> 48;
150
seed16[7] ^=
t
>> 56;
151
}
152
if
(frand) {
153
fclose(frand);
154
}
155
}
156
157
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]);
158
testrand_seed
(seed16);
159
}
160
161
static
void
testrand_finish
(
void
) {
162
unsigned
char
run32[32];
163
testrand256
(run32);
164
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]);
165
}
166
167
#endif
/* SECP256K1_TESTRAND_IMPL_H */
hash.h
secp256k1_sha256_initialize
static void secp256k1_sha256_initialize(secp256k1_sha256 *hash)
secp256k1_sha256_finalize
static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32)
secp256k1_sha256_write
static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size)
util.h
SECP256K1_INLINE
#define SECP256K1_INLINE
Definition
util.h:54
VERIFY_CHECK
#define VERIFY_CHECK(cond)
Definition
util.h:159
ByteUnit::k
@ k
Definition
strencodings.h:46
ByteUnit::t
@ t
Definition
strencodings.h:52
string.h
secp256k1_sha256
Definition
hash.h:13
testrand.h
testrand_flip
static void testrand_flip(unsigned char *b, size_t len)
Definition
testrand_impl.h:120
testrand256_test
static void testrand256_test(unsigned char *b32)
Definition
testrand_impl.h:116
testrand64
static SECP256K1_INLINE uint64_t testrand64(void)
Definition
testrand_impl.h:43
testrand256
static void testrand256(unsigned char *b32)
Definition
testrand_impl.h:84
testrand32
static SECP256K1_INLINE uint32_t testrand32(void)
Definition
testrand_impl.h:61
testrand_bits
static SECP256K1_INLINE uint64_t testrand_bits(int bits)
Definition
testrand_impl.h:56
secp256k1_test_state
static uint64_t secp256k1_test_state[4]
Definition
testrand_impl.h:18
testrand_int
static uint32_t testrand_int(uint32_t range)
Definition
testrand_impl.h:65
testrand_seed
static SECP256K1_INLINE void testrand_seed(const unsigned char *seed16)
Definition
testrand_impl.h:20
testrand_init
static void testrand_init(const char *hexseed)
Definition
testrand_impl.h:124
rotl
static SECP256K1_INLINE uint64_t rotl(const uint64_t x, int k)
Definition
testrand_impl.h:39
testrand_bytes_test
static void testrand_bytes_test(unsigned char *bytes, size_t len)
Definition
testrand_impl.h:100
testrand_finish
static void testrand_finish(void)
Definition
testrand_impl.h:161
Generated on
for Bitcoin Core by
1.17.0