barretenberg
Loading...
Searching...
No Matches
element.hpp
1#pragma once
2
3#include "affine_element.hpp"
4#include "barretenberg/common/compiler_hints.hpp"
5#include "barretenberg/common/mem.hpp"
6#include "barretenberg/numeric/random/engine.hpp"
7#include "barretenberg/numeric/uint256/uint256.hpp"
8#include "wnaf.hpp"
9#include <array>
10#include <random>
11#include <vector>
12
13namespace barretenberg::group_elements {
14
27template <class Fq, class Fr, class Params> class alignas(32) element {
28 public:
29 static constexpr Fq curve_b = Params::b;
30
31 element() noexcept = default;
32
33 constexpr element(const Fq& a, const Fq& b, const Fq& c) noexcept;
34 constexpr element(const element& other) noexcept;
35 constexpr element(element&& other) noexcept;
36 constexpr element(const affine_element<Fq, Fr, Params>& other) noexcept;
37 constexpr ~element() noexcept = default;
38
39 static constexpr element one() noexcept { return { Params::one_x, Params::one_y, Fq::one() }; };
40 static constexpr element zero() noexcept
41 {
42 element zero;
43 zero.self_set_infinity();
44 return zero;
45 };
46
47 constexpr element& operator=(const element& other) noexcept;
48 constexpr element& operator=(element&& other) noexcept;
49
50 constexpr operator affine_element<Fq, Fr, Params>() const noexcept;
51
52 static element random_element(numeric::random::Engine* engine = nullptr) noexcept;
53
54 constexpr element dbl() const noexcept;
55 constexpr void self_dbl() noexcept;
56 constexpr void self_mixed_add_or_sub(const affine_element<Fq, Fr, Params>& other, uint64_t predicate) noexcept;
57
58 constexpr element operator+(const element& other) const noexcept;
59 constexpr element operator+(const affine_element<Fq, Fr, Params>& other) const noexcept;
60 constexpr element operator+=(const element& other) noexcept;
61 constexpr element operator+=(const affine_element<Fq, Fr, Params>& other) noexcept;
62
63 constexpr element operator-(const element& other) const noexcept;
64 constexpr element operator-(const affine_element<Fq, Fr, Params>& other) const noexcept;
65 constexpr element operator-() const noexcept;
66 constexpr element operator-=(const element& other) noexcept;
67 constexpr element operator-=(const affine_element<Fq, Fr, Params>& other) noexcept;
68
69 friend constexpr element operator+(const affine_element<Fq, Fr, Params>& left, const element& right) noexcept
70 {
71 return right + left;
72 }
73 friend constexpr element operator-(const affine_element<Fq, Fr, Params>& left, const element& right) noexcept
74 {
75 return -right + left;
76 }
77
78 element operator*(const Fr& exponent) const noexcept;
79 element operator*=(const Fr& exponent) noexcept;
80
81 // If you end up implementing this, congrats, you've solved the DL problem!
82 // P.S. This is a joke, don't even attempt! 😂
83 // constexpr Fr operator/(const element& other) noexcept {}
84
85 constexpr element normalize() const noexcept;
86 static element infinity();
87 BBERG_INLINE constexpr element set_infinity() const noexcept;
88 BBERG_INLINE constexpr void self_set_infinity() noexcept;
89 [[nodiscard]] BBERG_INLINE constexpr bool is_point_at_infinity() const noexcept;
90 [[nodiscard]] BBERG_INLINE constexpr bool on_curve() const noexcept;
91 BBERG_INLINE constexpr bool operator==(const element& other) const noexcept;
92
93 static void batch_normalize(element* elements, size_t num_elements) noexcept;
94 static std::vector<affine_element<Fq, Fr, Params>> batch_mul_with_endomorphism(
95 const std::vector<affine_element<Fq, Fr, Params>>& points, const Fr& exponent) noexcept;
96
97 Fq x;
98 Fq y;
99 Fq z;
100
101 private:
102 element mul_without_endomorphism(const Fr& exponent) const noexcept;
103 element mul_with_endomorphism(const Fr& exponent) const noexcept;
104
105 template <typename = typename std::enable_if<Params::can_hash_to_curve>>
106 static element random_coordinates_on_curve(numeric::random::Engine* engine = nullptr) noexcept;
107 // {
108 // bool found_one = false;
109 // Fq yy;
110 // Fq x;
111 // Fq y;
112 // Fq t0;
113 // while (!found_one) {
114 // x = Fq::random_element(engine);
115 // yy = x.sqr() * x + Params::b;
116 // if constexpr (Params::has_a) {
117 // yy += (x * Params::a);
118 // }
119 // y = yy.sqrt();
120 // t0 = y.sqr();
121 // found_one = (yy == t0);
122 // }
123 // return { x, y, Fq::one() };
124 // }
125 // for serialization: update with new fields
126 MSGPACK_FIELDS(x, y, z);
127
128 static void conditional_negate_affine(const affine_element<Fq, Fr, Params>& in,
130 uint64_t predicate) noexcept;
131
132 friend std::ostream& operator<<(std::ostream& os, const element& a)
133 {
134 os << "{ " << a.x << ", " << a.y << ", " << a.z << " }";
135 return os;
136 }
137};
138
139template <class Fq, class Fr, class Params> std::ostream& operator<<(std::ostream& os, element<Fq, Fr, Params> const& e)
140{
141 return os << "x:" << e.x << " y:" << e.y << " z:" << e.z;
142}
143
144// constexpr element<Fq, Fr, Params>::one = element<Fq, Fr, Params>{ Params::one_x, Params::one_y, Fq::one() };
145// constexpr element<Fq, Fr, Params>::point_at_infinity = one.set_infinity();
146// constexpr element<Fq, Fr, Params>::curve_b = Params::b;
147} // namespace barretenberg::group_elements
148
149#include "./element_impl.hpp"
150
151template <class Fq, class Fr, class Params>
153 const barretenberg::group_elements::affine_element<Fq, Fr, Params>& base, const Fr& exponent) noexcept
154{
156 exponent);
157}
158
159template <class Fq, class Fr, class Params>
161 const barretenberg::group_elements::element<Fq, Fr, Params>& base, const Fr& exponent) noexcept
162{
163 return (barretenberg::group_elements::element(base) * exponent);
164}
Definition: affine_element.hpp:11
element class. Implements ecc group arithmetic using Jacobian coordinates See https://hyperelliptic....
Definition: element.hpp:27
static void batch_normalize(element *elements, size_t num_elements) noexcept
Definition: element_impl.hpp:870
Definition: engine.hpp:10