Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
aes_ctr_prf.tcc
Go to the documentation of this file.
1 /** @file
2  *****************************************************************************
3 
4  AES-Based PRF for ADSNARK.
5 
6  *****************************************************************************
7  * @author This file is part of libsnark, developed by SCIPR Lab
8  * and contributors (see AUTHORS).
9  * @copyright MIT license (see LICENSE file)
10  *****************************************************************************/
11 
12 #include "depends/libsnark-supercop/include/crypto_core_aes128encrypt.h"
13 #include "depends/libsnark-supercop/include/randombytes.h"
14 #include "gmp.h"
15 
16 #include <libsnark/common/default_types/r1cs_ppzkadsnark_pp.hpp>
17 
18 namespace libsnark
19 {
20 
21 template<> aesPrfKeyT prfGen<default_r1cs_ppzkadsnark_pp>()
22 {
23  aesPrfKeyT key;
24  randombytes(key.key_bytes, 32);
25  return key;
26 }
27 
28 template<>
29 libff::Fr<snark_pp<default_r1cs_ppzkadsnark_pp>> prfCompute<
30  default_r1cs_ppzkadsnark_pp>(const aesPrfKeyT &key, const labelT &label)
31 {
32  unsigned char seed_bytes[16];
33  mpz_t aux, Fr_mod;
34  unsigned char random_bytes[16 * 3];
35  size_t exp_len;
36 
37  mpz_init(aux);
38  mpz_init(Fr_mod);
39 
40  // compute random seed using AES as PRF
41  crypto_core_aes128encrypt_openssl(
42  seed_bytes, label.label_bytes, key.key_bytes, NULL);
43 
44  // use first 128 bits of output to seed AES-CTR
45  // PRG to expand to 3*128 bits
46  crypto_core_aes128encrypt_openssl(
47  random_bytes, seed_bytes, key.key_bytes + 16, NULL);
48 
49  mpz_import(aux, 16, 0, 1, 0, 0, seed_bytes);
50  mpz_add_ui(aux, aux, 1);
51  mpz_export(seed_bytes, &exp_len, 0, 1, 0, 0, aux);
52  while (exp_len < 16)
53  seed_bytes[exp_len++] = 0;
54 
55  crypto_core_aes128encrypt_openssl(
56  random_bytes + 16, seed_bytes, key.key_bytes + 16, NULL);
57 
58  mpz_add_ui(aux, aux, 1);
59  mpz_export(seed_bytes, &exp_len, 0, 1, 0, 0, aux);
60  while (exp_len < 16)
61  seed_bytes[exp_len++] = 0;
62 
63  crypto_core_aes128encrypt_openssl(
64  random_bytes + 32, seed_bytes, key.key_bytes + 16, NULL);
65 
66  // see output as integer and reduce modulo r
67  mpz_import(aux, 16 * 3, 0, 1, 0, 0, random_bytes);
68  libff::Fr<snark_pp<default_r1cs_ppzkadsnark_pp>>::mod.to_mpz(Fr_mod);
69  mpz_mod(aux, aux, Fr_mod);
70 
71  return libff::Fr<snark_pp<default_r1cs_ppzkadsnark_pp>>(
72  libff::bigint<
73  libff::Fr<snark_pp<default_r1cs_ppzkadsnark_pp>>::num_limbs>(aux));
74 }
75 
76 } // namespace libsnark