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