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,
75 template <
typename BaseField =
Fq,
141 if (
value.is_point_at_infinity()) {
144 memset(
buffer, 255,
sizeof(
Fq) * 2);
184 throw_or_abort(
"affine_element::serialize_from_buffer: point is not on the curve");
194 [[nodiscard]]
inline std::vector<uint8_t>
to_buffer()
const
203 os <<
"{ " <<
a.x <<
", " <<
a.y <<
" }";
219 size_t max_num_bits = 0,
220 bool with_edgecases =
true,
227 template <typename T>
251 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL
254 if constexpr (is_field2_v<Fq>) {
255 raw_element.x = { all_ones, all_ones };
256 raw_element.y = { all_ones, all_ones };
258 raw_element.x = all_ones;
259 raw_element.y = all_ones;
263 if constexpr (is_field2_v<Fq>) {
264 raw_element.x = {
x.c0,
x.c1 };
265 raw_element.y = {
y.c0,
y.c1 };
271 packer.pack(raw_element);
280 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL, 0xffffffffffffffffUL
284 if constexpr (is_field2_v<Fq>) {
285 is_infinity = (raw_element.
x[0] == all_ones && raw_element.
x[1] == all_ones &&
286 raw_element.
y[0] == all_ones && raw_element.
y[1] == all_ones);
288 is_infinity = (raw_element.
x == all_ones && raw_element.
y == all_ones);
295 if constexpr (is_field2_v<Fq>) {
296 x.c0 = raw_element.
x[0];
297 x.c1 = raw_element.
x[1];
298 y.c0 = raw_element.
y[0];
299 y.c1 = raw_element.
y[1];
309 if (packer.set_emitted(schema_name)) {
310 packer.pack(schema_name);
314 packer.pack(
"__typename");
315 packer.pack(schema_name);
317 packer.pack_schema(
x);
319 packer.pack_schema(
y);
323template <
typename B,
typename Fq_,
typename Fr_,
typename Params>
333template <
typename B,
typename Fq_,
typename Fr_,
typename Params>
void msgpack_unpack(auto o)
friend std::ostream & operator<<(std::ostream &os, const affine_element &a)
bool is_in_prime_subgroup() const noexcept
Check that the point lies in the prime-order subgroup of size Fr::modulus.
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 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 batch_mul(std::span< const affine_element > points, std::span< 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 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.
static affine_element hash_to_curve(const std::vector< uint8_t > &seed, uint8_t attempt_count=0) noexcept
Hash a seed buffer into a point.
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
SERIALIZATION_FIELDS(x, y)
std::conditional_t< is_field2_v< Fq >, std::array< uint256_t, 2 >, uint256_t > FieldType
void throw_or_abort(std::string const &err)