2 *****************************************************************************
3 * @author This file is part of libsnark, developed by SCIPR Lab
4 * and contributors (see AUTHORS).
5 * @copyright MIT license (see LICENSE file)
6 *****************************************************************************/
7 #ifndef DIGEST_SELECTOR_GADGET_TCC_
8 #define DIGEST_SELECTOR_GADGET_TCC_
13 template<typename FieldT>
14 digest_selector_gadget<FieldT>::digest_selector_gadget(
15 protoboard<FieldT> &pb,
16 const size_t digest_size,
17 const digest_variable<FieldT> &input,
18 const pb_linear_combination<FieldT> &is_right,
19 const digest_variable<FieldT> &left,
20 const digest_variable<FieldT> &right,
21 const std::string &annotation_prefix)
22 : gadget<FieldT>(pb, annotation_prefix)
23 , digest_size(digest_size)
31 template<typename FieldT>
32 void digest_selector_gadget<FieldT>::generate_r1cs_constraints()
34 for (size_t i = 0; i < digest_size; ++i) {
36 input = is_right * right + (1-is_right) * left
37 input - left = is_right(right - left)
39 this->pb.add_r1cs_constraint(
40 r1cs_constraint<FieldT>(
42 right.bits[i] - left.bits[i],
43 input.bits[i] - left.bits[i]),
44 FMT(this->annotation_prefix, " propagate_%zu", i));
48 template<typename FieldT>
49 void digest_selector_gadget<FieldT>::generate_r1cs_witness()
51 is_right.evaluate(this->pb);
54 this->pb.lc_val(is_right) == FieldT::one() ||
55 this->pb.lc_val(is_right) == FieldT::zero());
56 if (this->pb.lc_val(is_right) == FieldT::one()) {
57 for (size_t i = 0; i < digest_size; ++i) {
58 this->pb.val(right.bits[i]) = this->pb.val(input.bits[i]);
61 for (size_t i = 0; i < digest_size; ++i) {
62 this->pb.val(left.bits[i]) = this->pb.val(input.bits[i]);
67 } // namespace libsnark
69 #endif // DIGEST_SELECTOR_GADGET_TCC_