Zeth - Zerocash on Ethereum  0.8
Reference implementation of the Zeth protocol by Clearmatics
g_primitive.tcc
Go to the documentation of this file.
1 // Copyright (c) 2015-2022 Clearmatics Technologies Ltd
2 //
3 // SPDX-License-Identifier: LGPL-3.0+
4 
5 #ifndef __ZETH_CIRCUITS_G_PRIMITIVE_TCC__
6 #define __ZETH_CIRCUITS_G_PRIMITIVE_TCC__
7 
8 namespace libzeth
9 {
10 
11 // See: Section 3.1 of https://tools.ietf.org/html/rfc7693
12 template<typename FieldT>
13 g_primitive<FieldT>::g_primitive(
14  libsnark::protoboard<FieldT> &pb,
15  libsnark::pb_variable_array<FieldT> a,
16  libsnark::pb_variable_array<FieldT> b,
17  libsnark::pb_variable_array<FieldT> c,
18  libsnark::pb_variable_array<FieldT> d,
19  libsnark::pb_variable_array<FieldT> x,
20  libsnark::pb_variable_array<FieldT> y,
21  libsnark::pb_variable_array<FieldT> a2,
22  libsnark::pb_variable_array<FieldT> b2,
23  libsnark::pb_variable_array<FieldT> c2,
24  libsnark::pb_variable_array<FieldT> d2,
25  const std::string &annotation_prefix)
26  : libsnark::gadget<FieldT>(pb, annotation_prefix)
27  , a2(a2)
28  , b2(b2)
29  , c2(c2)
30  , d2(d2)
31 {
32  a1.allocate(pb, 32, " a1");
33  b1.allocate(pb, 32, " b1");
34  c1.allocate(pb, 32, " c1");
35  d1.allocate(pb, 32, " d1");
36  a1_temp.allocate(pb, 32, " a1_temp");
37  a2_temp.allocate(pb, 32, " a2_temp");
38 
39  // v[a] := (v[a] + v[b] + x) mod 2^32
40  a1_1_sum_gadget.reset(
41  new double_bit32_sum_eq_gadget<FieldT>(pb, a, b, a1_temp));
42  a1_2_sum_gadget.reset(
43  new double_bit32_sum_eq_gadget<FieldT>(pb, a1_temp, x, a1));
44  // v[d] := (v[d] ^ v[a]) >>> R1
45  d1_xor_gadget.reset(
46  new xor_rot_gadget<FieldT>(pb, d, a1, rotation_constant_r1, d1));
47  // v[c] := (v[c] + v[d]) mod 2^32
48  c1_sum_gadget.reset(new double_bit32_sum_eq_gadget<FieldT>(pb, c, d1, c1));
49  // v[b] := (v[b] ^ v[c]) >>> R2
50  b1_xor_gadget.reset(
51  new xor_rot_gadget<FieldT>(pb, b, c1, rotation_constant_r2, b1));
52 
53  // v[a] := (v[a] + v[b] + y) mod 2^32
54  a2_1_sum_gadget.reset(
55  new double_bit32_sum_eq_gadget<FieldT>(pb, a1, b1, a2_temp));
56  a2_2_sum_gadget.reset(
57  new double_bit32_sum_eq_gadget<FieldT>(pb, a2_temp, y, a2));
58  // v[d] := (v[d] ^ v[a]) >>> R3
59  d2_xor_gadget.reset(
60  new xor_rot_gadget<FieldT>(pb, d1, a2, rotation_constant_r3, d2));
61  // v[c] := (v[c] + v[d]) mod 2^32
62  c2_sum_gadget.reset(new double_bit32_sum_eq_gadget<FieldT>(pb, c1, d2, c2));
63  // v[b] := (v[b] ^ v[c]) >>> R4
64  b2_xor_gadget.reset(
65  new xor_rot_gadget<FieldT>(pb, b1, c2, rotation_constant_r4, b2));
66 };
67 
68 template<typename FieldT> void g_primitive<FieldT>::generate_r1cs_constraints()
69 {
70  // 262 constraints (4 * 32 (xor) + 4 * 33 (add true) + 2 * 1 (add false))
71  // Note: we do not check the booleaness of this temp variable
72  a1_1_sum_gadget->generate_r1cs_constraints(false);
73  a1_2_sum_gadget->generate_r1cs_constraints();
74  d1_xor_gadget->generate_r1cs_constraints();
75  c1_sum_gadget->generate_r1cs_constraints();
76  b1_xor_gadget->generate_r1cs_constraints();
77 
78  // Note: we do not check the booleaness of this temp variable
79  a2_1_sum_gadget->generate_r1cs_constraints(false);
80  a2_2_sum_gadget->generate_r1cs_constraints();
81  d2_xor_gadget->generate_r1cs_constraints();
82  c2_sum_gadget->generate_r1cs_constraints();
83  b2_xor_gadget->generate_r1cs_constraints();
84 };
85 
86 template<typename FieldT> void g_primitive<FieldT>::generate_r1cs_witness()
87 {
88  a1_1_sum_gadget->generate_r1cs_witness();
89  a1_2_sum_gadget->generate_r1cs_witness();
90  d1_xor_gadget->generate_r1cs_witness();
91  c1_sum_gadget->generate_r1cs_witness();
92  b1_xor_gadget->generate_r1cs_witness();
93 
94  a2_1_sum_gadget->generate_r1cs_witness();
95  a2_2_sum_gadget->generate_r1cs_witness();
96  d2_xor_gadget->generate_r1cs_witness();
97  c2_sum_gadget->generate_r1cs_witness();
98  b2_xor_gadget->generate_r1cs_witness();
99 };
100 
101 } // namespace libzeth
102 
103 #endif // __ZETH_CIRCUITS_G_PRIMITIVE_TCC__