Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ipa_recursive.test.cpp
Go to the documentation of this file.
1
13
14using namespace bb;
15
16namespace {
17using NativeCurve = curve::Grumpkin;
20
21class IPARecursiveTests : public CommitmentTest<NativeCurve> {
22 public:
23 using Fr = typename NativeCurve::ScalarField;
24 using GroupElement = typename NativeCurve::Element;
28 using Commitment = typename NativeCurve::AffineElement;
30
32 template <size_t log_poly_length>
34 {
35 using NativeIPA = IPA<NativeCurve, log_poly_length>;
36 static constexpr size_t poly_length = 1UL << log_poly_length;
37
38 // First generate an ipa proof
39 auto poly = Polynomial::random(poly_length);
40 // Commit to a zero polynomial
41 Commitment commitment = this->commit(poly);
42
43 auto [x, eval] = this->random_eval(poly);
44 const OpeningPair<NativeCurve> opening_pair = { x, eval };
45 const OpeningClaim<NativeCurve> opening_claim{ opening_pair, commitment };
46
47 // initialize empty prover transcript
48 auto prover_transcript = std::make_shared<NativeTranscript>();
49 NativeIPA::compute_opening_proof(this->ck(), { poly, opening_pair }, prover_transcript);
50
51 // Export proof
52 auto proof = prover_transcript->export_proof();
53
54 // initialize verifier transcript from proof data
55 auto verifier_transcript = std::make_shared<NativeTranscript>();
56 verifier_transcript->load_proof(proof);
57
58 auto result = NativeIPA::reduce_verify(this->vk(), opening_claim, verifier_transcript);
59 EXPECT_TRUE(result);
60
61 // Recursively verify the proof
62 auto stdlib_comm = Curve::Group::from_witness(&builder, commitment);
63 auto stdlib_x = Curve::ScalarField::from_witness(&builder, x);
64 auto stdlib_eval = Curve::ScalarField::from_witness(&builder, eval);
65 OpeningClaim<Curve> stdlib_opening_claim{ { stdlib_x, stdlib_eval }, stdlib_comm };
66
67 // Construct stdlib verifier transcript
68 auto recursive_verifier_transcript = std::make_shared<StdlibTranscript>();
69 recursive_verifier_transcript->load_proof(StdlibProof(builder, proof));
70 return { recursive_verifier_transcript, stdlib_opening_claim };
71 }
72 template <size_t log_poly_length> Builder build_ipa_recursive_verifier_circuit()
73 {
74 using RecursiveIPA = IPA<Curve, log_poly_length>;
75
77 auto [stdlib_transcript, stdlib_claim] = create_ipa_claim<log_poly_length>(builder);
78
79 RecursiveIPA::reduce_verify(stdlib_claim, stdlib_transcript);
81 builder.finalize_circuit(/*ensure_nonzero=*/true);
82 return builder;
83 }
84
90 template <size_t poly_length> void test_recursive_ipa()
91 {
92 Builder builder(build_ipa_recursive_verifier_circuit<poly_length>());
93 info("IPA Recursive Verifier num finalized gates = ", builder.get_num_finalized_gates());
94 EXPECT_TRUE(CircuitChecker::check(builder));
95 }
96
103 template <size_t poly_length> void test_accumulation()
104 {
105 using NativeIPA = IPA<NativeCurve, poly_length>;
106 using RecursiveIPA = IPA<Curve, poly_length>;
107
108 // We create a circuit that does two IPA verifications. However, we don't do the full verifications and instead
109 // accumulate the claims into one claim. This accumulation is done in circuit. Create two accumulators, which
110 // contain the commitment and an opening claim.
112
113 auto [transcript_1, claim_1] = create_ipa_claim<poly_length>(builder);
114 auto [transcript_2, claim_2] = create_ipa_claim<poly_length>(builder);
115
116 // Creates two IPA accumulators and accumulators from the two claims. Also constructs the accumulated h
117 // polynomial.
118 auto [output_claim, ipa_proof] =
119 RecursiveIPA::accumulate(this->ck(), transcript_1, claim_1, transcript_2, claim_2);
120 output_claim.set_public();
121 builder.ipa_proof = ipa_proof;
122 builder.finalize_circuit(/*ensure_nonzero=*/false);
123 info("Circuit with 2 IPA Recursive Verifiers and IPA Accumulation num finalized gates = ",
124 builder.get_num_finalized_gates());
125
126 EXPECT_TRUE(CircuitChecker::check(builder));
127
128 const OpeningPair<NativeCurve> opening_pair{ bb::fq(output_claim.opening_pair.challenge.get_value()),
129 bb::fq(output_claim.opening_pair.evaluation.get_value()) };
130 Commitment native_comm = output_claim.commitment.get_value();
131 const OpeningClaim<NativeCurve> opening_claim{ opening_pair, native_comm };
132
133 // Natively verify this proof to check it.
134 auto verifier_transcript = std::make_shared<NativeTranscript>();
135 verifier_transcript->load_proof(ipa_proof);
136
137 auto result = NativeIPA::reduce_verify(this->vk(), opening_claim, verifier_transcript);
138 EXPECT_TRUE(result);
139 }
140};
141} // namespace
142
143#define IPA_TEST
144
149TEST_F(IPARecursiveTests, RecursiveSmall)
150{
151 static constexpr size_t log_poly_length = 2;
152 test_recursive_ipa<log_poly_length>();
153}
154
159TEST_F(IPARecursiveTests, RecursiveMedium)
160{
161 static constexpr size_t log_poly_length = 10;
162 test_recursive_ipa<log_poly_length>();
163}
164
169TEST_F(IPARecursiveTests, RecursiveLarge)
170{
171 static constexpr size_t log_poly_length = CONST_ECCVM_LOG_N;
172 test_recursive_ipa<log_poly_length>();
173}
174
179TEST_F(IPARecursiveTests, AccumulateSmall)
180{
181 static constexpr size_t log_poly_length = 2;
182 test_accumulation<log_poly_length>();
183}
184
189TEST_F(IPARecursiveTests, AccumulateMedium)
190{
191 static constexpr size_t log_poly_length = 10;
192 test_accumulation<log_poly_length>();
193}
194
195TEST_F(IPARecursiveTests, FullRecursiveVerifier)
196{
197
198 static constexpr size_t log_poly_length = 10;
199 static constexpr size_t poly_length = 1UL << log_poly_length;
200 using RecursiveIPA = IPA<Curve, log_poly_length>;
201 //
203 auto [stdlib_transcript, stdlib_claim] = create_ipa_claim<log_poly_length>(builder);
204
205 VerifierCommitmentKey<Curve> stdlib_pcs_vkey(&builder, poly_length, this->vk());
206 auto result = RecursiveIPA::full_verify_recursive(stdlib_pcs_vkey, stdlib_claim, stdlib_transcript);
207 EXPECT_TRUE(result);
208 builder.finalize_circuit(/*ensure_nonzero=*/true);
209 info("Full IPA Recursive Verifier num finalized gates for length ",
210 1UL << log_poly_length,
211 " = ",
212 builder.get_num_finalized_gates());
213 EXPECT_TRUE(CircuitChecker::check(builder));
214}
215
216TEST_F(IPARecursiveTests, AccumulationAndFullRecursiveVerifier)
217{
218 static constexpr size_t log_poly_length = 10;
219 using RecursiveIPA = IPA<Curve, log_poly_length>;
220
221 // We create a circuit that does two IPA verifications. However, we don't do the full verifications and instead
222 // accumulate the claims into one claim. This accumulation is done in circuit. Create two accumulators, which
223 // contain the commitment and an opening claim.
225
226 auto [transcript_1, claim_1] = create_ipa_claim<log_poly_length>(builder);
227 auto [transcript_2, claim_2] = create_ipa_claim<log_poly_length>(builder);
228
229 // Creates two IPA accumulators and accumulators from the two claims. Also constructs the accumulated h
230 // polynomial.
231 auto [output_claim, ipa_proof] = RecursiveIPA::accumulate(this->ck(), transcript_1, claim_1, transcript_2, claim_2);
232 output_claim.set_public();
233 builder.ipa_proof = ipa_proof;
234 builder.finalize_circuit(/*ensure_nonzero=*/false);
235 info("Circuit with 2 IPA Recursive Verifiers and IPA Accumulation num finalized gates = ",
236 builder.get_num_finalized_gates());
237
238 EXPECT_TRUE(CircuitChecker::check(builder));
239
240 Builder root_rollup;
241 // Fully recursively verify this proof to check it.
242 VerifierCommitmentKey<Curve> stdlib_pcs_vkey(&root_rollup, 1UL << log_poly_length, this->vk());
243 auto stdlib_verifier_transcript = std::make_shared<StdlibTranscript>();
244 stdlib_verifier_transcript->load_proof(StdlibProof(root_rollup, ipa_proof));
245 OpeningClaim<Curve> ipa_claim;
246 ipa_claim.opening_pair.challenge =
247 Curve::ScalarField::create_from_u512_as_witness(&root_rollup, output_claim.opening_pair.challenge.get_value());
248 ipa_claim.opening_pair.evaluation =
249 Curve::ScalarField::create_from_u512_as_witness(&root_rollup, output_claim.opening_pair.evaluation.get_value());
250 ipa_claim.commitment = Curve::AffineElement::from_witness(&root_rollup, output_claim.commitment.get_value());
251 auto result = RecursiveIPA::full_verify_recursive(stdlib_pcs_vkey, ipa_claim, stdlib_verifier_transcript);
252 root_rollup.finalize_circuit(/*ensure_nonzero=*/true);
253 EXPECT_TRUE(result);
254 info("Full IPA Recursive Verifier num finalized gates for length ",
255 1UL << log_poly_length,
256 " = ",
257 root_rollup.get_num_finalized_gates());
258}
CommitmentKey object over a pairing group 𝔾₁.
Commitment commit(const Polynomial &polynomial)
OpeningPair< Curve > random_eval(const Polynomial &polynomial)
IPA (inner product argument) commitment scheme class.
Definition ipa.hpp:95
Unverified claim (C,r,v) for some witness polynomial p(X) such that.
Definition claim.hpp:53
OpeningPair< Curve > opening_pair
Definition claim.hpp:62
Commitment commitment
Definition claim.hpp:64
Opening pair (r,v) for some witness polynomial p(X) such that p(r) = v.
Definition claim.hpp:19
Structured polynomial class that represents the coefficients 'a' of a_0 + a_1 x .....
static Polynomial random(size_t size, size_t start_index=0)
static bool check(const Builder &circuit)
Check the witness satisifies the circuit.
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
void info(Args... args)
Definition log.hpp:70
AluTraceBuilder builder
Definition alu.test.cpp:123
BaseTranscript< StdlibTranscriptParams< Builder > > StdlibTranscript
BaseTranscript< StdlibTranscriptParams< UltraCircuitBuilder > > UltraStdlibTranscript
stdlib::Proof< Builder > StdlibProof
Entry point for Barretenberg command-line interface.
field< Bn254FqParams > fq
Definition fq.hpp:169
TEST_F(IPATest, ChallengesAreZero)
Definition ipa.test.cpp:123
UltraCircuitBuilder_< UltraExecutionTraceBlocks > UltraCircuitBuilder
CommitmentKey< Curve > ck
VerifierCommitmentKey< Curve > vk
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Curve grumpkin in circuit setting.
Definition grumpkin.hpp:21
static void add_default_to_public_inputs(Builder &builder)
Adds default public inputs to the builder.