Botan 3.7.1
Crypto and TLS for C&
ec_scalar.h
Go to the documentation of this file.
1/*
2* (C) 2024 Jack Lloyd
3*
4* Botan is released under the Simplified BSD License (see license.txt)
5*/
6
7#ifndef BOTAN_EC_SCALAR_H_
8#define BOTAN_EC_SCALAR_H_
9
10#include <botan/concepts.h>
11#include <botan/types.h>
12#include <optional>
13#include <span>
14#include <vector>
15
16namespace Botan {
17
18class BigInt;
19class RandomNumberGenerator;
20class EC_Group;
21class EC_Group_Data;
22class EC_Scalar_Data;
23
24/**
25* Represents an integer modulo the prime group order of an elliptic curve
26*/
28 public:
29 /**
30 * Deserialize a scalar
31 *
32 * The span must be exactly bytes() long; this function does not accept
33 * either short inputs (eg [1] to encode the integer 1) or inputs with
34 * excess leading zero bytes.
35 *
36 * Returns nullopt if the length is incorrect or if the integer is not
37 * within the range [0,n) where n is the group order.
38 */
39 static std::optional<EC_Scalar> deserialize(const EC_Group& group, std::span<const uint8_t> bytes);
40
41 /**
42 * Convert a bytestring to an EC_Scalar
43 *
44 * This uses the truncation rules from ECDSA
45 */
46 static EC_Scalar from_bytes_with_trunc(const EC_Group& group, std::span<const uint8_t> bytes);
47
48 /**
49 * Convert a bytestring to an EC_Scalar
50 *
51 * This reduces the bytes modulo the group order. The input can be at most
52 * 2*bytes() long
53 */
54 static EC_Scalar from_bytes_mod_order(const EC_Group& group, std::span<const uint8_t> bytes);
55
56 /**
57 * Convert a bytestring to an EC_Scalar
58 *
59 * This is similar to deserialize but instead of returning nullopt if the input
60 * is invalid, it will throw an exception.
61 */
62 BOTAN_DEPRECATED("Use EC_Scalar::deserialize") EC_Scalar(const EC_Group& group, std::span<const uint8_t> bytes);
63
64 /**
65 * Deserialize a pair of scalars
66 *
67 * Returns nullopt if the length is not 2*bytes(), or if either scalar is
68 * out of range or zero
69 */
70 static std::optional<std::pair<EC_Scalar, EC_Scalar>> deserialize_pair(const EC_Group& group,
71 std::span<const uint8_t> bytes);
72
73 /**
74 * Return a new random scalar value
75 */
76 static EC_Scalar random(const EC_Group& group, RandomNumberGenerator& rng);
77
78 /**
79 * Return the scalar value 1
80 */
81 static EC_Scalar one(const EC_Group& group);
82
83 /**
84 * Convert from the argument BigInt to a EC_Scalar
85 *
86 * Throws an exception if the provided bn is negative or too large
87 */
88 static EC_Scalar from_bigint(const EC_Group& group, const BigInt& bn);
89
90 /**
91 * Compute the elliptic curve scalar multiplication (g*k) where g is the
92 * standard base point on the curve. Then extract the x coordinate of
93 * the resulting point, and reduce it modulo the group order.
94 *
95 * Workspace argument is transitional
96 */
97 static EC_Scalar gk_x_mod_order(const EC_Scalar& scalar, RandomNumberGenerator& rng, std::vector<BigInt>& ws);
98
99 /**
100 * Return the byte size of this scalar
101 */
102 size_t bytes() const;
103
104 /**
105 * Write the fixed length serialization to bytes
106 *
107 * The provided span must be exactly bytes() long
108 */
109 void serialize_to(std::span<uint8_t> bytes) const;
110
111 /**
112 * Return the bytes of the encoded scalar in a container
113 */
114 template <concepts::resizable_byte_buffer T = std::vector<uint8_t>>
115 T serialize() const {
116 T s(this->bytes());
117 this->serialize_to(s);
118 return s;
119 }
120
121 /**
122 * Write the fixed length serialization to bytes
123 *
124 * The provided span must be exactly 2*bytes() long
125 */
126 static void serialize_pair_to(std::span<uint8_t> bytes, const EC_Scalar& r, const EC_Scalar& s);
127
128 /**
129 * Return the bytes of the encoded scalar in a container
130 */
131 template <concepts::resizable_byte_buffer T = std::vector<uint8_t>>
132 static T serialize_pair(const EC_Scalar& r, const EC_Scalar& s) {
133 T bytes(r.bytes() + s.bytes());
134 serialize_pair_to(bytes, r, s);
135 return bytes;
136 }
137
138 /**
139 * Return true if this EC_Scalar is zero
140 */
141 bool is_zero() const;
142
143 /**
144 * Return true if this EC_Scalar is not zero
145 */
146 bool is_nonzero() const { return !is_zero(); }
147
148 /**
149 * Constant time modular inversion
150 *
151 * Return the modular inverse of this EC_Scalar
152 *
153 * If *this is zero, then invert() returns zero
154 */
155 EC_Scalar invert() const;
156
157 /**
158 * Variable time modular inversion
159 *
160 * Return the modular inverse of this EC_Scalar
161 *
162 * If *this is zero, then invert_vartime() returns zero
163 */
164 EC_Scalar invert_vartime() const;
165
166 /**
167 * Return the additive inverse of *this
168 */
169 EC_Scalar negate() const;
170
171 /**
172 * Scalar addition (modulo group order)
173 */
174 EC_Scalar add(const EC_Scalar& x) const;
175
176 /**
177 * Scalar subtraction (modulo group order)
178 */
179 EC_Scalar sub(const EC_Scalar& x) const;
180
181 /**
182 * Scalar multiplication (modulo group order)
183 */
184 EC_Scalar mul(const EC_Scalar& x) const;
185
186 /**
187 * Assign a scalar
188 */
189 void assign(const EC_Scalar& x);
190
191 /**
192 * Set *this to its own square modulo the group order
193 */
194 void square_self();
195
196 /**
197 * Test for equality
198 */
199 bool is_eq(const EC_Scalar& x) const;
200
201 /**
202 * Convert *this to a BigInt
203 */
204 BigInt to_bigint() const;
205
206 friend EC_Scalar operator+(const EC_Scalar& x, const EC_Scalar& y) { return x.add(y); }
207
208 friend EC_Scalar operator-(const EC_Scalar& x, const EC_Scalar& y) { return x.sub(y); }
209
210 friend EC_Scalar operator*(const EC_Scalar& x, const EC_Scalar& y) { return x.mul(y); }
211
212 friend bool operator==(const EC_Scalar& x, const EC_Scalar& y) { return x.is_eq(y); }
213
214 EC_Scalar(const EC_Scalar& other);
215 EC_Scalar(EC_Scalar&& other) noexcept;
216
217 EC_Scalar& operator=(const EC_Scalar& other);
218 EC_Scalar& operator=(EC_Scalar&& other) noexcept;
219
221
222 const EC_Scalar_Data& _inner() const { return inner(); }
223
224 static EC_Scalar _from_inner(std::unique_ptr<EC_Scalar_Data> inner);
225
226 private:
227 friend class EC_AffinePoint;
228
229 EC_Scalar(std::unique_ptr<EC_Scalar_Data> scalar);
230
231 const EC_Scalar_Data& inner() const { return *m_scalar; }
232
233 std::unique_ptr<EC_Scalar_Data> m_scalar;
234};
235
236} // namespace Botan
237
238#endif
#define BOTAN_UNSTABLE_API
Definition api.h:32
#define BOTAN_DEPRECATED(msg)
Definition api.h:59
const EC_Scalar_Data & _inner() const
Definition ec_scalar.h:222
bool is_eq(const EC_Scalar &x) const
EC_Scalar mul(const EC_Scalar &x) const
EC_Scalar add(const EC_Scalar &x) const
friend EC_Scalar operator*(const EC_Scalar &x, const EC_Scalar &y)
Definition ec_scalar.h:210
size_t bytes() const
Definition ec_scalar.cpp:41
static T serialize_pair(const EC_Scalar &r, const EC_Scalar &s)
Definition ec_scalar.h:132
T serialize() const
Definition ec_scalar.h:115
friend EC_Scalar operator+(const EC_Scalar &x, const EC_Scalar &y)
Definition ec_scalar.h:206
friend bool operator==(const EC_Scalar &x, const EC_Scalar &y)
Definition ec_scalar.h:212
bool is_nonzero() const
Definition ec_scalar.h:146
EC_Scalar sub(const EC_Scalar &x) const
friend EC_Scalar operator-(const EC_Scalar &x, const EC_Scalar &y)
Definition ec_scalar.h:208
int(* final)(unsigned char *, CTX *)
FE_25519 T
Definition ge.cpp:34