compliance_predicate.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 // @file Declaration of interfaces for a compliance predicate for R1CS PCD.
26 //
27 // A compliance predicate specifies a local invariant to be enforced, by PCD,
28 // throughout a dynamic distributed computation. A compliance predicate
29 // receives input messages, local data, and an output message (and perhaps some
30 // other auxiliary information), and then either accepts or rejects.
31 //---------------------------------------------------------------------------//
32 
33 #ifndef CRYPTO3_ZK_COMPLIANCE_PREDICATE_HPP
34 #define CRYPTO3_ZK_COMPLIANCE_PREDICATE_HPP
35 
36 #include <memory>
37 #include <set>
38 
40 
41 namespace nil {
42  namespace crypto3 {
43  namespace zk {
44  namespace snark {
45 
46  /********************************* Message ***********************************/
47 
55  template<typename FieldType>
57  std::size_t type;
58 
59  r1cs_pcd_message(std::size_t type) : type(type) {
60  }
64  result.insert(result.begin(), typename FieldType::value_type(this->type));
65  return result;
66  }
67 
68  virtual ~r1cs_pcd_message() = default;
69  };
70 
71  /******************************* Local data **********************************/
72 
76  template<typename FieldType>
78  r1cs_pcd_local_data() = default;
80  virtual ~r1cs_pcd_local_data() = default;
81  };
82 
83  /******************************** Witness ************************************/
84 
85  template<typename FieldType>
86  using r1cs_pcd_witness = std::vector<typename FieldType::value_type>;
87 
88  /*************************** Compliance predicate ****************************/
89 
122  template<typename FieldType>
124  public:
125  std::size_t name;
126  std::size_t type;
127 
129 
131  std::size_t max_arity;
132  std::vector<std::size_t> incoming_message_payload_lengths;
133  std::size_t local_data_length;
134  std::size_t witness_length;
135 
137  std::set<std::size_t> accepted_input_types;
138 
143  std::size_t name,
144  std::size_t type,
147  std::size_t max_arity,
148  const std::vector<std::size_t> &incoming_message_payload_lengths,
149  std::size_t local_data_length,
150  std::size_t witness_length,
152  const std::set<std::size_t> &accepted_input_types = std::set<std::size_t>());
153 
156 
157  bool is_well_formed() const;
160 
161  bool
162  is_satisfied(const std::shared_ptr<r1cs_pcd_message<FieldType>> &outgoing_message,
163  const std::vector<std::shared_ptr<r1cs_pcd_message<FieldType>>> &incoming_messages,
164  const std::shared_ptr<r1cs_pcd_local_data<FieldType>> &local_data,
165  const r1cs_pcd_witness<FieldType> &witness) const;
166 
168  };
169 
170  template<typename FieldType>
172 
173  template<typename FieldType>
175 
176  template<typename FieldType>
178  std::size_t name,
179  std::size_t type,
180  const r1cs_constraint_system<FieldType> &constraint_system,
181  std::size_t outgoing_message_payload_length,
182  std::size_t max_arity,
183  const std::vector<std::size_t> &incoming_message_payload_lengths,
184  std::size_t local_data_length,
185  std::size_t witness_length,
186  bool relies_on_same_type_inputs,
187  const std::set<std::size_t> &accepted_input_types) :
188  name(name),
189  type(type), constraint_system(constraint_system),
190  outgoing_message_payload_length(outgoing_message_payload_length), max_arity(max_arity),
191  incoming_message_payload_lengths(incoming_message_payload_lengths),
192  local_data_length(local_data_length), witness_length(witness_length),
193  relies_on_same_type_inputs(relies_on_same_type_inputs), accepted_input_types(accepted_input_types) {
195  }
196 
197  template<typename FieldType>
199  const bool type_not_zero = (type != 0);
200  const bool incoming_message_payload_lengths_well_specified =
201  (incoming_message_payload_lengths.size() == max_arity);
202 
203  std::size_t all_message_payload_lengths = outgoing_message_payload_length;
204  for (std::size_t i = 0; i < incoming_message_payload_lengths.size(); ++i) {
205  all_message_payload_lengths += incoming_message_payload_lengths[i];
206  }
207  const std::size_t type_vec_length = max_arity + 1;
208  const std::size_t arity_length = 1;
209 
210  const bool correct_num_inputs =
211  ((outgoing_message_payload_length + 1) == constraint_system.num_inputs());
212  const bool correct_num_variables =
213  ((all_message_payload_lengths + local_data_length + type_vec_length + arity_length +
214  witness_length) == constraint_system.num_variables());
215 
216  return (type_not_zero && incoming_message_payload_lengths_well_specified && correct_num_inputs &&
217  correct_num_variables);
218  }
219 
220  template<typename FieldType>
222  for (std::size_t i = 0; i < incoming_message_payload_lengths.size(); ++i) {
223  if (incoming_message_payload_lengths[i] != outgoing_message_payload_length) {
224  return false;
225  }
226  }
227 
228  return true;
229  }
230 
231  template<typename FieldType>
233  for (std::size_t i = 1; i < incoming_message_payload_lengths.size(); ++i) {
234  if (incoming_message_payload_lengths[i] != incoming_message_payload_lengths[0]) {
235  return false;
236  }
237  }
238 
239  return true;
240  }
241 
242  template<typename FieldType>
244  const r1cs_pcd_compliance_predicate<FieldType> &other) const {
245  return (this->name == other.name && this->type == other.type &&
246  this->constraint_system == other.constraint_system &&
247  this->outgoing_message_payload_length == other.outgoing_message_payload_length &&
248  this->max_arity == other.max_arity &&
249  this->incoming_message_payload_lengths == other.incoming_message_payload_lengths &&
250  this->local_data_length == other.local_data_length &&
251  this->witness_length == other.witness_length &&
252  this->relies_on_same_type_inputs == other.relies_on_same_type_inputs &&
253  this->accepted_input_types == other.accepted_input_types);
254  }
255 
256  template<typename FieldType>
258  const std::shared_ptr<r1cs_pcd_message<FieldType>> &outgoing_message,
259  const std::vector<std::shared_ptr<r1cs_pcd_message<FieldType>>> &incoming_messages,
260  const std::shared_ptr<r1cs_pcd_local_data<FieldType>> &local_data,
261  const r1cs_pcd_witness<FieldType> &witness) const {
262  assert(outgoing_message.payload_as_r1cs_variable_assignment().size() ==
263  outgoing_message_payload_length);
264  assert(incoming_messages.size() <= max_arity);
265  for (std::size_t i = 0; i < incoming_messages.size(); ++i) {
266  assert(incoming_messages[i].payload_as_r1cs_variable_assignment().size() ==
267  incoming_message_payload_lengths[i]);
268  }
269  assert(local_data.as_r1cs_variable_assignment().size() == local_data_length);
270 
271  r1cs_pcd_compliance_predicate_primary_input<FieldType> cp_primary_input(outgoing_message);
272  r1cs_pcd_compliance_predicate_auxiliary_input<FieldType> cp_auxiliary_input(incoming_messages,
273  local_data, witness);
274 
275  return constraint_system.is_satisfied(
276  cp_primary_input.as_r1cs_primary_input(),
277  cp_auxiliary_input.as_r1cs_auxiliary_input(incoming_message_payload_lengths));
278  }
279  } // namespace snark
280  } // namespace zk
281  } // namespace crypto3
282 } // namespace nil
283 
284 #endif // COMPLIANCE_PREDICATE_HPP
r1cs_auxiliary_input< FieldType > as_r1cs_auxiliary_input(const std::vector< std::size_t > &incoming_message_payload_lengths) const
Definition: r1cs_pcd_params.hpp:68
r1cs_primary_input< FieldType > as_r1cs_primary_input() const
Definition: r1cs_pcd_params.hpp:48
Definition: compliance_predicate.hpp:123
bool has_equal_input_lengths() const
Definition: compliance_predicate.hpp:232
std::vector< std::size_t > incoming_message_payload_lengths
Definition: compliance_predicate.hpp:132
std::set< std::size_t > accepted_input_types
Definition: compliance_predicate.hpp:137
bool is_satisfied(const std::shared_ptr< r1cs_pcd_message< FieldType >> &outgoing_message, const std::vector< std::shared_ptr< r1cs_pcd_message< FieldType >>> &incoming_messages, const std::shared_ptr< r1cs_pcd_local_data< FieldType >> &local_data, const r1cs_pcd_witness< FieldType > &witness) const
Definition: compliance_predicate.hpp:257
bool relies_on_same_type_inputs
Definition: compliance_predicate.hpp:136
r1cs_constraint_system< FieldType > constraint_system
Definition: compliance_predicate.hpp:128
r1cs_pcd_compliance_predicate< FieldType > & operator=(const r1cs_pcd_compliance_predicate< FieldType > &other)=default
bool operator==(const r1cs_pcd_compliance_predicate< FieldType > &other) const
Definition: compliance_predicate.hpp:243
std::size_t witness_length
Definition: compliance_predicate.hpp:134
std::size_t type
Definition: compliance_predicate.hpp:126
std::size_t name
Definition: compliance_predicate.hpp:125
std::size_t local_data_length
Definition: compliance_predicate.hpp:133
r1cs_pcd_compliance_predicate(r1cs_pcd_compliance_predicate< FieldType > &&other)=default
bool is_well_formed() const
Definition: compliance_predicate.hpp:198
std::size_t max_arity
Definition: compliance_predicate.hpp:131
bool has_equal_input_and_output_lengths() const
Definition: compliance_predicate.hpp:221
r1cs_pcd_compliance_predicate(std::size_t name, std::size_t type, const r1cs_constraint_system< FieldType > &constraint_system, std::size_t outgoing_message_payload_length, std::size_t max_arity, const std::vector< std::size_t > &incoming_message_payload_lengths, std::size_t local_data_length, std::size_t witness_length, bool relies_on_same_type_inputs, const std::set< std::size_t > &accepted_input_types=std::set< std::size_t >())
Definition: compliance_predicate.hpp:177
std::size_t outgoing_message_payload_length
Definition: compliance_predicate.hpp:130
r1cs_pcd_compliance_predicate(const r1cs_pcd_compliance_predicate< FieldType > &other)=default
vector(T, U...) -> vector< std::enable_if_t<(std::is_same_v< T, U > &&...), T >, 1+sizeof...(U)>
deduction guide for uniform initialization
std::vector< typename FieldType::value_type > r1cs_pcd_witness
Definition: compliance_predicate.hpp:86
std::vector< typename FieldType::value_type > r1cs_variable_assignment
Definition: r1cs.hpp:107
Definition: pair.hpp:31
bool is_satisfied(const r1cs_primary_input< FieldType > &primary_input, const r1cs_auxiliary_input< FieldType > &auxiliary_input) const
Definition: r1cs.hpp:162
std::size_t num_inputs() const
Definition: r1cs.hpp:135
std::size_t num_variables() const
Definition: r1cs.hpp:139
Definition: compliance_predicate.hpp:77
virtual r1cs_variable_assignment< FieldType > as_r1cs_variable_assignment() const =0
Definition: compliance_predicate.hpp:56
r1cs_pcd_message(std::size_t type)
Definition: compliance_predicate.hpp:59
std::size_t type
Definition: compliance_predicate.hpp:57
r1cs_variable_assignment< FieldType > as_r1cs_variable_assignment() const
Definition: compliance_predicate.hpp:62
virtual r1cs_variable_assignment< FieldType > payload_as_r1cs_variable_assignment() const =0