Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
chonk_step_processor.cpp
Go to the documentation of this file.
8
9namespace bb {
10namespace {
11
12template <typename VK> void validate_vk_size(const std::vector<uint8_t>& vk_bytes)
13{
14 const size_t expected_size = VK::calc_num_data_types() * sizeof(bb::fr);
15 if (vk_bytes.size() != expected_size) {
16 throw_or_abort("verification key has wrong size: expected " + std::to_string(expected_size) + ", got " +
17 std::to_string(vk_bytes.size()));
18 }
19}
20
21template <typename VK> std::shared_ptr<VK> deserialize_vk(const std::vector<uint8_t>& vk_bytes)
22{
23 validate_vk_size<VK>(vk_bytes);
24 return from_buffer<std::shared_ptr<VK>>(vk_bytes);
25}
26
27template <typename VK, typename Instance> std::shared_ptr<VK> compute_vk_from_program(acir_format::AcirProgram& program)
28{
29 auto builder = acir_format::create_circuit<Chonk::ClientCircuit>(program);
30 return std::make_shared<VK>(Instance(builder).get_precomputed());
31}
32
33template <typename VK, typename Instance> ChonkVkData compute_vk_data(acir_format::AcirProgram& program)
34{
35 auto vk = compute_vk_from_program<VK, Instance>(program);
36 return { .bytes = to_buffer(*vk), .fields = vk->to_field_elements() };
37}
38
39template <typename VK, typename Instance>
40ChonkVkCheckResult check_vk(acir_format::AcirProgram& program, const std::vector<uint8_t>& precomputed_vk_bytes)
41{
42 auto computed_vk = compute_vk_from_program<VK, Instance>(program);
43 auto precomputed_vk = deserialize_vk<VK>(precomputed_vk_bytes);
44 if (*computed_vk == *precomputed_vk) {
45 return {};
46 }
47 return { .valid = false, .actual_vk = to_buffer(*computed_vk) };
48}
49
50void accumulate_next_chonk_circuit(Chonk& ivc,
51 Chonk::ClientCircuit& circuit,
53 const std::vector<uint8_t>& precomputed_vk,
55{
56 // Throw (not BB_ASSERT) so it survives release/WASM: `kind` defaults to None (an unset step, or
57 // one from an old/external msgpack) and never matches the expected kind, failing clearly here.
58 if (kind != ivc.current_kind()) {
59 throw_or_abort("ChonkStepProcessor: supplied CircuitKind disagrees with the kinds the IVC was started with");
60 }
61
62 dispatch_kind(kind, [&]<Chonk::CircuitKind K>() {
63 using FlavorT = flavor_for<K>;
64 using VK = typename FlavorT::VerificationKey;
67 vk = std::make_shared<VK>(ProverInstance_<FlavorT>(circuit).get_precomputed());
68 } else {
69 if (precomputed_vk.empty()) {
70 throw_or_abort("Chonk: precomputed VK is required");
71 }
72 vk = deserialize_vk<VK>(precomputed_vk);
73 if (policy == ChonkPrecomputedVkPolicy::CHECK) {
74 auto computed_vk = std::make_shared<VK>(ProverInstance_<FlavorT>(circuit).get_precomputed());
75 if (*vk != *computed_vk) {
76 throw_or_abort("Chonk: precomputed VK does not match computed VK");
77 }
78 }
79 }
80 ivc.accumulate(circuit, Chonk::CircuitVerificationKey{ vk });
81 });
82}
83
84} // namespace
85
86ChonkStepProcessor::ChonkStepProcessor(std::vector<CircuitKind> circuit_kinds)
87 : ivc(std::make_shared<Chonk>(std::move(circuit_kinds)))
88{}
89
91{
92 const acir_format::ProgramMetadata metadata{ .ivc = ivc };
93 auto circuit = acir_format::create_circuit<Chonk::ClientCircuit>(step.program, metadata);
94
95 info("Chonk: accumulating ", step.name);
98 }
99 accumulate_next_chonk_circuit(*ivc, circuit, step.kind, step.precomputed_vk, policy);
100}
101
103{
104 return ivc->prove();
105}
106
108{
109 return ivc->get_hiding_kernel_vk_and_hash();
110}
111
113{
114 return dispatch_kind(kind, [&]<CircuitKind K>() {
115 using FlavorT = flavor_for<K>;
116 return compute_vk_data<typename FlavorT::VerificationKey, ProverInstance_<FlavorT>>(program);
117 });
118}
119
121 const std::vector<uint8_t>& precomputed_vk,
122 CircuitKind kind)
123{
124 return dispatch_kind(kind, [&]<CircuitKind K>() {
125 using FlavorT = flavor_for<K>;
126 return check_vk<typename FlavorT::VerificationKey, ProverInstance_<FlavorT>>(program, precomputed_vk);
127 });
128}
129
131{
132 return deserialize_vk<Chonk::MegaZKVerificationKey>(vk);
133}
134
139
140} // namespace bb
The IVC scheme used by the aztec client for private function execution.
Definition chonk.hpp:42
bb::CircuitVerificationKey CircuitVerificationKey
Definition chonk.hpp:101
bb::CircuitKind CircuitKind
Definition chonk.hpp:100
MegaCircuitBuilder ClientCircuit
Definition chonk.hpp:58
std::shared_ptr< MegaZKFlavor::VKAndHash > get_hiding_kernel_vk_and_hash() const
std::shared_ptr< Chonk > ivc
ChonkStepProcessor(std::vector< CircuitKind > circuit_kinds)
void process_step(ChonkExecutionStep &&step, ChonkPrecomputedVkPolicy policy=ChonkPrecomputedVkPolicy::DEFAULT)
#define info(...)
Definition log.hpp:93
AluTraceBuilder builder
Definition alu.test.cpp:124
void validate_vk_size(const std::vector< uint8_t > &vk_bytes)
Validate verification key size before deserialization.
bool use_memory_profile
MemoryProfile GLOBAL_MEMORY_PROFILE
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
field< Bn254FrParams > fr
Definition fr.hpp:155
std::shared_ptr< MegaZKFlavor::VKAndHash > deserialize_chonk_vk_and_hash(const std::vector< uint8_t > &vk)
typename flavor_for_impl< K >::type flavor_for
ChonkVkCheckResult check_precomputed_chonk_vk(acir_format::AcirProgram &program, const std::vector< uint8_t > &precomputed_vk, CircuitKind kind)
std::shared_ptr< Chonk::MegaZKVerificationKey > deserialize_chonk_vk(const std::vector< uint8_t > &vk)
ChonkVkData compute_chonk_vk(acir_format::AcirProgram &program, CircuitKind kind)
constexpr decltype(auto) dispatch_kind(CircuitKind kind, F &&f)
VerifierCommitmentKey< Curve > vk
STL namespace.
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
std::vector< uint8_t > to_buffer(T const &value)
Struct containing both the constraints to be added to the circuit and the witness vector.
Metadata required to create a circuit.
std::shared_ptr< bb::Chonk > ivc
void set_circuit_name(const std::string &name)
void throw_or_abort(std::string const &err)