Botan 3.11.0
Crypto and TLS for C&
curve448_gf.h
Go to the documentation of this file.
1/*
2* X448 Gf Modulo 2^448 - 2^224 - 1
3* (C) 2024 Jack Lloyd
4* 2024 Fabian Albert - Rohde & Schwarz Cybersecurity
5*
6* Botan is released under the Simplified BSD License (see license.txt)
7*/
8#ifndef BOTAN_CURVE_448_GF_H_
9#define BOTAN_CURVE_448_GF_H_
10
11#include <botan/mem_ops.h>
12#include <botan/types.h>
13#include <botan/internal/bit_ops.h>
14#include <botan/internal/ct_utils.h>
15
16#include <array>
17#include <span>
18
19namespace Botan {
20
21constexpr size_t BYTES_448 = ceil_tobytes<size_t>(448);
22/* uint64_t words to store a 448 bit value */
23constexpr size_t WORDS_448 = 7;
24
25/**
26 * This class represents a GF element in the field GF(2^448 - 2^224 - 1). Computations are
27 * performed using optimized operations as defined in the paper:
28 * "Reduction Modulo 2^448 - 2^224 - 1" by Kaushik Nath and Palash Sarkar
29 * (https://eprint.iacr.org/2019/1304).
30 *
31 * The representation of the field element is a 448-bit uint, stored in little-endian order
32 * as 7*64bit words. Note that the internal representation is not necessarily canonical, i.e.
33 * the value might be larger than the prime modulus. When calling the to_bytes() method, the
34 * canonical representation is returned.
35 */
36class Gf448Elem final {
37 public:
38 /**
39 * @brief Construct a GF element from a 448-bit integer gives as 56 bytes @p x in
40 * little-endian order.
41 */
42 explicit Gf448Elem(std::span<const uint8_t, BYTES_448> x);
43
44 /**
45 * @brief Construct a GF element from a 448-bit integer gives as 7 uint64_t words @p x in
46 * little-endian order.
47 */
48 explicit Gf448Elem(std::span<const uint64_t, WORDS_448> data) /* NOLINT(*-member-init) */ { copy_mem(m_x, data); }
49
50 /**
51 * @brief Construct a GF element by passing the least significant 64 bits as a word.
52 * All other become zero.
53 */
54 explicit Gf448Elem(uint64_t least_sig_word);
55
56 /**
57 * Return the constant value zero
58 */
59 static Gf448Elem zero() { return Gf448Elem(0); }
60
61 /**
62 * Return the constant value one
63 */
64 static Gf448Elem one() { return Gf448Elem(1); }
65
66 /**
67 * @brief Store the canonical representation of the GF element as 56 bytes in little-endian
68 * order.
69 *
70 * @param out The 56 byte output buffer.
71 */
72 void to_bytes(std::span<uint8_t, BYTES_448> out) const;
73
74 /**
75 * @brief Return the canonical representation of the GF element as 56 bytes in little-endian
76 * order.
77 */
78 std::array<uint8_t, BYTES_448> to_bytes() const;
79
80 /**
81 * @brief Swap this and @p other if @p mask is set. Constant time.
82 */
83 void ct_cond_swap(CT::Mask<uint64_t> mask, Gf448Elem& other);
84
85 /**
86 * @brief Set this to @p other if @p mask is true. Constant time.
87 */
88 void ct_cond_assign(CT::Mask<uint64_t> mask, const Gf448Elem& other);
89
90 Gf448Elem operator+(const Gf448Elem& other) const;
91
92 Gf448Elem operator-(const Gf448Elem& other) const;
93
94 Gf448Elem operator-() const;
95
96 Gf448Elem operator*(const Gf448Elem& other) const;
97
98 Gf448Elem operator/(const Gf448Elem& other) const;
99
100 bool operator==(const Gf448Elem& other) const;
101
102 bool operator!=(const Gf448Elem& other) const = default;
103
104 /**
105 * @brief Return true iff this element is zero. Constant time.
106 */
107 bool is_zero() const;
108
109 /**
110 * @brief Return true iff this element is odd. Constant time.
111 */
112 bool is_odd() const;
113
114 /**
115 * @brief Accessor to the internal words of the GF element.
116 *
117 * Note that the internal representation is not necessarily canonical, i.e.
118 * the value might be larger than the prime modulus.
119 */
120 std::span<uint64_t, WORDS_448> words() { return m_x; }
121
122 /**
123 * @brief Constant accessor to the internal words of the GF element.
124 *
125 * Note that the internal representation is not necessarily canonical, i.e.
126 * the value might be larger than the prime modulus.
127 */
128 std::span<const uint64_t, WORDS_448> words() const { return m_x; }
129
130 /**
131 * @brief Given 56 bytes, checks that the (little endian) number from this
132 * bytes is a valid GF element, i.e. is smaller than the prime modulus.
133 */
134 static bool bytes_are_canonical_representation(std::span<const uint8_t, BYTES_448> x);
135
136 private:
137 std::array<uint64_t, WORDS_448> m_x;
138};
139
140/**
141 * @brief Multiply a field element by the Curve448 constant a24 = 39081.
142 */
143Gf448Elem mul_a24(const Gf448Elem& a);
144
145/**
146 * @brief Computes elem^2. Faster than operator*.
147 */
148Gf448Elem square(const Gf448Elem& elem);
149
150/**
151 * @brief Compute the root of @p elem in the field.
152 *
153 * The root of a in GF(p) is computed as r = a^((p+1)/4) mod p.
154 * Note that the root is not unique, i.e. r and p-r are both roots.
155 *
156 * @return GfPElem The root of this element.
157 */
158Gf448Elem root(const Gf448Elem& elem);
159
160} // namespace Botan
161
162#endif // BOTAN_CURVE_448_GF_H_
static Gf448Elem zero()
Definition curve448_gf.h:59
std::span< const uint64_t, WORDS_448 > words() const
Constant accessor to the internal words of the GF element.
void ct_cond_swap(CT::Mask< uint64_t > mask, Gf448Elem &other)
Swap this and other if mask is set. Constant time.
Gf448Elem operator*(const Gf448Elem &other) const
Gf448Elem operator-() const
static bool bytes_are_canonical_representation(std::span< const uint8_t, BYTES_448 > x)
Given 56 bytes, checks that the (little endian) number from this bytes is a valid GF element,...
std::array< uint8_t, BYTES_448 > to_bytes() const
Return the canonical representation of the GF element as 56 bytes in little-endian order.
Gf448Elem operator/(const Gf448Elem &other) const
bool operator!=(const Gf448Elem &other) const =default
bool is_odd() const
Return true iff this element is odd. Constant time.
Gf448Elem(std::span< const uint64_t, WORDS_448 > data)
Construct a GF element from a 448-bit integer gives as 7 uint64_t words x in little-endian order.
Definition curve448_gf.h:48
Gf448Elem operator+(const Gf448Elem &other) const
bool operator==(const Gf448Elem &other) const
std::span< uint64_t, WORDS_448 > words()
Accessor to the internal words of the GF element.
Gf448Elem(std::span< const uint8_t, BYTES_448 > x)
Construct a GF element from a 448-bit integer gives as 56 bytes x in little-endian order.
static Gf448Elem one()
Definition curve448_gf.h:64
void ct_cond_assign(CT::Mask< uint64_t > mask, const Gf448Elem &other)
Set this to other if mask is true. Constant time.
bool is_zero() const
Return true iff this element is zero. Constant time.
Gf448Elem mul_a24(const Gf448Elem &a)
Multiply a field element by the Curve448 constant a24 = 39081.
Gf448Elem root(const Gf448Elem &elem)
Compute the root of elem in the field.
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:144
BigInt square(const BigInt &x)
Definition numthry.cpp:184
BOTAN_FORCE_INLINE constexpr T ceil_tobytes(T bits)
Definition bit_ops.h:175
constexpr size_t WORDS_448
Definition curve448_gf.h:23
constexpr size_t BYTES_448
Definition curve448_gf.h:21