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