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
13
14namespace bb::stdlib::recursion {
15
24template <typename Builder_> struct PairingPoints {
25 using Builder = Builder_;
27 using Group = typename Curve::Group;
28 using Fr = typename Curve::ScalarField;
31
32 bool has_data = false;
33
34 // Number of bb::fr field elements used to represent a goblin element in the public inputs
35 static constexpr size_t PUBLIC_INPUTS_SIZE = PAIRING_POINTS_SIZE;
36
37 PairingPoints() = default;
38
39 PairingPoints(const Group& P0, const Group& P1)
40 : P0(P0)
41 , P1(P1)
42 , has_data(true)
43 {}
44
46 : PairingPoints(points[0], points[1])
47 {}
48
49 typename Curve::bool_ct operator==(PairingPoints const& other) const { return P0 == other.P0 && P1 == other.P1; };
50
58 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1376): Potentially switch a batch_mul approach to
59 // aggregation rather than individually aggregating 1 object at a time.
60 void aggregate(PairingPoints const& other)
61 {
62 ASSERT(other.has_data, "Cannot aggregate null pairing points.");
63
64 // If LHS is empty, simply set it equal to the incoming pairing points
65 if (!this->has_data && other.has_data) {
66 *this = other;
67 return;
68 }
69 // We use a Transcript because it provides us an easy way to hash to get a "random" separator.
71 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1375): Sometimes unnecesarily hashing constants
72
73 transcript.send_to_verifier("Accumulator_P0", P0);
74 transcript.send_to_verifier("Accumulator_P1", P1);
75 transcript.send_to_verifier("Aggregated_P0", other.P0);
76 transcript.send_to_verifier("Aggregated_P1", other.P1);
77 auto recursion_separator =
78 transcript.template get_challenge<typename Curve::ScalarField>("recursion_separator");
79 // If Mega Builder is in use, the EC operations are deferred via Goblin
81 // TODO(https://github.com/AztecProtocol/barretenberg/issues/1385): Can we improve efficiency here?
82 P0 = Group::batch_mul({ P0, other.P0 }, { 1, recursion_separator });
83 P1 = Group::batch_mul({ P1, other.P1 }, { 1, recursion_separator });
84 } else {
85 // Save gates using short scalars. We don't apply `bn254_endo_batch_mul` to the vector {1,
86 // recursion_separator} directly to avoid edge cases.
87 Group point_to_aggregate = other.P0.scalar_mul(recursion_separator, 128);
88 P0 += point_to_aggregate;
89 point_to_aggregate = other.P1.scalar_mul(recursion_separator, 128);
90 P1 += point_to_aggregate;
91 }
92 }
93
99 uint32_t set_public()
100 {
101 ASSERT(this->has_data, "Calling set_public on empty pairing points.");
102 uint32_t start_idx = P0.set_public();
103 P1.set_public();
104
105 return start_idx;
106 }
107
115 {
116 const size_t FRS_PER_POINT = Group::PUBLIC_INPUTS_SIZE;
117 std::span<const Fr, FRS_PER_POINT> P0_limbs{ limbs.data(), FRS_PER_POINT };
118 std::span<const Fr, FRS_PER_POINT> P1_limbs{ limbs.data() + FRS_PER_POINT, FRS_PER_POINT };
119 Group P0 = Group::reconstruct_from_public(P0_limbs);
120 Group P1 = Group::reconstruct_from_public(P1_limbs);
121 return { P0, P1 };
122 }
123
125 {
126 // We just biggroup here instead of Group (which is either biggroup or biggroup_goblin) because this is the most
127 // efficient way of setting the default pairing points. If we use biggroup_goblin elements, we have to convert
128 // them back to biggroup elements anyway to add them to the public inputs...
129 using BigGroup = element_default::
130 element<Builder, bigfield<Builder, bb::Bn254FqParams>, field_t<Builder>, curve::BN254::Group>;
131 std::array<fr, PUBLIC_INPUTS_SIZE> dummy_pairing_points_values;
132 size_t idx = 0;
133 for (size_t i = 0; i < 2; i++) {
134 std::array<fr, BigGroup::PUBLIC_INPUTS_SIZE> element_vals = BigGroup::construct_dummy();
135 for (auto& val : element_vals) {
136 dummy_pairing_points_values[idx++] = val;
137 }
138 }
139
140 return dummy_pairing_points_values;
141 }
142
151 {
152 // TODO(https://github.com/AztecProtocol/barretenberg/issues/911): These are pairing points extracted from a
153 // valid proof. This is a workaround because we can't represent the point at infinity in biggroup yet.
155 fq("0x031e97a575e9d05a107acb64952ecab75c020998797da7842ab5d6d1986846cf"));
157 fq("0x178cbf4206471d722669117f9758a4c410db10a01750aebb5666547acf8bd5a4"));
159 fq("0x0f94656a2ca489889939f81e9c74027fd51009034b3357f0e91b8a11e7842c38"));
161 fq("0x1b52c2020d7464a0c80c0da527a08193fe27776f50224bd6fb128b46c1ddb67f"));
162
167
168 x0.set_public();
169 y0.set_public();
170 x1.set_public();
171 y1.set_public();
172 }
173};
174
175template <typename Builder> void read(uint8_t const*& it, PairingPoints<Builder>& as)
176{
177 using serialize::read;
178
179 read(it, as.P0);
180 read(it, as.P1);
181 read(it, as.has_data);
182};
183
184template <typename Builder> void write(std::vector<uint8_t>& buf, PairingPoints<Builder> const& as)
185{
186 using serialize::write;
187
188 write(buf, as.P0);
189 write(buf, as.P1);
190 write(buf, as.has_data);
191};
192
193template <typename NCT> std::ostream& operator<<(std::ostream& os, PairingPoints<NCT> const& as)
194{
195 return os << "P0: " << as.P0 << "\n"
196 << "P1: " << as.P1 << "\n"
197 << "has_data: " << as.has_data << "\n";
198}
199
200} // namespace bb::stdlib::recursion
#define ASSERT(expression,...)
Definition assert.hpp:49
Common transcript class for both parties. Stores the data for the current round, as well as the manif...
void send_to_verifier(const std::string &label, const T &element)
Adds a prover message to the transcript, only intended to be used by the prover.
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)