1 // Copyright (c) 2015-2022 Clearmatics Technologies Ltd
3 // SPDX-License-Identifier: LGPL-3.0+
5 #ifndef __ZETH_CIRCUITS_G_PRIMITIVE_TCC__
6 #define __ZETH_CIRCUITS_G_PRIMITIVE_TCC__
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)
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");
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
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
51 new xor_rot_gadget<FieldT>(pb, b, c1, rotation_constant_r2, b1));
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
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
65 new xor_rot_gadget<FieldT>(pb, b1, c2, rotation_constant_r4, b2));
68 template<typename FieldT> void g_primitive<FieldT>::generate_r1cs_constraints()
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();
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();
86 template<typename FieldT> void g_primitive<FieldT>::generate_r1cs_witness()
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();
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();
101 } // namespace libzeth
103 #endif // __ZETH_CIRCUITS_G_PRIMITIVE_TCC__