barretenberg
Loading...
Searching...
No Matches
affine_element.hpp
1#pragma once
2#include "barretenberg/ecc/curves/bn254/fq2.hpp"
3#include "barretenberg/numeric/uint256/uint256.hpp"
4#include "barretenberg/serialize/msgpack.hpp"
5#include <type_traits>
6#include <vector>
7
8namespace barretenberg::group_elements {
9template <typename T>
10concept SupportsHashToCurve = T::can_hash_to_curve;
11template <typename Fq, typename Fr, typename Params> class alignas(64) affine_element {
12 public:
13 using in_buf = const uint8_t*;
14 using vec_in_buf = const uint8_t*;
15 using out_buf = uint8_t*;
16 using vec_out_buf = uint8_t**;
17
18 affine_element() noexcept = default;
19 ~affine_element() noexcept = default;
20
21 constexpr affine_element(const Fq& a, const Fq& b) noexcept;
22
23 constexpr affine_element(const affine_element& other) noexcept = default;
24
25 constexpr affine_element(affine_element&& other) noexcept = default;
26
27 static constexpr affine_element one() noexcept { return { Params::one_x, Params::one_y }; };
28
38 template <typename BaseField = Fq,
39 typename CompileTimeEnabled = std::enable_if_t<(BaseField::modulus >> 255) == uint256_t(0), void>>
40 static constexpr affine_element from_compressed(const uint256_t& compressed) noexcept;
41
51 template <typename BaseField = Fq,
52 typename CompileTimeEnabled = std::enable_if_t<(BaseField::modulus >> 255) == uint256_t(1), void>>
53 static constexpr std::array<affine_element, 2> from_compressed_unsafe(const uint256_t& compressed) noexcept;
54
55 constexpr affine_element& operator=(const affine_element& other) noexcept = default;
56
57 constexpr affine_element& operator=(affine_element&& other) noexcept = default;
58
59 constexpr affine_element operator+(const affine_element& other) const noexcept;
60
61 template <typename BaseField = Fq,
62 typename CompileTimeEnabled = std::enable_if_t<(BaseField::modulus >> 255) == uint256_t(0), void>>
63 [[nodiscard]] constexpr uint256_t compress() const noexcept;
64
65 static affine_element infinity();
66 constexpr affine_element set_infinity() const noexcept;
67 constexpr void self_set_infinity() noexcept;
68
69 [[nodiscard]] constexpr bool is_point_at_infinity() const noexcept;
70
71 [[nodiscard]] constexpr bool on_curve() const noexcept;
72
73 static constexpr std::optional<affine_element> derive_from_x_coordinate(const Fq& x, bool sign_bit) noexcept;
74
80 static affine_element random_element(numeric::random::Engine* engine = nullptr) noexcept;
81 static constexpr affine_element hash_to_curve(const std::vector<uint8_t>& seed, uint8_t attempt_count = 0) noexcept
82 requires SupportsHashToCurve<Params>;
83
84 constexpr bool operator==(const affine_element& other) const noexcept;
85
86 constexpr affine_element operator-() const noexcept { return { x, -y }; }
87
88 constexpr bool operator>(const affine_element& other) const noexcept;
89 constexpr bool operator<(const affine_element& other) const noexcept { return (other > *this); }
90
100 static void serialize_to_buffer(const affine_element& value, uint8_t* buffer)
101 {
102 if (value.is_point_at_infinity()) {
103 if constexpr (Fq::modulus.get_msb() == 255) {
104 write(buffer, uint256_t(0));
105 write(buffer, Fq::modulus);
106 } else {
107 write(buffer, uint256_t(0));
108 write(buffer, uint256_t(1) << 255);
109 }
110 } else {
111 Fq::serialize_to_buffer(value.y, buffer);
112 Fq::serialize_to_buffer(value.x, buffer + sizeof(Fq));
113 }
114 }
115
128 static affine_element serialize_from_buffer(uint8_t* buffer)
129 {
130 affine_element result;
131
132 // need to read a raw uint256_t to avoid reductions so we can check whether the point is the point at infinity
133 auto raw_x = from_buffer<uint256_t>(buffer + sizeof(Fq));
134
135 if constexpr (Fq::modulus.get_msb() == 255) {
136 if (raw_x == Fq::modulus) {
137 result.y = Fq::zero();
138 result.x.data[0] = raw_x.data[0];
139 result.x.data[1] = raw_x.data[1];
140 result.x.data[2] = raw_x.data[2];
141 result.x.data[3] = raw_x.data[3];
142 } else {
143 result.y = Fq::serialize_from_buffer(buffer);
144 result.x = Fq(raw_x);
145 }
146 } else {
147 if (raw_x.get_msb() == 255) {
148 result.y = Fq::zero();
149 result.x = Fq::zero();
150 result.self_set_infinity();
151 } else {
152 // conditional here to avoid reading the same data twice in case of a field of prime order
153 if constexpr (std::is_same<Fq, fq2>::value) {
154 result.y = Fq::serialize_from_buffer(buffer);
155 result.x = Fq::serialize_from_buffer(buffer + sizeof(Fq));
156 } else {
157 result.y = Fq::serialize_from_buffer(buffer);
158 result.x = Fq(raw_x);
159 }
160 }
161 }
162 return result;
163 }
164
170 [[nodiscard]] inline std::vector<uint8_t> to_buffer() const
171 {
172 std::vector<uint8_t> buffer(sizeof(affine_element));
173 affine_element::serialize_to_buffer(*this, &buffer[0]);
174 return buffer;
175 }
176
177 friend std::ostream& operator<<(std::ostream& os, const affine_element& a)
178 {
179 os << "{ " << a.x << ", " << a.y << " }";
180 return os;
181 }
182 Fq x;
183 Fq y;
184 // for serialization: update with new fields
185 MSGPACK_FIELDS(x, y);
186};
187} // namespace barretenberg::group_elements
188
189#include "./affine_element_impl.hpp"
Definition: affine_element.hpp:11
static void serialize_to_buffer(const affine_element &value, uint8_t *buffer)
Serialize the point to the given buffer.
Definition: affine_element.hpp:100
static affine_element serialize_from_buffer(uint8_t *buffer)
Restore point from a buffer.
Definition: affine_element.hpp:128
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.
Definition: affine_element_impl.hpp:224
static constexpr affine_element from_compressed(const uint256_t &compressed) noexcept
Reconstruct a point in affine coordinates from compressed form.
constexpr bool operator>(const affine_element &other) const noexcept
Definition: affine_element_impl.hpp:153
static affine_element random_element(numeric::random::Engine *engine=nullptr) noexcept
Samples a random point on the curve.
Definition: affine_element_impl.hpp:266
std::vector< uint8_t > to_buffer() const
Serialize the point to a byte vector.
Definition: affine_element.hpp:170
static constexpr std::array< affine_element, 2 > from_compressed_unsafe(const uint256_t &compressed) noexcept
Reconstruct a point in affine coordinates from compressed form.
Definition: uint256.hpp:25
Definition: affine_element.hpp:10
Definition: field2_declarations.hpp:6