23static constexpr uint64_t UINT256_TOP_LIMB_MSB = 0x8000000000000000ULL;
27template <
typename Fq_,
typename Fr_,
typename Params_>
class alignas(64)
affine_element {
63 template <
typename BaseField =
Fq,
76 template <
typename BaseField =
Fq,
126 if (
value.is_point_at_infinity()) {
129 memset(
buffer, 255,
sizeof(
Fq) * 2);
174 [[nodiscard]]
inline std::vector<uint8_t>
to_buffer()
const
183 os <<
"{ " <<
a.x <<
", " <<
a.y <<
" }";
199 size_t max_num_bits = 0,
200 bool with_edgecases =
true,
207 template <typename T>
231 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL
234 if constexpr (is_field2_v<Fq>) {
235 raw_element.x = { all_ones, all_ones };
236 raw_element.y = { all_ones, all_ones };
238 raw_element.x = all_ones;
239 raw_element.y = all_ones;
243 if constexpr (is_field2_v<Fq>) {
244 raw_element.x = {
x.c0,
x.c1 };
245 raw_element.y = {
y.c0,
y.c1 };
251 packer.pack(raw_element);
260 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL
264 if constexpr (is_field2_v<Fq>) {
265 is_infinity = (raw_element.
x[0] == all_ones && raw_element.
x[1] == all_ones &&
266 raw_element.
y[0] == all_ones && raw_element.
y[1] == all_ones);
268 is_infinity = (raw_element.
x == all_ones && raw_element.
y == all_ones);
275 if constexpr (is_field2_v<Fq>) {
276 x.c0 = raw_element.
x[0];
277 x.c1 = raw_element.
x[1];
278 y.c0 = raw_element.
y[0];
279 y.c1 = raw_element.
y[1];
289 if (packer.set_emitted(schema_name)) {
290 packer.pack(schema_name);
294 packer.pack(
"__typename");
295 packer.pack(schema_name);
297 packer.pack_schema(
x);
299 packer.pack_schema(
y);
303template <
typename B,
typename Fq_,
typename Fr_,
typename Params>
313template <
typename B,
typename Fq_,
typename Fr_,
typename Params>
void msgpack_unpack(auto o)
friend std::ostream & operator<<(std::ostream &os, const affine_element &a)
static constexpr std::array< affine_element, 2 > from_compressed_unsafe(const uint256_t &compressed) noexcept
Reconstruct a point in affine coordinates from compressed form.
constexpr bool is_point_at_infinity() const noexcept
constexpr affine_element & operator=(const affine_element &other) noexcept=default
static constexpr affine_element hash_to_curve(const std::vector< uint8_t > &seed, uint8_t attempt_count=0) noexcept
Hash a seed buffer into a point.
static affine_element batch_mul(std::span< const affine_element > points, std::span< const Fr > scalars, size_t max_num_bits=0, bool with_edgecases=true, const Fr &masking_scalar=Fr(1)) noexcept
Multi-scalar multiplication: compute sum_i(scalars[i] * points[i])
static affine_element random_element(numeric::RNG *engine=nullptr) noexcept
Samples a random point on the curve.
std::vector< uint8_t > to_buffer() const
Serialize the point to a byte vector.
void msgpack_pack(auto &packer) const
const uint8_t * vec_in_buf
static affine_element serialize_from_buffer(const uint8_t *buffer, bool write_x_first=false)
Restore point from a buffer.
constexpr void self_set_infinity() noexcept
constexpr affine_element & operator=(affine_element &&other) noexcept=default
static constexpr affine_element infinity()
constexpr bool operator<(const affine_element &other) const noexcept
constexpr affine_element operator+(const affine_element &other) const noexcept
static constexpr affine_element from_compressed(const uint256_t &compressed) noexcept
Reconstruct a point in affine coordinates from compressed form.
constexpr bool on_curve() const noexcept
affine_element() noexcept=default
static constexpr affine_element one() noexcept
static constexpr size_t PUBLIC_INPUTS_SIZE
static constexpr std::optional< affine_element > derive_from_x_coordinate(const Fq &x, bool sign_bit) noexcept
static void serialize_to_buffer(const affine_element &value, uint8_t *buffer, bool write_x_first=false)
Serialize the point to the given buffer.
static constexpr bool is_field2_v
constexpr bool operator>(const affine_element &other) const noexcept
constexpr affine_element operator*(const Fr &exponent) const noexcept
void msgpack_schema(auto &packer) const
constexpr affine_element set_infinity() const noexcept
element class. Implements ecc group arithmetic using Jacobian coordinates See https://hyperelliptic....
std::unique_ptr< uint8_t[]> buffer
void read(B &it, group_elements::affine_element< Fq_, Fr_, Params > &element)
void write(B &it, group_elements::affine_element< Fq_, Fr_, Params > const &element)
AffineElement const size_t Fq *scratch_space noexcept
std::string msgpack_schema_name(g1::affine_element const &)
constexpr decltype(auto) get(::tuplet::tuple< T... > &&t) noexcept
static constexpr size_t PUBLIC_INPUTS_SIZE
std::conditional_t< is_field2_v< Fq >, std::array< uint256_t, 2 >, uint256_t > FieldType