Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
ecc_lookup_relation.hpp
Go to the documentation of this file.
1// === AUDIT STATUS ===
2// internal: { status: not started, auditors: [], date: YYYY-MM-DD }
3// external_1: { status: not started, auditors: [], date: YYYY-MM-DD }
4// external_2: { status: not started, auditors: [], date: YYYY-MM-DD }
5// =====================
6
7#pragma once
8#include <array>
9#include <tuple>
10
14
15namespace bb {
16
17template <typename FF_> class ECCVMLookupRelationImpl {
18 public:
19 using FF = FF_;
20 static constexpr size_t READ_TERMS = 4;
21 static constexpr size_t WRITE_TERMS = 2;
22 // 1 + polynomial degree of this relation
23 static constexpr size_t LENGTH = READ_TERMS + WRITE_TERMS + 3; // 9
24
25 static constexpr std::array<size_t, 2> SUBRELATION_PARTIAL_LENGTHS{
26 LENGTH, // grand product construction sub-relation
27 LENGTH // left-shiftable polynomial sub-relation
28 };
29
30 static constexpr std::array<bool, 2> SUBRELATION_LINEARLY_INDEPENDENT = { true, false };
31
32 template <typename AllValues> static bool operation_exists_at_row(const AllValues& row)
33
34 {
35 return (row.msm_add == 1) || (row.msm_skew == 1) || (row.precompute_select == 1);
36 }
37
45 template <typename AllEntities> static auto& get_inverse_polynomial(AllEntities& in) { return in.lookup_inverses; }
46
47 template <typename Accumulator, typename AllEntities>
48 static Accumulator compute_inverse_exists(const AllEntities& in)
49 {
50 using View = typename Accumulator::View;
51
52 const auto row_has_write = View(in.precompute_select);
53 const auto row_has_read = View(in.msm_add) + View(in.msm_skew);
54 return row_has_write + row_has_read - (row_has_write * row_has_read);
55 }
56
57 template <typename Accumulator, size_t index, typename AllEntities>
58 static Accumulator lookup_read_counts(const AllEntities& in)
59 {
60 using View = typename Accumulator::View;
61
62 if constexpr (index == 0) {
63 return Accumulator(View(in.lookup_read_counts_0));
64 }
65 if constexpr (index == 1) {
66 return Accumulator(View(in.lookup_read_counts_1));
67 }
68 return Accumulator(1);
69 }
70
71 template <typename Accumulator, size_t read_index, typename AllEntities>
72 static Accumulator compute_read_term_predicate(const AllEntities& in)
73
74 {
75 using View = typename Accumulator::View;
76
77 if constexpr (read_index == 0) {
78 return Accumulator(View(in.msm_add1));
79 }
80 if constexpr (read_index == 1) {
81 return Accumulator(View(in.msm_add2));
82 }
83 if constexpr (read_index == 2) {
84 return Accumulator(View(in.msm_add3));
85 }
86 if constexpr (read_index == 3) {
87 return Accumulator(View(in.msm_add4));
88 }
89 return Accumulator(1);
90 }
91
92 template <typename Accumulator, size_t write_index, typename AllEntities>
93 static Accumulator compute_write_term_predicate(const AllEntities& in)
94 {
95 using View = typename Accumulator::View;
96
97 if constexpr (write_index == 0) {
98 return Accumulator(View(in.precompute_select));
99 }
100 if constexpr (write_index == 1) {
101 // TODO(https://github.com/AztecProtocol/barretenberg/issues/750) Is this a bug?
102 return Accumulator(View(in.precompute_select));
103 }
104 return Accumulator(1);
105 }
106
107 template <typename Accumulator, size_t write_index, typename AllEntities, typename Parameters>
108 static Accumulator compute_write_term(const AllEntities& in, const Parameters& params)
109 {
110 using View = typename Accumulator::View;
111
112 static_assert(write_index < WRITE_TERMS);
113
114 // what are we looking up?
115 // we want to map:
116 // 1: point pc
117 // 2: point slice
118 // 3: point x
119 // 4: point y
120 // for each point in our point table, we want to map `slice` to (x, -y) AND `slice + 8` to (x, y)
121
122 // round starts at 0 and increments to 7
123 // point starts at 15[P] and decrements to [P]
124 // a slice value of 0 maps to -15[P]
125 // 1 -> -13[P]
126 // 7 -> -[P]
127 // 8 -> P
128 // 15 -> 15[P]
129 // negative points map pc, round, x, -y
130 // positive points map pc, 15 - (round * 2), x, y
131 const auto& precompute_pc = View(in.precompute_pc);
132 const auto& tx = View(in.precompute_tx);
133 const auto& ty = View(in.precompute_ty);
134 const auto& precompute_round = View(in.precompute_round);
135 const auto& gamma = params.gamma;
136 const auto& beta = params.beta;
137 const auto& beta_sqr = params.beta_sqr;
138 const auto& beta_cube = params.beta_cube;
139
140 // slice value : (wnaf value) : lookup term
141 // 0 : -15 : 0
142 // 1 : -13 : 1
143 // 7 : -1 : 7
144 // 8 : 1 : 0
145 // 9 : 3 : 1
146 // 15 : 15 : 7
147
148 // slice value : negative term : positive term
149 // 0 : 0 : 7
150 // 1 : 1 : 6
151 // 2 : 2 : 5
152 // 3 : 3 : 4
153 // 7 : 7 : 0
154
155 // | 0 | 15[P].x | 15[P].y | 0, -15[P].x, -15[P].y | 15, 15[P].x, 15[P].y |
156 // | 1 | 13[P].x | 13[P].y | 1, -13[P].x, -13[P].y | 14, 13[P].x, 13[P].y
157 // | 2 | 11[P].x | 11[P].y
158 // | 3 | 9[P].x | 9[P].y
159 // | 4 | 7[P].x | 7[P].y
160 // | 5 | 5[P].x | 5[P].y
161 // | 6 | 3[P].x | 3[P].y
162 // | 7 | 1[P].x | 1[P].y | 7, -[P].x, -[P].y | 8 , [P].x, [P].y |
163
164 // todo optimize this?
165 if constexpr (write_index == 0) {
166 const auto positive_slice_value = -(precompute_round) + 15;
167 const auto positive_term =
168 precompute_pc + gamma + positive_slice_value * beta + tx * beta_sqr + ty * beta_cube;
169 return positive_term; // degree 1
170 }
171 if constexpr (write_index == 1) {
172 const auto negative_term = precompute_pc + gamma + precompute_round * beta + tx * beta_sqr - ty * beta_cube;
173 return negative_term; // degree 1
174 }
175 return Accumulator(1);
176 }
177
178 template <typename Accumulator, size_t read_index, typename AllEntities, typename Parameters>
179 static Accumulator compute_read_term(const AllEntities& in, const Parameters& params)
180 {
181 using View = typename Accumulator::View;
182
183 // read term:
184 // pc, slice, x, y
185 static_assert(read_index < READ_TERMS);
186 const auto& gamma = params.gamma;
187 const auto& beta = params.beta;
188 const auto& beta_sqr = params.beta_sqr;
189 const auto& beta_cube = params.beta_cube;
190 const auto& msm_pc = View(in.msm_pc);
191 const auto& msm_count = View(in.msm_count);
192 const auto& msm_slice1 = View(in.msm_slice1);
193 const auto& msm_slice2 = View(in.msm_slice2);
194 const auto& msm_slice3 = View(in.msm_slice3);
195 const auto& msm_slice4 = View(in.msm_slice4);
196 const auto& msm_x1 = View(in.msm_x1);
197 const auto& msm_x2 = View(in.msm_x2);
198 const auto& msm_x3 = View(in.msm_x3);
199 const auto& msm_x4 = View(in.msm_x4);
200 const auto& msm_y1 = View(in.msm_y1);
201 const auto& msm_y2 = View(in.msm_y2);
202 const auto& msm_y3 = View(in.msm_y3);
203 const auto& msm_y4 = View(in.msm_y4);
204
205 // how do we get pc value
206 // row pc = value of pc after msm
207 // row count = num processed points in round
208 // size_of_msm = msm_size
209 // value of pc at start of msm = msm_pc - msm_size_of_msm
210 // value of current pc = msm_pc - msm_size_of_msm + msm_count + (0,1,2,3)
211 const auto current_pc = msm_pc - msm_count;
212
213 if constexpr (read_index == 0) {
214 const auto read_term1 = (current_pc) + gamma + msm_slice1 * beta + msm_x1 * beta_sqr + msm_y1 * beta_cube;
215 return read_term1; // degree 1
216 }
217 if constexpr (read_index == 1) {
218 const auto read_term2 =
219 (current_pc - 1) + gamma + msm_slice2 * beta + msm_x2 * beta_sqr + msm_y2 * beta_cube;
220 return read_term2; // degree 1
221 }
222 if constexpr (read_index == 2) {
223 const auto read_term3 =
224 (current_pc - 2) + gamma + msm_slice3 * beta + msm_x3 * beta_sqr + msm_y3 * beta_cube;
225 return read_term3; // degree 1
226 }
227 if constexpr (read_index == 3) {
228 const auto read_term4 =
229 (current_pc - 3) + gamma + msm_slice4 * beta + msm_x4 * beta_sqr + msm_y4 * beta_cube;
230 return read_term4; // degree 1
231 }
232 return Accumulator(1);
233 }
234
248 template <typename ContainerOverSubrelations, typename AllEntities, typename Parameters>
249 static void accumulate(ContainerOverSubrelations& accumulator,
250 const AllEntities& in,
251 const Parameters& params,
252 const FF& scaling_factor);
253};
254
256
257} // namespace bb
static Accumulator compute_inverse_exists(const AllEntities &in)
static constexpr size_t READ_TERMS
static Accumulator compute_write_term_predicate(const AllEntities &in)
static Accumulator compute_read_term(const AllEntities &in, const Parameters &params)
static Accumulator compute_read_term_predicate(const AllEntities &in)
static auto & get_inverse_polynomial(AllEntities &in)
Get the inverse lookup polynomial.
static constexpr size_t LENGTH
static Accumulator compute_write_term(const AllEntities &in, const Parameters &params)
static constexpr std::array< size_t, 2 > SUBRELATION_PARTIAL_LENGTHS
static constexpr std::array< bool, 2 > SUBRELATION_LINEARLY_INDEPENDENT
static constexpr size_t WRITE_TERMS
static bool operation_exists_at_row(const AllValues &row)
static Accumulator lookup_read_counts(const AllEntities &in)
static void accumulate(ContainerOverSubrelations &accumulator, const AllEntities &in, const Parameters &params, const FF &scaling_factor)
Expression for ECCVM lookup tables.
A wrapper for Relations to expose methods used by the Sumcheck prover or verifier to add the contribu...
Entry point for Barretenberg command-line interface.
typename Flavor::FF FF