blob: a6bca13d7734aa1c3146e6aebfadb2b0ec2ad10b (
plain)
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
|
#include "rnd.h"
#include "util_rt.h"
#include <string.h>
#include <errno.h>
typedef struct {
uint32_t state[16];
size_t index;
} rnd_well512_ctx_t;
static uint32_t rnd_well512_pull (rnd_well512_ctx_t *ctx) {
uint32_t a, b, c, d;
a = ctx->state[ctx->index];
c = ctx->state[(ctx->index + 13) & 15];
b = a ^ c ^ (a << 16) ^ (c << 15);
c = ctx->state[(ctx->index + 9) & 15];
c ^= (c >> 11);
a = ctx->state[ctx->index] = b ^ c;
d = a ^ ((a << 5) & 0xDA442D24UL);
ctx->index = (ctx->index + 15) & 15;
a = ctx->state[ctx->index];
ctx->state[ctx->index] = a ^ b ^ d ^ (a << 2) ^ (b << 18) ^ (c << 28);
return ctx->state[ctx->index];
}
static bool rnd_well512_f (void *p, uint8_t *buf, size_t len) {
rnd_well512_ctx_t *ctx = (rnd_well512_ctx_t*)p;
size_t consume;
uint32_t n;
while (len > 0) {
n = rnd_well512_pull(ctx);
consume = prne_op_min(len, sizeof(n));
memcpy(buf, &n, consume);
buf += consume;
len -= consume;
}
return true;
}
static void rnd_free_well512 (void *p) {
prne_free(p);
}
bool prne_rnd_alloc_well512 (
prne_rnd_t *p,
const uint8_t *is)
{
rnd_well512_ctx_t *ctx;
ctx = (rnd_well512_ctx_t*)prne_calloc(sizeof(rnd_well512_ctx_t), 1);
if (ctx == NULL) {
return false;
}
prne_free_rnd(p);
memcpy(ctx->state, is, sizeof(ctx->state));
p->ctx = ctx;
p->free_ctx_f = rnd_free_well512;
p->random = rnd_well512_f;
return true;
}
|