#include #include #include #include #include "salsarnd.h" #define ROTATE(v,c) (((v) << (c)) | ((v) >> (32 - (c)))) #define XOR(v,w) ((v) ^ (w)) #define PLUS(v,w) (((v) + (w))) #define PLUSONE(v) (PLUS((v),1)) #define QUARTERROUND(a,b,c,d) \ x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]),16); \ x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]),12); \ x[a] = PLUS(x[a],x[b]); x[d] = ROTATE(XOR(x[d],x[a]), 8); \ x[c] = PLUS(x[c],x[d]); x[b] = ROTATE(XOR(x[b],x[c]), 7); static void salsa20(void *__out, void *__in) { int i; uint32_t x[16]; uint32_t *input = __in; uint32_t *output32 = __out; for (i = 0;i < 16;++i) x[i] = input[i]; for (i = 8;i > 0;i -= 2) { QUARTERROUND( 0, 4, 8,12) QUARTERROUND( 1, 5, 9,13) QUARTERROUND( 2, 6,10,14) QUARTERROUND( 3, 7,11,15) QUARTERROUND( 0, 5,10,15) QUARTERROUND( 1, 6,11,12) QUARTERROUND( 2, 7, 8,13) QUARTERROUND( 3, 4, 9,14) } for (i = 0;i < 16;++i) x[i] = PLUS(x[i],input[i]); for (i = 0;i < 16;++i) output32[i] = x[i]; } uint32_t get_random32(void) { static __thread uint32_t salsa20_out[16]; static __thread uint32_t salsa20_in[16]; static __thread int salsa20_nrints; static __thread int salsa20_rndinit; if (!salsa20_rndinit) { FILE *frandom; salsa20_rndinit = 1; frandom = fopen("/dev/urandom", "rb"); if (frandom == NULL) { _exit(1); } setbuf(frandom, NULL); if (fread(salsa20_in, 1, sizeof(salsa20_in), frandom) != sizeof(salsa20_in)) { _exit(1); } fclose(frandom); } if (salsa20_nrints == 0) { if (!++salsa20_in[0]) if (!++salsa20_in[1]) if (!++salsa20_in[2]) if (!++salsa20_in[3]) if (!++salsa20_in[4]) if (!++salsa20_in[5]) if (!++salsa20_in[6]) if (!++salsa20_in[7]) if (!++salsa20_in[8]) if (!++salsa20_in[9]) if (!++salsa20_in[10]) if (!++salsa20_in[11]) if (!++salsa20_in[12]) if (!++salsa20_in[13]) if (!++salsa20_in[14]) ++salsa20_in[15]; salsa20(salsa20_out, salsa20_in); salsa20_nrints = 16; } return salsa20_out[--salsa20_nrints]; }