Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
translator_recursive_verifier.test.cpp
Go to the documentation of this file.
8#include <gtest/gtest.h>
9namespace bb {
10
18// TODO(https://github.com/AztecProtocol/barretenberg/issues/980): Add failing tests after we have a proper shared
19// transcript interface between ECCVM and Translator and we are able to deserialise and serialise the transcript
20// correctly.
21class TranslatorRecursiveTests : public ::testing::Test {
22 public:
32
34
40
42
44
46
47 // Helper function to add no-ops
48 static void add_random_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue, size_t count)
49 {
50 for (size_t i = 0; i < count; i++) {
51 op_queue->random_op_ultra_only();
52 }
53 }
54
55 // Helper function to create an MSM
56 static void add_mixed_ops(std::shared_ptr<bb::ECCOpQueue>& op_queue, size_t count = 100)
57 {
58 auto P1 = InnerG1::random_element();
59 auto P2 = InnerG1::random_element();
60 auto z = InnerFF::random_element();
61 for (size_t i = 0; i < count; i++) {
62 op_queue->add_accumulate(P1);
63 op_queue->mul_accumulate(P2, z);
64 }
65 op_queue->eq_and_reset();
66 }
67
68 // Construct a test circuit based on some random operations
69 static InnerBuilder generate_test_circuit(const InnerBF& batching_challenge_v,
70 const InnerBF& evaluation_challenge_x,
71 const size_t circuit_size_parameter = 500)
72 {
73
74 // Add the same operations to the ECC op queue; the native computation is performed under the hood.
75 auto op_queue = std::make_shared<bb::ECCOpQueue>();
76 op_queue->no_op_ultra_only();
78 add_mixed_ops(op_queue, circuit_size_parameter / 2);
79 op_queue->merge();
80 add_mixed_ops(op_queue, circuit_size_parameter / 2);
82 op_queue->merge(MergeSettings::APPEND, ECCOpQueue::OP_QUEUE_SIZE - op_queue->get_current_subtable_size());
83
84 return InnerBuilder{ batching_challenge_v, evaluation_challenge_x, op_queue };
85 }
86
88 {
89 using NativeVerifierCommitmentKey = InnerFlavor::VerifierCommitmentKey;
90 // Add the same operations to the ECC op queue; the native computation is performed under the hood.
91
92 auto prover_transcript = std::make_shared<Transcript>();
93 prover_transcript->send_to_verifier("init", InnerBF::random_element());
94 // normally this would be the eccvm proof
95 auto fake_inital_proof = prover_transcript->export_proof();
96
97 InnerBF batching_challenge_v = InnerBF::random_element();
98 InnerBF evaluation_challenge_x = InnerBF::random_element();
99
100 InnerBuilder circuit_builder = generate_test_circuit(batching_challenge_v, evaluation_challenge_x);
101 EXPECT_TRUE(TranslatorCircuitChecker::check(circuit_builder));
102 auto proving_key = std::make_shared<TranslatorProvingKey>(circuit_builder);
103 InnerProver prover{ proving_key, prover_transcript };
104 auto proof = prover.construct_proof();
105
106 OuterBuilder outer_circuit;
107
108 // Mock a previous verifier that would in reality be the ECCVM recursive verifier
109 stdlib::Proof<OuterBuilder> stdlib_proof(outer_circuit, fake_inital_proof);
111 transcript->load_proof(stdlib_proof);
112 [[maybe_unused]] auto _ = transcript->template receive_from_prover<RecursiveFlavor::BF>("init");
113
114 auto verification_key = std::make_shared<typename InnerFlavor::VerificationKey>(prover.key->proving_key);
115 RecursiveVerifier verifier{ &outer_circuit, verification_key, transcript };
116 typename RecursiveVerifier::PairingPoints pairing_points =
117 verifier.verify_proof(proof, evaluation_challenge_x, batching_challenge_v);
118 pairing_points.set_public();
119 info("Recursive Verifier: num gates = ", outer_circuit.num_gates);
120
121 // Check for a failure flag in the recursive verifier circuit
122 EXPECT_EQ(outer_circuit.failed(), false) << outer_circuit.err();
123
124 auto native_verifier_transcript = std::make_shared<Transcript>();
125 native_verifier_transcript->load_proof(fake_inital_proof);
126 native_verifier_transcript->template receive_from_prover<InnerBF>("init");
127 InnerVerifier native_verifier(verification_key, native_verifier_transcript);
128 bool native_result = native_verifier.verify_proof(proof, evaluation_challenge_x, batching_challenge_v);
129 NativeVerifierCommitmentKey pcs_vkey{};
130 auto recursive_result = pcs_vkey.pairing_check(pairing_points.P0.get_value(), pairing_points.P1.get_value());
131 EXPECT_EQ(recursive_result, native_result);
132
133 auto recursive_manifest = verifier.transcript->get_manifest();
134 auto native_manifest = native_verifier.transcript->get_manifest();
135 for (size_t i = 0; i < recursive_manifest.size(); ++i) {
136 EXPECT_EQ(recursive_manifest[i], native_manifest[i])
137 << "Recursive Verifier/Verifier manifest discrepency in round " << i;
138 }
139
140 EXPECT_EQ(static_cast<uint64_t>(verifier.key->log_circuit_size.get_value()),
141 verification_key->log_circuit_size);
142 EXPECT_EQ(static_cast<uint64_t>(verifier.key->num_public_inputs.get_value()),
143 verification_key->num_public_inputs);
144 for (auto [vk_poly, native_vk_poly] : zip_view(verifier.key->get_all(), verification_key->get_all())) {
145 EXPECT_EQ(vk_poly.get_value(), native_vk_poly);
146 }
147
148 {
149 auto prover_instance = std::make_shared<OuterProverInstance>(outer_circuit);
150 auto verification_key = std::make_shared<OuterFlavor::VerificationKey>(prover_instance->get_precomputed());
151 OuterProver prover(prover_instance, verification_key);
152 OuterVerifier verifier(verification_key);
153 auto proof = prover.construct_proof();
154 bool verified = verifier.template verify_proof<DefaultIO>(proof).result;
155
156 ASSERT_TRUE(verified);
157 }
158 }
159
161 {
162
163 // Retrieves the trace blocks (each consisting of a specific gate) from the recursive verifier circuit
164 auto get_blocks = [](size_t num_ops)
166 auto prover_transcript = std::make_shared<Transcript>();
167 prover_transcript->send_to_verifier("init", InnerBF::random_element());
168
169 // normally this would be the eccvm proof
170 auto fake_inital_proof = prover_transcript->export_proof();
171 InnerBF batching_challenge_v = InnerBF::random_element();
172 InnerBF evaluation_challenge_x = InnerBF::random_element();
173
174 InnerBuilder inner_circuit = generate_test_circuit(batching_challenge_v, evaluation_challenge_x, num_ops);
175
176 // Generate a proof over the inner circuit
177 auto inner_proving_key = std::make_shared<TranslatorProvingKey>(inner_circuit);
178 InnerProver inner_prover(inner_proving_key, prover_transcript);
179 info("test circuit size: ", inner_proving_key->proving_key->circuit_size);
180 auto verification_key =
182 auto inner_proof = inner_prover.construct_proof();
183
184 // Create a recursive verification circuit for the proof of the inner circuit
185 OuterBuilder outer_circuit;
186
187 // Mock a previous verifier that would in reality be the ECCVM recursive verifier
188 stdlib::Proof<OuterBuilder> stdlib_proof(outer_circuit, fake_inital_proof);
190 transcript->load_proof(stdlib_proof);
191 [[maybe_unused]] auto _ = transcript->template receive_from_prover<typename RecursiveFlavor::BF>("init");
192
193 RecursiveVerifier verifier{ &outer_circuit, verification_key, transcript };
194 // Manually hashing the evaluation and batching challenges to ensure they get a proper origin tag
195 auto stdlib_evaluation_challenge_x = TranslatorBF::from_witness(&outer_circuit, evaluation_challenge_x);
196 auto stdlib_batching_challenge_v = TranslatorBF::from_witness(&outer_circuit, batching_challenge_v);
197 transcript->add_to_hash_buffer("evaluation_challenge_x", stdlib_evaluation_challenge_x);
198 transcript->add_to_hash_buffer("batching_challenge_v", stdlib_batching_challenge_v);
199 typename RecursiveVerifier::PairingPoints pairing_points =
200 verifier.verify_proof(inner_proof, stdlib_evaluation_challenge_x, stdlib_batching_challenge_v);
201 pairing_points.set_public();
202
203 auto outer_proving_key = std::make_shared<OuterProverInstance>(outer_circuit);
204 auto outer_verification_key =
205 std::make_shared<typename OuterFlavor::VerificationKey>(outer_proving_key->get_precomputed());
206
207 return { outer_circuit.blocks, outer_verification_key };
208 };
209
210 auto [blocks_256, verification_key_256] = get_blocks(256);
211 auto [blocks_512, verification_key_512] = get_blocks(512);
212
213 compare_ultra_blocks_and_verification_keys<OuterFlavor>({ blocks_256, blocks_512 },
214 { verification_key_256, verification_key_512 });
215 };
216};
217
222
227} // namespace bb
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
const std::string & err() const
static const size_t OP_QUEUE_SIZE
A ProverInstance is normally constructed from a finalized circuit and it contains all the information...
TranslatorCircuitBuilder creates a circuit that evaluates the correctness of the evaluation of EccOpQ...
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
TranslatorCircuitBuilder CircuitBuilder
Curve::ScalarField FF
Curve::AffineElement Commitment
bb::VerifierCommitmentKey< Curve > VerifierCommitmentKey
NativeTranscript Transcript
std::shared_ptr< TranslatorProvingKey > key
The recursive counterpart of the native Translator flavor.
Test suite for standalone recursive verification of translation proofs.
static void add_mixed_ops(std::shared_ptr< bb::ECCOpQueue > &op_queue, size_t count=100)
static InnerBuilder generate_test_circuit(const InnerBF &batching_challenge_v, const InnerBF &evaluation_challenge_x, const size_t circuit_size_parameter=500)
std::conditional_t< IsMegaBuilder< OuterBuilder >, MegaFlavor, UltraFlavor > OuterFlavor
static void add_random_ops(std::shared_ptr< bb::ECCOpQueue > &op_queue, size_t count)
bool verify_proof(const HonkProof &proof, const uint256_t &evaluation_input_x, const BF &batching_challenge_v)
This function verifies a TranslatorFlavor Honk proof for given program settings.
std::shared_ptr< Transcript > transcript
A simple wrapper around a vector of stdlib field elements representing a proof.
Definition proof.hpp:19
void info(Args... args)
Definition log.hpp:74
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
Entry point for Barretenberg command-line interface.
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:188
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static field random_element(numeric::RNG *engine=nullptr) noexcept
uint32_t set_public()
Set the witness indices for the limbs of the pairing points to public.