ed25519-randombytes.h 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  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. Not threadsafe or securely initialized, only for deterministic testing
  6. */
  7. typedef struct isaacp_state_t {
  8. uint32_t state[256];
  9. unsigned char buffer[1024];
  10. uint32_t a, b, c;
  11. size_t left;
  12. } isaacp_state;
  13. #define isaacp_step(offset, mix) \
  14. x = mm[i + offset]; \
  15. a = (a ^ (mix)) + (mm[(i + offset + 128) & 0xff]); \
  16. y = (a ^ b) + mm[(x >> 2) & 0xff]; \
  17. mm[i + offset] = y; \
  18. b = (x + a) ^ mm[(y >> 10) & 0xff]; \
  19. U32TO8_LE(out + (i + offset) * 4, b);
  20. static void
  21. isaacp_mix(isaacp_state *st) {
  22. uint32_t i, x, y;
  23. uint32_t a = st->a, b = st->b, c = st->c;
  24. uint32_t *mm = st->state;
  25. unsigned char *out = st->buffer;
  26. c = c + 1;
  27. b = b + c;
  28. for (i = 0; i < 256; i += 4) {
  29. isaacp_step(0, ROTL32(a,13))
  30. isaacp_step(1, ROTR32(a, 6))
  31. isaacp_step(2, ROTL32(a, 2))
  32. isaacp_step(3, ROTR32(a,16))
  33. }
  34. st->a = a;
  35. st->b = b;
  36. st->c = c;
  37. st->left = 1024;
  38. }
  39. static void
  40. isaacp_random(isaacp_state *st, void *p, size_t len) {
  41. size_t use;
  42. unsigned char *c = (unsigned char *)p;
  43. while (len) {
  44. use = (len > st->left) ? st->left : len;
  45. memcpy(c, st->buffer + (sizeof(st->buffer) - st->left), use);
  46. st->left -= use;
  47. c += use;
  48. len -= use;
  49. if (!st->left)
  50. isaacp_mix(st);
  51. }
  52. }
  53. void
  54. ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len) {
  55. static int initialized = 0;
  56. static isaacp_state rng;
  57. if (!initialized) {
  58. memset(&rng, 0, sizeof(rng));
  59. isaacp_mix(&rng);
  60. isaacp_mix(&rng);
  61. initialized = 1;
  62. }
  63. isaacp_random(&rng, p, len);
  64. }
  65. #elif defined(ED25519_CUSTOMRANDOM)
  66. #include "ed25519-randombytes-custom.h"
  67. #else
  68. #include <openssl/rand.h>
  69. void
  70. ED25519_FN(ed25519_randombytes_unsafe) (void *p, size_t len) {
  71. RAND_bytes(p, (int) len);
  72. }
  73. #endif