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