-
Notifications
You must be signed in to change notification settings - Fork 30
/
ed25519-randombytes.h
91 lines (73 loc) · 1.8 KB
/
ed25519-randombytes.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#if defined(ED25519_TEST)
/*
ISAAC+ "variant", the paper is not clear on operator precedence and other
things. This is the "first in, first out" option!
Not threadsafe or securely initialized, only for deterministic testing
*/
typedef struct isaacp_state_t {
uint32_t state[256];
unsigned char buffer[1024];
uint32_t a, b, c;
size_t left;
} isaacp_state;
#define isaacp_step(offset, mix) \
x = mm[i + offset]; \
a = (a ^ (mix)) + (mm[(i + offset + 128) & 0xff]); \
y = (a ^ b) + mm[(x >> 2) & 0xff]; \
mm[i + offset] = y; \
b = (x + a) ^ mm[(y >> 10) & 0xff]; \
U32TO8_LE(out + (i + offset) * 4, b);
static void
isaacp_mix(isaacp_state *st) {
uint32_t i, x, y;
uint32_t a = st->a, b = st->b, c = st->c;
uint32_t *mm = st->state;
unsigned char *out = st->buffer;
c = c + 1;
b = b + c;
for (i = 0; i < 256; i += 4) {
isaacp_step(0, ROTL32(a,13))
isaacp_step(1, ROTR32(a, 6))
isaacp_step(2, ROTL32(a, 2))
isaacp_step(3, ROTR32(a,16))
}
st->a = a;
st->b = b;
st->c = c;
st->left = 1024;
}
static void
isaacp_random(isaacp_state *st, void *p, size_t len) {
size_t use;
unsigned char *c = (unsigned char *)p;
while (len) {
use = (len > st->left) ? st->left : len;
memcpy(c, st->buffer + (sizeof(st->buffer) - st->left), use);
st->left -= use;
c += use;
len -= use;
if (!st->left)
isaacp_mix(st);
}
}
void
ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len) {
static int initialized = 0;
static isaacp_state rng;
if (!initialized) {
memset(&rng, 0, sizeof(rng));
isaacp_mix(&rng);
isaacp_mix(&rng);
initialized = 1;
}
isaacp_random(&rng, p, len);
}
#elif defined(ED25519_CUSTOMRNG)
#include "ed25519-randombytes-custom.h"
#else
#include <openssl/rand.h>
void
ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len) {
RAND_bytes(p, (int) len);
}
#endif