51 broke -E logic completely, rewise it
[tfcrypt.git] / tfprng.c
1 #include <string.h>
2 #include "tfe.h"
3 #include "tfprng.h"
4
5 struct tf_prng_data {
6         struct tfe_stream tfe;
7         short init;
8 };
9
10 struct tf_prng_data tf_prng_sdata;
11
12 size_t tf_prng_datasize(void)
13 {
14         return sizeof(struct tf_prng_data);
15 }
16
17 void tf_prng_seedkey_r(void *sdata, const void *skey)
18 {
19         TF_UNIT_TYPE k[TF_NR_KEY_UNITS];
20         struct tf_prng_data *rprng = sdata;
21
22         memset(rprng, 0, tf_prng_datasize());
23         if (!skey) return;
24
25         memcpy(k, skey, TF_KEY_SIZE);
26         tfe_init(&rprng->tfe, k);
27         rprng->init = 1;
28
29         memset(k, 0, TF_KEY_SIZE);
30 }
31
32 void tf_prng_seedkey(const void *skey)
33 {
34         tf_prng_seedkey_r(&tf_prng_sdata, skey);
35 }
36
37 void tf_prng_genrandom_r(void *sdata, void *result, size_t need)
38 {
39         struct tf_prng_data *rprng = sdata;
40         memset(result, 0, need);
41         tfe_emit(result, need, &rprng->tfe);
42 }
43
44 void tf_prng_genrandom(void *result, size_t need)
45 {
46         tf_prng_genrandom_r(&tf_prng_sdata, result, need);
47 }
48
49 void tf_prng_seed_r(void *sdata, TF_UNIT_TYPE seed)
50 {
51         TF_UNIT_TYPE k[TF_NR_KEY_UNITS];
52         struct tf_prng_data *rprng = sdata;
53         size_t x;
54
55         memset(rprng, 0, tf_prng_datasize());
56         for (x = 0; x < TF_NR_KEY_UNITS; x++) k[x] = seed;
57         tfe_init(&rprng->tfe, k);
58         rprng->init = 1;
59
60         memset(k, 0, TF_KEY_SIZE);
61 }
62
63 void tf_prng_seed(TF_UNIT_TYPE seed)
64 {
65         tf_prng_seed_r(&tf_prng_sdata, seed);
66 }
67
68 TF_UNIT_TYPE tf_prng_random_r(void *sdata)
69 {
70         struct tf_prng_data *rprng = sdata;
71         TF_UNIT_TYPE r;
72
73         if (!rprng->init) return 0;
74
75         tfe_emit(&r, sizeof(r), &rprng->tfe);
76         return r;
77 }
78
79 TF_UNIT_TYPE tf_prng_random(void)
80 {
81         return tf_prng_random_r(&tf_prng_sdata);
82 }
83
84 TF_UNIT_TYPE tf_prng_range_r(void *sdata, TF_UNIT_TYPE s, TF_UNIT_TYPE d)
85 {
86         TF_UNIT_TYPE c = tf_prng_random_r(sdata);
87         if (d <= s) return s;
88         return TF_PRNG_RANGE(c, TF_UNIT_TYPE, s, d);
89 }
90
91 TF_UNIT_TYPE tf_prng_range(TF_UNIT_TYPE s, TF_UNIT_TYPE d)
92 {
93         return tf_prng_range_r(&tf_prng_sdata, s, d);
94 }