2 // Content taken and adapted from:
3 // https://github.com/HarryR/ethsnarks/blob/master/src/gadgets/merkle_tree.hpp
4 // https://github.com/HarryR/ethsnarks/blob/master/src/gadgets/merkle_tree.cpp
6 #ifndef __ZETH_CIRCUITS_MERKLE_PATH_SELECTOR_TCC__
7 #define __ZETH_CIRCUITS_MERKLE_PATH_SELECTOR_TCC__
12 template<typename FieldT>
13 merkle_path_selector<FieldT>::merkle_path_selector(
14 libsnark::protoboard<FieldT> &pb,
15 const libsnark::pb_variable<FieldT> &input,
16 const libsnark::pb_variable<FieldT> &pathvar,
17 const libsnark::pb_variable<FieldT> &is_right,
18 const std::string &annotation_prefix)
19 : libsnark::gadget<FieldT>(pb, annotation_prefix)
24 // We allocate the selector's outputs left and right
25 left.allocate(pb, FMT(this->annotation_prefix, " left"));
26 right.allocate(pb, FMT(this->annotation_prefix, " right"));
29 template<typename FieldT>
30 void merkle_path_selector<FieldT>::generate_r1cs_constraints()
32 // Constrain is_right to be boolean
33 this->pb.add_r1cs_constraint(
34 libsnark::r1cs_constraint<FieldT>(is_right, 1 - is_right, 0),
35 FMT(this->annotation_prefix, " is_right"));
37 // We then constrain left to be the authentication node if is_right = 1,
39 this->pb.add_r1cs_constraint(
40 libsnark::r1cs_constraint<FieldT>(
41 is_right, pathvar - input, left - input),
42 FMT(this->annotation_prefix,
43 " is_right*pathvar+(1-is_right)*input=left"));
45 // Inversely, we constrain right to be the input if is_right = 1, the
46 // authentication node otherwise
47 this->pb.add_r1cs_constraint(
48 libsnark::r1cs_constraint<FieldT>(
49 is_right, input - pathvar, right - pathvar),
50 FMT(this->annotation_prefix,
51 " is_right*input+(1-is_right)*pathvar=right"));
54 template<typename FieldT>
55 void merkle_path_selector<FieldT>::generate_r1cs_witness()
57 // We compute left and right according to the constrains
60 this->pb.val(is_right) * (this->pb.val(pathvar) - this->pb.val(input));
62 this->pb.val(pathvar) +
63 this->pb.val(is_right) * (this->pb.val(input) - this->pb.val(pathvar));
66 template<typename FieldT>
67 const libsnark::pb_variable<FieldT> &merkle_path_selector<FieldT>::get_left()
72 template<typename FieldT>
73 const libsnark::pb_variable<FieldT> &merkle_path_selector<FieldT>::get_right()
78 } // namespace libzeth
80 #endif // __ZETH_CIRCUITS_MERKLE_PATH_SELECTOR_TCC__