49 Builder*
builder = validate_context<Builder>(p0.get_context(), p1.get_context());
56 info(
"Are Pairing Points with tag ",
tag_index,
" valid? ", native_pp.
check() ?
"true" :
"false");
67 constexpr size_t GROUP_SIZE = Codec::template calc_num_fields<Group>();
68 Group p0 = Codec::template deserialize_from_fields<Group>(limbs.template subspan<0, GROUP_SIZE>());
69 Group p1 = Codec::template deserialize_from_fields<Group>(limbs.template subspan<GROUP_SIZE, GROUP_SIZE>());
96 size_t num_points = pairing_points.size();
97 BB_ASSERT_GT(num_points, 0UL,
"Must provide at least one PairingPoints for aggregation");
98 for (
const auto& points : pairing_points) {
99 BB_ASSERT(points.has_data_,
"Cannot aggregate null pairing points.");
101 if (num_points == 1) {
102 return pairing_points[0];
106 first_components.reserve(num_points);
108 second_components.reserve(num_points);
109 for (
const auto& points : pairing_points) {
110 first_components.emplace_back(points.P0());
111 second_components.emplace_back(points.P1());
116 std::vector<std::string> labels;
117 labels.reserve(num_points - 1);
118 for (
size_t idx = 0;
auto [first, second] :
zip_view(first_components, second_components)) {
120 transcript.add_to_hash_buffer(
"second_component_" +
std::to_string(idx), second);
123 labels.emplace_back(
"pp_aggregation_challenge_" +
std::to_string(idx));
128 std::vector<Fr> challenges = transcript.template get_short_challenges<Fr>(labels);
139 std::vector<Fr> scalars;
140 scalars.reserve(num_points);
141 scalars.push_back(
Fr(1));
142 scalars.insert(scalars.end(), challenges.begin(), challenges.end());
144 P0 = Group::batch_mul(first_components, scalars);
145 P1 = Group::batch_mul(second_components, scalars);
148 std::vector<Group> remaining_first(first_components.begin() + 1, first_components.end());
149 std::vector<Group> remaining_second(second_components.begin() + 1, second_components.end());
151 P0 = first_components[0];
152 P1 = second_components[0];
154 P0 += Group::batch_mul(remaining_first, challenges, 128, handle_edge_cases);
155 P1 += Group::batch_mul(remaining_second, challenges, 128, handle_edge_cases);
163 for (
const auto& points : pairing_points) {
164 builder->pairing_points_tagging.merge_pairing_point_tags(aggregated_points.
tag_index, points.tag_index);
168 return aggregated_points;
190 transcript.add_to_hash_buffer(
"Accumulator_P1",
P1());
191 transcript.add_to_hash_buffer(
"Aggregated_P0", other.
P0());
192 transcript.add_to_hash_buffer(
"Aggregated_P1", other.
P1());
194 auto recursion_separator =
195 transcript.template get_short_challenge<typename Curve::ScalarField>(
"recursion_separator");
201 _points[0] = Group::batch_mul({
P0(), other.
P0() }, { 1, recursion_separator });
202 _points[1] = Group::batch_mul({
P1(), other.
P1() }, { 1, recursion_separator });
205 Group point_to_aggregate = other.
P0().scalar_mul(recursion_separator, 128);
206 _points[0] += point_to_aggregate;
207 point_to_aggregate = other.
P1().scalar_mul(recursion_separator, 128);
208 _points[1] += point_to_aggregate;
214 builder->pairing_points_tagging.merge_pairing_point_tags(this->tag_index, other.
tag_index);
219 info(
"Are aggregated Pairing Points with tag ",
tag_index,
" valid? ", native_pp.
check() ?
"true" :
"false");
234 Builder*
builder = validate_context<Builder>(ctx,
P0().get_context(),
P1().get_context());
235 BB_ASSERT(
builder !=
nullptr,
"set_public on default pairing points requires a builder context.");
238 Builder*
builder = validate_context<Builder>(ctx,
P0().get_context(),
P1().get_context());
239 BB_ASSERT(
builder !=
nullptr,
"set_public on pairing points requires a builder context.");
240 builder->pairing_points_tagging.set_public_pairing_points();
241 uint32_t start_idx =
P0().set_public();
264 return native_pp.
check();
276 builder->pairing_points_tagging.set_public_pairing_points();
279 uint32_t start_idx =
static_cast<uint32_t
>(
builder->num_public_inputs());
308 return os <<
"P0: " << as.
P0() <<
"\n"
309 <<
"P1: " << as.
P1() <<
"\n"
311 <<
"tag_index: " << as.
tag_index <<
"\n";
#define BB_ASSERT(expression,...)
#define BB_ASSERT_GT(left, right,...)
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
void add_to_hash_buffer(const std::string &label, const T &element)
Adds an element to the transcript.
An object storing two EC points that represent the inputs to a pairing check.
bool check() const
Verify the pairing equation e(P0, [1]₂) · e(P1, [x]₂) = 1.
typename grumpkin::g1 Group
std::ostream & operator<<(std::ostream &os, PairingPoints< NCT > const &as)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
std::string to_string(bb::avm2::ValueTag tag)
StdlibCodec for in-circuit (recursive) verification transcript handling.
An object storing two EC points that represent the inputs to a pairing check.
typename Curve::Builder Builder
static constexpr size_t PUBLIC_INPUTS_SIZE
bool check() const
Perform native pairing check on the witness values.
static uint32_t set_default_to_public(Builder *builder)
Set the witness indices for the default (infinity) pairing points to public.
static PairingPoints aggregate_multiple(std::vector< PairingPoints > &pairing_points, bool handle_edge_cases=true)
Aggregate multiple PairingPoints using random linear combination.
static PairingPoints reconstruct_from_public(const std::span< const stdlib::field_t< Builder >, PUBLIC_INPUTS_SIZE > &limbs)
Reconstruct PairingPoints from public input limbs.
void aggregate(PairingPoints const &other)
Aggregate another PairingPoints into this one via random linear combination.
bool is_populated() const
std::array< Group, 2 > _points
static PairingPoints construct_default()
Construct default pairing points (both at infinity).
void fix_witness()
Record the witness values of pairing points' coordinates in the selectors.
uint32_t set_public(Builder *ctx=nullptr)
Set the witness indices for the pairing points to public.
PairingPoints(const Group &p0, const Group &p1)