Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
flavor.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
72#pragma once
91
92#include <array>
93#include <concepts>
94#include <cstddef>
95#include <numeric>
96#include <utility>
97#include <vector>
98
99namespace bb {
100
105 FULL, // Serialize all metadata (log_circuit_size, num_public_inputs, pub_inputs_offset)
106 NO_METADATA // Serialize only commitments, no metadata
107};
108
109// Specifies the regions of the execution trace containing non-trivial wire values
111 void add_range(const size_t start, const size_t end)
112 {
113 BB_ASSERT_GTE(start, current_end, "Ranges should be non-overlapping and increasing.");
114 ranges.emplace_back(start, end);
115 for (size_t i = start; i < end; ++i) {
116 idxs.push_back(i);
117 }
118 current_end = end;
119 }
120
122 size_t get_idx(const size_t idx) const { return idxs[idx]; }
123 std::pair<size_t, size_t> get_range(const size_t idx) const { return ranges.at(idx); }
124 size_t size() const { return idxs.size(); }
125 size_t num_ranges() const { return ranges.size(); }
126
127 private:
128 std::vector<std::pair<size_t, size_t>> ranges; // active ranges [start_i, end_i) of the execution trace
129 std::vector<size_t> idxs; // full set of poly indices corresposponding to active ranges
130 size_t current_end{ 0 }; // end of last range; for ensuring monotonicity of ranges
131};
132
136struct MetaData {
137 size_t dyadic_size = 0; // power-of-2 size of the execution trace
140};
141
145template <typename Polynomial, size_t NUM_PRECOMPUTED_ENTITIES> struct PrecomputedData_ {
146 RefArray<Polynomial, NUM_PRECOMPUTED_ENTITIES> polynomials; // polys whose commitments comprise the VK
147 MetaData metadata; // execution trace metadata
148};
149
158template <typename PrecomputedCommitments,
159 typename Transcript,
161class NativeVerificationKey_ : public PrecomputedCommitments {
162 public:
163 using Commitment = typename PrecomputedCommitments::DataType;
164 uint64_t log_circuit_size = 0;
165 uint64_t num_public_inputs = 0;
166 uint64_t pub_inputs_offset = 0;
167
168 bool operator==(const NativeVerificationKey_&) const = default;
169 virtual ~NativeVerificationKey_() = default;
171 NativeVerificationKey_(const size_t circuit_size, const size_t num_public_inputs)
172 {
173 this->log_circuit_size = numeric::get_msb(circuit_size);
174 this->num_public_inputs = num_public_inputs;
175 };
176
181 static size_t calc_num_data_types()
182 {
183 // Create a temporary instance to get the number of precomputed entities
184 size_t commitments_size =
185 PrecomputedCommitments::size() * Transcript::template calc_num_data_types<Commitment>();
186 size_t metadata_size = 0;
187 if constexpr (SerializeMetadata == VKSerializationMode::FULL) {
188 // 3 metadata fields + commitments
189 metadata_size = 3 * Transcript::template calc_num_data_types<uint64_t>();
190 }
191 // else NO_METADATA: metadata_size remains 0
192 return metadata_size + commitments_size;
193 }
194
201 {
202
203 auto serialize = [](const auto& input, std::vector<typename Transcript::DataType>& buffer) {
205 buffer.insert(buffer.end(), input_fields.begin(), input_fields.end());
206 };
207
209
210 if constexpr (SerializeMetadata == VKSerializationMode::FULL) {
211 serialize(this->log_circuit_size, elements);
212 serialize(this->num_public_inputs, elements);
213 serialize(this->pub_inputs_offset, elements);
214 }
215 // else NO_METADATA: skip metadata serialization
216
217 for (const Commitment& commitment : this->get_all()) {
218 serialize(commitment, elements);
219 }
220
222 key.from_field_elements(elements);
223 return elements;
224 };
225
231 {
232
233 size_t idx = 0;
234 auto deserialize = [&idx, &elements]<typename T>(T& target) {
235 size_t size = Transcript::template calc_num_data_types<T>();
236 target = Transcript::template deserialize<T>(elements.subspan(idx, size));
237 idx += size;
238 };
239
240 if constexpr (SerializeMetadata == VKSerializationMode::FULL) {
241 deserialize(this->log_circuit_size);
242 deserialize(this->num_public_inputs);
243 deserialize(this->pub_inputs_offset);
244 }
245 // else NO_METADATA: skip metadata deserialization
246
247 for (Commitment& commitment : this->get_all()) {
248 deserialize(commitment);
249 }
250 return idx;
251 }
252
258 fr hash() const
259 {
260 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1498): should hash be dependent on transcript?
261 fr vk_hash = Transcript::hash(this->to_field_elements());
262 return vk_hash;
263 }
264
277 virtual typename Transcript::DataType hash_through_transcript(const std::string& domain_separator,
278 Transcript& transcript) const
279 {
280 transcript.add_to_independent_hash_buffer(domain_separator + "vk_log_circuit_size", this->log_circuit_size);
281 transcript.add_to_independent_hash_buffer(domain_separator + "vk_num_public_inputs", this->num_public_inputs);
282 transcript.add_to_independent_hash_buffer(domain_separator + "vk_pub_inputs_offset", this->pub_inputs_offset);
283
284 for (const Commitment& commitment : this->get_all()) {
285 transcript.add_to_independent_hash_buffer(domain_separator + "vk_commitment", commitment);
286 }
287
288 return transcript.hash_independent_buffer();
289 }
290};
291
300template <typename Builder_,
301 typename PrecomputedCommitments,
303class StdlibVerificationKey_ : public PrecomputedCommitments {
304 public:
305 using Builder = Builder_;
307 using Commitment = typename PrecomputedCommitments::DataType;
312
313 bool operator==(const StdlibVerificationKey_&) const = default;
314 virtual ~StdlibVerificationKey_() = default;
316 StdlibVerificationKey_(const size_t circuit_size, const size_t num_public_inputs)
317 {
318 this->log_circuit_size = numeric::get_msb(circuit_size);
319 this->num_public_inputs = num_public_inputs;
320 };
321
327 virtual std::vector<FF> to_field_elements() const
328 {
329 using Codec = stdlib::StdlibCodec<FF>;
330
331 auto serialize_to_field_buffer = []<typename T>(const T& input, std::vector<FF>& buffer) {
332 std::vector<FF> input_fields = Codec::template serialize_to_fields<T>(input);
333 buffer.insert(buffer.end(), input_fields.begin(), input_fields.end());
334 };
335
336 std::vector<FF> elements;
337
338 serialize_to_field_buffer(this->log_circuit_size, elements);
339 serialize_to_field_buffer(this->num_public_inputs, elements);
340 serialize_to_field_buffer(this->pub_inputs_offset, elements);
341
342 for (const Commitment& commitment : this->get_all()) {
343 serialize_to_field_buffer(commitment, elements);
344 }
345
346 return elements;
347 };
348
356 {
358 return vk_hash;
359 }
360
373 virtual FF hash_through_transcript(const std::string& domain_separator, Transcript& transcript) const
374 {
375 transcript.add_to_independent_hash_buffer(domain_separator + "vk_log_circuit_size", this->log_circuit_size);
376 transcript.add_to_independent_hash_buffer(domain_separator + "vk_num_public_inputs", this->num_public_inputs);
377 transcript.add_to_independent_hash_buffer(domain_separator + "vk_pub_inputs_offset", this->pub_inputs_offset);
378 for (const Commitment& commitment : this->get_all()) {
379 transcript.add_to_independent_hash_buffer(domain_separator + "vk_commitment", commitment);
380 }
381 return transcript.hash_independent_buffer();
382 }
383};
384
385template <typename FF, typename VerificationKey> class VKAndHash_ {
386 public:
387 using Builder = VerificationKey::Builder;
388 using NativeVerificationKey = VerificationKey::NativeVerificationKey;
389
390 VKAndHash_() = default;
391 VKAndHash_(const std::shared_ptr<VerificationKey>& vk)
392 : vk(vk)
393 , hash(vk->hash())
394 {}
395
396 VKAndHash_(const std::shared_ptr<VerificationKey>& vk, const FF& hash)
397 : vk(vk)
398 , hash(hash)
399 {}
400
402 : vk(std::make_shared<VerificationKey>(&builder, native_vk))
403 , hash(FF::from_witness(&builder, native_vk->hash()))
404 {}
405 std::shared_ptr<VerificationKey> vk;
407};
408
409// Because of how Gemini is written, it is important to put the polynomials out in this order.
410auto get_unshifted_then_shifted(const auto& all_entities)
411{
412 return concatenate(all_entities.get_unshifted(), all_entities.get_shifted());
413};
414
420template <typename Tuple> constexpr size_t compute_max_partial_relation_length()
421{
423 return []<std::size_t... Is>(std::index_sequence<Is...>) {
424 return std::max({ std::tuple_element_t<Is, Tuple>::RELATION_LENGTH... });
425 }(seq);
426}
427
433template <typename Tuple> constexpr size_t compute_max_total_relation_length()
434{
436 return []<std::size_t... Is>(std::index_sequence<Is...>) {
437 return std::max({ std::tuple_element_t<Is, Tuple>::TOTAL_RELATION_LENGTH... });
438 }(seq);
439}
440
444template <typename Tuple> constexpr size_t compute_number_of_subrelations()
445{
447 return []<std::size_t... I>(std::index_sequence<I...>) {
448 return (0 + ... + std::tuple_element_t<I, Tuple>::SUBRELATION_PARTIAL_LENGTHS.size());
449 }(seq);
450}
451
460template <typename Tuple, size_t NUM_INSTANCES, bool optimized = false>
462{
464 return []<size_t... I>(std::index_sequence<I...>) {
465 if constexpr (optimized) {
467 typename std::tuple_element_t<I, Tuple>::template ProtogalaxyTupleOfUnivariatesOverSubrelations<
468 NUM_INSTANCES>{}...);
469 } else {
472 template ProtogalaxyTupleOfUnivariatesOverSubrelationsNoOptimisticSkipping<NUM_INSTANCES>{}...);
473 }
474 }(seq);
475}
476
483template <typename RelationsTuple> constexpr auto create_sumcheck_tuple_of_tuples_of_univariates()
484{
486 return []<size_t... I>(std::index_sequence<I...>) {
488 typename std::tuple_element_t<I, RelationsTuple>::SumcheckTupleOfUnivariatesOverSubrelations{}...);
489 }(seq);
490}
491
506template <typename RelationsTuple> constexpr auto create_tuple_of_arrays_of_values()
507{
509 return []<size_t... I>(std::index_sequence<I...>) {
511 typename std::tuple_element_t<I, RelationsTuple>::SumcheckArrayOfValuesOverSubrelations{}...);
512 }(seq);
513}
514
515} // namespace bb
516
517// Forward declare honk flavors
518namespace bb {
519class UltraFlavor;
520class UltraZKFlavor;
521class UltraRollupFlavor;
522class ECCVMFlavor;
523class UltraKeccakFlavor;
524#ifdef STARKNET_GARAGA_FLAVORS
525class UltraStarknetFlavor;
526class UltraStarknetZKFlavor;
527#endif
528class UltraKeccakZKFlavor;
529class MegaFlavor;
530class MegaZKFlavor;
531class TranslatorFlavor;
532class ECCVMRecursiveFlavor;
533class TranslatorRecursiveFlavor;
534class AvmRecursiveFlavor;
535class MultilinearBatchingRecursiveFlavor;
536
537template <typename BuilderType> class UltraRecursiveFlavor_;
538template <typename BuilderType> class UltraZKRecursiveFlavor_;
539template <typename BuilderType> class UltraRollupRecursiveFlavor_;
540template <typename BuilderType> class MegaRecursiveFlavor_;
541template <typename BuilderType> class MegaZKRecursiveFlavor_;
542
543// Serialization methods for NativeVerificationKey_.
544// These should cover all base classes that do not need additional members, as long as the appropriate SerializeMetadata
545// is set in the template parameters.
546template <typename PrecomputedCommitments, typename Transcript, VKSerializationMode SerializeMetadata>
548{
549 using serialize::read;
550
551 // Get the size directly from the static method
552 size_t num_frs =
554
555 // Read exactly num_frs field elements from the buffer
556 std::vector<typename Transcript::DataType> field_elements(num_frs);
557 for (auto& element : field_elements) {
558 read(it, element);
559 }
560 // Then use from_field_elements to populate the verification key
561 vk.from_field_elements(field_elements);
562}
563
564template <typename PrecomputedCommitments, typename Transcript, VKSerializationMode SerializeMetadata>
565inline void write(std::vector<uint8_t>& buf,
567{
568 using serialize::write;
569 size_t before = buf.size();
570 // Convert to field elements and write them directly without length prefix
571 auto field_elements = vk.to_field_elements();
572 for (const auto& element : field_elements) {
573 write(buf, element);
574 }
575 size_t after = buf.size();
576 size_t num_frs =
578 BB_ASSERT_EQ(after - before, num_frs * sizeof(bb::fr), "VK serialization mismatch");
579}
580
581namespace avm2 {
583}
584
585} // namespace bb
#define BB_ASSERT_GTE(left, right,...)
Definition assert.hpp:133
#define BB_ASSERT_EQ(actual, expected,...)
Definition assert.hpp:88
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
typename Codec::DataType DataType
static DataType hash(const std::vector< DataType > &data)
Static hash method that forwards to Codec hash.
void add_to_independent_hash_buffer(const std::string &label, const T &element)
Adds an element to an independent hash buffer.
static std::vector< DataType > serialize(const T &element)
Serialize a size_t to a vector of field elements.
DataType hash_independent_buffer()
Hashes the independent hash buffer and clears it.
Base Native verification key class.
Definition flavor.hpp:161
static size_t calc_num_data_types()
Calculate the number of field elements needed for serialization.
Definition flavor.hpp:181
bool operator==(const NativeVerificationKey_ &) const =default
typename PrecomputedCommitments::DataType Commitment
Definition flavor.hpp:163
NativeVerificationKey_(const size_t circuit_size, const size_t num_public_inputs)
Definition flavor.hpp:171
size_t from_field_elements(const std::span< const typename Transcript::DataType > &elements)
Populate verification key from field elements.
Definition flavor.hpp:230
fr hash() const
A model function to show how to compute the VK hash(without the Transcript abstracting things away)
Definition flavor.hpp:258
virtual std::vector< typename Transcript::DataType > to_field_elements() const
Serialize verification key to field elements.
Definition flavor.hpp:200
virtual ~NativeVerificationKey_()=default
virtual Transcript::DataType hash_through_transcript(const std::string &domain_separator, Transcript &transcript) const
Hashes the vk using the transcript's independent buffer and returns the hash.
Definition flavor.hpp:277
A template class for a reference array. Behaves as if std::array<T&, N> was possible.
Definition ref_array.hpp:22
Base Stdlib verification key class.
Definition flavor.hpp:303
virtual ~StdlibVerificationKey_()=default
virtual std::vector< FF > to_field_elements() const
Serialize verification key to field elements.
Definition flavor.hpp:327
StdlibVerificationKey_(const size_t circuit_size, const size_t num_public_inputs)
Definition flavor.hpp:316
virtual FF hash_through_transcript(const std::string &domain_separator, Transcript &transcript) const
Hashes the vk using the transcript's independent buffer and returns the hash.
Definition flavor.hpp:373
typename PrecomputedCommitments::DataType Commitment
Definition flavor.hpp:307
FF hash()
A model function to show how to compute the VK hash (without the Transcript abstracting things away).
Definition flavor.hpp:355
bool operator==(const StdlibVerificationKey_ &) const =default
VerificationKey::NativeVerificationKey NativeVerificationKey
Definition flavor.hpp:388
VKAndHash_()=default
VKAndHash_(Builder &builder, const std::shared_ptr< NativeVerificationKey > &native_vk)
Definition flavor.hpp:401
std::shared_ptr< VerificationKey > vk
Definition flavor.hpp:405
VKAndHash_(const std::shared_ptr< VerificationKey > &vk, const FF &hash)
Definition flavor.hpp:396
VerificationKey::Builder Builder
Definition flavor.hpp:387
VKAndHash_(const std::shared_ptr< VerificationKey > &vk)
Definition flavor.hpp:391
static FF hash(const std::vector< FF > &input)
Hashes a vector of field elements.
AluTraceBuilder builder
Definition alu.test.cpp:123
uint8_t const * buf
Definition data_store.hpp:9
ECCVMFlavor::Transcript Transcript
uint8_t buffer[RANDOM_BUFFER_SIZE]
Definition engine.cpp:34
UltraKeccakFlavor::VerificationKey VerificationKey
constexpr T get_msb(const T in)
Definition get_msb.hpp:47
Entry point for Barretenberg command-line interface.
void write(std::vector< uint8_t > &buf, ClientIVC::VerificationKey const &vk)
void read(uint8_t const *&it, ClientIVC::VerificationKey &vk)
typename Flavor::FF FF
constexpr auto create_protogalaxy_tuple_of_tuples_of_univariates()
Utility function to construct a container for the subrelation accumulators of Protogalaxy folding.
Definition flavor.hpp:461
VKSerializationMode
Enum to control verification key metadata serialization.
Definition flavor.hpp:104
RefArray< T,(Ns+...)> constexpr concatenate(const RefArray< T, Ns > &... ref_arrays)
Concatenates multiple RefArray objects into a single RefArray.
constexpr size_t compute_number_of_subrelations()
Utility function to find the number of subrelations.
Definition flavor.hpp:444
constexpr auto create_tuple_of_arrays_of_values()
Definition flavor.hpp:506
constexpr size_t compute_max_partial_relation_length()
Utility function to find max PARTIAL_RELATION_LENGTH tuples of Relations.
Definition flavor.hpp:420
constexpr size_t compute_max_total_relation_length()
Utility function to find max TOTAL_RELATION_LENGTH among tuples of Relations.
Definition flavor.hpp:433
constexpr auto create_sumcheck_tuple_of_tuples_of_univariates()
Utility function to construct a container for the subrelation accumulators of sumcheck proving.
Definition flavor.hpp:483
auto get_unshifted_then_shifted(const auto &all_entities)
Definition flavor.hpp:410
VerifierCommitmentKey< Curve > vk
void read(auto &it, msgpack_concepts::HasMsgPack auto &obj)
Automatically derived read for any object that defines .msgpack() (implicitly defined by MSGPACK_FIEL...
void write(auto &buf, const msgpack_concepts::HasMsgPack auto &obj)
Automatically derived write for any object that defines .msgpack() (implicitly defined by MSGPACK_FIE...
STL namespace.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
TUPLET_INLINE constexpr auto make_tuple(Ts &&... args)
Definition tuplet.hpp:1062
std::pair< size_t, size_t > get_range(const size_t idx) const
Definition flavor.hpp:123
size_t get_idx(const size_t idx) const
Definition flavor.hpp:122
std::vector< std::pair< size_t, size_t > > ranges
Definition flavor.hpp:128
size_t size() const
Definition flavor.hpp:124
size_t num_ranges() const
Definition flavor.hpp:125
void add_range(const size_t start, const size_t end)
Definition flavor.hpp:111
std::vector< size_t > idxs
Definition flavor.hpp:129
std::vector< std::pair< size_t, size_t > > get_ranges() const
Definition flavor.hpp:121
Dyadic trace size and public inputs metadata; Common between prover and verifier keys.
Definition flavor.hpp:136
size_t pub_inputs_offset
Definition flavor.hpp:139
size_t num_public_inputs
Definition flavor.hpp:138
size_t dyadic_size
Definition flavor.hpp:137
The precomputed data needed to compute a Honk VK.
Definition flavor.hpp:145
RefArray< Polynomial, NUM_PRECOMPUTED_ENTITIES > polynomials
Definition flavor.hpp:146