barretenberg
Loading...
Searching...
No Matches
field2.hpp
1#pragma once
2
3#include "./field2_declarations.hpp"
4
11namespace barretenberg {
12template <class base, class T> constexpr field2<base, T> field2<base, T>::operator*(const field2& other) const noexcept
13{
14 // no funny primes please! we assume -1 is not a quadratic residue
15 static_assert((base::modulus.data[0] & 0x3UL) == 0x3UL);
16 base t1 = c0 * other.c0;
17 base t2 = c1 * other.c1;
18 base t3 = c0 + c1;
19 base t4 = other.c0 + other.c1;
20
21 return { t1 - t2, t3 * t4 - (t1 + t2) };
22}
23
24template <class base, class T> constexpr field2<base, T> field2<base, T>::operator+(const field2& other) const noexcept
25{
26 return { c0 + other.c0, c1 + other.c1 };
27}
28
29template <class base, class T> constexpr field2<base, T> field2<base, T>::operator-(const field2& other) const noexcept
30{
31 return { c0 - other.c0, c1 - other.c1 };
32}
33
34template <class base, class T> constexpr field2<base, T> field2<base, T>::operator-() const noexcept
35{
36 return { -c0, -c1 };
37}
38
39template <class base, class T> constexpr field2<base, T> field2<base, T>::operator/(const field2& other) const noexcept
40{
41 return operator*(other.invert());
42}
43
44template <class base, class T> constexpr field2<base, T> field2<base, T>::operator*=(const field2& other) noexcept
45{
46 *this = operator*(other);
47 return *this;
48}
49
50template <class base, class T> constexpr field2<base, T> field2<base, T>::operator+=(const field2& other) noexcept
51{
52 *this = operator+(other);
53 return *this;
54}
55
56template <class base, class T> constexpr field2<base, T> field2<base, T>::operator-=(const field2& other) noexcept
57{
58 *this = operator-(other);
59 return *this;
60}
61
62template <class base, class T> constexpr field2<base, T> field2<base, T>::operator/=(const field2& other) noexcept
63{
64 *this = operator/(other);
65 return *this;
66}
67
68template <class base, class T> constexpr field2<base, T> field2<base, T>::sqr() const noexcept
69{
70 base t1 = (c0 * c1);
71 return { (c0 + c1) * (c0 - c1), t1 + t1 };
72}
73
74template <class base, class T> constexpr void field2<base, T>::self_sqr() noexcept
75{
76 *this = sqr();
77}
78
79template <class base, class T> constexpr field2<base, T> field2<base, T>::to_montgomery_form() const noexcept
80{
81 return { c0.to_montgomery_form(), c1.to_montgomery_form() };
82}
83
84template <class base, class T> constexpr field2<base, T> field2<base, T>::from_montgomery_form() const noexcept
85{
86 return { c0.from_montgomery_form(), c1.from_montgomery_form() };
87}
88
89template <class base, class T> constexpr void field2<base, T>::self_to_montgomery_form() noexcept
90{
91 c0.self_to_montgomery_form();
92 c1.self_to_montgomery_form();
93}
94
95template <class base, class T> constexpr void field2<base, T>::self_from_montgomery_form() noexcept
96{
97 c0.self_from_montgomery_form();
98 c1.self_from_montgomery_form();
99}
100
101template <class base, class T> constexpr field2<base, T> field2<base, T>::reduce_once() const noexcept
102{
103 return *this;
104 // return { c0.reduce_once(), c1.reduce_once() };
105}
106
107template <class base, class T> constexpr void field2<base, T>::self_reduce_once() noexcept
108{
109 // c0.self_reduce_once();
110 // c1.self_reduce_once();
111}
112
113template <class base, class T> constexpr void field2<base, T>::self_neg() noexcept
114{
115 c0.self_neg();
116 c1.self_neg();
117}
118
119template <class base, class T> constexpr field2<base, T> field2<base, T>::pow(const uint256_t& exponent) const noexcept
120{
121
122 field2 accumulator = *this;
123 field2 to_mul = *this;
124 const uint64_t maximum_set_bit = exponent.get_msb();
125
126 for (int i = static_cast<int>(maximum_set_bit) - 1; i >= 0; --i) {
127 accumulator.self_sqr();
128 if (exponent.get_bit(static_cast<uint64_t>(i))) {
129 accumulator *= to_mul;
130 }
131 }
132
133 if (*this == zero()) {
134 accumulator = zero();
135 } else if (exponent == uint256_t(0)) {
136 accumulator = one();
137 }
138 return accumulator;
139}
140
141template <class base, class T> constexpr field2<base, T> field2<base, T>::pow(const uint64_t exponent) const noexcept
142{
143 return pow({ exponent, 0, 0, 0 });
144}
145
146template <class base, class T> constexpr field2<base, T> field2<base, T>::invert() const noexcept
147{
148 base t3 = (c0.sqr() + c1.sqr()).invert();
149 return { c0 * t3, -(c1 * t3) };
150}
151
152template <class base, class T>
153constexpr void field2<base, T>::self_conditional_negate(const uint64_t predicate) noexcept
154{
155 *this = predicate != 0U ? -(*this) : *this;
156}
157
158template <class base, class T> constexpr void field2<base, T>::self_set_msb() noexcept
159{
160 c0.data[3] = 0ULL | (1ULL << 63ULL);
161}
162
163template <class base, class T> constexpr bool field2<base, T>::is_msb_set() const noexcept
164{
165 return (c0.data[3] >> 63ULL) == 1ULL;
166}
167
168template <class base, class T> constexpr uint64_t field2<base, T>::is_msb_set_word() const noexcept
169{
170 return (c0.data[3] >> 63ULL);
171}
172
173template <class base, class T> constexpr bool field2<base, T>::is_zero() const noexcept
174{
175 return (c0.is_zero() && c1.is_zero());
176}
177
178template <class base, class T> constexpr bool field2<base, T>::operator==(const field2& other) const noexcept
179{
180 return (c0 == other.c0) && (c1 == other.c1);
181}
182
183template <class base, class T> constexpr field2<base, T> field2<base, T>::frobenius_map() const noexcept
184{
185 return { c0, -c1 };
186}
187
188template <class base, class T> constexpr void field2<base, T>::self_frobenius_map() noexcept
189{
190 c1.self_neg();
191}
192
193template <class base, class T> field2<base, T> field2<base, T>::random_element(numeric::random::Engine* engine)
194{
195 return { base::random_element(engine), base::random_element(engine) };
196}
197} // namespace barretenberg
Definition: engine.hpp:10
Definition: uint256.hpp:25
constexpr_utils defines some helper methods that perform some stl-equivalent operations but in a cons...
Definition: constexpr_utils.hpp:16