42 for (
size_t i = 0; i < num_elements; ++i) {
43 limb_max[0] =
std::max(limb_max[0], rom_data[i]._x.binary_basis_limbs[0].maximum_value);
44 limb_max[1] =
std::max(limb_max[1], rom_data[i]._x.binary_basis_limbs[1].maximum_value);
45 limb_max[2] =
std::max(limb_max[2], rom_data[i]._x.binary_basis_limbs[2].maximum_value);
46 limb_max[3] =
std::max(limb_max[3], rom_data[i]._x.binary_basis_limbs[3].maximum_value);
47 limb_max[4] =
std::max(limb_max[4], rom_data[i]._y.binary_basis_limbs[0].maximum_value);
48 limb_max[5] =
std::max(limb_max[5], rom_data[i]._y.binary_basis_limbs[1].maximum_value);
49 limb_max[6] =
std::max(limb_max[6], rom_data[i]._y.binary_basis_limbs[2].maximum_value);
50 limb_max[7] =
std::max(limb_max[7], rom_data[i]._y.binary_basis_limbs[3].maximum_value);
53 rom_data[i]._x.binary_basis_limbs[1].element });
55 rom_data[i]._x.binary_basis_limbs[3].element });
57 rom_data[i]._y.binary_basis_limbs[1].element });
59 rom_data[i]._y.binary_basis_limbs[3].element });
60 prime_limbs.emplace_back(
79 const auto xlo = tables[0][
index];
80 const auto xhi = tables[1][
index];
81 const auto ylo = tables[2][
index];
82 const auto yhi = tables[3][
index];
83 const auto xyprime = tables[4][
index];
86 Fq x_fq = Fq::unsafe_construct_from_limbs(xlo[0], xlo[1], xhi[0], xhi[1], xyprime[0]);
87 Fq y_fq = Fq::unsafe_construct_from_limbs(ylo[0], ylo[1], yhi[0], yhi[1], xyprime[1]);
88 x_fq.binary_basis_limbs[0].maximum_value = limb_max[0];
89 x_fq.binary_basis_limbs[1].maximum_value = limb_max[1];
90 x_fq.binary_basis_limbs[2].maximum_value = limb_max[2];
91 x_fq.binary_basis_limbs[3].maximum_value = limb_max[3];
92 y_fq.binary_basis_limbs[0].maximum_value = limb_max[4];
93 y_fq.binary_basis_limbs[1].maximum_value = limb_max[5];
94 y_fq.binary_basis_limbs[2].maximum_value = limb_max[6];
95 y_fq.binary_basis_limbs[3].maximum_value = limb_max[7];
98 const auto output =
element(x_fq, y_fq,
false);
127 const auto get_plookup_tags = [
this]() {
128 switch (curve_type) {
131 use_endomorphism ? MultiTableId::SECP256K1_XLO_ENDO : MultiTableId::SECP256K1_XLO,
132 use_endomorphism ? MultiTableId::SECP256K1_XHI_ENDO : MultiTableId::SECP256K1_XHI,
133 MultiTableId::SECP256K1_YLO,
134 MultiTableId::SECP256K1_YHI,
135 use_endomorphism ? MultiTableId::SECP256K1_XYPRIME_ENDO : MultiTableId::SECP256K1_XYPRIME,
139 throw_or_abort(
"eight_bit_fixed_base_table only supports SECP256K1 curve type");
144 const auto tags = get_plookup_tags();
154 Fq x = Fq::unsafe_construct_from_limbs(xlo.first, xlo.second, xhi.first, xhi.second, xyprime.first);
155 Fq y = Fq::unsafe_construct_from_limbs(ylo.first, ylo.second, yhi.first, yhi.second, xyprime.second);
157 if (use_endomorphism) {
178 static_assert(
length <= 6,
"lookup_table_plookup only supports up to 6 input elements");
180 if constexpr (
length == 2) {
182 element_table[0] = A0;
183 element_table[1] = A1;
184 }
else if constexpr (
length == 3) {
185 auto [R0, R1] =
inputs[1].checked_unconditional_add_sub(
inputs[0]);
187 auto [T0, T1] =
inputs[2].checked_unconditional_add_sub(R0);
188 auto [T2, T3] =
inputs[2].checked_unconditional_add_sub(R1);
190 element_table[0] = T0;
191 element_table[1] = T2;
192 element_table[2] = T3;
193 element_table[3] = T1;
194 }
else if constexpr (
length == 4) {
195 auto [T0, T1] =
inputs[1].checked_unconditional_add_sub(
inputs[0]);
196 auto [T2, T3] =
inputs[3].checked_unconditional_add_sub(
inputs[2]);
198 auto [F0, F3] = T2.checked_unconditional_add_sub(T0);
199 auto [F1, F2] = T2.checked_unconditional_add_sub(T1);
200 auto [F4, F7] = T3.checked_unconditional_add_sub(T0);
201 auto [F5, F6] = T3.checked_unconditional_add_sub(T1);
203 element_table[0] = F0;
204 element_table[1] = F1;
205 element_table[2] = F2;
206 element_table[3] = F3;
207 element_table[4] = F4;
208 element_table[5] = F5;
209 element_table[6] = F6;
210 element_table[7] = F7;
211 }
else if constexpr (
length == 5) {
212 auto [A0, A1] =
inputs[1].checked_unconditional_add_sub(
inputs[0]);
213 auto [T2, T3] =
inputs[3].checked_unconditional_add_sub(
inputs[2]);
215 auto [E0, E3] =
inputs[4].checked_unconditional_add_sub(T2);
216 auto [E1, E2] =
inputs[4].checked_unconditional_add_sub(T3);
218 auto [F0, F3] = E0.checked_unconditional_add_sub(A0);
219 auto [F1, F2] = E0.checked_unconditional_add_sub(A1);
220 auto [F4, F7] = E1.checked_unconditional_add_sub(A0);
221 auto [F5, F6] = E1.checked_unconditional_add_sub(A1);
222 auto [F8, F11] = E2.checked_unconditional_add_sub(A0);
223 auto [F9, F10] = E2.checked_unconditional_add_sub(A1);
224 auto [F12, F15] = E3.checked_unconditional_add_sub(A0);
225 auto [F13, F14] = E3.checked_unconditional_add_sub(A1);
227 element_table[0] = F0;
228 element_table[1] = F1;
229 element_table[2] = F2;
230 element_table[3] = F3;
231 element_table[4] = F4;
232 element_table[5] = F5;
233 element_table[6] = F6;
234 element_table[7] = F7;
235 element_table[8] = F8;
236 element_table[9] = F9;
237 element_table[10] = F10;
238 element_table[11] = F11;
239 element_table[12] = F12;
240 element_table[13] = F13;
241 element_table[14] = F14;
242 element_table[15] = F15;
243 }
else if constexpr (
length == 6) {
246 auto [A0, A1] =
inputs[1].checked_unconditional_add_sub(
inputs[0]);
247 auto [E0, E1] =
inputs[4].checked_unconditional_add_sub(
inputs[3]);
248 auto [C0,
C3] =
inputs[2].checked_unconditional_add_sub(A0);
249 auto [
C1,
C2] =
inputs[2].checked_unconditional_add_sub(A1);
251 auto [F0, F3] =
inputs[5].checked_unconditional_add_sub(E0);
252 auto [F1, F2] =
inputs[5].checked_unconditional_add_sub(E1);
254 auto [R0, R7] = F0.checked_unconditional_add_sub(C0);
255 auto [R1, R6] = F0.checked_unconditional_add_sub(
C1);
256 auto [R2, R5] = F0.checked_unconditional_add_sub(
C2);
257 auto [R3, R4] = F0.checked_unconditional_add_sub(
C3);
259 auto [S0, S7] = F1.checked_unconditional_add_sub(C0);
260 auto [S1, S6] = F1.checked_unconditional_add_sub(
C1);
261 auto [S2, S5] = F1.checked_unconditional_add_sub(
C2);
262 auto [S3, S4] = F1.checked_unconditional_add_sub(
C3);
264 auto [U0, U7] = F2.checked_unconditional_add_sub(C0);
265 auto [
U1, U6] = F2.checked_unconditional_add_sub(
C1);
266 auto [U2, U5] = F2.checked_unconditional_add_sub(
C2);
267 auto [U3, U4] = F2.checked_unconditional_add_sub(
C3);
269 auto [W0, W7] = F3.checked_unconditional_add_sub(C0);
270 auto [W1, W6] = F3.checked_unconditional_add_sub(
C1);
271 auto [W2, W5] = F3.checked_unconditional_add_sub(
C2);
272 auto [W3, W4] = F3.checked_unconditional_add_sub(
C3);
274 element_table[0] = R0;
275 element_table[1] = R1;
276 element_table[2] = R2;
277 element_table[3] = R3;
278 element_table[4] = R4;
279 element_table[5] = R5;
280 element_table[6] = R6;
281 element_table[7] = R7;
283 element_table[8] = S0;
284 element_table[9] = S1;
285 element_table[10] = S2;
286 element_table[11] = S3;
287 element_table[12] = S4;
288 element_table[13] = S5;
289 element_table[14] = S6;
290 element_table[15] = S7;
292 element_table[16] = U0;
293 element_table[17] =
U1;
294 element_table[18] = U2;
295 element_table[19] = U3;
296 element_table[20] = U4;
297 element_table[21] = U5;
298 element_table[22] = U6;
299 element_table[23] = U7;
301 element_table[24] = W0;
302 element_table[25] = W1;
303 element_table[26] = W2;
304 element_table[27] = W3;
305 element_table[28] = W4;
306 element_table[29] = W5;
307 element_table[30] = W6;
308 element_table[31] = W7;
310 for (
size_t i = 0; i < table_size / 2; ++i) {
311 element_table[i + (table_size / 2)] = (-element_table[(table_size / 2) - 1 - i]);
313 coordinates = create_group_element_rom_tables<table_size>(element_table, limb_max);