aboutsummaryrefslogtreecommitdiff
path: root/src/ext/ed25519/donna/ed25519-randombytes.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/ext/ed25519/donna/ed25519-randombytes.h')
-rw-r--r--src/ext/ed25519/donna/ed25519-randombytes.h91
1 files changed, 91 insertions, 0 deletions
diff --git a/src/ext/ed25519/donna/ed25519-randombytes.h b/src/ext/ed25519/donna/ed25519-randombytes.h
new file mode 100644
index 0000000000..1dc629028e
--- /dev/null
+++ b/src/ext/ed25519/donna/ed25519-randombytes.h
@@ -0,0 +1,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_CUSTOMRANDOM)
+
+#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