Barretenberg
The ZK-SNARK library at the core of Aztec
Loading...
Searching...
No Matches
pairing_points.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
12
13namespace bb::stdlib::recursion {
14
23template <typename Builder_> struct PairingPoints {
24 using Builder = Builder_;
26 using Group = typename Curve::Group;
27 using Fr = typename Curve::ScalarField;
30
31 bool has_data = false;
32
33 // Number of bb::fr field elements used to represent a goblin element in the public inputs
34 static constexpr size_t PUBLIC_INPUTS_SIZE = PAIRING_POINTS_SIZE;
35
36 PairingPoints() = default;
37
38 PairingPoints(const Group& P0, const Group& P1)
39 : P0(P0)
40 , P1(P1)
41 , has_data(true)
42 {}
43
45 : PairingPoints(points[0], points[1])
46 {}
47
48 typename Curve::bool_ct operator==(PairingPoints const& other) const { return P0 == other.P0 && P1 == other.P1; };
49
57 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1376): Potentially switch a batch_mul approach to
58 // aggregation rather than individually aggregating 1 object at a time.
59 void aggregate(PairingPoints const& other)
60 {
61 ASSERT(other.has_data, "Cannot aggregate null pairing points.");
62
63 // If LHS is empty, simply set it equal to the incoming pairing points
64 if (!this->has_data && other.has_data) {
65 *this = other;
66 return;
67 }
68 // We use a Transcript because it provides us an easy way to hash to get a "random" separator.
69 StdlibTranscript<Builder> transcript{};
70 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1375): Sometimes unnecesarily hashing constants
71
72 transcript.add_to_hash_buffer("Accumulator_P0", P0);
73 transcript.add_to_hash_buffer("Accumulator_P1", P1);
74 transcript.add_to_hash_buffer("Aggregated_P0", other.P0);
75 transcript.add_to_hash_buffer("Aggregated_P1", other.P1);
76 auto recursion_separator =
77 transcript.template get_challenge<typename Curve::ScalarField>("recursion_separator");
78 // If Mega Builder is in use, the EC operations are deferred via Goblin
80 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1385): Can we improve efficiency here?
81 P0 = Group::batch_mul({ P0, other.P0 }, { 1, recursion_separator });
82 P1 = Group::batch_mul({ P1, other.P1 }, { 1, recursion_separator });
83 } else {
84 // Save gates using short scalars. We don't apply `bn254_endo_batch_mul` to the vector {1,
85 // recursion_separator} directly to avoid edge cases.
86 Group point_to_aggregate = other.P0.scalar_mul(recursion_separator, 128);
87 P0 += point_to_aggregate;
88 point_to_aggregate = other.P1.scalar_mul(recursion_separator, 128);
89 P1 += point_to_aggregate;
90 }
91 }
92
98 uint32_t set_public()
99 {
100 ASSERT(this->has_data, "Calling set_public on empty pairing points.");
101 uint32_t start_idx = P0.set_public();
102 P1.set_public();
103
104 return start_idx;
105 }
106
114 {
115 const size_t FRS_PER_POINT = Group::PUBLIC_INPUTS_SIZE;
116 std::span<const Fr, FRS_PER_POINT> P0_limbs{ limbs.data(), FRS_PER_POINT };
117 std::span<const Fr, FRS_PER_POINT> P1_limbs{ limbs.data() + FRS_PER_POINT, FRS_PER_POINT };
118 Group P0 = Group::reconstruct_from_public(P0_limbs);
119 Group P1 = Group::reconstruct_from_public(P1_limbs);
120 return { P0, P1 };
121 }
122
124 {
125 // We just biggroup here instead of Group (which is either biggroup or biggroup_goblin) because this is the most
126 // efficient way of setting the default pairing points. If we use biggroup_goblin elements, we have to convert
127 // them back to biggroup elements anyway to add them to the public inputs...
128 using BigGroup = element_default::
129 element<Builder, bigfield<Builder, bb::Bn254FqParams>, field_t<Builder>, curve::BN254::Group>;
130 std::array<fr, PUBLIC_INPUTS_SIZE> dummy_pairing_points_values;
131 size_t idx = 0;
132 for (size_t i = 0; i < 2; i++) {
133 std::array<fr, BigGroup::PUBLIC_INPUTS_SIZE> element_vals = BigGroup::construct_dummy();
134 for (auto& val : element_vals) {
135 dummy_pairing_points_values[idx++] = val;
136 }
137 }
138
139 return dummy_pairing_points_values;
140 }
141
150 {
151 // TODO(https://github.com/AztecProtocol/barretenberg/issues/911): These are pairing points extracted from a
152 // valid proof. This is a workaround because we can't represent the point at infinity in biggroup yet.
154 fq("0x031e97a575e9d05a107acb64952ecab75c020998797da7842ab5d6d1986846cf"));
156 fq("0x178cbf4206471d722669117f9758a4c410db10a01750aebb5666547acf8bd5a4"));
158 fq("0x0f94656a2ca489889939f81e9c74027fd51009034b3357f0e91b8a11e7842c38"));
160 fq("0x1b52c2020d7464a0c80c0da527a08193fe27776f50224bd6fb128b46c1ddb67f"));
161
166
167 x0.set_public();
168 y0.set_public();
169 x1.set_public();
170 y1.set_public();
171 }
172};
173
174template <typename Builder> void read(uint8_t const*& it, PairingPoints<Builder>& as)
175{
176 using serialize::read;
177
178 read(it, as.P0);
179 read(it, as.P1);
180 read(it, as.has_data);
181};
182
183template <typename Builder> void write(std::vector<uint8_t>& buf, PairingPoints<Builder> const& as)
184{
185 using serialize::write;
186
187 write(buf, as.P0);
188 write(buf, as.P1);
189 write(buf, as.has_data);
190};
191
192template <typename NCT> std::ostream& operator<<(std::ostream& os, PairingPoints<NCT> const& as)
193{
194 return os << "P0: " << as.P0 << "\n"
195 << "P1: " << as.P1 << "\n"
196 << "has_data: " << as.has_data << "\n";
197}
198
199} // namespace bb::stdlib::recursion
#define ASSERT(expression,...)
Definition assert.hpp:77
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.
typename bb::g1 Group
Definition bn254.hpp:20
void convert_constant_to_fixed_witness(Builder *builder)
Definition bigfield.hpp:677
uint32_t set_public() const
Set the witness indices of the binary basis limbs to public.
Definition bigfield.hpp:746
Implements boolean logic in-circuit.
Definition bool.hpp:59
AluTraceBuilder builder
Definition alu.test.cpp:123
uint8_t const * buf
Definition data_store.hpp:9
void write(std::vector< uint8_t > &buf, PairingPoints< Builder > const &as)
void read(uint8_t const *&it, PairingPoints< Builder > &as)
std::ostream & operator<<(std::ostream &os, PairingPoints< NCT > const &as)
field< Bn254FqParams > fq
Definition fq.hpp:169
void read(auto &it, msgpack_concepts::HasMsgPack auto &obj)
Automatically derived read for any object that defines .msgpack() (implicitly defined by MSGPACK_FIEL...
void write(auto &buf, const msgpack_concepts::HasMsgPack auto &obj)
Automatically derived write for any object that defines .msgpack() (implicitly defined by MSGPACK_FIE...
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
Definition tuple.hpp:13
field_t< CircuitBuilder > ScalarField
Definition bn254.hpp:33
element< CircuitBuilder, bigfield< CircuitBuilder, bb::Bn254FqParams >, ScalarField, GroupNative > Group
Definition bn254.hpp:34
An object storing two EC points that represent the inputs to a pairing check.
PairingPoints(std::array< Group, 2 > const &points)
Curve::bool_ct operator==(PairingPoints const &other) const
static std::array< fr, PUBLIC_INPUTS_SIZE > construct_dummy()
typename Curve::ScalarField Fr
PairingPoints(const Group &P0, const Group &P1)
static void add_default_to_public_inputs(Builder &builder)
Adds default public inputs to the builder.
void aggregate(PairingPoints const &other)
Compute a linear combination of the present pairing points with an input set of pairing points.
uint32_t set_public()
Set the witness indices for the limbs of the pairing points to public.
static constexpr size_t PUBLIC_INPUTS_SIZE
static PairingPoints< Builder > reconstruct_from_public(const std::span< const Fr, PUBLIC_INPUTS_SIZE > &limbs)
Reconstruct an PairingPoints from its representation as limbs (generally stored in the public inputs)