Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
eccvm.test.cpp
Go to the documentation of this file.
1#include <cstddef>
2#include <cstdint>
3#include <gtest/gtest.h>
4#include <vector>
5
18
19using namespace bb;
23class ECCVMTests : public ::testing::Test {
24 protected:
26};
27namespace {
29}
30
38{
39 using Curve = curve::BN254;
40 using G1 = Curve::Element;
41 using Fr = Curve::ScalarField;
42
44 G1 a = G1::random_element(engine);
45 G1 b = G1::random_element(engine);
46 G1 c = G1::random_element(engine);
49
50 op_queue->add_accumulate(a);
51 op_queue->mul_accumulate(a, x);
52 op_queue->mul_accumulate(b, x);
53 op_queue->mul_accumulate(b, y);
54 op_queue->add_accumulate(a);
55 op_queue->mul_accumulate(b, x);
56 op_queue->eq_and_reset();
57 op_queue->add_accumulate(c);
58 op_queue->mul_accumulate(a, x);
59 op_queue->mul_accumulate(b, x);
60 op_queue->eq_and_reset();
61 op_queue->mul_accumulate(a, x);
62 op_queue->mul_accumulate(b, x);
63 op_queue->mul_accumulate(c, x);
64 op_queue->merge();
65 ECCVMCircuitBuilder builder{ op_queue };
66 return builder;
67}
68
69// returns a CircuitBuilder consisting of mul_add ops of the following form: either 0*g, for a group element, or
70// x * e, where x is a scalar and e is the identity element of the group.
71ECCVMCircuitBuilder generate_zero_circuit([[maybe_unused]] numeric::RNG* engine = nullptr, bool zero_scalars = 1)
72{
73 using Curve = curve::BN254;
74 using G1 = Curve::Element;
75 using Fr = Curve::ScalarField;
76
78
79 if (!zero_scalars) {
80 for (auto i = 0; i < 8; i++) {
82 op_queue->mul_accumulate(Curve::Group::affine_point_at_infinity, x);
83 }
84 } else {
85 for (auto i = 0; i < 8; i++) {
86 G1 g = G1::random_element(engine);
87 op_queue->mul_accumulate(g, 0);
88 }
89 }
90 op_queue->merge();
91
92 ECCVMCircuitBuilder builder{ op_queue };
93 return builder;
94}
95
98 std::vector<FF>& gate_challenges)
99{
100 // Prepare the inputs for the sumcheck prover:
101 // Compute and add beta to relation parameters
102 const FF beta = FF::random_element();
103 const FF gamma = FF::random_element();
104 const FF beta_sqr = beta * beta;
105 relation_parameters.gamma = gamma;
106 relation_parameters.beta = beta;
107 relation_parameters.beta_sqr = beta_sqr;
108 relation_parameters.beta_cube = beta_sqr * beta;
109 relation_parameters.eccvm_set_permutation_delta =
110 gamma * (gamma + beta_sqr) * (gamma + beta_sqr + beta_sqr) * (gamma + beta_sqr + beta_sqr + beta_sqr);
111 relation_parameters.eccvm_set_permutation_delta = relation_parameters.eccvm_set_permutation_delta.invert();
112
113 const size_t unmasked_witness_size = pk->circuit_size - NUM_DISABLED_ROWS_IN_SUMCHECK;
114 // Compute z_perm and inverse polynomial for our logarithmic-derivative lookup method
115 compute_logderivative_inverse<FF, ECCVMFlavor::LookupRelation>(
116 pk->polynomials, relation_parameters, unmasked_witness_size);
117 compute_grand_products<ECCVMFlavor>(pk->polynomials, relation_parameters, unmasked_witness_size);
118
119 // Generate gate challenges
120 for (size_t idx = 0; idx < CONST_ECCVM_LOG_N; idx++) {
121 gate_challenges[idx] = FF::random_element();
122 }
123}
124TEST_F(ECCVMTests, ZeroesCoefficients)
125{
127
128 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
129 ECCVMProver prover(builder, prover_transcript);
130 ECCVMProof proof = prover.construct_proof();
131
132 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
133 ECCVMVerifier verifier(verifier_transcript);
134 bool verified = verifier.verify_proof(proof);
135
136 ASSERT_TRUE(verified);
137}
138TEST_F(ECCVMTests, PointAtInfinity)
139{
141
142 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
143 ECCVMProver prover(builder, prover_transcript);
144 ECCVMProof proof = prover.construct_proof();
145
146 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
147 ECCVMVerifier verifier(verifier_transcript);
148 bool verified = verifier.verify_proof(proof);
149
150 ASSERT_TRUE(verified);
151}
152TEST_F(ECCVMTests, ScalarEdgeCase)
153{
154 using Curve = curve::BN254;
155 using G1 = Curve::Element;
156 using Fr = Curve::ScalarField;
157
159 G1 a = G1::one();
160
161 op_queue->mul_accumulate(a, Fr(uint256_t(1) << 128));
162 op_queue->eq_and_reset();
163 op_queue->merge();
164 ECCVMCircuitBuilder builder{ op_queue };
165
166 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
167 ECCVMProver prover(builder, prover_transcript);
168 ECCVMProof proof = prover.construct_proof();
169
170 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
171 ECCVMVerifier verifier(verifier_transcript);
172 bool verified = verifier.verify_proof(proof);
173
174 ASSERT_TRUE(verified);
175}
183TEST_F(ECCVMTests, ProofLengthCheck)
184{
186
187 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
188 ECCVMProver prover(builder, prover_transcript);
189 ECCVMProof proof = prover.construct_proof();
191}
192
193TEST_F(ECCVMTests, BaseCaseFixedSize)
194{
196
197 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
198 ECCVMProver prover(builder, prover_transcript);
199 ECCVMProof proof = prover.construct_proof();
200
201 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
202 ECCVMVerifier verifier(verifier_transcript);
203 bool verified = verifier.verify_proof(proof);
204
205 ASSERT_TRUE(verified);
206}
207
208TEST_F(ECCVMTests, EqFailsFixedSize)
209{
211 // Tamper with the eq op such that the expected value is incorect
212 builder.op_queue->add_erroneous_equality_op_for_testing();
213 builder.op_queue->merge();
214
215 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
216 ECCVMProver prover(builder, prover_transcript);
217
218 ECCVMProof proof = prover.construct_proof();
219
220 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
221 ECCVMVerifier verifier(verifier_transcript);
222 bool verified = verifier.verify_proof(proof);
223 ASSERT_FALSE(verified);
224}
225
226TEST_F(ECCVMTests, CommittedSumcheck)
227{
228 using Flavor = ECCVMFlavor;
229 using ProvingKey = ECCVMFlavor::ProvingKey;
230 using FF = ECCVMFlavor::FF;
232 using ZKData = ZKSumcheckData<Flavor>;
233
234 bb::RelationParameters<FF> relation_parameters;
235 std::vector<FF> gate_challenges(CONST_ECCVM_LOG_N);
236
238 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
239 ECCVMProver prover(builder, prover_transcript);
241
242 // Prepare the inputs for the sumcheck prover:
243 // Compute and add beta to relation parameters
244 const FF alpha = FF::random_element();
245 complete_proving_key_for_test(relation_parameters, pk, gate_challenges);
246
247 // Clear the transcript
248 prover_transcript = std::make_shared<Transcript>();
249
250 // Run Sumcheck on the ECCVM Prover polynomials
252 SumcheckProver sumcheck_prover(pk->circuit_size,
253 pk->polynomials,
254 prover_transcript,
255 alpha,
256 gate_challenges,
257 relation_parameters,
258 CONST_ECCVM_LOG_N);
259
260 ZKData zk_sumcheck_data = ZKData(CONST_ECCVM_LOG_N, prover_transcript);
261
262 auto prover_output = sumcheck_prover.prove(zk_sumcheck_data);
263
264 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
265 verifier_transcript->load_proof(prover_transcript->export_proof());
266
267 // Execute Sumcheck Verifier
268 SumcheckVerifier<Flavor> sumcheck_verifier(verifier_transcript, alpha, CONST_ECCVM_LOG_N);
269 SumcheckOutput<ECCVMFlavor> verifier_output = sumcheck_verifier.verify(relation_parameters, gate_challenges);
270
271 // Evaluate prover's round univariates at corresponding challenges and compare them with the claimed evaluations
272 // computed by the verifier
273 for (size_t idx = 0; idx < CONST_ECCVM_LOG_N; idx++) {
274 FF true_eval_at_the_challenge = prover_output.round_univariates[idx].evaluate(prover_output.challenge[idx]);
275 FF verifier_eval_at_the_challenge = verifier_output.round_univariate_evaluations[idx][2];
276 EXPECT_TRUE(true_eval_at_the_challenge == verifier_eval_at_the_challenge);
277 }
278
279 // Check that the first sumcheck univariate is consistent with the claimed ZK Sumchek Sum
280 FF prover_target_sum = zk_sumcheck_data.libra_challenge * zk_sumcheck_data.libra_total_sum;
281
282 EXPECT_TRUE(prover_target_sum == verifier_output.round_univariate_evaluations[0][0] +
283 verifier_output.round_univariate_evaluations[0][1]);
284
285 EXPECT_TRUE(verifier_output.verified);
286}
287
295{
296 // Generate a circuit and its verification key (computed at runtime from the proving key)
298 std::shared_ptr<Transcript> prover_transcript = std::make_shared<Transcript>();
299 ECCVMProver prover(builder, prover_transcript);
300
301 std::shared_ptr<Transcript> verifier_transcript = std::make_shared<Transcript>();
302 ECCVMVerifier verifier(verifier_transcript);
303
304 // Generate the default fixed VK
306 // Generate a VK from PK
307 ECCVMFlavor::VerificationKey vk_computed_by_prover(prover.key);
308
309 // Set verifier PCS key to null in both the fixed VK and the generated VK
310 fixed_vk.pcs_verification_key = VerifierCommitmentKey<curve::Grumpkin>();
312
313 auto labels = verifier.key->get_labels();
314 size_t index = 0;
315 for (auto [vk_commitment, fixed_commitment] : zip_view(vk_computed_by_prover.get_all(), fixed_vk.get_all())) {
316 EXPECT_EQ(vk_commitment, fixed_commitment)
317 << "Mismatch between vk_commitment and fixed_commitment at label: " << labels[index];
318 ++index;
319 }
320
321 // Check that the fixed VK is equal to the generated VK
322 EXPECT_EQ(fixed_vk, vk_computed_by_prover);
323}
void SetUp() override
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
The proving key is responsible for storing the polynomials used by the prover.
The verification key is responsible for storing the commitments to the precomputed (non-witnessk) pol...
VerifierCommitmentKey pcs_verification_key
typename Curve::ScalarField FF
static constexpr size_t PROOF_LENGTH_WITHOUT_PUB_INPUTS
NativeTranscript Transcript
ECCVMProof construct_proof()
std::shared_ptr< ProvingKey > key
bool verify_proof(const ECCVMProof &proof)
This function verifies an ECCVM Honk proof for given program settings.
std::shared_ptr< VerificationKey > key
NativeTranscript Transcript
The implementation of the sumcheck Prover for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:126
SumcheckOutput< Flavor > prove()
Non-ZK version: Compute round univariate, place it in transcript, compute challenge,...
Definition sumcheck.hpp:246
Implementation of the sumcheck Verifier for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:698
SumcheckOutput< Flavor > verify(const bb::RelationParameters< FF > &relation_parameters, std::vector< FF > &gate_challenges, const std::vector< FF > &padding_indicator_array)
Extract round univariate, check sum, generate challenge, compute next target sum.....
Definition sumcheck.hpp:771
Representation of the Grumpkin Verifier Commitment Key inside a bn254 circuit.
typename Group::element Element
Definition grumpkin.hpp:55
AluTraceBuilder builder
Definition alu.test.cpp:123
FF a
FF b
void complete_proving_key_for_test(bb::RelationParameters< FF > &relation_parameters, std::shared_ptr< PK > &pk, std::vector< FF > &gate_challenges)
ECCVMCircuitBuilder generate_zero_circuit(numeric::RNG *engine=nullptr, bool zero_scalars=1)
ECCVMCircuitBuilder generate_circuit(numeric::RNG *engine=nullptr)
Adds operations in BN254 to the op_queue and then constructs and ECCVM circuit from the op_queue.
RNG & get_debug_randomness(bool reset, std::uint_fast64_t seed)
Definition engine.cpp:190
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
typename Flavor::FF FF
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
Curve::ScalarField Fr
Curve::AffineElement G1
size_t size() const
Definition proof.hpp:27
Container for parameters used by the grand product (permutation, lookup) Honk relations.
Contains the evaluations of multilinear polynomials at the challenge point . These are computed by S...
std::vector< std::array< FF, 3 > > round_univariate_evaluations
This structure is created to contain various polynomials and constants required by ZK Sumcheck.
static field random_element(numeric::RNG *engine=nullptr) noexcept