Botan 3.6.1
Crypto and TLS for C&
Botan::Ed448Point Class Reference

Representation of a point on the Ed448 curve. More...

#include <ed448_internal.h>

Public Member Functions

void ct_conditional_assign (bool cond, const Ed448Point &other)
 Assign other to this if cond is true (constant time)
 
Ed448Point double_point () const
 Double a point (RFC 8032 5.2.4)
 
 Ed448Point (const Gf448Elem &x, const Gf448Elem &y)
 Create a point from its coordinates x, y.
 
 Ed448Point (const Gf448Elem &x, const Gf448Elem &y, const Gf448Elem &z)
 Create a point from its projective coordinates X, Y, Z.
 
std::array< uint8_t, ED448_LENencode () const
 Encode the point to its 57-byte representation (RFC 8032 5.2.2)
 
Ed448Point operator+ (const Ed448Point &other) const
 Add two points (RFC 8032 5.2.4)
 
bool operator== (const Ed448Point &other) const
 Check if two points are equal (constant time)
 
Ed448Point scalar_mul (const Scalar448 &scalar) const
 Scalar multiplication.
 
Gf448Elem x () const
 Getter for point coordinate x.
 
Gf448Elem x_proj () const
 Getter for projective coordinate X.
 
Gf448Elem y () const
 Getter for point coordinate y.
 
Gf448Elem y_proj () const
 Getter for projective coordinate Y.
 
Gf448Elem z_proj () const
 Getter for projective coordinate Z.
 

Static Public Member Functions

static Ed448Point base_point ()
 Create the curve's base point ('B' in RFC 8032 5.2)
 
static Ed448Point decode (std::span< const uint8_t, ED448_LEN > enc)
 Decode a point from its 57-byte encoding (RFC 8032 5.2.3)
 

Detailed Description

Representation of a point on the Ed448 curve.

The point is represented in projective coordinates (X, Y, Z). All operations are constant time.

Definition at line 25 of file ed448_internal.h.

Constructor & Destructor Documentation

◆ Ed448Point() [1/2]

Botan::Ed448Point::Ed448Point ( const Gf448Elem & x,
const Gf448Elem & y,
const Gf448Elem & z )
inline

Create a point from its projective coordinates X, Y, Z.

Definition at line 34 of file ed448_internal.h.

34: m_x(x), m_y(y), m_z(z) {}
Gf448Elem y() const
Getter for point coordinate y.
Gf448Elem x() const
Getter for point coordinate x.

Referenced by base_point(), double_point(), and operator+().

◆ Ed448Point() [2/2]

Botan::Ed448Point::Ed448Point ( const Gf448Elem & x,
const Gf448Elem & y )
inline

Create a point from its coordinates x, y.

Definition at line 37 of file ed448_internal.h.

37: m_x(x), m_y(y), m_z(1) {}

Member Function Documentation

◆ base_point()

Ed448Point Botan::Ed448Point::base_point ( )
static

Create the curve's base point ('B' in RFC 8032 5.2)

Definition at line 123 of file ed448_internal.cpp.

123 {
124 constexpr std::array<const uint64_t, WORDS_448> x = {0x2626a82bc70cc05e,
125 0x433b80e18b00938e,
126 0x12ae1af72ab66511,
127 0xea6de324a3d3a464,
128 0x9e146570470f1767,
129 0x221d15a622bf36da,
130 0x4f1970c66bed0ded};
131 constexpr std::array<const uint64_t, WORDS_448> y = {0x9808795bf230fa14,
132 0xfdbd132c4ed7c8ad,
133 0x3ad3ff1ce67c39c4,
134 0x87789c1e05a0c2d7,
135 0x4bea73736ca39840,
136 0x8876203756c9c762,
137 0x693f46716eb6bc24};
138 return Ed448Point(Gf448Elem(x), Gf448Elem(y));
139}
Ed448Point(const Gf448Elem &x, const Gf448Elem &y, const Gf448Elem &z)
Create a point from its projective coordinates X, Y, Z.

References Ed448Point(), x(), and y().

Referenced by Botan::create_pk_from_sk(), Botan::sign_message(), and Botan::verify_signature().

◆ ct_conditional_assign()

void Botan::Ed448Point::ct_conditional_assign ( bool cond,
const Ed448Point & other )

Assign other to this if cond is true (constant time)

Definition at line 214 of file ed448_internal.cpp.

214 {
215 m_x.ct_cond_assign(cond, other.m_x);
216 m_y.ct_cond_assign(cond, other.m_y);
217 m_z.ct_cond_assign(cond, other.m_z);
218}
void ct_cond_assign(bool b, const Gf448Elem &other)
Set this to other if b is true. Constant time for any b.

References Botan::Gf448Elem::ct_cond_assign().

Referenced by scalar_mul().

◆ decode()

Ed448Point Botan::Ed448Point::decode ( std::span< const uint8_t, ED448_LEN > enc)
static

Decode a point from its 57-byte encoding (RFC 8032 5.2.3)

Definition at line 73 of file ed448_internal.cpp.

73 {
74 // RFC 8032 5.2.3 Decoding
75 // 1. First, interpret the string as an integer in little-endian
76 // representation. Bit 455 of this number is the least significant
77 // bit of the x-coordinate, and denote this value x_0. The
78 // y-coordinate is recovered simply by clearing this bit. If the
79 // resulting value is >= p, decoding fails.
80 if((enc.back() & 0x7F) != 0) { // last byte is either 0x00 or 0x80
81 throw Decoding_Error("Ed448 point has unacceptable x-distinguisher");
82 }
83 const bool x_distinguisher = enc.back() != 0;
84 const auto y_data = std::span(enc).first<56>();
86 throw Decoding_Error("Ed448 y-coordinate is not smaller than p");
87 }
88 const auto y = Gf448Elem(y_data);
89
90 // 2. To recover the x-coordinate, the curve equation implies
91 // x^2 = (y^2 - 1) / (d y^2 - 1) (mod p). The denominator is always
92 // non-zero mod p. Let u = y^2 - 1 and v = d y^2 - 1. To compute
93 // the square root of (u/v), the first step is to compute the
94 // candidate root x = (u/v)^((p+1)/4). This can be done using the
95 // following trick, to use a single modular powering for both the
96 // inversion of v and the square root:
97 // (p+1)/4 3 (p-3)/4
98 // x = (u/v) = u v (u^5 v^3) (mod p)
99 const auto d = -Gf448Elem(MINUS_D);
100 const auto u = square(Gf448Elem(y)) - 1;
101 const auto v = d * square(Gf448Elem(y)) - 1;
102 const auto maybe_x = (u * square(u)) * v * root((square(square(u)) * u) * square(v) * v);
103
104 // 3. If v * x^2 = u, the recovered x-coordinate is x. Otherwise, no
105 // square root exists, and the decoding fails.
106 if(v * square(maybe_x) != u) {
107 throw Decoding_Error("Square root does not exist");
108 }
109 // 4. Finally, use the x_0 bit to select the right square root. If
110 // x = 0, and x_0 = 1, decoding fails. Otherwise, if x_0 != x mod
111 // 2, set x <-- p - x. Return the decoded point (x,y).
112 if(maybe_x.is_zero() && x_distinguisher) {
113 throw Decoding_Error("Square root of zero cannot be odd");
114 }
115 bool maybe_x_parity = maybe_x.is_odd();
116 std::array<uint64_t, WORDS_448> x_data;
117 CT::Mask<uint64_t>::expand(maybe_x_parity == x_distinguisher)
118 .select_n(x_data.data(), maybe_x.words().data(), (-maybe_x).words().data(), 7);
119
120 return {Gf448Elem(x_data), y};
121}
static constexpr Mask< T > expand(T v)
Definition ct_utils.h:389
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,...
bool is_odd() const
Return true iff this element is odd. Constant time.
Gf448Elem root(const Gf448Elem &elem)
Compute the root of elem in the field.
BigInt square(const BigInt &x)
Definition numthry.cpp:157

References Botan::Gf448Elem::bytes_are_canonical_representation(), Botan::CT::Mask< T >::expand(), Botan::Gf448Elem::is_odd(), Botan::root(), Botan::square(), and y().

Referenced by Botan::Ed448_PublicKey::check_key(), and Botan::verify_signature().

◆ double_point()

Ed448Point Botan::Ed448Point::double_point ( ) const

Double a point (RFC 8032 5.2.4)

Definition at line 175 of file ed448_internal.cpp.

175 {
176 // RFC 8032 5.2.4. - Point Addition (Double)
177 const Gf448Elem B = square(m_x + m_y);
178 const Gf448Elem C = square(m_x);
179 const Gf448Elem D = square(m_y);
180 const Gf448Elem E = C + D;
181 const Gf448Elem H = square(m_z);
182 const Gf448Elem J = E - (H + H);
183 const Gf448Elem X3 = (B - E) * J;
184 const Gf448Elem Y3 = E * (C - D);
185 const Gf448Elem Z3 = E * J;
186
187 return Ed448Point(X3, Y3, Z3);
188}

References Ed448Point(), and Botan::square().

Referenced by scalar_mul().

◆ encode()

std::array< uint8_t, ED448_LEN > Botan::Ed448Point::encode ( ) const

Encode the point to its 57-byte representation (RFC 8032 5.2.2)

Definition at line 141 of file ed448_internal.cpp.

141 {
142 std::array<uint8_t, ED448_LEN> res_buf = {0};
143
144 // RFC 8032 5.2.2
145 // All values are coded as octet strings, and integers are coded using
146 // little-endian convention. [...]
147 // First, encode the y-coordinate as a little-endian string of 57 octets.
148 // The final octet is always zero.
149 y().to_bytes(std::span(res_buf).first<56>());
150
151 // To form the encoding of the point, copy the least significant bit of
152 // the x-coordinate to the most significant bit of the final octet.
153 res_buf.back() = (static_cast<uint8_t>(x().is_odd()) << 7);
154
155 return res_buf;
156}
void to_bytes(std::span< uint8_t, BYTES_448 > out) const
Store the canonical representation of the GF element as 56 bytes in little-endian order.

References Botan::Gf448Elem::is_odd(), Botan::Gf448Elem::to_bytes(), x(), and y().

◆ operator+()

Ed448Point Botan::Ed448Point::operator+ ( const Ed448Point & other) const

Add two points (RFC 8032 5.2.4)

Definition at line 158 of file ed448_internal.cpp.

158 {
159 // RFC 8032 5.2.4. - Point Addition (Add)
160 const Gf448Elem A = m_z * other.m_z;
161 const Gf448Elem B = square(A);
162 const Gf448Elem C = m_x * other.m_x;
163 const Gf448Elem D = m_y * other.m_y;
164 const Gf448Elem E = (-Gf448Elem(MINUS_D)) * C * D;
165 const Gf448Elem F = B - E;
166 const Gf448Elem G = B + E;
167 const Gf448Elem H = (m_x + m_y) * (other.m_x + other.m_y);
168 const Gf448Elem X3 = A * F * (H - C - D);
169 const Gf448Elem Y3 = A * G * (D - C);
170 const Gf448Elem Z3 = F * G;
171
172 return Ed448Point(X3, Y3, Z3);
173}

References Ed448Point(), and Botan::square().

◆ operator==()

bool Botan::Ed448Point::operator== ( const Ed448Point & other) const

Check if two points are equal (constant time)

Definition at line 206 of file ed448_internal.cpp.

206 {
207 // Note that the operator== of of Gf448Elem is constant time
208 const auto mask_x = CT::Mask<uint8_t>::expand(x() == other.x());
209 const auto mask_y = CT::Mask<uint8_t>::expand(y() == other.y());
210
211 return (mask_x & mask_y).as_bool();
212}

References Botan::CT::Mask< T >::expand(), x(), and y().

◆ scalar_mul()

Ed448Point Botan::Ed448Point::scalar_mul ( const Scalar448 & scalar) const

Scalar multiplication.

Definition at line 190 of file ed448_internal.cpp.

190 {
191 Ed448Point res(0, 1);
192
193 // Square and multiply (double and add) in constant time.
194 // TODO: Optimization potential. E.g. for a = *this precompute
195 // 0, a, 2a, 3a, ..., 15a and ct select and add the right one for
196 // each 4 bit window instead of conditional add.
197 for(int16_t i = 445; i >= 0; --i) {
198 res = res.double_point();
199 // Conditional add if bit is set
200 auto add_sum = res + *this;
201 res.ct_conditional_assign(s.get_bit(i), add_sum);
202 }
203 return res;
204}

References ct_conditional_assign(), double_point(), and Botan::Scalar448::get_bit().

Referenced by Botan::operator*().

◆ x()

Gf448Elem Botan::Ed448Point::x ( ) const
inline

Getter for point coordinate x.

Definition at line 61 of file ed448_internal.h.

61{ return m_x / m_z; }

Referenced by base_point(), encode(), and operator==().

◆ x_proj()

Gf448Elem Botan::Ed448Point::x_proj ( ) const
inline

Getter for projective coordinate X.

Definition at line 52 of file ed448_internal.h.

52{ return m_x; }

◆ y()

Gf448Elem Botan::Ed448Point::y ( ) const
inline

Getter for point coordinate y.

Definition at line 64 of file ed448_internal.h.

64{ return m_y / m_z; }

Referenced by base_point(), decode(), encode(), and operator==().

◆ y_proj()

Gf448Elem Botan::Ed448Point::y_proj ( ) const
inline

Getter for projective coordinate Y.

Definition at line 55 of file ed448_internal.h.

55{ return m_y; }

◆ z_proj()

Gf448Elem Botan::Ed448Point::z_proj ( ) const
inline

Getter for projective coordinate Z.

Definition at line 58 of file ed448_internal.h.

58{ return m_z; }

The documentation for this class was generated from the following files: