3#include "../bigfield/bigfield.hpp"
4#include "../byte_array/byte_array.hpp"
5#include "../circuit_builders/circuit_builders_fwd.hpp"
6#include "../field/field.hpp"
7#include "../memory/rom_table.hpp"
8#include "../memory/twin_rom_table.hpp"
9#include "barretenberg/ecc/curves/bn254/g1.hpp"
10#include "barretenberg/ecc/curves/secp256k1/secp256k1.hpp"
11#include "barretenberg/ecc/curves/secp256r1/secp256r1.hpp"
16template <
typename Builder,
typename NativeGroup>
19namespace proof_system::plonk::stdlib {
22template <
class Builder,
class Fq,
class Fr,
class NativeGroup>
class element {
25 std::vector<field_t<Builder>> wnaf;
29 bool has_wnaf_fragment =
false;
37 element(
const typename NativeGroup::affine_element& input);
43 static element from_witness(
Builder* ctx,
const typename NativeGroup::affine_element& input)
45 Fq x = Fq::from_witness(ctx, input.x);
46 Fq y = Fq::from_witness(ctx, input.y);
48 out.validate_on_curve();
52 void validate_on_curve()
const
54 Fq b(get_context(),
uint256_t(NativeGroup::curve_b));
55 if constexpr (!NativeGroup::has_a) {
57 Fq::mult_madd({ x.
sqr(), y }, { x, -y }, { b },
true);
59 Fq a(get_context(),
uint256_t(NativeGroup::curve_a));
61 Fq::mult_madd({ x.
sqr(), x, y }, { x, a, -y }, { b },
true);
65 static element one(
Builder* ctx)
71 return element(x_fq, y_fq);
74 element& operator=(
const element& other);
75 element& operator=(element&& other);
77 byte_array<Builder> to_byte_array()
const
79 byte_array<Builder> result(get_context());
80 result.write(y.to_byte_array());
81 result.write(x.to_byte_array());
85 element operator+(
const element& other)
const;
86 element operator-(
const element& other)
const;
87 element operator-()
const
89 element result(*
this);
93 element operator+=(
const element& other)
95 *
this = *
this + other;
98 element operator-=(
const element& other)
100 *
this = *
this - other;
103 std::array<element, 2>
add_sub(
const element& other)
const;
107 element conditional_negate(
const bool_t<Builder>& predicate)
const
109 element result(*
this);
110 result.y = result.y.conditional_negate(predicate);
114 element normalize()
const
116 element result(*
this);
117 result.x.assert_is_in_field();
118 result.y.assert_is_in_field();
122 element reduce()
const
124 element result(*
this);
125 result.x.self_reduce();
126 result.y.self_reduce();
141 bool is_element =
false;
177 typename NativeGroup::affine_element get_value()
const
179 uint512_t x_val = x.get_value();
180 uint512_t y_val = y.get_value();
181 return typename NativeGroup::affine_element(x_val.lo, y_val.lo);
188 template <
size_t max_num_bits = 0>
189 static element wnaf_batch_mul(
const std::vector<element>& points,
const std::vector<Fr>& scalars);
191 const std::vector<Fr>& scalars,
192 const size_t max_num_bits = 0);
197 const std::vector<Fr>& scalars,
198 const size_t max_num_bits = 0);
212 template <typename X = NativeGroup, typename = typename std::enable_if_t<std::is_same<X, barretenberg::g1>::value>>
214 static element bn254_endo_batch_mul(
const std::vector<element>& big_points,
215 const std::vector<Fr>& big_scalars,
216 const std::vector<element>& small_points,
217 const std::vector<Fr>& small_scalars,
218 const size_t max_num_small_bits);
220 template <typename X = NativeGroup, typename = typename std::enable_if_t<std::is_same<X, barretenberg::g1>::value>>
222 static element bn254_endo_batch_mul_with_generator(
const std::vector<element>& big_points,
223 const std::vector<Fr>& big_scalars,
224 const std::vector<element>& small_points,
225 const std::vector<Fr>& small_scalars,
226 const Fr& generator_scalar,
227 const size_t max_num_small_bits);
229 template <typename X = NativeGroup, typename = typename std::enable_if_t<std::is_same<X, secp256k1::g1>::value>>
230 static element secp256k1_ecdsa_mul(
const element& pubkey,
const Fr& u1,
const Fr& u2);
232 static std::vector<bool_t<Builder>> compute_naf(
const Fr& scalar,
const size_t max_num_bits = 0);
234 template <
size_t max_num_bits = 0,
size_t WNAF_SIZE = 4>
235 static std::vector<field_t<Builder>> compute_wnaf(
const Fr& scalar);
237 template <
size_t wnaf_size,
size_t staggered_lo_offset = 0,
size_t staggered_hi_offset = 0>
242 if (x.context !=
nullptr) {
245 if (y.context !=
nullptr) {
251 Builder* get_context(
const element& other)
const
253 if (x.context !=
nullptr) {
256 if (y.context !=
nullptr) {
259 if (other.x.context !=
nullptr) {
260 return other.x.context;
262 if (other.y.context !=
nullptr) {
263 return other.y.context;
272 template <
size_t num_elements,
typename =
typename std::enable_if<HasPlookup<Builder>>>
273 static std::array<twin_rom_table<Builder>, 5> create_group_element_rom_tables(
274 const std::array<element, num_elements>& elements, std::array<uint256_t, 8>& limb_max);
276 template <
size_t num_elements,
typename =
typename std::enable_if<HasPlookup<Builder>>>
277 static element read_group_element_rom_tables(
const std::array<twin_rom_table<Builder>, 5>& tables,
279 const std::array<uint256_t, 8>& limb_max);
281 static std::pair<element, element> compute_offset_generators(
const size_t num_rounds);
283 template <
typename =
typename std::enable_if<HasPlookup<Builder>>>
struct four_bit_table_plookup {
284 four_bit_table_plookup(){};
285 four_bit_table_plookup(
const element& input);
287 four_bit_table_plookup(
const four_bit_table_plookup& other) =
default;
288 four_bit_table_plookup& operator=(
const four_bit_table_plookup& other) =
default;
291 element operator[](
const size_t idx)
const {
return element_table[idx]; }
292 std::array<element, 16> element_table;
293 std::array<twin_rom_table<Builder>, 5> coordinates;
294 std::array<uint256_t, 8> limb_max;
297 template <
typename =
typename std::enable_if<HasPlookup<Builder>>>
struct eight_bit_fixed_base_table {
298 enum CurveType { BN254, SECP256K1, SECP256R1 };
299 eight_bit_fixed_base_table(
const CurveType input_curve_type,
bool use_endo)
300 : curve_type(input_curve_type)
301 , use_endomorphism(use_endo){};
303 eight_bit_fixed_base_table(
const eight_bit_fixed_base_table& other) =
default;
304 eight_bit_fixed_base_table& operator=(
const eight_bit_fixed_base_table& other) =
default;
308 element operator[](
const size_t idx)
const;
310 CurveType curve_type;
311 bool use_endomorphism;
314 template <
typename =
typename std::enable_if<HasPlookup<Builder>>>
315 static std::pair<four_bit_table_plookup<>, four_bit_table_plookup<>> create_endo_pair_four_bit_table_plookup(
316 const element& input)
318 four_bit_table_plookup<> P1;
319 four_bit_table_plookup<> endoP1;
320 element d2 = input.dbl();
322 P1.element_table[8] = input;
323 for (
size_t i = 9; i < 16; ++i) {
324 P1.element_table[i] = P1.element_table[i - 1] + d2;
326 for (
size_t i = 0; i < 8; ++i) {
327 P1.element_table[i] = (-P1.element_table[15 - i]);
329 for (
size_t i = 0; i < 16; ++i) {
330 endoP1.element_table[i].y = P1.element_table[15 - i].y;
334 for (
size_t i = 0; i < 8; ++i) {
335 endoP1.element_table[i].x = P1.element_table[i].x * beta;
336 endoP1.element_table[15 - i].x = endoP1.element_table[i].x;
338 P1.coordinates = create_group_element_rom_tables<16>(P1.element_table, P1.limb_max);
339 endoP1.coordinates = create_group_element_rom_tables<16>(endoP1.element_table, endoP1.limb_max);
340 auto result = std::make_pair<four_bit_table_plookup<>, four_bit_table_plookup<>>(
341 (four_bit_table_plookup<>)P1, (four_bit_table_plookup<>)endoP1);
364 template <
size_t length>
struct lookup_table_base {
365 static constexpr size_t table_size = (1ULL << (length - 1));
366 lookup_table_base(
const std::array<element, length>& inputs);
367 lookup_table_base(
const lookup_table_base& other) =
default;
368 lookup_table_base& operator=(
const lookup_table_base& other) =
default;
370 element get(
const std::array<bool_t<Builder>, length>& bits)
const;
372 element operator[](
const size_t idx)
const {
return element_table[idx]; }
374 std::array<field_t<Builder>, table_size> x_b0_table;
375 std::array<field_t<Builder>, table_size> x_b1_table;
376 std::array<field_t<Builder>, table_size> x_b2_table;
377 std::array<field_t<Builder>, table_size> x_b3_table;
379 std::array<field_t<Builder>, table_size> y_b0_table;
380 std::array<field_t<Builder>, table_size> y_b1_table;
381 std::array<field_t<Builder>, table_size> y_b2_table;
382 std::array<field_t<Builder>, table_size> y_b3_table;
385 std::array<element, table_size> element_table;
393 template <
size_t length,
typename =
typename std::enable_if<HasPlookup<Builder>>>
struct lookup_table_plookup {
394 static constexpr size_t table_size = (1ULL << (length));
395 lookup_table_plookup() {}
396 lookup_table_plookup(
const std::array<element, length>& inputs);
397 lookup_table_plookup(
const lookup_table_plookup& other) =
default;
398 lookup_table_plookup& operator=(
const lookup_table_plookup& other) =
default;
400 element get(
const std::array<bool_t<Builder>, length>& bits)
const;
402 element operator[](
const size_t idx)
const {
return element_table[idx]; }
404 std::array<element, table_size> element_table;
405 std::array<twin_rom_table<Builder>, 5> coordinates;
406 std::array<uint256_t, 8> limb_max;
409 using twin_lookup_table =
410 typename std::conditional<HasPlookup<Builder>, lookup_table_plookup<2, void>, lookup_table_base<2>>::type;
412 using triple_lookup_table =
413 typename std::conditional<HasPlookup<Builder>, lookup_table_plookup<3, void>, lookup_table_base<3>>::type;
415 using quad_lookup_table =
416 typename std::conditional<HasPlookup<Builder>, lookup_table_plookup<4, void>, lookup_table_base<4>>::type;
422 static std::pair<quad_lookup_table, quad_lookup_table> create_endo_pair_quad_lookup_table(
423 const std::array<element, 4>& inputs)
425 quad_lookup_table base_table(inputs);
426 quad_lookup_table endo_table;
430 for (
size_t i = 0; i < 8; ++i) {
431 endo_table.element_table[i + 8].x = base_table[7 - i].x * beta;
432 endo_table.element_table[i + 8].y = base_table[7 - i].y;
434 endo_table.element_table[7 - i] = (-endo_table.element_table[i + 8]);
437 endo_table.coordinates = create_group_element_rom_tables<16>(endo_table.element_table, endo_table.limb_max);
439 std::array<element, 4> endo_inputs(inputs);
440 for (
auto& input : endo_inputs) {
444 endo_table = quad_lookup_table(endo_inputs);
446 return std::make_pair<quad_lookup_table, quad_lookup_table>((quad_lookup_table)base_table,
447 (quad_lookup_table)endo_table);
454 template <
typename X =
typename std::enable_if<HasPlookup<Builder>>>
455 static std::pair<lookup_table_plookup<5, X>, lookup_table_plookup<5, X>> create_endo_pair_five_lookup_table(
456 const std::array<element, 5>& inputs)
458 lookup_table_plookup<5> base_table(inputs);
459 lookup_table_plookup<5> endo_table;
463 for (
size_t i = 0; i < 16; ++i) {
464 endo_table.element_table[i + 16].x = base_table[15 - i].x * beta;
465 endo_table.element_table[i + 16].y = base_table[15 - i].y;
467 endo_table.element_table[15 - i] = (-endo_table.element_table[i + 16]);
470 endo_table.coordinates = create_group_element_rom_tables<32>(endo_table.element_table, endo_table.limb_max);
472 return std::make_pair<lookup_table_plookup<5>, lookup_table_plookup<5>>((lookup_table_plookup<5>)base_table,
473 (lookup_table_plookup<5>)endo_table);
481 template <
typename X =
typename std::enable_if<HasPlookup<Builder>>>
struct batch_lookup_table_plookup {
482 batch_lookup_table_plookup(
const std::vector<element>& points)
484 num_points = points.size();
485 num_fives = num_points / 5;
488 if (num_fives * 5 == (num_points - 1)) {
491 }
else if (num_fives * 5 == (num_points - 2) && num_fives >= 2) {
494 }
else if (num_fives * 5 == (num_points - 3) && num_fives >= 3) {
499 has_quad = ((num_fives * 5 + num_sixes * 6) < num_points - 3) && (num_points >= 4);
501 has_triple = ((num_fives * 5 + num_sixes * 6 + (size_t)has_quad * 4) < num_points - 2) && (num_points >= 3);
504 ((num_fives * 5 + num_sixes * 6 + (size_t)has_quad * 4 + (
size_t)has_triple * 3) < num_points - 1) &&
507 has_singleton = num_points != ((num_fives * 5 + num_sixes * 6) + ((
size_t)has_quad * 4) +
508 ((
size_t)has_triple * 3) + ((
size_t)has_twin * 2));
511 for (
size_t i = 0; i < num_sixes; ++i) {
512 six_tables.push_back(lookup_table_plookup<6>({
513 points[offset + 6 * i],
514 points[offset + 6 * i + 1],
515 points[offset + 6 * i + 2],
516 points[offset + 6 * i + 3],
517 points[offset + 6 * i + 4],
518 points[offset + 6 * i + 5],
521 offset += 6 * num_sixes;
522 for (
size_t i = 0; i < num_fives; ++i) {
523 five_tables.push_back(lookup_table_plookup<5>({
524 points[offset + 5 * i],
525 points[offset + 5 * i + 1],
526 points[offset + 5 * i + 2],
527 points[offset + 5 * i + 3],
528 points[offset + 5 * i + 4],
531 offset += 5 * num_fives;
534 quad_tables.push_back(
535 quad_lookup_table({ points[offset], points[offset + 1], points[offset + 2], points[offset + 3] }));
539 triple_tables.push_back(
540 triple_lookup_table({ points[offset], points[offset + 1], points[offset + 2] }));
543 twin_tables.push_back(twin_lookup_table({ points[offset], points[offset + 1] }));
547 singletons.push_back(points[points.size() - 1]);
551 element get_initial_entry()
const
553 std::vector<element> add_accumulator;
554 for (
size_t i = 0; i < num_sixes; ++i) {
555 add_accumulator.push_back(six_tables[i][0]);
557 for (
size_t i = 0; i < num_fives; ++i) {
558 add_accumulator.push_back(five_tables[i][0]);
561 add_accumulator.push_back(quad_tables[0][0]);
564 add_accumulator.push_back(twin_tables[0][0]);
567 add_accumulator.push_back(triple_tables[0][0]);
570 add_accumulator.push_back(singletons[0]);
573 element accumulator = add_accumulator[0];
574 for (
size_t i = 1; i < add_accumulator.size(); ++i) {
575 accumulator = accumulator + add_accumulator[i];
580 chain_add_accumulator get_chain_initial_entry()
const
582 std::vector<element> add_accumulator;
583 for (
size_t i = 0; i < num_sixes; ++i) {
584 add_accumulator.push_back(six_tables[i][0]);
586 for (
size_t i = 0; i < num_fives; ++i) {
587 add_accumulator.push_back(five_tables[i][0]);
590 add_accumulator.push_back(quad_tables[0][0]);
593 add_accumulator.push_back(twin_tables[0][0]);
596 add_accumulator.push_back(triple_tables[0][0]);
599 add_accumulator.push_back(singletons[0]);
601 if (add_accumulator.size() >= 2) {
603 for (
size_t i = 2; i < add_accumulator.size(); ++i) {
608 return chain_add_accumulator(add_accumulator[0]);
611 element::chain_add_accumulator get_chain_add_accumulator(std::vector<bool_t<Builder>>& naf_entries)
const
613 std::vector<element> round_accumulator;
614 for (
size_t j = 0; j < num_sixes; ++j) {
615 round_accumulator.push_back(six_tables[j].get({ naf_entries[6 * j],
616 naf_entries[6 * j + 1],
617 naf_entries[6 * j + 2],
618 naf_entries[6 * j + 3],
619 naf_entries[6 * j + 4],
620 naf_entries[6 * j + 5] }));
622 size_t offset = num_sixes * 6;
623 for (
size_t j = 0; j < num_fives; ++j) {
624 round_accumulator.push_back(five_tables[j].get({ naf_entries[offset + j * 5],
625 naf_entries[offset + j * 5 + 1],
626 naf_entries[offset + j * 5 + 2],
627 naf_entries[offset + j * 5 + 3],
628 naf_entries[offset + j * 5 + 4] }));
630 offset += num_fives * 5;
632 round_accumulator.push_back(quad_tables[0].get({ naf_entries[offset],
633 naf_entries[offset + 1],
634 naf_entries[offset + 2],
635 naf_entries[offset + 3] }));
639 round_accumulator.push_back(
640 triple_tables[0].get({ naf_entries[offset], naf_entries[offset + 1], naf_entries[offset + 2] }));
643 round_accumulator.push_back(twin_tables[0].get({ naf_entries[offset], naf_entries[offset + 1] }));
646 round_accumulator.push_back(singletons[0].conditional_negate(naf_entries[num_points - 1]));
649 element::chain_add_accumulator accumulator;
650 if (round_accumulator.size() == 1) {
651 return element::chain_add_accumulator(round_accumulator[0]);
652 }
else if (round_accumulator.size() == 2) {
656 for (
size_t j = 2; j < round_accumulator.size(); ++j) {
660 return (accumulator);
663 element get(std::vector<bool_t<Builder>>& naf_entries)
const
665 std::vector<element> round_accumulator;
666 for (
size_t j = 0; j < num_sixes; ++j) {
667 round_accumulator.push_back(six_tables[j].get({ naf_entries[6 * j],
668 naf_entries[6 * j + 1],
669 naf_entries[6 * j + 2],
670 naf_entries[6 * j + 3],
671 naf_entries[6 * j + 4],
672 naf_entries[6 * j + 5] }));
674 size_t offset = num_sixes * 6;
676 for (
size_t j = 0; j < num_fives; ++j) {
677 round_accumulator.push_back(five_tables[j].get({ naf_entries[offset + 5 * j],
678 naf_entries[offset + 5 * j + 1],
679 naf_entries[offset + 5 * j + 2],
680 naf_entries[offset + 5 * j + 3],
681 naf_entries[offset + 5 * j + 4] }));
684 offset += num_fives * 5;
687 round_accumulator.push_back(quad_tables[0].get(
688 naf_entries[offset], naf_entries[offset + 1], naf_entries[offset + 2], naf_entries[offset + 3]));
692 round_accumulator.push_back(
693 triple_tables[0].get(naf_entries[offset], naf_entries[offset + 1], naf_entries[offset + 2]));
696 round_accumulator.push_back(twin_tables[0].get(naf_entries[offset], naf_entries[offset + 1]));
699 round_accumulator.push_back(singletons[0].conditional_negate(naf_entries[num_points - 1]));
702 element result = round_accumulator[0];
703 element::chain_add_accumulator accumulator;
704 if (round_accumulator.size() == 1) {
706 }
else if (round_accumulator.size() == 2) {
707 return result + round_accumulator[1];
710 for (
size_t j = 2; j < round_accumulator.size(); ++j) {
717 std::vector<lookup_table_plookup<6>> six_tables;
718 std::vector<lookup_table_plookup<5>> five_tables;
719 std::vector<quad_lookup_table> quad_tables;
720 std::vector<triple_lookup_table> triple_tables;
721 std::vector<twin_lookup_table> twin_tables;
722 std::vector<element> singletons;
737 struct batch_lookup_table_base {
738 batch_lookup_table_base(
const std::vector<element>& points)
740 num_points = points.size();
741 num_quads = num_points / 4;
743 has_triple = ((num_quads * 4) < num_points - 2) && (num_points >= 3);
745 has_twin = ((num_quads * 4 + (size_t)has_triple * 3) < num_points - 1) && (num_points >= 2);
747 has_singleton = num_points != (num_quads * 4 + ((size_t)has_triple * 3) + ((size_t)has_twin * 2));
749 for (
size_t i = 0; i < num_quads; ++i) {
750 quad_tables.push_back(
751 quad_lookup_table({ points[4 * i], points[4 * i + 1], points[4 * i + 2], points[4 * i + 3] }));
755 triple_tables.push_back(triple_lookup_table(
756 { points[4 * num_quads], points[4 * num_quads + 1], points[4 * num_quads + 2] }));
759 twin_tables.push_back(twin_lookup_table({ points[4 * num_quads], points[4 * num_quads + 1] }));
763 singletons.push_back(points[points.size() - 1]);
767 element get_initial_entry()
const
769 std::vector<element> add_accumulator;
770 for (
size_t i = 0; i < num_quads; ++i) {
771 add_accumulator.push_back(quad_tables[i][0]);
774 add_accumulator.push_back(twin_tables[0][0]);
777 add_accumulator.push_back(triple_tables[0][0]);
780 add_accumulator.push_back(singletons[0]);
783 element accumulator = add_accumulator[0];
784 for (
size_t i = 1; i < add_accumulator.size(); ++i) {
785 accumulator = accumulator + add_accumulator[i];
790 chain_add_accumulator get_chain_initial_entry()
const
792 std::vector<element> add_accumulator;
793 for (
size_t i = 0; i < num_quads; ++i) {
794 add_accumulator.push_back(quad_tables[i][0]);
797 add_accumulator.push_back(twin_tables[0][0]);
800 add_accumulator.push_back(triple_tables[0][0]);
803 add_accumulator.push_back(singletons[0]);
805 if (add_accumulator.size() >= 2) {
807 for (
size_t i = 2; i < add_accumulator.size(); ++i) {
812 return chain_add_accumulator(add_accumulator[0]);
815 element::chain_add_accumulator get_chain_add_accumulator(std::vector<bool_t<Builder>>& naf_entries)
const
817 std::vector<element> round_accumulator;
818 for (
size_t j = 0; j < num_quads; ++j) {
819 round_accumulator.push_back(quad_tables[j].get(std::array<bool_t<Builder>, 4>{
820 naf_entries[4 * j], naf_entries[4 * j + 1], naf_entries[4 * j + 2], naf_entries[4 * j + 3] }));
824 round_accumulator.push_back(triple_tables[0].get(std::array<bool_t<Builder>, 3>{
825 naf_entries[num_quads * 4], naf_entries[num_quads * 4 + 1], naf_entries[num_quads * 4 + 2] }));
828 round_accumulator.push_back(twin_tables[0].get(
829 std::array<bool_t<Builder>, 2>{ naf_entries[num_quads * 4], naf_entries[num_quads * 4 + 1] }));
832 round_accumulator.push_back(singletons[0].conditional_negate(naf_entries[num_points - 1]));
835 element::chain_add_accumulator accumulator;
836 if (round_accumulator.size() == 1) {
837 accumulator.x3_prev = round_accumulator[0].x;
838 accumulator.y3_prev = round_accumulator[0].y;
839 accumulator.is_element =
true;
841 }
else if (round_accumulator.size() == 2) {
845 for (
size_t j = 2; j < round_accumulator.size(); ++j) {
849 return (accumulator);
852 element get(std::vector<bool_t<Builder>>& naf_entries)
const
854 std::vector<element> round_accumulator;
855 for (
size_t j = 0; j < num_quads; ++j) {
856 round_accumulator.push_back(quad_tables[j].get(
857 { naf_entries[4 * j], naf_entries[4 * j + 1], naf_entries[4 * j + 2], naf_entries[4 * j + 3] }));
861 round_accumulator.push_back(triple_tables[0].get(std::array<bool_t<Builder>, 3>{
862 naf_entries[num_quads * 4], naf_entries[num_quads * 4 + 1], naf_entries[num_quads * 4 + 2] }));
865 round_accumulator.push_back(
866 twin_tables[0].get({ naf_entries[num_quads * 4], naf_entries[num_quads * 4 + 1] }));
869 round_accumulator.push_back(singletons[0].conditional_negate(naf_entries[num_points - 1]));
872 element result = round_accumulator[0];
873 element::chain_add_accumulator accumulator;
874 if (round_accumulator.size() == 1) {
876 }
else if (round_accumulator.size() == 2) {
877 return result + round_accumulator[1];
880 for (
size_t j = 2; j < round_accumulator.size(); ++j) {
887 std::vector<quad_lookup_table> quad_tables;
888 std::vector<triple_lookup_table> triple_tables;
889 std::vector<twin_lookup_table> twin_tables;
890 std::vector<element> singletons;
899 using batch_lookup_table =
900 typename std::conditional<HasPlookup<Builder>, batch_lookup_table_plookup<>, batch_lookup_table_base>::type;
903template <
typename C,
typename Fq,
typename Fr,
typename G>
904inline std::ostream& operator<<(std::ostream& os, element<C, Fq, Fr, G>
const& v)
906 return os <<
"{ " << v.x <<
" , " << v.y <<
" }";
910#include "biggroup_batch_mul.hpp"
911#include "biggroup_bn254.hpp"
912#include "biggroup_goblin.hpp"
913#include "biggroup_impl.hpp"
914#include "biggroup_nafs.hpp"
915#include "biggroup_secp256k1.hpp"
916#include "biggroup_tables.hpp"
Definition: uint256.hpp:25
constexpr uint256_t slice(uint64_t start, uint64_t end) const
Definition: uint256_impl.hpp:157
Definition: standard_circuit_builder.hpp:12
Definition: biggroup.hpp:22
static secp256k1_wnaf_pair compute_secp256k1_endo_wnaf(const Fr &scalar)
Definition: biggroup_nafs.hpp:96
element multiple_montgomery_ladder(const std::vector< chain_add_accumulator > &to_add) const
Perform repeated iterations of the montgomery ladder algorithm.
Definition: biggroup_impl.hpp:458
element quadruple_and_add(const std::vector< element > &to_add) const
Compute 4.P + to_add[0] + ... + to_add[to_add.size() - 1].
Definition: biggroup_impl.hpp:363
static element batch_mul(const std::vector< element > &points, const std::vector< Fr > &scalars, const size_t max_num_bits=0)
Definition: biggroup_impl.hpp:620
element montgomery_ladder(const element &other) const
Definition: biggroup_impl.hpp:282
static element goblin_batch_mul(const std::vector< element > &points, const std::vector< Fr > &scalars, const size_t max_num_bits=0)
Goblin style batch multiplication.
Definition: biggroup_goblin.hpp:30
static chain_add_accumulator chain_add(const element &p1, const chain_add_accumulator &accumulator)
Definition: biggroup_impl.hpp:183
std::array< element, 2 > add_sub(const element &other) const
Compute (*this) + other AND (*this) - other as a size-2 array.
Definition: biggroup_impl.hpp:108
static chain_add_accumulator chain_add_start(const element &p1, const element &p2)
Definition: biggroup_impl.hpp:165
element operator*(const Fr &other) const
Definition: biggroup_impl.hpp:679
static element chain_add_end(const chain_add_accumulator &accumulator)
Definition: biggroup_impl.hpp:228
Contains all the headers required to adequately compile the types defined in circuit_builders_fwd....
Definition: circuit_builders.hpp:11
Definition: circuit_builders.hpp:15
Definition: circuit_builders.hpp:17
Definition: biggroup.hpp:17
BBERG_INLINE constexpr field sqr() const noexcept
Definition: field_impl.hpp:61
Definition: biggroup.hpp:135
Definition: biggroup.hpp:31
Definition: biggroup.hpp:24