Botan 3.4.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(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 {
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 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 Gf448Elem(std::span<const uint64_t, WORDS_448> data) { 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 Gf448Elem(uint64_t least_sig_word);
54
55 /**
56 * @brief Store the canonical representation of the GF element as 56 bytes in little-endian
57 * order.
58 *
59 * @param out The 56 byte output buffer.
60 */
61 void to_bytes(std::span<uint8_t, BYTES_448> out) const;
62
63 /**
64 * @brief Return the canonical representation of the GF element as 56 bytes in little-endian
65 * order.
66 */
67 std::array<uint8_t, BYTES_448> to_bytes() const;
68
69 /**
70 * @brief Swap this and other if b == true. Constant time for any b.
71 */
72 void ct_cond_swap(bool b, Gf448Elem& other);
73
74 /**
75 * @brief Set this to @p other if b is true. Constant time for any b.
76 */
77 void ct_cond_assign(bool b, const Gf448Elem& other);
78
79 Gf448Elem operator+(const Gf448Elem& other) const;
80
81 Gf448Elem operator-(const Gf448Elem& other) const;
82
83 Gf448Elem operator-() const;
84
85 Gf448Elem operator*(const Gf448Elem& other) const;
86
87 Gf448Elem operator/(const Gf448Elem& other) const;
88
89 bool operator==(const Gf448Elem& other) const;
90
91 bool operator!=(const Gf448Elem& other) const = default;
92
93 /**
94 * @brief Return true iff this element is zero. Constant time.
95 */
96 bool is_zero() const;
97
98 /**
99 * @brief Return true iff this element is odd. Constant time.
100 */
101 bool is_odd() const;
102
103 /**
104 * @brief Accessor to the internal words of the GF element.
105 *
106 * Note that the internal representation is not necessarily canonical, i.e.
107 * the value might be larger than the prime modulus.
108 */
109 std::span<uint64_t, WORDS_448> words() { return m_x; }
110
111 /**
112 * @brief Constant accessor to the internal words of the GF element.
113 *
114 * Note that the internal representation is not necessarily canonical, i.e.
115 * the value might be larger than the prime modulus.
116 */
117 std::span<const uint64_t, WORDS_448> words() const { return m_x; }
118
119 /**
120 * @brief Given 56 bytes, checks that the (little endian) number from this
121 * bytes is a valid GF element, i.e. is smaller than the prime modulus.
122 */
123 static bool bytes_are_canonical_representation(std::span<const uint8_t, BYTES_448> x);
124
125 private:
126 std::array<uint64_t, WORDS_448> m_x;
127};
128
129/**
130 * @brief Computes elem^2. Faster than operator*.
131 */
132Gf448Elem square(const Gf448Elem& elem);
133
134/**
135 * @brief Compute the root of @p elem in the field.
136 *
137 * The root of a in GF(p) is computed as r = a^((p+1)/4) mod p.
138 * Note that the root is not unique, i.e. r and p-r are both roots.
139 *
140 * @return GfPElem The root of this element.
141 */
142Gf448Elem root(const Gf448Elem& elem);
143
144} // namespace Botan
145
146#endif // BOTAN_CURVE_448_GF_H_
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.
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.
BigInt square(const BigInt &x)
Definition numthry.cpp:157
constexpr T ceil_tobytes(T bits)
Definition bit_ops.h:144
constexpr void copy_mem(T *out, const T *in, size_t n)
Definition mem_ops.h:146
constexpr size_t WORDS_448
Definition curve448_gf.h:22
constexpr size_t BYTES_448
Definition curve448_gf.h:20