Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ecc_set_short_relation_impl.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Planned, auditors: [], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
8
11
12#include <type_traits>
13
14namespace bb {
15
16template <typename FF>
17template <typename Accumulator, typename AllEntities, typename Parameters>
19 const Parameters& params)
20{
22
23 const auto precompute_round = View(in.precompute_round);
24 const auto precompute_round2 = precompute_round + precompute_round;
25 const auto precompute_round4 = precompute_round2 + precompute_round2;
26
27 const auto& gamma = params.gamma;
28 const auto& beta = params.beta;
29 const auto& beta_sqr = params.beta_sqr;
30 const auto& beta_cube = params.beta_cube;
31 const auto& beta_quartic = params.beta_quartic;
32 const auto precompute_pc = View(in.precompute_pc);
33 const auto precompute_select = View(in.precompute_select);
34
35 const auto first_term_tag = beta_quartic * Base::FIRST_TERM_TAG;
36 const auto second_term_tag = beta_quartic * Base::SECOND_TERM_TAG;
37 const auto third_term_tag = beta_quartic * Base::THIRD_TERM_TAG;
38
39 const auto make_wnaf_input = [&](const auto& hi, const auto& lo, const auto& round_offset) {
40 auto wnaf_slice = hi + hi;
41 wnaf_slice += wnaf_slice;
42 wnaf_slice += lo;
43 return wnaf_slice + gamma + precompute_pc * beta + (precompute_round4 + round_offset) * beta_sqr +
44 first_term_tag;
45 };
46
47 const auto wnaf_slice_input0 = make_wnaf_input(View(in.precompute_s1hi), View(in.precompute_s1lo), FF(0));
48 const auto wnaf_slice_input1 = make_wnaf_input(View(in.precompute_s2hi), View(in.precompute_s2lo), FF(1));
49 const auto wnaf_slice_input2 = make_wnaf_input(View(in.precompute_s3hi), View(in.precompute_s3lo), FF(2));
50 const auto wnaf_slice_input3 = make_wnaf_input(View(in.precompute_s4hi), View(in.precompute_s4lo), FF(3));
51
52 auto numerator =
53 Accumulator(wnaf_slice_input0 * wnaf_slice_input1) * Accumulator(wnaf_slice_input2 * wnaf_slice_input3);
54
55 const auto skew = View(in.precompute_skew);
56 const auto precompute_point_transition = View(in.precompute_point_transition);
57 const auto skew_linear =
58 skew + gamma + precompute_pc * beta + (precompute_round4 + FF(4)) * beta_sqr + first_term_tag;
59 const auto skew_input = precompute_point_transition * skew_linear + (-precompute_point_transition + 1);
60 numerator *= Accumulator(skew_input);
61
62 const auto& eccvm_set_permutation_delta = params.eccvm_set_permutation_delta;
63 const auto precompute_select_factor =
64 precompute_select * (-eccvm_set_permutation_delta + 1) + eccvm_set_permutation_delta;
65 numerator *= Accumulator(precompute_select_factor);
66
67 const auto table_x = View(in.precompute_tx);
68 const auto table_y = View(in.precompute_ty);
69 const auto precompute_skew = View(in.precompute_skew);
70 const auto negative_inverse_seven = []() {
71 if constexpr (std::same_as<FF, grumpkin::fr>) {
72 static constexpr FF negative_inverse_seven = FF(-7).invert();
73 return negative_inverse_seven;
74 } else {
75 FF negative_inverse_seven = FF(-7).invert();
76 return negative_inverse_seven;
77 }
78 };
79 auto adjusted_skew = precompute_skew * negative_inverse_seven();
80
81 const auto wnaf_scalar_sum = View(in.precompute_scalar_sum);
82 const auto w0 = convert_to_wnaf<Accumulator>(View(in.precompute_s1hi), View(in.precompute_s1lo));
83 const auto w1 = convert_to_wnaf<Accumulator>(View(in.precompute_s2hi), View(in.precompute_s2lo));
84 const auto w2 = convert_to_wnaf<Accumulator>(View(in.precompute_s3hi), View(in.precompute_s3lo));
85 const auto w3 = convert_to_wnaf<Accumulator>(View(in.precompute_s4hi), View(in.precompute_s4lo));
86
87 auto row_slice = w0;
88 row_slice += row_slice;
89 row_slice += row_slice;
90 row_slice += row_slice;
91 row_slice += row_slice;
92 row_slice += w1;
93 row_slice += row_slice;
94 row_slice += row_slice;
95 row_slice += row_slice;
96 row_slice += row_slice;
97 row_slice += w2;
98 row_slice += row_slice;
99 row_slice += row_slice;
100 row_slice += row_slice;
101 row_slice += row_slice;
102 row_slice += w3;
103
104 auto scalar_sum_full = wnaf_scalar_sum * FF(1ULL << 16);
105 scalar_sum_full += row_slice + adjusted_skew;
106
107 auto point_table_init_read_linear =
108 precompute_pc + table_x * beta + table_y * beta_sqr + scalar_sum_full * beta_cube + second_term_tag;
109 auto point_table_init_read =
110 precompute_point_transition * (point_table_init_read_linear + gamma) + (-precompute_point_transition + 1);
111 numerator *= Accumulator(point_table_init_read);
112
113 const auto lagrange_first = View(in.lagrange_first);
114 const auto partial_msm_transition_shift = View(in.msm_transition_shift);
115 const auto msm_transition_shift = (-lagrange_first + 1) * partial_msm_transition_shift;
116 const auto msm_pc_shift = View(in.msm_pc_shift);
117 const auto msm_x_shift = View(in.msm_accumulator_x_shift);
118 const auto msm_y_shift = View(in.msm_accumulator_y_shift);
119 const auto msm_size = View(in.msm_size_of_msm);
120
121 auto msm_result_write_linear =
122 msm_pc_shift + msm_x_shift * beta + msm_y_shift * beta_sqr + msm_size * beta_cube + third_term_tag;
123 auto msm_result_write = Accumulator(msm_transition_shift) * Accumulator(msm_result_write_linear + gamma) +
124 Accumulator(-msm_transition_shift + 1);
125 numerator *= msm_result_write;
126
127 return numerator;
128}
129
130template <typename FF>
131template <typename Accumulator, typename AllEntities, typename Parameters>
133 const Parameters& params)
134{
136
137 const auto& gamma = params.gamma;
138 const auto& beta = params.beta;
139 const auto& beta_sqr = params.beta_sqr;
140 const auto& beta_cube = params.beta_cube;
141 const auto& beta_quartic = params.beta_quartic;
142 const auto msm_pc = View(in.msm_pc);
143 const auto msm_count = View(in.msm_count);
144 const auto msm_round = View(in.msm_round);
145
146 const auto first_term_tag = beta_quartic * Base::FIRST_TERM_TAG;
147 const auto second_term_tag = beta_quartic * Base::SECOND_TERM_TAG;
148 const auto third_term_tag = beta_quartic * Base::THIRD_TERM_TAG;
149
150 const auto make_wnaf_output = [&](const auto& add, const auto& slice, const auto& count_offset) {
151 const auto input =
152 slice + gamma + (msm_pc - msm_count - count_offset) * beta + msm_round * beta_sqr + first_term_tag;
153 return add * input + (-add + 1);
154 };
155
156 const auto wnaf_slice_output1 = make_wnaf_output(View(in.msm_add1), View(in.msm_slice1), FF(0));
157 const auto wnaf_slice_output2 = make_wnaf_output(View(in.msm_add2), View(in.msm_slice2), FF(1));
158 const auto wnaf_slice_output3 = make_wnaf_output(View(in.msm_add3), View(in.msm_slice3), FF(2));
159 const auto wnaf_slice_output4 = make_wnaf_output(View(in.msm_add4), View(in.msm_slice4), FF(3));
160
161 auto denominator = Accumulator(wnaf_slice_output1) * Accumulator(wnaf_slice_output2);
162 denominator *= Accumulator(wnaf_slice_output3);
163 denominator *= Accumulator(wnaf_slice_output4);
164
165 const auto transcript_pc = View(in.transcript_pc);
166 const auto transcript_Px = View(in.transcript_Px);
167 const auto transcript_Py = View(in.transcript_Py);
168 const auto z1 = View(in.transcript_z1);
169 const auto z2 = View(in.transcript_z2);
170 const auto z1_zero = View(in.transcript_z1zero);
171 const auto z2_zero = View(in.transcript_z2zero);
172 const auto base_infinity = View(in.transcript_base_infinity);
173 const auto transcript_mul = View(in.transcript_mul);
174
175 const auto lookup_first = -z1_zero + 1;
176 const auto lookup_second = -z2_zero + 1;
177 FF cube_root_unity = FF(bb::fq::cube_root_of_unity());
178
179 auto transcript_input1_linear =
180 transcript_pc + transcript_Px * beta + transcript_Py * beta_sqr + z1 * beta_cube + second_term_tag;
181 auto transcript_input2_linear = (transcript_pc - lookup_first) + transcript_Px * cube_root_unity * beta -
182 transcript_Py * beta_sqr + z2 * beta_cube + second_term_tag;
183
184 auto transcript_input1 = (transcript_input1_linear + gamma) * lookup_first + (-lookup_first + 1);
185 auto transcript_input2 = (transcript_input2_linear + gamma) * lookup_second + (-lookup_second + 1);
186
187 auto transcript_product = Accumulator(transcript_input1) * Accumulator(transcript_input2);
188 transcript_product *= Accumulator(-base_infinity + 1);
189 transcript_product += Accumulator(base_infinity);
190
191 auto point_table_init_write = Accumulator(transcript_mul) * transcript_product + Accumulator(-transcript_mul + 1);
192 denominator *= point_table_init_write;
193
194 const auto transcript_pc_shift = View(in.transcript_pc_shift);
195 const auto transcript_msm_x = View(in.transcript_msm_x);
196 const auto transcript_msm_y = View(in.transcript_msm_y);
197 const auto transcript_msm_transition = View(in.transcript_msm_transition);
198 const auto transcript_msm_count = View(in.transcript_msm_count);
199
200 auto full_msm_count = Accumulator(transcript_msm_count);
201 full_msm_count += Accumulator(transcript_mul * (lookup_first + lookup_second)) * Accumulator(-base_infinity + 1);
202
203 auto msm_result_read =
204 Accumulator(transcript_pc_shift + transcript_msm_x * beta + transcript_msm_y * beta_sqr + third_term_tag);
205 msm_result_read += full_msm_count * beta_cube;
206 msm_result_read += gamma;
207 msm_result_read =
208 Accumulator(transcript_msm_transition) * msm_result_read + Accumulator(-transcript_msm_transition + 1);
209 denominator *= msm_result_read;
210
211 return denominator;
212}
213
214template <typename FF>
215template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
216void ECCVMSetShortRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulator,
217 const AllEntities& in,
218 const Parameters& params,
219 const FF& scaling_factor)
220{
221 using GrandProductAccumulator = typename std::tuple_element_t<Base::GRAND_PRODUCT, ContainerOverSubrelations>;
223
224 GrandProductAccumulator numerator_evaluation = compute_grand_product_numerator<GrandProductAccumulator>(in, params);
225 GrandProductAccumulator denominator_evaluation =
226 compute_grand_product_denominator<GrandProductAccumulator>(in, params);
227
228 const auto z_perm = GrandProductView(in.z_perm);
229 const auto z_perm_shift = GrandProductView(in.z_perm_shift);
230 const auto lagrange_first = GrandProductView(in.lagrange_first);
231 const auto lagrange_last = GrandProductView(in.lagrange_last);
232
233 const auto z_perm_and_first_scaled = (z_perm + lagrange_first) * scaling_factor;
234 const auto z_perm_shift_and_last_scaled = (z_perm_shift + lagrange_last) * scaling_factor;
235 std::get<Base::GRAND_PRODUCT>(accumulator) +=
236 GrandProductAccumulator(z_perm_and_first_scaled) * numerator_evaluation -
237 GrandProductAccumulator(z_perm_shift_and_last_scaled) * denominator_evaluation;
238
240 using LeftShiftableView = ECCVMShortMonomialView<LeftShiftableAccumulator>;
241 const auto lagrange_last_short = LeftShiftableView(in.lagrange_last);
242 const auto z_perm_shift_short = LeftShiftableView(in.z_perm_shift);
243 std::get<Base::LEFT_SHIFTABLE>(accumulator) +=
244 LeftShiftableAccumulator((lagrange_last_short * z_perm_shift_short) * scaling_factor);
245
248 const auto lagrange_first_init = InitView(in.lagrange_first);
249 const auto z_perm_init = InitView(in.z_perm);
250 std::get<Base::Z_PERM_INIT>(accumulator) += InitAccumulator((lagrange_first_init * z_perm_init) * scaling_factor);
251}
252
253} // namespace bb
bb::field< bb::Bn254FrParams > FF
Definition field.cpp:24
static Accumulator compute_grand_product_numerator(const AllEntities &in, const Parameters &params)
static void accumulate(ContainerOverSubrelations &accumulator, const AllEntities &in, const Parameters &params, const FF &scaling_factor)
static Accumulator compute_grand_product_denominator(const AllEntities &in, const Parameters &params)
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
C slice(C const &container, size_t start)
Definition container.hpp:9
typename Accumulator::CoefficientAccumulator ECCVMShortMonomialView
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
static constexpr field cube_root_of_unity()
constexpr field invert() const noexcept