Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
goblin_verifier.test.cpp
Go to the documentation of this file.
11
13class GoblinAvmRecursiveVerifierTests : public testing::Test {
14 public:
18
24
27
28 using TableCommitments = std::array<Commitment, UltraCircuitBuilder::NUM_WIRES>;
30
35
36 // Compute the size of a Translator commitment (in bb::fr's)
37 static constexpr size_t comm_frs = FrCodec::calc_num_fields<Commitment>(); // 4
38 static constexpr size_t eval_frs = FrCodec::calc_num_fields<FF>(); // 1
39
45 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1298):
46 // Better recursion testing - create more flexible proof tampering tests.
47 // Tamper with the `op` commitment in the table commitments (op commitments are no longer in translator proof)
48 static void tamper_with_op_commitment(TableCommitments& table_commitments)
49 {
50 // The first commitment in table is the `op` wire commitment
51 table_commitments[0] = table_commitments[0] * FF(2);
52 };
53
54 // Translator proof ends with [..., Libra:quotient_eval, Shplonk:Q, KZG:W]. We invalidate the proof by multiplying
55 // the eval by 2 (it leads to a Libra consistency check failure).
56 static void tamper_with_libra_eval(HonkProof& translator_proof)
57 {
58 // Proof tail size
59 static constexpr size_t tail_size = 2 * comm_frs + eval_frs; // 2*4 + 1 = 9
60
61 // Index of the target field (one fr) from the beginning
62 const size_t idx = translator_proof.size() - tail_size;
63
64 // Tamper: multiply by 2 (or tweak however you like)
65 translator_proof[idx] = translator_proof[idx] + translator_proof[idx];
66 };
67
68 // ECCVM pre-IPA proof ends with evaluations including `op`. We tamper with the `op` evaluation.
69 // The structure is: [..., op_eval, x_lo_y_hi_eval, x_hi_z_1_eval, y_lo_z_2_eval, IPA_proof...]
70 // So op_eval is 3 fields before the IPA proof starts.
71 static void tamper_with_eccvm_op_eval(HonkProof& eccvm_proof)
72 {
73 // The `op` evaluation is located 3 evaluations before the end of pre-IPA proof
74 // (followed by x_lo_y_hi, x_hi_z_1, y_lo_z_2 evaluations)
75 static constexpr size_t evals_after_op = 3; // x_lo_y_hi, x_hi_z_1, y_lo_z_2
76 const size_t op_eval_idx = eccvm_proof.size() - evals_after_op;
77
78 // Tamper with the op evaluation
79 eccvm_proof[op_eval_idx] += FF(1);
80 };
81
88 {
89 auto op_queue = std::make_shared<ECCOpQueue>();
90 InnerBuilder inner_builder(op_queue);
91 GoblinAvm goblin(inner_builder);
93
94 auto goblin_proof = goblin.prove();
95
96 // Subtable values and commitments
97 TableCommitments table_commitments;
98 auto ultra_ops_table_columns = goblin.op_queue->construct_ultra_ops_table_columns();
99 CommitmentKey<curve::BN254> pcs_commitment_key(goblin.op_queue->get_ultra_ops_table_num_rows());
100 for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) {
101 table_commitments[idx] = pcs_commitment_key.commit(ultra_ops_table_columns[idx]);
102 }
103
104 RecursiveTableCommitments recursive_table_commitments;
105 for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) {
106 recursive_table_commitments[idx] = RecursiveCommitment::from_witness(outer_builder, table_commitments[idx]);
107 // Removing the free witness tag, since the table commitments in the full scheme are supposed to
108 // be fiat-shamirred earlier
109 recursive_table_commitments[idx].unset_free_witness_tag();
110 }
111
112 // Output is a goblin proof plus table commitments
113 return { goblin_proof, table_commitments, recursive_table_commitments };
114 }
115};
116
122{
123 OuterBuilder builder;
124
125 auto [proof, table_commitments, recursive_table_commitments] = create_goblin_avm_prover_output(&builder);
126
127 auto transcript = std::make_shared<Transcript>();
128 GoblinAvmStdlibProof stdlib_proof(builder, proof);
129 bb::GoblinAvmRecursiveVerifier verifier{ transcript, stdlib_proof, recursive_table_commitments };
130 auto output = verifier.reduce_to_pairing_check_and_ipa_opening();
131
133 inputs.pairing_inputs = output.translator_pairing_points;
134 inputs.ipa_claim = output.ipa_claim;
135 inputs.set_public();
136
137 builder.ipa_proof = output.ipa_proof.get_value();
138
139 info("Recursive Verifier: num gates = ", builder.num_gates());
140
141 EXPECT_EQ(builder.failed(), false) << builder.err();
142
143 EXPECT_TRUE(CircuitChecker::check(builder));
144
145 // Construct and verify a proof for the Goblin Recursive Verifier circuit
146 {
147 auto prover_instance = std::make_shared<OuterProverInstance>(builder);
148 auto verification_key =
149 std::make_shared<typename OuterFlavor::VerificationKey>(prover_instance->get_precomputed());
150 auto vk_and_hash = std::make_shared<typename OuterFlavor::VKAndHash>(verification_key);
151 OuterProver prover(prover_instance, verification_key);
152 OuterVerifier verifier(vk_and_hash);
153 auto proof = prover.construct_proof();
154 bool verified = verifier.verify_proof(proof).result;
155
156 ASSERT_TRUE(verified);
157 }
158}
159
165{
166 BB_DISABLE_ASSERTS(); // Avoid on_curve assertion failure in cycle_group etc
167 OuterBuilder builder;
168
169 auto [proof, table_commitments, recursive_table_commitments] = create_goblin_avm_prover_output(&builder);
170
171 // Tamper with the ECCVM proof
172 for (auto& val : proof.eccvm_proof) {
173 if (val > 0) { // tamper by finding the first non-zero value and incrementing it by 1
174 val += 1;
175 break;
176 }
177 }
178
179 auto transcript = std::make_shared<Transcript>();
180 GoblinAvmStdlibProof stdlib_proof(builder, proof);
181 bb::GoblinAvmRecursiveVerifier verifier{ transcript, stdlib_proof, recursive_table_commitments };
182 auto goblin_rec_verifier_output = verifier.reduce_to_pairing_check_and_ipa_opening();
183 EXPECT_FALSE(CircuitChecker::check(builder));
184
186 auto crs_factory = srs::get_grumpkin_crs_factory();
187 VerifierCommitmentKey<curve::Grumpkin> grumpkin_verifier_commitment_key(1 << CONST_ECCVM_LOG_N, crs_factory);
188 OpeningClaim<curve::Grumpkin> native_claim = goblin_rec_verifier_output.ipa_claim.get_native_opening_claim();
189 auto native_ipa_transcript = std::make_shared<NativeTranscript>(goblin_rec_verifier_output.ipa_proof.get_value());
190
191 bool native_result =
192 IPA<curve::Grumpkin>::reduce_verify(grumpkin_verifier_commitment_key, native_claim, native_ipa_transcript);
193 EXPECT_FALSE(native_result);
194}
195
201{
202 // Tamper with the op commitment in table commitments (used by Translator verifier)
203 {
204 OuterBuilder builder;
205
206 auto [proof, table_commitments, _] = create_goblin_avm_prover_output(&builder);
207 TableCommitments tampered_table_commitments = table_commitments;
208 tamper_with_op_commitment(tampered_table_commitments);
209
210 RecursiveTableCommitments recursive_table_commitments;
211 for (size_t idx = 0; idx < MegaFlavor::NUM_WIRES; idx++) {
212 recursive_table_commitments[idx] =
213 RecursiveCommitment::from_witness(&builder, tampered_table_commitments[idx]);
214 recursive_table_commitments[idx].fix_witness();
215 }
216
217 auto transcript = std::make_shared<Transcript>();
218 GoblinAvmStdlibProof stdlib_proof(builder, proof);
219 bb::GoblinAvmRecursiveVerifier verifier{ transcript, stdlib_proof, recursive_table_commitments };
220 auto goblin_rec_verifier_output = verifier.reduce_to_pairing_check_and_ipa_opening();
221
222 // Circuit is correct but pairing check should fail
223 EXPECT_TRUE(CircuitChecker::check(builder));
224
225 // Check that the pairing fails natively
226 bb::PairingPoints<curve::BN254> native_pairing_points(
227 goblin_rec_verifier_output.translator_pairing_points.P0.get_value(),
228 goblin_rec_verifier_output.translator_pairing_points.P1.get_value());
229 bool pairing_result = native_pairing_points.check();
230 EXPECT_FALSE(pairing_result);
231 }
232 // Tamper with the Translator proof non - preamble values
233 {
234 OuterBuilder builder;
235
236 auto [proof, table_commitments, recursive_table_commitments] = create_goblin_avm_prover_output(&builder);
237 auto tampered_proof = proof;
238 tamper_with_libra_eval(tampered_proof.translator_proof);
239
240 auto transcript = std::make_shared<Transcript>();
241 GoblinAvmStdlibProof stdlib_proof(builder, tampered_proof);
242 bb::GoblinAvmRecursiveVerifier verifier{ transcript, stdlib_proof, recursive_table_commitments };
243 [[maybe_unused]] auto goblin_rec_verifier_output = verifier.reduce_to_pairing_check_and_ipa_opening();
244 EXPECT_FALSE(CircuitChecker::check(builder));
245 }
246}
247
252TEST_F(GoblinAvmRecursiveVerifierTests, TranslationEvaluationsFailure)
253{
254 OuterBuilder builder;
255
256 auto [proof, table_commitments, recursive_table_commitments] = create_goblin_avm_prover_output(&builder);
257 // Tamper with the `op` evaluation in the ECCVM proof using the helper function
258 tamper_with_eccvm_op_eval(proof.eccvm_proof);
259
260 auto transcript = std::make_shared<Transcript>();
261 GoblinAvmStdlibProof stdlib_proof(builder, proof);
262 bb::GoblinAvmRecursiveVerifier verifier{ transcript, stdlib_proof, recursive_table_commitments };
263 [[maybe_unused]] auto goblin_rec_verifier_output = verifier.reduce_to_pairing_check_and_ipa_opening();
264
265 EXPECT_FALSE(CircuitChecker::check(builder));
266}
267} // namespace bb::stdlib::recursion::honk
#define BB_DISABLE_ASSERTS()
Definition assert.hpp:33
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
CommitmentKey object over a pairing group 𝔾₁.
Commitment commit(PolynomialSpan< const Fr > polynomial) const
Uses the ProverSRS to create a commitment to p(X)
Simple verification key class for fixed-size circuits (ECCVM, Translator).
Definition flavor.hpp:136
Specialization of Goblin for the AVM.
GoblinAvmProof prove()
Constuct a full GoblinAvm proof (ECCVM, Translator)
TranslatorFlavor::VerificationKey TranslatorVerificationKey
ECCVMFlavor::VerificationKey ECCVMVerificationKey
std::array< Commitment, UltraCircuitBuilder::NUM_WIRES > TableCommitments
std::shared_ptr< OpQueue > op_queue
Definition goblin.hpp:54
IPA (inner product argument) commitment scheme class.
Definition ipa.hpp:92
static constexpr size_t NUM_WIRES
static void construct_arithmetic_circuit(Builder &builder, const size_t target_log2_dyadic_size=4, bool include_public_inputs=true)
Populate a builder with a specified number of arithmetic gates; includes a PI.
Unverified claim (C,r,v) for some witness polynomial p(X) such that.
Definition claim.hpp:53
auto get_native_opening_claim() const
Definition claim.hpp:129
An object storing two EC points that represent the inputs to a pairing check.
bool check() const
Perform the pairing check.
A ProverInstance is normally constructed from a finalized circuit and it contains all the information...
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
Curve::ScalarField FF
Curve::AffineElement Commitment
UltraCircuitBuilder CircuitBuilder
UltraRollupFlavor extends UltraFlavor with IPA proof support.
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
bb::GoblinAvmRecursiveVerifier::Commitment RecursiveCommitment
bb::GoblinAvmRecursiveVerifier::TableCommitments RecursiveTableCommitments
static void tamper_with_libra_eval(HonkProof &translator_proof)
static ProverOutput create_goblin_avm_prover_output(OuterBuilder *outer_builder)
Create a goblin proof and the VM verification keys needed by the goblin recursive verifier.
std::array< Commitment, UltraCircuitBuilder::NUM_WIRES > TableCommitments
static void tamper_with_op_commitment(TableCommitments &table_commitments)
The data that is propagated on the public inputs of a rollup circuit.
#define info(...)
Definition log.hpp:93
AluTraceBuilder builder
Definition alu.test.cpp:124
AvmProvingInputs inputs
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
std::shared_ptr< factories::CrsFactory< curve::Grumpkin > > get_grumpkin_crs_factory()
TEST_F(BoomerangGoblinRecursiveVerifierTests, graph_description_basic)
Construct and check a goblin recursive verification circuit.
std::vector< fr > HonkProof
Definition proof.hpp:15
BaseTranscript< stdlib::StdlibCodec< stdlib::field_t< UltraCircuitBuilder > >, stdlib::poseidon2< UltraCircuitBuilder > > UltraStdlibTranscript
MegaCircuitBuilder_< field< Bn254FrParams > > MegaCircuitBuilder
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13