Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ecc_wnaf_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
10
11namespace bb {
12
13template <typename FF>
14template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
15void ECCVMWnafShortRelationImpl<FF>::accumulate(ContainerOverSubrelations& accumulator,
16 const AllEntities& in,
17 const Parameters& /*unused*/,
18 const FF& scaling_factor)
19{
20 // Universal "deepest" accumulator type used by the deg-4 subrelations (RANGE_S* and FIRST_SLICE_POSITIVE).
21 // Smaller subrelations construct their own narrower Accumulator (Acc4 / Acc3) via tuple_element_t<INDEX, ...>.
26
27 const auto lagrange_first = View(in.lagrange_first);
28 const auto scalar_sum = View(in.precompute_scalar_sum);
29 const auto scalar_sum_shift = View(in.precompute_scalar_sum_shift);
30 const auto q_transition = View(in.precompute_point_transition);
31 const auto round = View(in.precompute_round);
32 const auto round_shift = View(in.precompute_round_shift);
33 const auto pc = View(in.precompute_pc);
34 const auto pc_shift = View(in.precompute_pc_shift);
35 const auto precompute_select = View(in.precompute_select);
36 const auto precompute_select_shift = View(in.precompute_select_shift);
37 const auto precompute_skew = View(in.precompute_skew);
38
39 const std::array<View, 8> slices{
40 View(in.precompute_s1hi), View(in.precompute_s1lo), View(in.precompute_s2hi), View(in.precompute_s2lo),
41 View(in.precompute_s3hi), View(in.precompute_s3lo), View(in.precompute_s4hi), View(in.precompute_s4lo),
42 };
43
44 // Range checks ((s-1)^2 - 1) * ((s-2)^2 - 1) * scaling_factor — degree 4, length 5.
45 const auto range_check_scaled = [scaling_factor](const View& s, auto& acc) {
46 const auto s_minus_1 = s - FF(1);
47 const auto s_minus_2 = s - FF(2);
48 const auto term1 = s_minus_1.sqr() - FF(1); // length 3
49 const auto term2 = s_minus_2.sqr() - FF(1); // length 3
50 acc += Accumulator(term1) * Accumulator(term2 * scaling_factor);
51 };
52 range_check_scaled(slices[0], std::get<Base::RANGE_S1HI>(accumulator));
53 range_check_scaled(slices[1], std::get<Base::RANGE_S1LO>(accumulator));
54 range_check_scaled(slices[2], std::get<Base::RANGE_S2HI>(accumulator));
55 range_check_scaled(slices[3], std::get<Base::RANGE_S2LO>(accumulator));
56 range_check_scaled(slices[4], std::get<Base::RANGE_S3HI>(accumulator));
57 range_check_scaled(slices[5], std::get<Base::RANGE_S3LO>(accumulator));
58 range_check_scaled(slices[6], std::get<Base::RANGE_S4HI>(accumulator));
59 range_check_scaled(slices[7], std::get<Base::RANGE_S4LO>(accumulator));
60
61 const auto convert_to_wnaf = [](const View& hi, const View& lo) {
62 auto t = hi + hi;
63 t += t;
64 t += lo;
65 return t + t - FF(15);
66 };
67
68 const auto scaled_transition_short = q_transition * scaling_factor; // length 2
69 const auto scaled_lagrange_first_short = lagrange_first * scaling_factor; // length 2
70 const auto scaled_transition_is_zero_short = -scaled_transition_short + scaling_factor;
71 const auto scaled_transition_plus_lagrange_first_short = scaled_transition_short + scaled_lagrange_first_short;
72
73 // FIRST_SLICE_POSITIVE: deg 4, length 5.
74 {
75 const auto s1hi_shift = View(in.precompute_s1hi_shift);
76 const auto s1hi_shift_msb_set = (s1hi_shift - FF(2)) * (s1hi_shift - FF(3)); // length 3
77 const auto first_factor = scaled_transition_plus_lagrange_first_short * precompute_select_shift; // length 3
79 Accumulator(first_factor) * Accumulator(s1hi_shift_msb_set);
80 }
81
82 // wNAF digits and row_slice (length 2, shared with INACTIVE_SLICE_W*).
83 const auto w0 = convert_to_wnaf(slices[0], slices[1]);
84 const auto w1 = convert_to_wnaf(slices[2], slices[3]);
85 const auto w2 = convert_to_wnaf(slices[4], slices[5]);
86 const auto w3 = convert_to_wnaf(slices[6], slices[7]);
87
88 auto row_slice = w0;
89 row_slice += row_slice;
90 row_slice += row_slice;
91 row_slice += row_slice;
92 row_slice += row_slice;
93 row_slice += w1;
94 row_slice += row_slice;
95 row_slice += row_slice;
96 row_slice += row_slice;
97 row_slice += row_slice;
98 row_slice += w2;
99 row_slice += row_slice;
100 row_slice += row_slice;
101 row_slice += row_slice;
102 row_slice += row_slice;
103 row_slice += w3;
104
105 // SCALAR_SUM_CHECK: deg 3, length 4.
106 {
107 const auto sum_delta = scalar_sum * FF(1ULL << 16) + row_slice;
108 const auto check_sum = scalar_sum_shift - sum_delta; // length 2
109 const auto factor = precompute_select * scaled_transition_is_zero_short; // length 3
110 std::get<Base::SCALAR_SUM_CHECK>(accumulator) += Acc4(factor) * Acc4(check_sum);
111 }
112
113 // PRECOMPUTE_SELECT_SHAPE: deg 3, length 4.
114 {
115 const auto scaled_lagrange_first_minus_one_short = scaled_lagrange_first_short - scaling_factor; // length 2
116 const auto precompute_select_check = precompute_select_shift * (precompute_select - FF(1)); // length 3
118 Acc4(scaled_lagrange_first_minus_one_short) * Acc4(precompute_select_check);
119 }
120
121 // ROUND_CHECK: deg 3, length 4.
122 {
123 const auto round_check = round_shift - round - FF(1); // length 2
124 const auto term_a = round - round_check - FF(7); // length 2
125 const auto term_a_mul = term_a * scaled_transition_short; // length 3
126 const auto term_b = round_check * scaling_factor; // length 2
127 const auto inner = term_a_mul + term_b; // length 3
128 std::get<Base::ROUND_CHECK>(accumulator) += Acc4(precompute_select) * Acc4(inner);
129 }
130
131 // ROUND_SHIFT_ZERO / SCALAR_SUM_SHIFT_ZERO: deg 3, length 4.
132 const auto precompute_select_transition_plus_lagrange_first_short =
133 precompute_select * scaled_transition_short + scaled_lagrange_first_short; // length 3
135 Acc4(precompute_select_transition_plus_lagrange_first_short) * Acc4(round_shift);
137 Acc4(precompute_select_transition_plus_lagrange_first_short) * Acc4(scalar_sum_shift);
138
139 // PC_CHECK: deg 3, length 4.
140 {
141 const auto pc_delta = pc_shift - pc; // length 2
142 const auto inner_a = (-pc_delta - pc_delta - FF(1)) * scaled_transition_short; // length 3
143 const auto inner_b = pc_delta * scaling_factor; // length 2
144 const auto inner = inner_a + inner_b; // length 3
145 std::get<Base::PC_CHECK>(accumulator) += Acc4(precompute_select) * Acc4(inner);
146 }
147
148 // SKEW_RANGE: deg 3, length 4.
149 {
150 const auto skew_quadratic = precompute_skew * (precompute_skew - FF(7)); // length 3
151 std::get<Base::SKEW_RANGE>(accumulator) += Acc4(precompute_select * scaling_factor) * Acc4(skew_quadratic);
152 }
153
154 // Inactive-row enforcement: deg 2, length 3.
155 const auto precompute_select_zero_short = -precompute_select * scaling_factor + scaling_factor; // length 2
156 std::get<Base::INACTIVE_SLICE_W0>(accumulator) += Acc3(precompute_select_zero_short * (w0 + FF(15)));
157 std::get<Base::INACTIVE_SLICE_W1>(accumulator) += Acc3(precompute_select_zero_short * (w1 + FF(15)));
158 std::get<Base::INACTIVE_SLICE_W2>(accumulator) += Acc3(precompute_select_zero_short * (w2 + FF(15)));
159 std::get<Base::INACTIVE_SLICE_W3>(accumulator) += Acc3(precompute_select_zero_short * (w3 + FF(15)));
160 std::get<Base::INACTIVE_ROUND>(accumulator) += Acc3(precompute_select_zero_short * round);
161 std::get<Base::INACTIVE_PC>(accumulator) += Acc3(precompute_select_zero_short * pc);
162 std::get<Base::INACTIVE_POINT_TRANSITION>(accumulator) += Acc3(precompute_select_zero_short * q_transition);
163}
164
165} // namespace bb
bb::field< bb::Bn254FrParams > FF
Definition field.cpp:24
static void accumulate(ContainerOverSubrelations &accumulator, const AllEntities &in, const Parameters &params, const FF &scaling_factor)
Entry point for Barretenberg command-line interface.
Definition api.hpp:5
typename Accumulator::CoefficientAccumulator ECCVMShortMonomialView
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13