Zeth - Zerocash on Ethereum  0.8
Reference implementation of the Zeth protocol by Clearmatics
blake2s.hpp
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_BLAKE2S_HPP__
6 #define __ZETH_CIRCUITS_BLAKE2S_HPP__
7 
11 #include "libzeth/core/bits.hpp"
12 #include "libzeth/core/utils.hpp"
13 
14 #include <libsnark/gadgetlib1/gadget.hpp>
15 #include <libsnark/gadgetlib1/gadgets/basic_gadgets.hpp>
16 #include <libsnark/gadgetlib1/gadgets/hashes/hash_io.hpp>
17 #include <math.h>
18 
19 namespace libzeth
20 {
21 
24 template<typename FieldT> class BLAKE2s_256 : public libsnark::gadget<FieldT>
25 {
26 private:
27  // Parameter block, size set to 32 bytes, fanout and depth set to serial
28  // mode. See: Section 2.8 https://blake2.net/blake2.pdf Table 2. Note, byte
29  // endianness has been swapped to avoid doing this repeatedly at runtime.
30  const std::array<const bits<BLAKE2s_word_size>, 8> parameter_block = {
31  {{
32  // Digest byte length, Key byte length, Fanout, Depth
33  0, 0, 0, 0, 0, 0, 0, 1, // 0x01 (depth 1)
34  0, 0, 0, 0, 0, 0, 0, 1, // 0x01 (fanout 1)
35  0, 0, 0, 0, 0, 0, 0, 0, // 0x00 (key length)
36  0, 0, 1, 0, 0, 0, 0, 0, // 0x20 (32 bytes)
37  },
38  {
39  // Leaf length
40  0, 0, 0, 0, 0, 0, 0, 0, // 00
41  0, 0, 0, 0, 0, 0, 0, 0, // 00
42  0, 0, 0, 0, 0, 0, 0, 0, // 00
43  0, 0, 0, 0, 0, 0, 0, 0, // 00
44  },
45  {
46  // Node offset
47  0, 0, 0, 0, 0, 0, 0, 0, // 00
48  0, 0, 0, 0, 0, 0, 0, 0, // 00
49  0, 0, 0, 0, 0, 0, 0, 0, // 00
50  0, 0, 0, 0, 0, 0, 0, 0, // 00
51  },
52  {
53  // Node offset (cont.), Node depth, Inner length
54  0, 0, 0, 0, 0, 0, 0, 0, // 00 (inner length)
55  0, 0, 0, 0, 0, 0, 0, 0, // 00 (node depth)
56  0, 0, 0, 0, 0, 0, 0, 0, // 00
57  0, 0, 0, 0, 0, 0, 0, 0, // 00
58  },
59  {
60  // Salt
61  0, 0, 0, 0, 0, 0, 0, 0, // 00
62  0, 0, 0, 0, 0, 0, 0, 0, // 00
63  0, 0, 0, 0, 0, 0, 0, 0, // 00
64  0, 0, 0, 0, 0, 0, 0, 0, // 00
65  },
66  {
67  0, 0, 0, 0, 0, 0, 0, 0, // 00
68  0, 0, 0, 0, 0, 0, 0, 0, // 00
69  0, 0, 0, 0, 0, 0, 0, 0, // 00
70  0, 0, 0, 0, 0, 0, 0, 0, // 00
71  },
72  {
73  // Personalization
74  0, 0, 0, 0, 0, 0, 0, 0, // 00
75  0, 0, 0, 0, 0, 0, 0, 0, // 00
76  0, 0, 0, 0, 0, 0, 0, 0, // 00
77  0, 0, 0, 0, 0, 0, 0, 0, // 00
78  },
79  {
80  0, 0, 0, 0, 0, 0, 0, 0, // 00
81  0, 0, 0, 0, 0, 0, 0, 0, // 00
82  0, 0, 0, 0, 0, 0, 0, 0, // 00
83  0, 0, 0, 0, 0, 0, 0, 0, // 00
84  }}};
85 
86  // See: Appendix A.2 of https://blake2.net/blake2.pdf for the specification
87  // of the IV used in BLAKE2s
88  std::array<bits<BLAKE2s_word_size>, 8> BLAKE2s_IV = {
89  {{
90  0, 1, 1, 0, 1, 0, 1, 0, // 6A
91  0, 0, 0, 0, 1, 0, 0, 1, // 09
92  1, 1, 1, 0, 0, 1, 1, 0, // E6
93  0, 1, 1, 0, 0, 1, 1, 1 // 67
94  },
95  {
96  1, 0, 1, 1, 1, 0, 1, 1, // BB
97  0, 1, 1, 0, 0, 1, 1, 1, // 67
98  1, 0, 1, 0, 1, 1, 1, 0, // AE
99  1, 0, 0, 0, 0, 1, 0, 1 // 85
100  },
101  {
102  0, 0, 1, 1, 1, 1, 0, 0, // 3C
103  0, 1, 1, 0, 1, 1, 1, 0, // 6E
104  1, 1, 1, 1, 0, 0, 1, 1, // F3
105  0, 1, 1, 1, 0, 0, 1, 0 // 72
106  },
107  {
108  1, 0, 1, 0, 0, 1, 0, 1, // A5
109  0, 1, 0, 0, 1, 1, 1, 1, // 4F
110  1, 1, 1, 1, 0, 1, 0, 1, // F5
111  0, 0, 1, 1, 1, 0, 1, 0 // 3A
112  },
113  {
114  0, 1, 0, 1, 0, 0, 0, 1, // 51
115  0, 0, 0, 0, 1, 1, 1, 0, // 0E
116  0, 1, 0, 1, 0, 0, 1, 0, // 52
117  0, 1, 1, 1, 1, 1, 1, 1 // 7F
118  },
119  {
120  1, 0, 0, 1, 1, 0, 1, 1, // 9B
121  0, 0, 0, 0, 0, 1, 0, 1, // 05
122  0, 1, 1, 0, 1, 0, 0, 0, // 68
123  1, 0, 0, 0, 1, 1, 0, 0 // 8C
124  },
125  {
126  0, 0, 0, 1, 1, 1, 1, 1, // 1F
127  1, 0, 0, 0, 0, 0, 1, 1, // 83
128  1, 1, 0, 1, 1, 0, 0, 1, // D9
129  1, 0, 1, 0, 1, 0, 1, 1 // AB
130  },
131  {
132  0, 1, 0, 1, 1, 0, 1, 1, // 5B
133  1, 1, 1, 0, 0, 0, 0, 0, // E0
134  1, 1, 0, 0, 1, 1, 0, 1, // CD
135  0, 0, 0, 1, 1, 0, 0, 1 // 19
136  }}};
137 
138  std::vector<libsnark::block_variable<FieldT>> block;
139  // Chaining values
140  std::vector<libsnark::digest_variable<FieldT>> h;
141 
142  libsnark::block_variable<FieldT> input;
143  libsnark::digest_variable<FieldT> output;
144 
145  // Vector of compression functions
146  std::vector<BLAKE2s_256_comp<FieldT>> BLAKE2sC_vector;
147 
148 public:
149  BLAKE2s_256(
150  libsnark::protoboard<FieldT> &pb,
151  const libsnark::block_variable<FieldT> &input,
152  const libsnark::digest_variable<FieldT> &output,
153  const std::string &annotation_prefix = "blake2s_gadget");
154 
155  // //!\\ Beware we do not check the booleaness of the input block
156  // Unused ensure_output_bitness
157  // This gadget ensures automatically the booleaness of the digest output
158  void generate_r1cs_constraints(const bool ensure_output_bitness = true);
159  void generate_r1cs_witness();
160 
161  static constexpr size_t get_block_len();
162  static constexpr size_t get_digest_len();
163  static libff::bit_vector get_hash(const libff::bit_vector &input);
164 
165  static size_t expected_constraints(const bool ensure_output_bitness);
166 };
167 
168 } // namespace libzeth
169 
171 
172 #endif // __ZETH_CIRCUITS_BLAKE2S_HPP__
libzeth::BLAKE2s_256::generate_r1cs_constraints
void generate_r1cs_constraints(const bool ensure_output_bitness=true)
blake2s_comp.hpp
utils.hpp
binary_operation.hpp
libzeth::BLAKE2s_256::BLAKE2s_256
BLAKE2s_256(libsnark::protoboard< FieldT > &pb, const libsnark::block_variable< FieldT > &input, const libsnark::digest_variable< FieldT > &output, const std::string &annotation_prefix="blake2s_gadget")
libzeth
Definition: binary_operation.hpp:15
circuit_utils.hpp
libzeth::BLAKE2s_256::get_block_len
static constexpr size_t get_block_len()
libzeth::BLAKE2s_256::expected_constraints
static size_t expected_constraints(const bool ensure_output_bitness)
libzeth::BLAKE2s_256::get_hash
static libff::bit_vector get_hash(const libff::bit_vector &input)
libzeth::BLAKE2s_256
Definition: blake2s.hpp:24
blake2s.tcc
bits.hpp
libzeth::BLAKE2s_256::get_digest_len
static constexpr size_t get_digest_len()
libzeth::BLAKE2s_256::generate_r1cs_witness
void generate_r1cs_witness()