Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
permutation_relation.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: Complete, auditors: [Luke, Raju], commit: }
3// external_1: { status: not started, auditors: [], commit: }
4// external_2: { status: not started, auditors: [], commit: }
5// =====================
6
7#pragma once
9namespace bb {
39template <typename FF_> class UltraPermutationRelationImpl {
40 public:
41 using FF = FF_;
42
43 static constexpr std::array<size_t, 3> SUBRELATION_PARTIAL_LENGTHS{
44 6, // grand product construction sub-relation
45 3, // left-shiftable polynomial sub-relation
46 3 // z_perm initialization sub-relation
47 };
48
53 template <typename AllEntities> inline static bool skip(const AllEntities& in)
54 {
55 // If z_perm == z_perm_shift, this implies that none of the wire values for the present input are involved in
56 // non-trivial copy constraints.
58 }
59
60 template <typename AllEntities> inline static auto& get_grand_product_polynomial(AllEntities& in)
61 {
63 }
64 template <typename AllEntities> inline static auto& get_shifted_grand_product_polynomial(AllEntities& in)
65 {
67 }
68
69 template <typename Accumulator, typename AllEntities, typename Parameters>
70 inline static Accumulator compute_grand_product_numerator(const AllEntities& in, const Parameters& params)
71 {
72 using View = typename Accumulator::View;
73 using ParameterView = Parameters::DataType;
74
75 auto w_1 = View(in[AllEntities::EntityId::w_l]);
76 auto w_2 = View(in[AllEntities::EntityId::w_r]);
77 auto w_3 = View(in[AllEntities::EntityId::w_o]);
78 auto w_4 = View(in[AllEntities::EntityId::w_4]);
79 auto id_1 = View(in[AllEntities::EntityId::id_1]);
80 auto id_2 = View(in[AllEntities::EntityId::id_2]);
81 auto id_3 = View(in[AllEntities::EntityId::id_3]);
82 auto id_4 = View(in[AllEntities::EntityId::id_4]);
83
84 const auto& beta = ParameterView(params.beta);
85 const auto& gamma = ParameterView(params.gamma);
86
87 // witness degree 4
88 return (w_1 + id_1 * beta + gamma) * (w_2 + id_2 * beta + gamma) * (w_3 + id_3 * beta + gamma) *
89 (w_4 + id_4 * beta + gamma);
90 }
91
92 template <typename Accumulator, typename AllEntities, typename Parameters>
93 inline static Accumulator compute_grand_product_denominator(const AllEntities& in, const Parameters& params)
94 {
95 using View = typename Accumulator::View;
96 using ParameterView = Parameters::DataType;
97
98 auto w_1 = View(in[AllEntities::EntityId::w_l]);
99 auto w_2 = View(in[AllEntities::EntityId::w_r]);
100 auto w_3 = View(in[AllEntities::EntityId::w_o]);
101 auto w_4 = View(in[AllEntities::EntityId::w_4]);
102
103 auto sigma_1 = View(in[AllEntities::EntityId::sigma_1]);
104 auto sigma_2 = View(in[AllEntities::EntityId::sigma_2]);
105 auto sigma_3 = View(in[AllEntities::EntityId::sigma_3]);
106 auto sigma_4 = View(in[AllEntities::EntityId::sigma_4]);
107
108 const auto& beta = ParameterView(params.beta);
109 const auto& gamma = ParameterView(params.gamma);
110
111 // witness degree 4
112 return (w_1 + sigma_1 * beta + gamma) * (w_2 + sigma_2 * beta + gamma) * (w_3 + sigma_3 * beta + gamma) *
113 (w_4 + sigma_4 * beta + gamma);
114 }
115
124 template <typename Accumulator, typename GateCoefficientAccumulator>
125 static bool subrelation_is_active(const GateCoefficientAccumulator& gate)
126 {
127 if constexpr (IsProverAccumulator<Accumulator>) {
128 return !gate.is_zero();
129 } else {
130 return true;
131 }
132 }
133
150 template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
151 inline static void accumulate(ContainerOverSubrelations& accumulators,
152 const AllEntities& in,
153 const Parameters& params,
154 const FF& scaling_factor)
155 {
156 // Contribution (1)
158 using CoefficientAccumulator = typename Accumulator::CoefficientAccumulator;
159 using ParameterView = Parameters::DataType;
160 using ParameterCoefficientAccumulator = typename ParameterView::CoefficientAccumulator;
161
162 const CoefficientAccumulator w_1_m(in[AllEntities::EntityId::w_l]);
163 const CoefficientAccumulator w_2_m(in[AllEntities::EntityId::w_r]);
164 const CoefficientAccumulator w_3_m(in[AllEntities::EntityId::w_o]);
165 const CoefficientAccumulator w_4_m(in[AllEntities::EntityId::w_4]);
166 const CoefficientAccumulator id_1_m(in[AllEntities::EntityId::id_1]);
167 const CoefficientAccumulator id_2_m(in[AllEntities::EntityId::id_2]);
168 const CoefficientAccumulator id_3_m(in[AllEntities::EntityId::id_3]);
169 const CoefficientAccumulator id_4_m(in[AllEntities::EntityId::id_4]);
170 const CoefficientAccumulator sigma_1_m(in[AllEntities::EntityId::sigma_1]);
171 const CoefficientAccumulator sigma_2_m(in[AllEntities::EntityId::sigma_2]);
172 const CoefficientAccumulator sigma_3_m(in[AllEntities::EntityId::sigma_3]);
173 const CoefficientAccumulator sigma_4_m(in[AllEntities::EntityId::sigma_4]);
174
175 const ParameterCoefficientAccumulator gamma_m(params.gamma);
176 const ParameterCoefficientAccumulator beta_m(params.beta);
177
178 const auto w_1_plus_gamma = w_1_m + gamma_m;
179 const auto w_2_plus_gamma = w_2_m + gamma_m;
180 const auto w_3_plus_gamma = w_3_m + gamma_m;
181 const auto w_4_plus_gamma = w_4_m + gamma_m;
182
183 auto t1 = (id_1_m * beta_m);
184 t1 += w_1_plus_gamma;
185 t1 *= scaling_factor;
186 auto t2 = id_2_m * beta_m;
187 t2 += w_2_plus_gamma;
188 auto t3 = id_3_m * beta_m;
189 t3 += w_3_plus_gamma;
190 auto t4 = id_4_m * beta_m;
191 t4 += w_4_plus_gamma;
192
193 auto t5 = sigma_1_m * beta_m;
194 t5 += w_1_plus_gamma;
195 t5 *= scaling_factor;
196 auto t6 = sigma_2_m * beta_m;
197 t6 += w_2_plus_gamma;
198 auto t7 = sigma_3_m * beta_m;
199 t7 += w_3_plus_gamma;
200 auto t8 = sigma_4_m * beta_m;
201 t8 += w_4_plus_gamma;
202
203 // t1..t8 are degree-1 coefficient-basis monomials. The prover pairs them as (t1*t2)(t3*t4): Karatsuba
204 // on the degree-1 pairs reduces the naive 36 muls (chaining 6 pointwise length-6 products) to 24.
205 Accumulator numerator;
206 Accumulator denominator;
207 if constexpr (IsProverAccumulator<Accumulator>) {
208 numerator = Accumulator(t1 * t2);
209 numerator *= Accumulator(t3 * t4);
210 denominator = Accumulator(t5 * t6);
211 denominator *= Accumulator(t7 * t8);
212 } else {
213 numerator = Accumulator(t1);
214 numerator *= Accumulator(t2);
215 numerator *= Accumulator(t3);
216 numerator *= Accumulator(t4);
217
218 denominator = Accumulator(t5);
219 denominator *= Accumulator(t6);
220 denominator *= Accumulator(t7);
221 denominator *= Accumulator(t8);
222 }
223
224 const ParameterCoefficientAccumulator public_input_delta_m(params.public_input_delta);
225 const auto z_perm_m = CoefficientAccumulator(in[AllEntities::EntityId::z_perm]);
226 const auto z_perm_shift_m = CoefficientAccumulator(in[AllEntities::EntityId::z_perm_shift]);
227 const auto lagrange_first_m = CoefficientAccumulator(in[AllEntities::EntityId::lagrange_first]);
228 const auto lagrange_last_m = CoefficientAccumulator(in[AllEntities::EntityId::lagrange_last]);
229
230 // Prover fast path (guarded on ::LENGTH so it never enters the verifiers, which must not branch on witness
231 // values). lagrange_first/last are one-hot and vanish on almost every edge pair under folding; when both are
232 // zero the public-input term collapses to z_perm_shift and the (z_perm + L_first) factor to z_perm, and
233 // subrelations (2),(3) vanish -- the same accumulator value as the general path below, skipping ~12 muls.
234 if constexpr (IsProverAccumulator<Accumulator>) {
235 if (lagrange_first_m.is_zero() && lagrange_last_m.is_zero()) {
236 const Accumulator public_input_term(z_perm_shift_m);
237 std::get<0>(accumulators) += ((Accumulator(z_perm_m) * numerator) - (public_input_term * denominator));
238 return;
239 }
240 }
241
242 auto public_input_term_m = lagrange_last_m * public_input_delta_m;
243 public_input_term_m += z_perm_shift_m;
244 const Accumulator public_input_term(public_input_term_m);
245 // witness degree: deg 5 - deg 5 = deg 5
246 std::get<0>(accumulators) +=
247 ((Accumulator(z_perm_m + lagrange_first_m) * numerator) - (public_input_term * denominator));
248
249 // Contribution (2): gated by lagrange_last (zero on all but the last row).
251 if (subrelation_is_active<Accumulator>(lagrange_last_m)) {
252 std::get<1>(accumulators) += ShortAccumulator((lagrange_last_m * z_perm_shift_m) * scaling_factor);
253 }
254
255 // Contribution (3): Enforce z_perm starts at 0. The grand product initialization relies on
256 // z_perm[0] = 0 so that (z_perm + L_first) evaluates to 1 at the first row.
257 // Without this constraint, a cheating prover could set z_perm[0] to a non-zero value.
258 // Gated by lagrange_first (zero on all but the first row).
260 if (subrelation_is_active<Accumulator>(lagrange_first_m)) {
261 std::get<2>(accumulators) += InitAccumulator((lagrange_first_m * z_perm_m) * scaling_factor);
262 }
263 };
264};
265
267
268} // namespace bb
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
static auto & get_shifted_grand_product_polynomial(AllEntities &in)
static auto & get_grand_product_polynomial(AllEntities &in)
static bool skip(const AllEntities &in)
Returns true if the contribution from all subrelations for the provided inputs is identically zero.
static bool subrelation_is_active(const GateCoefficientAccumulator &gate)
Whether a one-hot-gated subrelation can contribute on this edge.
static void accumulate(ContainerOverSubrelations &accumulators, const AllEntities &in, const Parameters &params, const FF &scaling_factor)
Compute contribution of the permutation relation for a given edge (internal function)
static Accumulator compute_grand_product_numerator(const AllEntities &in, const Parameters &params)
static constexpr std::array< size_t, 3 > SUBRELATION_PARTIAL_LENGTHS
static Accumulator compute_grand_product_denominator(const AllEntities &in, const Parameters &params)
True for the accumulator type used by the sumcheck PROVER, as opposed to either verifier.
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13