/src/openssl/crypto/ec/curve448/point_448.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright 2017-2023 The OpenSSL Project Authors. All Rights Reserved. |
3 | | * Copyright 2015-2016 Cryptography Research, Inc. |
4 | | * |
5 | | * Licensed under the Apache License 2.0 (the "License"). You may not use |
6 | | * this file except in compliance with the License. You can obtain a copy |
7 | | * in the file LICENSE in the source distribution or at |
8 | | * https://www.openssl.org/source/license.html |
9 | | * |
10 | | * Originally written by Mike Hamburg |
11 | | */ |
12 | | |
13 | | #ifndef OSSL_CRYPTO_EC_CURVE448_POINT_448_H |
14 | | # define OSSL_CRYPTO_EC_CURVE448_POINT_448_H |
15 | | |
16 | | # include "curve448utils.h" |
17 | | # include "field.h" |
18 | | |
19 | | /* Comb config: number of combs, n, t, s. */ |
20 | 0 | #define COMBS_N 5 |
21 | 0 | #define COMBS_T 5 |
22 | 0 | #define COMBS_S 18 |
23 | | |
24 | | /* Projective Niels coordinates */ |
25 | | typedef struct { |
26 | | gf a, b, c; |
27 | | } niels_s, niels_t[1]; |
28 | | typedef struct { |
29 | | niels_t n; |
30 | | gf z; |
31 | | } pniels_t[1]; |
32 | | |
33 | | /* Precomputed base */ |
34 | | struct curve448_precomputed_s { |
35 | | niels_t table[COMBS_N << (COMBS_T - 1)]; |
36 | | }; |
37 | | |
38 | 0 | # define C448_SCALAR_LIMBS ((446-1)/C448_WORD_BITS+1) |
39 | | |
40 | | /* The number of bits in a scalar */ |
41 | 0 | # define C448_SCALAR_BITS 446 |
42 | | |
43 | | /* Number of bytes in a serialized scalar. */ |
44 | 0 | # define C448_SCALAR_BYTES 56 |
45 | | |
46 | | /* X448 encoding ratio. */ |
47 | 0 | # define X448_ENCODE_RATIO 2 |
48 | | |
49 | | /* Number of bytes in an x448 public key */ |
50 | | # define X448_PUBLIC_BYTES 56 |
51 | | |
52 | | /* Number of bytes in an x448 private key */ |
53 | 0 | # define X448_PRIVATE_BYTES 56 |
54 | | |
55 | | /* Twisted Edwards extended homogeneous coordinates */ |
56 | | typedef struct curve448_point_s { |
57 | | gf x, y, z, t; |
58 | | } curve448_point_t[1]; |
59 | | |
60 | | /* Precomputed table based on a point. Can be trivial implementation. */ |
61 | | struct curve448_precomputed_s; |
62 | | |
63 | | /* Precomputed table based on a point. Can be trivial implementation. */ |
64 | | typedef struct curve448_precomputed_s curve448_precomputed_s; |
65 | | |
66 | | /* Scalar is stored packed, because we don't need the speed. */ |
67 | | typedef struct curve448_scalar_s { |
68 | | c448_word_t limb[C448_SCALAR_LIMBS]; |
69 | | } curve448_scalar_t[1]; |
70 | | |
71 | | /* A scalar equal to 1. */ |
72 | | extern const curve448_scalar_t ossl_curve448_scalar_one; |
73 | | |
74 | | /* A scalar equal to 0. */ |
75 | | extern const curve448_scalar_t ossl_curve448_scalar_zero; |
76 | | |
77 | | /* The identity point on the curve. */ |
78 | | extern const curve448_point_t ossl_curve448_point_identity; |
79 | | |
80 | | /* Precomputed table for the base point on the curve. */ |
81 | | extern const struct curve448_precomputed_s *ossl_curve448_precomputed_base; |
82 | | extern const niels_t *ossl_curve448_wnaf_base; |
83 | | |
84 | | /* |
85 | | * Read a scalar from wire format or from bytes. |
86 | | * |
87 | | * ser (in): Serialized form of a scalar. |
88 | | * out (out): Deserialized form. |
89 | | * |
90 | | * Returns: |
91 | | * C448_SUCCESS: The scalar was correctly encoded. |
92 | | * C448_FAILURE: The scalar was greater than the modulus, and has been reduced |
93 | | * modulo that modulus. |
94 | | */ |
95 | | c448_error_t |
96 | | ossl_curve448_scalar_decode(curve448_scalar_t out, |
97 | | const unsigned char ser[C448_SCALAR_BYTES]); |
98 | | |
99 | | /* |
100 | | * Read a scalar from wire format or from bytes. Reduces mod scalar prime. |
101 | | * |
102 | | * ser (in): Serialized form of a scalar. |
103 | | * ser_len (in): Length of serialized form. |
104 | | * out (out): Deserialized form. |
105 | | */ |
106 | | void |
107 | | ossl_curve448_scalar_decode_long(curve448_scalar_t out, |
108 | | const unsigned char *ser, size_t ser_len); |
109 | | |
110 | | /* |
111 | | * Serialize a scalar to wire format. |
112 | | * |
113 | | * ser (out): Serialized form of a scalar. |
114 | | * s (in): Deserialized scalar. |
115 | | */ |
116 | | void |
117 | | ossl_curve448_scalar_encode(unsigned char ser[C448_SCALAR_BYTES], |
118 | | const curve448_scalar_t s); |
119 | | |
120 | | /* |
121 | | * Add two scalars. |a|, |b| and |out| may alias each other. |
122 | | * |
123 | | * a (in): One scalar. |
124 | | * b (in): Another scalar. |
125 | | * out (out): a+b. |
126 | | */ |
127 | | void |
128 | | ossl_curve448_scalar_add(curve448_scalar_t out, |
129 | | const curve448_scalar_t a, const curve448_scalar_t b); |
130 | | |
131 | | /* |
132 | | * Subtract two scalars. |a|, |b| and |out| may alias each other. |
133 | | * a (in): One scalar. |
134 | | * b (in): Another scalar. |
135 | | * out (out): a-b. |
136 | | */ |
137 | | void |
138 | | ossl_curve448_scalar_sub(curve448_scalar_t out, |
139 | | const curve448_scalar_t a, const curve448_scalar_t b); |
140 | | |
141 | | /* |
142 | | * Multiply two scalars. |a|, |b| and |out| may alias each other. |
143 | | * |
144 | | * a (in): One scalar. |
145 | | * b (in): Another scalar. |
146 | | * out (out): a*b. |
147 | | */ |
148 | | void |
149 | | ossl_curve448_scalar_mul(curve448_scalar_t out, |
150 | | const curve448_scalar_t a, const curve448_scalar_t b); |
151 | | |
152 | | /* |
153 | | * Halve a scalar. |a| and |out| may alias each other. |
154 | | * |
155 | | * a (in): A scalar. |
156 | | * out (out): a/2. |
157 | | */ |
158 | | void |
159 | | ossl_curve448_scalar_halve(curve448_scalar_t out, const curve448_scalar_t a); |
160 | | |
161 | | /* |
162 | | * Copy a scalar. The scalars may alias each other, in which case this |
163 | | * function does nothing. |
164 | | * |
165 | | * a (in): A scalar. |
166 | | * out (out): Will become a copy of a. |
167 | | */ |
168 | | static ossl_inline void curve448_scalar_copy(curve448_scalar_t out, |
169 | | const curve448_scalar_t a) |
170 | 0 | { |
171 | 0 | *out = *a; |
172 | 0 | } Unexecuted instantiation: curve448.c:curve448_scalar_copy Unexecuted instantiation: curve448_tables.c:curve448_scalar_copy Unexecuted instantiation: eddsa.c:curve448_scalar_copy Unexecuted instantiation: scalar.c:curve448_scalar_copy |
173 | | |
174 | | /* |
175 | | * Copy a point. The input and output may alias, in which case this function |
176 | | * does nothing. |
177 | | * |
178 | | * a (out): A copy of the point. |
179 | | * b (in): Any point. |
180 | | */ |
181 | | static ossl_inline void curve448_point_copy(curve448_point_t a, |
182 | | const curve448_point_t b) |
183 | 0 | { |
184 | 0 | *a = *b; |
185 | 0 | } Unexecuted instantiation: curve448.c:curve448_point_copy Unexecuted instantiation: curve448_tables.c:curve448_point_copy Unexecuted instantiation: eddsa.c:curve448_point_copy Unexecuted instantiation: scalar.c:curve448_point_copy |
186 | | |
187 | | /* |
188 | | * Test whether two points are equal. If yes, return C448_TRUE, else return |
189 | | * C448_FALSE. |
190 | | * |
191 | | * a (in): A point. |
192 | | * b (in): Another point. |
193 | | * |
194 | | * Returns: |
195 | | * C448_TRUE: The points are equal. |
196 | | * C448_FALSE: The points are not equal. |
197 | | */ |
198 | | __owur c448_bool_t |
199 | | ossl_curve448_point_eq(const curve448_point_t a, |
200 | | const curve448_point_t b); |
201 | | |
202 | | /* |
203 | | * Double a point. Equivalent to curve448_point_add(two_a,a,a), but potentially |
204 | | * faster. |
205 | | * |
206 | | * two_a (out): The sum a+a. |
207 | | * a (in): A point. |
208 | | */ |
209 | | void |
210 | | ossl_curve448_point_double(curve448_point_t two_a, const curve448_point_t a); |
211 | | |
212 | | /* |
213 | | * RFC 7748 Diffie-Hellman scalarmul. This function uses a different |
214 | | * (non-Decaf) encoding. |
215 | | * |
216 | | * out (out): The scaled point base*scalar |
217 | | * base (in): The point to be scaled. |
218 | | * scalar (in): The scalar to multiply by. |
219 | | * |
220 | | * Returns: |
221 | | * C448_SUCCESS: The scalarmul succeeded. |
222 | | * C448_FAILURE: The scalarmul didn't succeed, because the base point is in a |
223 | | * small subgroup. |
224 | | */ |
225 | | __owur c448_error_t |
226 | | ossl_x448_int(uint8_t out[X448_PUBLIC_BYTES], |
227 | | const uint8_t base[X448_PUBLIC_BYTES], |
228 | | const uint8_t scalar[X448_PRIVATE_BYTES]); |
229 | | |
230 | | /* |
231 | | * Multiply a point by X448_ENCODE_RATIO, then encode it like RFC 7748. |
232 | | * |
233 | | * This function is mainly used internally, but is exported in case |
234 | | * it will be useful. |
235 | | * |
236 | | * The ratio is necessary because the internal representation doesn't |
237 | | * track the cofactor information, so on output we must clear the cofactor. |
238 | | * This would multiply by the cofactor, but in fact internally points are always |
239 | | * even, so it multiplies by half the cofactor instead. |
240 | | * |
241 | | * As it happens, this aligns with the base point definitions; that is, |
242 | | * if you pass the Decaf/Ristretto base point to this function, the result |
243 | | * will be X448_ENCODE_RATIO times the X448 |
244 | | * base point. |
245 | | * |
246 | | * out (out): The scaled and encoded point. |
247 | | * p (in): The point to be scaled and encoded. |
248 | | */ |
249 | | void |
250 | | ossl_curve448_point_mul_by_ratio_and_encode_like_x448( |
251 | | uint8_t out[X448_PUBLIC_BYTES], |
252 | | const curve448_point_t p); |
253 | | |
254 | | /* |
255 | | * RFC 7748 Diffie-Hellman base point scalarmul. This function uses a different |
256 | | * (non-Decaf) encoding. |
257 | | * |
258 | | * out (out): The scaled point base*scalar |
259 | | * scalar (in): The scalar to multiply by. |
260 | | */ |
261 | | void |
262 | | ossl_x448_derive_public_key(uint8_t out[X448_PUBLIC_BYTES], |
263 | | const uint8_t scalar[X448_PRIVATE_BYTES]); |
264 | | |
265 | | /* |
266 | | * Multiply a precomputed base point by a scalar: out = scalar*base. |
267 | | * |
268 | | * scaled (out): The scaled point base*scalar |
269 | | * base (in): The point to be scaled. |
270 | | * scalar (in): The scalar to multiply by. |
271 | | */ |
272 | | void |
273 | | ossl_curve448_precomputed_scalarmul(curve448_point_t scaled, |
274 | | const curve448_precomputed_s *base, |
275 | | const curve448_scalar_t scalar); |
276 | | |
277 | | /* |
278 | | * Multiply two base points by two scalars: |
279 | | * combo = scalar1*curve448_point_base + scalar2*base2. |
280 | | * |
281 | | * Otherwise equivalent to curve448_point_double_scalarmul, but may be |
282 | | * faster at the expense of being variable time. |
283 | | * |
284 | | * combo (out): The linear combination scalar1*base + scalar2*base2. |
285 | | * scalar1 (in): A first scalar to multiply by. |
286 | | * base2 (in): A second point to be scaled. |
287 | | * scalar2 (in) A second scalar to multiply by. |
288 | | * |
289 | | * Warning: This function takes variable time, and may leak the scalars used. |
290 | | * It is designed for signature verification. |
291 | | */ |
292 | | void |
293 | | ossl_curve448_base_double_scalarmul_non_secret(curve448_point_t combo, |
294 | | const curve448_scalar_t scalar1, |
295 | | const curve448_point_t base2, |
296 | | const curve448_scalar_t scalar2); |
297 | | |
298 | | /* |
299 | | * Test that a point is valid, for debugging purposes. |
300 | | * |
301 | | * to_test (in): The point to test. |
302 | | * |
303 | | * Returns: |
304 | | * C448_TRUE The point is valid. |
305 | | * C448_FALSE The point is invalid. |
306 | | */ |
307 | | __owur c448_bool_t |
308 | | ossl_curve448_point_valid(const curve448_point_t to_test); |
309 | | |
310 | | /* Overwrite scalar with zeros. */ |
311 | | void ossl_curve448_scalar_destroy(curve448_scalar_t scalar); |
312 | | |
313 | | /* Overwrite point with zeros. */ |
314 | | void ossl_curve448_point_destroy(curve448_point_t point); |
315 | | |
316 | | #endif /* OSSL_CRYPTO_EC_CURVE448_POINT_448_H */ |