3#include "./field2_declarations.hpp"
12template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::operator*(
const field2& other)
const noexcept
15 static_assert((base::modulus.data[0] & 0x3UL) == 0x3UL);
16 base t1 = c0 * other.c0;
17 base t2 = c1 * other.c1;
19 base t4 = other.c0 + other.c1;
21 return { t1 - t2, t3 * t4 - (t1 + t2) };
24template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::operator+(
const field2& other)
const noexcept
26 return { c0 + other.c0, c1 + other.c1 };
29template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::operator-(
const field2& other)
const noexcept
31 return { c0 - other.c0, c1 - other.c1 };
34template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::operator-() const noexcept
39template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::operator/(
const field2& other)
const noexcept
41 return operator*(other.invert());
44template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::operator*=(
const field2& other)
noexcept
46 *
this = operator*(other);
50template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::operator+=(
const field2& other)
noexcept
52 *
this = operator+(other);
56template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::operator-=(
const field2& other)
noexcept
58 *
this = operator-(other);
62template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::operator/=(
const field2& other)
noexcept
64 *
this = operator/(other);
68template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::sqr() const noexcept
71 return { (c0 + c1) * (c0 - c1), t1 + t1 };
74template <
class base,
class T>
constexpr void field2<base, T>::self_sqr() noexcept
79template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::to_montgomery_form() const noexcept
81 return { c0.to_montgomery_form(), c1.to_montgomery_form() };
84template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::from_montgomery_form() const noexcept
86 return { c0.from_montgomery_form(), c1.from_montgomery_form() };
89template <
class base,
class T>
constexpr void field2<base, T>::self_to_montgomery_form() noexcept
91 c0.self_to_montgomery_form();
92 c1.self_to_montgomery_form();
95template <
class base,
class T>
constexpr void field2<base, T>::self_from_montgomery_form() noexcept
97 c0.self_from_montgomery_form();
98 c1.self_from_montgomery_form();
101template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::reduce_once() const noexcept
107template <
class base,
class T>
constexpr void field2<base, T>::self_reduce_once() noexcept
113template <
class base,
class T>
constexpr void field2<base, T>::self_neg() noexcept
119template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::pow(
const uint256_t& exponent)
const noexcept
122 field2 accumulator = *
this;
123 field2 to_mul = *
this;
124 const uint64_t maximum_set_bit = exponent.get_msb();
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;
133 if (*
this == zero()) {
134 accumulator = zero();
141template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::pow(
const uint64_t exponent)
const noexcept
143 return pow({ exponent, 0, 0, 0 });
146template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::invert() const noexcept
148 base t3 = (c0.sqr() + c1.sqr()).invert();
149 return { c0 * t3, -(c1 * t3) };
152template <
class base,
class T>
153constexpr void field2<base, T>::self_conditional_negate(
const uint64_t predicate)
noexcept
155 *
this = predicate != 0U ? -(*this) : *
this;
158template <
class base,
class T>
constexpr void field2<base, T>::self_set_msb() noexcept
160 c0.data[3] = 0ULL | (1ULL << 63ULL);
163template <
class base,
class T>
constexpr bool field2<base, T>::is_msb_set() const noexcept
165 return (c0.data[3] >> 63ULL) == 1ULL;
168template <
class base,
class T>
constexpr uint64_t field2<base, T>::is_msb_set_word() const noexcept
170 return (c0.data[3] >> 63ULL);
173template <
class base,
class T>
constexpr bool field2<base, T>::is_zero() const noexcept
175 return (c0.is_zero() && c1.is_zero());
178template <
class base,
class T>
constexpr bool field2<base, T>::operator==(
const field2& other)
const noexcept
180 return (c0 == other.c0) && (c1 == other.c1);
183template <
class base,
class T>
constexpr field2<base, T> field2<base, T>::frobenius_map() const noexcept
188template <
class base,
class T>
constexpr void field2<base, T>::self_frobenius_map() noexcept
195 return { base::random_element(engine), base::random_element(engine) };
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