Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
merge_verifier.test.cpp
Go to the documentation of this file.
11
13
21template <class RecursiveBuilder> class RecursiveMergeVerifierTest : public testing::Test {
22
23 // Types for recursive verifier circuit
27
28 // Define types relevant for inner circuit
32
33 // Define additional types for testing purposes
40
42
43 public:
45
46 static void tamper_with_proof(MergeProof& merge_proof, const TamperProofMode tampering_mode)
47 {
48 const size_t shift_idx = 0; // Index of shift_size in the merge proof
49 const size_t m_commitment_idx = 1; // Index of first commitment to merged table in merge proof
50 const size_t l_eval_idx = 34; // Index of first evaluation of l(1/kappa) in merge proof
51
52 switch (tampering_mode) {
54 // Tamper with the shift size in the proof
55 merge_proof[shift_idx] += 1;
56 break;
58 // Tamper with the commitment in the proof
59 Commitment m_commitment = FrCodec::deserialize_from_fields<Commitment>(
60 std::span{ merge_proof }.subspan(m_commitment_idx, FrCodec::calc_num_fields<Commitment>()));
61 m_commitment = m_commitment + Commitment::one();
62 auto m_commitment_frs = FrCodec::serialize_to_fields<Commitment>(m_commitment);
63 for (size_t idx = 0; idx < 4; ++idx) {
64 merge_proof[m_commitment_idx + idx] = m_commitment_frs[idx];
65 }
66 break;
67 }
69 // Tamper with the evaluation in the proof
70 merge_proof[l_eval_idx] -= FF(1);
71 break;
72 default:
73 // Nothing to do
74 break;
75 }
76 }
77
80 const TamperProofMode tampering_mode = TamperProofMode::None,
81 const bool expected = true)
82 {
83 RecursiveBuilder outer_circuit;
84
85 MergeProver merge_prover{ op_queue, settings };
86 auto merge_proof = merge_prover.construct_proof();
87 tamper_with_proof(merge_proof, tampering_mode);
88
89 // Subtable values and commitments - needed for (Recursive)MergeVerifier
90 MergeCommitments merge_commitments;
91 RecursiveMergeCommitments recursive_merge_commitments;
92 auto t_current = op_queue->construct_current_ultra_ops_subtable_columns();
93 auto T_prev = op_queue->construct_previous_ultra_ops_table_columns();
94 for (size_t idx = 0; idx < InnerFlavor::NUM_WIRES; idx++) {
95 merge_commitments.t_commitments[idx] = merge_prover.pcs_commitment_key.commit(t_current[idx]);
96 merge_commitments.T_prev_commitments[idx] = merge_prover.pcs_commitment_key.commit(T_prev[idx]);
97 recursive_merge_commitments.t_commitments[idx] =
98 RecursiveMergeVerifier::Commitment::from_witness(&outer_circuit, merge_commitments.t_commitments[idx]);
99 recursive_merge_commitments.T_prev_commitments[idx] = RecursiveMergeVerifier::Commitment::from_witness(
100 &outer_circuit, merge_commitments.T_prev_commitments[idx]);
101 // Removing the free witness tag, since the merge commitments in the full scheme are supposed to
102 // be fiat-shamirred earlier
103 recursive_merge_commitments.t_commitments[idx].unset_free_witness_tag();
104 recursive_merge_commitments.T_prev_commitments[idx].unset_free_witness_tag();
105 }
106
107 // Create a recursive merge verification circuit for the merge proof
108 RecursiveMergeVerifier verifier{ &outer_circuit, settings };
109 verifier.transcript->enable_manifest();
110 const stdlib::Proof<RecursiveBuilder> stdlib_merge_proof(outer_circuit, merge_proof);
111 auto [pairing_points, recursive_merged_table_commitments] =
112 verifier.verify_proof(stdlib_merge_proof, recursive_merge_commitments);
113
114 // Check for a failure flag in the recursive verifier circuit
115 EXPECT_EQ(outer_circuit.failed(), !expected) << outer_circuit.err();
116
117 // Check 1: Perform native merge verification then perform the pairing on the outputs of the recursive merge
118 // verifier and check that the result agrees.
119 MergeVerifier native_verifier{ settings };
120 native_verifier.transcript->enable_manifest();
121 auto [verified_native, merged_table_commitments] = native_verifier.verify_proof(merge_proof, merge_commitments);
122 VerifierCommitmentKey pcs_verification_key;
123 bool verified_recursive =
124 pcs_verification_key.pairing_check(pairing_points.P0.get_value(), pairing_points.P1.get_value());
125 EXPECT_EQ(verified_native, verified_recursive);
126 EXPECT_EQ(verified_recursive, expected);
127
128 // Check 2: Ensure that the underlying native and recursive merge verification algorithms agree by ensuring
129 // the manifests produced by each agree.
130 auto recursive_manifest = verifier.transcript->get_manifest();
131 auto native_manifest = native_verifier.transcript->get_manifest();
132 for (size_t i = 0; i < recursive_manifest.size(); ++i) {
133 EXPECT_EQ(recursive_manifest[i], native_manifest[i]);
134 }
135 }
136
141 {
142 auto op_queue = std::make_shared<ECCOpQueue>();
143
144 InnerBuilder circuit{ op_queue };
147 }
148
152 static void test_merge_failure()
153 {
154 auto op_queue = std::make_shared<ECCOpQueue>();
155
156 InnerBuilder circuit{ op_queue };
159 }
160
164 static void test_eval_failure()
165 {
166 auto op_queue = std::make_shared<ECCOpQueue>();
167
168 InnerBuilder circuit{ op_queue };
171 }
172
181 {
182 auto op_queue = std::make_shared<ECCOpQueue>();
183
184 InnerBuilder circuit{ op_queue };
186 prove_and_verify_merge(op_queue);
187
188 InnerBuilder circuit2{ op_queue };
190 prove_and_verify_merge(op_queue);
191
192 InnerBuilder circuit3{ op_queue };
195 }
196};
197
198using Builders = testing::Types<MegaCircuitBuilder, UltraCircuitBuilder>;
199
201
202TYPED_TEST(RecursiveMergeVerifierTest, SingleRecursiveVerification)
203{
204 TestFixture::test_recursive_merge_verification();
205};
206
208{
209 TestFixture::test_degree_check_failure();
210};
211
213{
214 TestFixture::test_merge_failure();
215};
216
218{
219 TestFixture::test_eval_failure();
220};
221
222} // namespace bb::stdlib::recursion::goblin
static void construct_simple_circuit(MegaBuilder &builder)
Generate a simple test circuit with some ECC op gates and conventional arithmetic gates.
Curve::ScalarField FF
static constexpr size_t NUM_WIRES
MegaCircuitBuilder CircuitBuilder
Curve::AffineElement Commitment
Prover class for the Goblin ECC op queue transcript merge protocol.
BB_PROFILE MergeProof construct_proof()
std::vector< FF > MergeProof
Verifier class for the Goblin ECC op queue transcript merge protocol.
std::array< Commitment, NUM_WIRES > TableCommitments
std::shared_ptr< Transcript > transcript
A ProverInstance is normally constructed from a finalized circuit and it contains all the information...
bool pairing_check(const GroupElement &p0, const GroupElement &p1)
verifies a pairing equation over 2 points using the verifier SRS
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
A simple wrapper around a vector of stdlib field elements representing a proof.
Definition proof.hpp:19
Test suite for recursive verification of Goblin Merge proofs.
static void test_recursive_merge_verification()
Test recursive merge verification for the ops generated by several sample circuit,...
static void test_eval_failure()
Test failure g_j(kappa) = kappa^{k-1} * l_j(1/kappa)
static void tamper_with_proof(MergeProof &merge_proof, const TamperProofMode tampering_mode)
static void prove_and_verify_merge(const std::shared_ptr< ECCOpQueue > &op_queue, const MergeSettings settings=MergeSettings::PREPEND, const TamperProofMode tampering_mode=TamperProofMode::None, const bool expected=true)
static void test_merge_failure()
Test failure when m \neq l + X^k r.
MergeRecursiveVerifier_< RecursiveBuilder >::TableCommitments RecursiveTableCommitments
static void test_degree_check_failure()
Test failure when degree(l) > shift_size (as read from the proof)
std::filesystem::path bb_crs_path()
void init_file_crs_factory(const std::filesystem::path &path)
TYPED_TEST_SUITE(BoomerangRecursiveMergeVerifierTest, Builder)
TYPED_TEST(BoomerangRecursiveMergeVerifierTest, RecursiveVerificationPrepend)
testing::Types< MegaCircuitBuilder, UltraCircuitBuilder > Builders
MergeSettings
The MergeSettings define whether an current subtable will be added at the beginning (PREPEND) or at t...
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13