emp-toolkit
prg.h
Go to the documentation of this file.
1 #ifndef PRG_H__
2 #define PRG_H__
3 #include "block.h"
4 #include "garble/aes.h"
5 #include "config.h"
6 #include "utils_ec.h"
7 #include <stdio.h>
8 #include <stdarg.h>
9 #include <gmp.h>
14 class PRG;
15 static PRG * rnd = nullptr;
16 class PRG { public:
17  uint64_t counter = 0;
19  PRG(const void * seed = nullptr, int id = 0) {
20  if(rnd == nullptr) {
21  char data[16];
22  FILE *fp;
23  fp = fopen("/dev/urandom", "r");
24  int r_bytes = 0;
25  while (r_bytes < 16) {
26  int r = fread(&data, 1, 16, fp);
27  if (r < 0) exit(1);
28  r_bytes+=r;
29  }
30  fclose(fp);
31  rnd = this;//make rnd not nullptr, to avoiding infinite recursion.
32  rnd = new PRG(data);
33  }
34  if (seed == nullptr) {
35  block data;
36  rnd->random_block(&data, 1);
37  reseed(&data, id);
38  } else
39  reseed(seed, id);
40  }
41  void reseed(const void * key, uint64_t id = 0) {
42  const char * k = (const char *)key;
43  __m128i v = _mm_load_si128((__m128i*)&k[0]);
44  v = xorBlocks(v, makeBlock(0LL, id));
45  AES_set_encrypt_key(v, &aes);
46  counter = 0;
47  }
48 
49  void random_data(void *data, int nbytes) {
50  random_block((block *)data, nbytes/16);
51  if (nbytes % 16 != 0) {
52  block extra;
53  random_block(&extra, 1);
54  memcpy((nbytes/16*16)+(char *) data, &extra, nbytes%16);
55  }
56  }
57  void random_bool(bool * data, int length) {
58  uint8_t * uint_data = (uint8_t*)data;
59  random_data(uint_data, length);
60  for(int i = 0; i < length; ++i)
61  data[i] = uint_data[i] & 1;
62  }
63  void random_data_unaligned(void *data, int nbytes) {
64  block tmp[AES_BATCH_SIZE];
65  for(int i = 0; i < nbytes/(AES_BATCH_SIZE*16); i++) {
67  memcpy((16*i*AES_BATCH_SIZE)+(uint8_t*)data, tmp, 16*AES_BATCH_SIZE);
68  }
69  if (nbytes % (16*AES_BATCH_SIZE) != 0) {
71  memcpy((nbytes/(16*AES_BATCH_SIZE)*(16*AES_BATCH_SIZE))+(uint8_t*) data, tmp, nbytes%(16*AES_BATCH_SIZE));
72  }
73  }
74 
75  void random_block(block * data, int nblocks=1) {
76  for (int i = 0; i < nblocks; ++i) {
77  data[i] = makeBlock(0LL, counter++);
78  }
79  int i = 0;
80  for(; i < nblocks-AES_BATCH_SIZE; i+=AES_BATCH_SIZE) {
81  AES_ecb_encrypt_blks(data+i, AES_BATCH_SIZE, &aes);
82  }
83  AES_ecb_encrypt_blks(data+i, (AES_BATCH_SIZE > nblocks-i) ? nblocks-i:AES_BATCH_SIZE, &aes);
84  }
85 
86  template<typename T, typename ... L>
87  void random_bn(T t, L... l) {
88  random_bn(l...);
89  random_bn(t);
90  }
91 
92  void random_bn(bn_t a, int sign = BN_POS, int bits = BIT_LEN) {
93  int digits;
94  SPLIT(bits, digits, bits, BN_DIG_LOG);
95  digits += (bits > 0 ? 1 : 0);
96  bn_grow(a, digits);
97  random_data((uint8_t*)a->dp, digits * sizeof(dig_t));
98  a->used = digits;
99  a->sign = sign;
100  if (bits > 0) {
101  dig_t mask = ((dig_t)1 << (dig_t)bits) - 1;
102  a->dp[a->used - 1] &= mask;
103  }
104  bn_trim(a);
105  }
106 
107  void random_bn(bn_t *a, int length=1, int sign = BN_POS, int bits = BIT_LEN) {
108  for(int i = 0; i < length; ++i)
109  random_bn(a[i]);
110  }
111 
112  template<typename T, typename ... L>
113  void random_eb(T t, L... l) {
114  random_eb(l...);
115  random_eb(t);
116  }
117 
118  void random_eb(eb_t p) {
119  bn_t n, k;
120  bn_new(k);
121  bn_new(n);
122  eb_curve_get_ord(n);
123  random_bn(k, BN_POS, bn_bits(n));
124  bn_mod(k, k, n);
125  eb_mul_gen(p, k);
126  }
127 
128  void random_eb(eb_t *p, int length=1) {
129  bn_t n, k;
130  bn_new(k);
131  bn_new(n);
132  eb_curve_get_ord(n);
133  for(int i = 0; i < length; ++i) {
134  random_bn(k, BN_POS, bn_bits(n));
135  bn_mod(k, k, n);
136  eb_mul_gen(p[i], k);
137  }
138  }
139 
140  void random_mpz(mpz_t out, int nbits) {
141  int nbytes = (nbits+1)/8;
142  uint8_t * data = new uint8_t[nbytes+16];
143  random_data(data, nbytes+16);
144  int n = nbytes;
145  for(int i = 3; i >= 0; i--) {
146  data[i] = (unsigned char) (n % (1 << 8));
147  n /= (1 << 8);
148  }
149  FILE *fp = fmemopen(data, nbytes+16, "rb");
150  int res = mpz_inp_raw(out, fp);
151  assert(res != 0);
152  }
153  void random_mpz(mpz_t rop, const mpz_t n) {
154  unsigned long size = mpz_sizeinbase(n, 2);
155  while(1) {
156  random_mpz(rop, size);
157  if(mpz_cmp(rop, n) < 0) {
158  break;
159  }
160  }
161  }
162 };
164 #endif// PRP_H__
void random_eb(eb_t *p, int length=1)
Definition: prg.h:128
#define AES_BATCH_SIZE
Definition: config.h:4
void random_bool(bool *data, int length)
Definition: prg.h:57
PRG(const void *seed=nullptr, int id=0)
Definition: prg.h:19
AES_KEY aes
Definition: prg.h:18
__m128i block
Definition: block.h:8
block xorBlocks(block x, block y)
Definition: block.h:35
#define makeBlock(X, Y)
Definition: block.h:69
void random_eb(eb_t p)
Definition: prg.h:118
#define BIT_LEN
Definition: utils_ec.h:10
Definition: aes.h:57
void random_block(block *data, int nblocks=1)
Definition: prg.h:75
void random_mpz(mpz_t out, int nbits)
Definition: prg.h:140
void reseed(const void *key, uint64_t id=0)
Definition: prg.h:41
void random_mpz(mpz_t rop, const mpz_t n)
Definition: prg.h:153
void random_bn(bn_t *a, int length=1, int sign=BN_POS, int bits=BIT_LEN)
Definition: prg.h:107
Definition: prg.h:16
uint64_t counter
Definition: prg.h:17
void random_bn(T t, L... l)
Definition: prg.h:87
void random_bn(bn_t a, int sign=BN_POS, int bits=BIT_LEN)
Definition: prg.h:92
void random_data(void *data, int nbytes)
Definition: prg.h:49
void random_eb(T t, L... l)
Definition: prg.h:113
void random_data_unaligned(void *data, int nbytes)
Definition: prg.h:63