1 #ifndef __ZETH_CIRCUITS_COMMITMENT_TCC__
2 #define __ZETH_CIRCUITS_COMMITMENT_TCC__
5 // Content Taken and adapted from Zcash
6 // https://github.com/zcash/zcash/blob/master/src/zcash/circuit/commitment.tcc
11 template<typename FieldT, typename HashT>
12 COMM_gadget<FieldT, HashT>::COMM_gadget(
13 libsnark::protoboard<FieldT> &pb,
14 const libsnark::pb_variable_array<FieldT> &x,
15 const libsnark::pb_variable_array<FieldT> &y,
16 std::shared_ptr<libsnark::digest_variable<FieldT>> result,
17 const std::string &annotation_prefix)
18 : libsnark::gadget<FieldT>(pb, annotation_prefix), result(result)
20 block.reset(new libsnark::block_variable<FieldT>(
21 pb, {x, y}, FMT(this->annotation_prefix, " block")));
23 hasher.reset(new HashT(
24 pb, *block, *result, FMT(this->annotation_prefix, " hasher_gadget")));
27 template<typename FieldT, typename HashT>
28 void COMM_gadget<FieldT, HashT>::generate_r1cs_constraints()
30 // ensure_output_bitness set to true
31 hasher->generate_r1cs_constraints(true);
34 template<typename FieldT, typename HashT>
35 void COMM_gadget<FieldT, HashT>::generate_r1cs_witness()
37 hasher->generate_r1cs_witness();
40 // See Zerocash extended paper, page 22
41 // The commitment cm is computed as
42 // HashT(HashT( trap_r || [HashT(a_pk, rho)]_[128]) || "0"*192 || v)
43 // We denote by trap_r the trapdoor r
44 template<typename FieldT, typename HashT>
45 COMM_cm_gadget<FieldT, HashT>::COMM_cm_gadget(
46 libsnark::protoboard<FieldT> &pb,
47 const libsnark::pb_variable_array<FieldT> &a_pk,
48 const libsnark::pb_variable_array<FieldT> &rho,
49 const libsnark::pb_variable_array<FieldT> &trap_r,
50 const libsnark::pb_variable_array<FieldT> &value_v,
51 libsnark::pb_variable<FieldT> result,
52 const std::string &annotation_prefix)
53 : libsnark::gadget<FieldT>(pb, annotation_prefix)
59 // Allocate temporary variable
62 ZETH_V_SIZE + 2 * HashT::get_digest_len(),
63 FMT(this->annotation_prefix, " cm_input"));
65 temp_result.reset(new libsnark::digest_variable<FieldT>(
67 HashT::get_digest_len(),
68 FMT(this->annotation_prefix, " cm_temp_output")));
71 com_gadget.reset(new COMM_gadget<FieldT, HashT>(
72 pb, trap_r, input, temp_result, annotation_prefix));
74 // This gadget casts the `temp_result` from bits to field element
75 // We reverse the order otherwise the resulting linear combination is built
76 // by interpreting our bit string as little endian.
77 bits_to_field.reset(new libsnark::packing_gadget<FieldT>(
79 libsnark::pb_variable_array<FieldT>(
80 temp_result->bits.rbegin(), temp_result->bits.rend()),
82 FMT(this->annotation_prefix, " cm_bits_to_field")));
85 template<typename FieldT, typename HashT>
86 void COMM_cm_gadget<FieldT, HashT>::generate_r1cs_constraints()
88 com_gadget->generate_r1cs_constraints();
90 // Flag set to true, to check booleaness of `final_k`
91 bits_to_field->generate_r1cs_constraints(true);
94 template<typename FieldT, typename HashT>
95 void COMM_cm_gadget<FieldT, HashT>::generate_r1cs_witness()
97 std::vector<bool> temp;
98 std::vector<bool> apk_bits = a_pk.get_bits(this->pb);
99 temp.insert(temp.end(), apk_bits.begin(), apk_bits.end());
100 std::vector<bool> rho_bits = rho.get_bits(this->pb);
101 temp.insert(temp.end(), rho_bits.begin(), rho_bits.end());
102 std::vector<bool> v_bits = value_v.get_bits(this->pb);
103 temp.insert(temp.end(), v_bits.begin(), v_bits.end());
104 input.fill_with_bits(this->pb, temp);
106 com_gadget->generate_r1cs_witness();
107 bits_to_field->generate_r1cs_witness_from_bits();
110 } // namespace libzeth
112 #endif // __ZETH_CIRCUITS_COMMITMENT_TCC__