hash_io.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2021 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020-2021 Nikita Kaskov <nbering@nil.foundation>
4 //
5 // MIT License
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //---------------------------------------------------------------------------//
25 
26 #ifndef CRYPTO3_ZK_BLUEPRINT_HASH_IO_HPP
27 #define CRYPTO3_ZK_BLUEPRINT_HASH_IO_HPP
28 
29 #include <cstddef>
30 #include <vector>
31 
36 
37 namespace nil {
38  namespace crypto3 {
39  namespace zk {
40  namespace components {
41 
42  template<typename FieldType>
43  class digest_variable : public component<FieldType> {
44  public:
45  std::size_t digest_size;
47 
49  component<FieldType>(bp), digest_size(digest_size) {
50 
51  bits.allocate(bp, digest_size);
52  }
53 
55  std::size_t digest_size,
56  const blueprint_variable_vector<FieldType> &partial_bits,
57  const blueprint_variable<FieldType> &padding) :
58  component<FieldType>(bp),
60 
61  assert(bits.size() <= digest_size);
62  bits = partial_bits;
63  while (bits.size() != digest_size) {
64  bits.emplace_back(padding);
65  }
66  }
67 
69  for (std::size_t i = 0; i < digest_size; ++i) {
70  generate_boolean_r1cs_constraint<FieldType>(this->bp, bits[i]);
71  }
72  }
73 
74  void generate_r1cs_witness(const std::vector<bool> &contents) {
75  bits.fill_with_bits(this->bp, contents);
76  }
77 
78  std::vector<bool> get_digest() const {
79  return bits.get_bits(this->bp);
80  }
81  };
82 
83  template<typename FieldType>
84  class block_variable : public component<FieldType> {
85  public:
86  std::size_t block_size;
88 
90  component<FieldType>(bp), block_size(block_size) {
91  bits.allocate(bp, block_size);
92  }
93 
96  component<FieldType>(bp) {
97 
98  for (auto &part : parts) {
99  bits.insert(bits.end(), part.begin(), part.end());
100  }
101  block_size = bits.size();
102  }
103 
105  const digest_variable<FieldType> &left,
106  const digest_variable<FieldType> &right) :
107  component<FieldType>(bp) {
108 
109  assert(left.bits.size() == right.bits.size());
110  block_size = 2 * left.bits.size();
111  bits.insert(bits.end(), left.bits.begin(), left.bits.end());
112  bits.insert(bits.end(), right.bits.begin(), right.bits.end());
113  }
114 
116  void generate_r1cs_witness(const std::vector<bool> &contents) {
117  bits.fill_with_bits(this->bp, contents);
118  }
119 
120  std::vector<bool> get_block() const {
121  return bits.get_bits(this->bp);
122  }
123  };
124 
125  template<typename FieldType>
126  class merkle_damagard_padding : public component<FieldType> {
127  public:
131 
133  size_t message_length,
134  size_t message_length_bits_size,
135  size_t block_bits) :
136  component<FieldType>(bp) {
137  assert(message_length_bits_size <= block_bits);
138  one.allocate(bp);
139  zero.allocate(bp);
140  std::size_t message_remainder = message_length % block_bits;
141  size_t padding_length = 2 * block_bits - message_remainder - message_length_bits_size;
142  padding_length = padding_length % block_bits;
143 
144  bits.resize(padding_length + message_length_bits_size);
145  if (padding_length > 0) {
146  bits[0] = one;
147  for (size_t i = 1; i < padding_length; ++i) {
148  bits[i] = zero;
149  }
150  }
151 
152  unsigned long long message_length_iter = message_length;
153  for (int i = message_length_bits_size - 1; i >= 0; --i) {
154  bits[padding_length + i] = (message_length_iter & 1 ? one : zero);
155  message_length_iter = message_length_iter >> 1;
156  }
157  assert(message_length_iter == 0);
158  }
159 
161  generate_r1cs_equals_const_constraint<FieldType>(this->bp, one, FieldType::value_type::one());
162  generate_r1cs_equals_const_constraint<FieldType>(this->bp, zero, FieldType::value_type::zero());
163  }
164 
166  this->bp.val(one) = 1;
167  this->bp.val(zero) = 0;
168  }
169  };
170  } // namespace components
171  } // namespace zk
172  } // namespace crypto3
173 } // namespace nil
174 #endif // CRYPTO3_ZK_BLUEPRINT_HASH_IO_HPP
std::size_t block_size
Definition: hash_io.hpp:86
void generate_r1cs_witness(const std::vector< bool > &contents)
Definition: hash_io.hpp:116
block_variable(blueprint< FieldType > &bp, const digest_variable< FieldType > &left, const digest_variable< FieldType > &right)
Definition: hash_io.hpp:104
blueprint_variable_vector< FieldType > bits
Definition: hash_io.hpp:87
block_variable(blueprint< FieldType > &bp, const std::vector< blueprint_variable_vector< FieldType >> &parts)
Definition: hash_io.hpp:94
block_variable(blueprint< FieldType > &bp, std::size_t block_size)
Definition: hash_io.hpp:89
std::vector< bool > get_block() const
Definition: hash_io.hpp:120
Definition: blueprint_variable.hpp:57
Definition: blueprint_variable.hpp:46
Definition: blueprint.hpp:46
Definition: component.hpp:37
blueprint< FieldType > & bp
Definition: component.hpp:39
std::vector< bool > get_digest() const
Definition: hash_io.hpp:78
std::size_t digest_size
Definition: hash_io.hpp:45
digest_variable(blueprint< FieldType > &bp, std::size_t digest_size, const blueprint_variable_vector< FieldType > &partial_bits, const blueprint_variable< FieldType > &padding)
Definition: hash_io.hpp:54
blueprint_variable_vector< FieldType > bits
Definition: hash_io.hpp:46
void generate_r1cs_constraints()
Definition: hash_io.hpp:68
void generate_r1cs_witness(const std::vector< bool > &contents)
Definition: hash_io.hpp:74
digest_variable(blueprint< FieldType > &bp, std::size_t digest_size)
Definition: hash_io.hpp:48
void generate_r1cs_constraints()
Definition: hash_io.hpp:160
blueprint_variable< FieldType > one
Definition: hash_io.hpp:129
merkle_damagard_padding(blueprint< FieldType > &bp, size_t message_length, size_t message_length_bits_size, size_t block_bits)
Definition: hash_io.hpp:132
void generate_r1cs_witness()
Definition: hash_io.hpp:165
blueprint_variable_vector< FieldType > bits
Definition: hash_io.hpp:128
blueprint_variable< FieldType > zero
Definition: hash_io.hpp:130
vector(T, U...) -> vector< std::enable_if_t<(std::is_same_v< T, U > &&...), T >, 1+sizeof...(U)>
deduction guide for uniform initialization
Definition: pair.hpp:31