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__