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