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__