Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
sumcheck.test.cpp
Go to the documentation of this file.
13
14#include <gtest/gtest.h>
15
16using namespace bb;
17
19using FF = typename Flavor::FF;
20
21class SumcheckTestsRealCircuit : public ::testing::Test {
22 protected:
24};
25
31{
32 using Flavor = UltraFlavor;
33 using FF = typename Flavor::FF;
34 using Transcript = typename Flavor::Transcript;
35 using SubrelationSeparators = typename Flavor::SubrelationSeparators;
36
37 // Create a composer and a dummy circuit with a few gates
39 FF a = FF::one();
40
41 // Add some basic add gates, with a public input for good measure
42 uint32_t a_idx = builder.add_public_variable(a);
43 FF b = FF::one();
44 FF c = a + b;
45 FF d = a + c;
46 uint32_t b_idx = builder.add_variable(b);
47 uint32_t c_idx = builder.add_variable(c);
48 uint32_t d_idx = builder.add_variable(d);
49 for (size_t i = 0; i < 16; i++) {
50 builder.create_add_gate({ a_idx, b_idx, c_idx, 1, 1, -1, 0 });
51 builder.create_add_gate({ d_idx, c_idx, a_idx, 1, -1, -1, 0 });
52 }
53
54 // Add a big add gate with use of next row to test q_arith = 2
55 FF e = a + b + c + d;
56 uint32_t e_idx = builder.add_variable(e);
57
58 uint32_t zero_idx = builder.zero_idx;
59 builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, -1, -1, -1, -1, 0 }, true); // use next row
60 builder.create_big_add_gate({ zero_idx, zero_idx, zero_idx, e_idx, 0, 0, 0, 0, 0 }, false);
61
62 // Add some lookup gates (related to pedersen hashing)
63 auto pedersen_input_value = FF::random_element();
64 const FF input_hi =
65 uint256_t(pedersen_input_value)
66 .slice(plookup::fixed_base::table::BITS_PER_LO_SCALAR,
67 plookup::fixed_base::table::BITS_PER_LO_SCALAR + plookup::fixed_base::table::BITS_PER_HI_SCALAR);
68 const FF input_lo = uint256_t(pedersen_input_value).slice(0, bb::plookup::fixed_base::table::BITS_PER_LO_SCALAR);
69 const auto input_hi_index = builder.add_variable(input_hi);
70 const auto input_lo_index = builder.add_variable(input_lo);
71
72 const auto sequence_data_hi =
74 const auto sequence_data_lo =
76
77 builder.create_gates_from_plookup_accumulators(
78 plookup::MultiTableId::FIXED_BASE_LEFT_HI, sequence_data_hi, input_hi_index);
79 builder.create_gates_from_plookup_accumulators(
80 plookup::MultiTableId::FIXED_BASE_LEFT_LO, sequence_data_lo, input_lo_index);
81
82 // Add a sort gate (simply checks that consecutive inputs have a difference of < 4)
83 a_idx = builder.add_variable(FF(0));
84 b_idx = builder.add_variable(FF(1));
85 c_idx = builder.add_variable(FF(2));
86 d_idx = builder.add_variable(FF(3));
87 builder.create_sort_constraint({ a_idx, b_idx, c_idx, d_idx });
88
89 // Add an elliptic curve addition gate
90 grumpkin::g1::affine_element p1 = grumpkin::g1::affine_element::random_element();
91 grumpkin::g1::affine_element p2 = grumpkin::g1::affine_element::random_element();
92
94
95 uint32_t x1 = builder.add_variable(p1.x);
96 uint32_t y1 = builder.add_variable(p1.y);
97 uint32_t x2 = builder.add_variable(p2.x);
98 uint32_t y2 = builder.add_variable(p2.y);
99 uint32_t x3 = builder.add_variable(p3.x);
100 uint32_t y3 = builder.add_variable(p3.y);
101
102 builder.create_ecc_add_gate({ x1, y1, x2, y2, x3, y3, 1 });
103
104 // Add some RAM gates
105 uint32_t ram_values[8]{
106 builder.add_variable(FF::random_element()), builder.add_variable(FF::random_element()),
107 builder.add_variable(FF::random_element()), builder.add_variable(FF::random_element()),
108 builder.add_variable(FF::random_element()), builder.add_variable(FF::random_element()),
109 builder.add_variable(FF::random_element()), builder.add_variable(FF::random_element()),
110 };
111
112 size_t ram_id = builder.create_RAM_array(8);
113
114 for (size_t i = 0; i < 8; ++i) {
115 builder.init_RAM_element(ram_id, i, ram_values[i]);
116 }
117
118 a_idx = builder.read_RAM_array(ram_id, builder.add_variable(5));
119 EXPECT_EQ(a_idx != ram_values[5], true);
120
121 b_idx = builder.read_RAM_array(ram_id, builder.add_variable(4));
122 c_idx = builder.read_RAM_array(ram_id, builder.add_variable(1));
123
124 builder.write_RAM_array(ram_id, builder.add_variable(4), builder.add_variable(500));
125 d_idx = builder.read_RAM_array(ram_id, builder.add_variable(4));
126
127 EXPECT_EQ(builder.get_variable(d_idx), 500);
128
129 // ensure these vars get used in another arithmetic gate
130 const auto e_value = builder.get_variable(a_idx) + builder.get_variable(b_idx) + builder.get_variable(c_idx) +
131 builder.get_variable(d_idx);
132 e_idx = builder.add_variable(e_value);
133
134 builder.create_big_add_gate({ a_idx, b_idx, c_idx, d_idx, -1, -1, -1, -1, 0 }, true);
135 builder.create_big_add_gate(
136 {
137 builder.zero_idx,
138 builder.zero_idx,
139 builder.zero_idx,
140 e_idx,
141 0,
142 0,
143 0,
144 0,
145 0,
146 },
147 false);
148
150 // Create a prover (it will compute proving key and witness)
152
154
155 auto prover_transcript = Transcript::prover_init_empty();
156 auto circuit_size = decider_pk->dyadic_size();
157 auto log_circuit_size = numeric::get_msb(circuit_size);
158 const size_t virtual_log_n = log_circuit_size + 2; // arbitrary but larger than genuine log n
159
160 SubrelationSeparators prover_alphas;
161 for (size_t idx = 0; idx < prover_alphas.size(); idx++) {
162 prover_alphas[idx] = prover_transcript->template get_challenge<FF>("Sumcheck:alpha_" + std::to_string(idx));
163 }
164
165 std::vector<FF> prover_gate_challenges(virtual_log_n);
166 for (size_t idx = 0; idx < virtual_log_n; idx++) {
167 prover_gate_challenges[idx] =
168 prover_transcript->template get_challenge<FF>("Sumcheck:gate_challenge_" + std::to_string(idx));
169 }
170 decider_pk->gate_challenges = prover_gate_challenges;
171
172 SumcheckProver<Flavor> sumcheck_prover(circuit_size,
173 decider_pk->polynomials,
174 prover_transcript,
175 prover_alphas,
176 prover_gate_challenges,
177 decider_pk->relation_parameters,
178 virtual_log_n);
179
180 auto prover_output = sumcheck_prover.prove();
181
182 auto verifier_transcript = Transcript::verifier_init_empty(prover_transcript);
183
184 SubrelationSeparators verifier_alphas;
185 for (size_t idx = 0; idx < verifier_alphas.size(); idx++) {
186 verifier_alphas[idx] = verifier_transcript->template get_challenge<FF>("Sumcheck:alpha_" + std::to_string(idx));
187 }
188 SumcheckVerifier<Flavor> sumcheck_verifier(verifier_transcript, verifier_alphas, virtual_log_n);
189
190 std::vector<FF> verifier_gate_challenges(virtual_log_n);
191 for (size_t idx = 0; idx < virtual_log_n; idx++) {
192 verifier_gate_challenges[idx] =
193 verifier_transcript->template get_challenge<FF>("Sumcheck:gate_challenge_" + std::to_string(idx));
194 }
195 std::vector<FF> padding_indicator_array(virtual_log_n);
196 for (size_t idx = 0; idx < padding_indicator_array.size(); idx++) {
197 padding_indicator_array[idx] = 1;
198 }
199 auto verifier_output =
200 sumcheck_verifier.verify(decider_pk->relation_parameters, verifier_gate_challenges, padding_indicator_array);
201
202 auto verified = verifier_output.verified;
203
204 ASSERT_TRUE(verified);
205}
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
static std::shared_ptr< BaseTranscript > verifier_init_empty(const std::shared_ptr< BaseTranscript > &transcript)
For testing: initializes transcript based on proof data then receives junk data produced by BaseTrans...
static std::shared_ptr< BaseTranscript > prover_init_empty()
For testing: initializes transcript with some arbitrary data so that a challenge can be generated aft...
Curve::ScalarField FF
std::array< FF, NUM_SUBRELATIONS - 1 > SubrelationSeparators
NativeTranscript Transcript
The implementation of the sumcheck Prover for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:123
SumcheckOutput< Flavor > prove()
Non-ZK version: Compute round univariate, place it in transcript, compute challenge,...
Definition sumcheck.hpp:231
Implementation of the sumcheck Verifier for statements of the form for multilinear polynomials .
Definition sumcheck.hpp:645
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:718
static void complete_proving_key_for_test(const std::shared_ptr< DeciderProvingKey_< Flavor > > &decider_pk)
TEST only method for completing computation of the prover polynomials using random challenges.
element class. Implements ecc group arithmetic using Jacobian coordinates See https://hyperelliptic....
Definition element.hpp:33
constexpr uint256_t slice(uint64_t start, uint64_t end) const
AluTraceBuilder builder
Definition alu.test.cpp:123
FF a
FF b
@ Ultra
constexpr T get_msb(const T in)
Definition get_msb.hpp:47
ReadData< bb::fr > get_lookup_accumulators(const MultiTableId id, const fr &key_a, const fr &key_b, const bool is_2_to_1_lookup)
Given a table ID and the key(s) for a key-value lookup, return the lookup accumulators.
@ FIXED_BASE_LEFT_LO
Definition types.hpp:100
@ FIXED_BASE_LEFT_HI
Definition types.hpp:101
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:123
typename Flavor::FF FF
UltraCircuitBuilder_< UltraExecutionTraceBlocks > UltraCircuitBuilder
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
std::string to_string(bb::avm2::ValueTag tag)
static constexpr size_t BITS_PER_LO_SCALAR
static void add_default_to_public_inputs(Builder &builder)
Adds default public inputs to the builder.