Zeth - Zerocash on Ethereum  0.8
Reference implementation of the Zeth protocol by Clearmatics
circuit_utils.tcc
Go to the documentation of this file.
1 // Copyright (c) 2015-2022 Clearmatics Technologies Ltd
2 //
3 // SPDX-License-Identifier: LGPL-3.0+
4 
5 #ifndef __ZETH_CIRCUITS_CIRCUITS_UTILS_TCC__
6 #define __ZETH_CIRCUITS_CIRCUITS_UTILS_TCC__
7 
8 #include <libsnark/gadgetlib1/pb_variable.hpp>
9 #include <vector>
10 
11 namespace libzeth
12 {
13 
14 // This define directive is useless/redundant, as ONE is defined here:
15 // libsnark/gadgetlib1/pb_variable.hpp#74
16 #ifdef ONE
17 #undef ONE
18 #endif
19 #define ONE libsnark::pb_variable<FieldT>(0)
20 //
21 // We know that a pb_variable takes an index in the constructor:
22 // See: libsnark/gadgetlib1/pb_variable.hpp#29
23 // Then the pb_variable can be allocated on the protoboard
24 // See here for the allocation function: libsnark/gadgetlib1/pb_variable.tcc#19
25 // This function calls the allocation function of the protoboard:
26 // libsnark/gadgetlib1/protoboard.tcc#38 This function basically allocates the
27 // variable on the protoboard at the index defined by the variable
28 // "next_free_var". It then returns the index the variable was allocated at,
29 // and, we can see in libsnark/gadgetlib1/pb_variable.tcc#19 that the index of
30 // the variable is given by the index where the variable was allocated on the
31 // protoboard. MOREOVER, we see in: libsnark/gadgetlib1/protoboard.tcc#19 (the
32 // constructor of the protoboard) that "next_free_var = 1;" to account for
33 // constant 1 term. Thus, the variable at index 0 on the protoboard is the
34 // constant_term variable, which value is FieldT::one() (which basically is the
35 // multiplicative identity of the field FieldT) Thus we are safe here. The ONE
36 // is well equal to the value FieldT::one()
37 
38 // Pack input binary strings into F_r and add the resulting field elements
39 // together
40 template<typename FieldT>
41 libsnark::linear_combination<FieldT> packed_addition(
42  const libsnark::pb_variable_array<FieldT> &inputs)
43 {
44  // We use `inputs.rbegin(), inputs.rend()` otherwise the resulting linear
45  // combination is built by interpreting our bit string as little endian.
46  // Thus here, we make sure our binary string is interpreted correctly.
47  return libsnark::pb_packing_sum<FieldT>(
48  libsnark::pb_variable_array<FieldT>(inputs.rbegin(), inputs.rend()));
49 }
50 
51 // Allocate an array of variables on a given protoboard, and set the values to
52 // zero or one based on a vector of bits.
53 template<typename FieldT>
54 libsnark::pb_variable_array<FieldT> pb_variable_array_from_bit_vector(
55  libsnark::protoboard<FieldT> &pb,
56  const std::vector<bool> &bits,
57  const std::string &annotation_prefix)
58 {
59  libsnark::pb_variable_array<FieldT> vars;
60  vars.allocate(pb, bits.size(), annotation_prefix);
61  vars.fill_with_bits(pb, bits);
62  return vars;
63 }
64 
65 } // namespace libzeth
66 
67 #endif // __ZETH_CIRCUITS_CIRCUITS_UTILS_TCC__