1 /*
2 * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright 2015-2016 Cryptography Research, Inc.
4 *
5 * Licensed under the OpenSSL license (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 #include <string.h>
13 #include <openssl/crypto.h>
14 #include <openssl/evp.h>
15 #include "curve448_local.h"
16 #include "word.h"
17 #include "ed448.h"
18 #include "internal/numbers.h"
19
20 #define COFACTOR 4
21
oneshot_hash(uint8_t * out,size_t outlen,const uint8_t * in,size_t inlen)22 static c448_error_t oneshot_hash(uint8_t *out, size_t outlen,
23 const uint8_t *in, size_t inlen)
24 {
25 EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
26
27 if (hashctx == NULL)
28 return C448_FAILURE;
29
30 if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL)
31 || !EVP_DigestUpdate(hashctx, in, inlen)
32 || !EVP_DigestFinalXOF(hashctx, out, outlen)) {
33 EVP_MD_CTX_free(hashctx);
34 return C448_FAILURE;
35 }
36
37 EVP_MD_CTX_free(hashctx);
38 return C448_SUCCESS;
39 }
40
clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES])41 static void clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES])
42 {
43 secret_scalar_ser[0] &= -COFACTOR;
44 secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 1] = 0;
45 secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 2] |= 0x80;
46 }
47
hash_init_with_dom(EVP_MD_CTX * hashctx,uint8_t prehashed,uint8_t for_prehash,const uint8_t * context,size_t context_len)48 static c448_error_t hash_init_with_dom(EVP_MD_CTX *hashctx, uint8_t prehashed,
49 uint8_t for_prehash,
50 const uint8_t *context,
51 size_t context_len)
52 {
53 #ifdef CHARSET_EBCDIC
54 const char dom_s[] = {0x53, 0x69, 0x67, 0x45,
55 0x64, 0x34, 0x34, 0x38, 0x00};
56 #else
57 const char dom_s[] = "SigEd448";
58 #endif
59 uint8_t dom[2];
60
61 if (context_len > UINT8_MAX)
62 return C448_FAILURE;
63
64 dom[0] = (uint8_t)(2 - (prehashed == 0 ? 1 : 0)
65 - (for_prehash == 0 ? 1 : 0));
66 dom[1] = (uint8_t)context_len;
67
68 if (!EVP_DigestInit_ex(hashctx, EVP_shake256(), NULL)
69 || !EVP_DigestUpdate(hashctx, dom_s, strlen(dom_s))
70 || !EVP_DigestUpdate(hashctx, dom, sizeof(dom))
71 || !EVP_DigestUpdate(hashctx, context, context_len))
72 return C448_FAILURE;
73
74 return C448_SUCCESS;
75 }
76
77 /* In this file because it uses the hash */
c448_ed448_convert_private_key_to_x448(uint8_t x[X448_PRIVATE_BYTES],const uint8_t ed[EDDSA_448_PRIVATE_BYTES])78 c448_error_t c448_ed448_convert_private_key_to_x448(
79 uint8_t x[X448_PRIVATE_BYTES],
80 const uint8_t ed [EDDSA_448_PRIVATE_BYTES])
81 {
82 /* pass the private key through oneshot_hash function */
83 /* and keep the first X448_PRIVATE_BYTES bytes */
84 return oneshot_hash(x, X448_PRIVATE_BYTES, ed,
85 EDDSA_448_PRIVATE_BYTES);
86 }
87
c448_ed448_derive_public_key(uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],const uint8_t privkey[EDDSA_448_PRIVATE_BYTES])88 c448_error_t c448_ed448_derive_public_key(
89 uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
90 const uint8_t privkey[EDDSA_448_PRIVATE_BYTES])
91 {
92 /* only this much used for keygen */
93 uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES];
94 curve448_scalar_t secret_scalar;
95 unsigned int c;
96 curve448_point_t p;
97
98 if (!oneshot_hash(secret_scalar_ser, sizeof(secret_scalar_ser), privkey,
99 EDDSA_448_PRIVATE_BYTES))
100 return C448_FAILURE;
101
102 clamp(secret_scalar_ser);
103
104 curve448_scalar_decode_long(secret_scalar, secret_scalar_ser,
105 sizeof(secret_scalar_ser));
106
107 /*
108 * Since we are going to mul_by_cofactor during encoding, divide by it
109 * here. However, the EdDSA base point is not the same as the decaf base
110 * point if the sigma isogeny is in use: the EdDSA base point is on
111 * Etwist_d/(1-d) and the decaf base point is on Etwist_d, and when
112 * converted it effectively picks up a factor of 2 from the isogenies. So
113 * we might start at 2 instead of 1.
114 */
115 for (c = 1; c < C448_EDDSA_ENCODE_RATIO; c <<= 1)
116 curve448_scalar_halve(secret_scalar, secret_scalar);
117
118 curve448_precomputed_scalarmul(p, curve448_precomputed_base, secret_scalar);
119
120 curve448_point_mul_by_ratio_and_encode_like_eddsa(pubkey, p);
121
122 /* Cleanup */
123 curve448_scalar_destroy(secret_scalar);
124 curve448_point_destroy(p);
125 OPENSSL_cleanse(secret_scalar_ser, sizeof(secret_scalar_ser));
126
127 return C448_SUCCESS;
128 }
129
c448_ed448_sign(uint8_t signature[EDDSA_448_SIGNATURE_BYTES],const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],const uint8_t * message,size_t message_len,uint8_t prehashed,const uint8_t * context,size_t context_len)130 c448_error_t c448_ed448_sign(
131 uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
132 const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
133 const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
134 const uint8_t *message, size_t message_len,
135 uint8_t prehashed, const uint8_t *context,
136 size_t context_len)
137 {
138 curve448_scalar_t secret_scalar;
139 EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
140 c448_error_t ret = C448_FAILURE;
141 curve448_scalar_t nonce_scalar;
142 uint8_t nonce_point[EDDSA_448_PUBLIC_BYTES] = { 0 };
143 unsigned int c;
144 curve448_scalar_t challenge_scalar;
145
146 if (hashctx == NULL)
147 return C448_FAILURE;
148
149 {
150 /*
151 * Schedule the secret key, First EDDSA_448_PRIVATE_BYTES is serialised
152 * secret scalar,next EDDSA_448_PRIVATE_BYTES bytes is the seed.
153 */
154 uint8_t expanded[EDDSA_448_PRIVATE_BYTES * 2];
155
156 if (!oneshot_hash(expanded, sizeof(expanded), privkey,
157 EDDSA_448_PRIVATE_BYTES))
158 goto err;
159 clamp(expanded);
160 curve448_scalar_decode_long(secret_scalar, expanded,
161 EDDSA_448_PRIVATE_BYTES);
162
163 /* Hash to create the nonce */
164 if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len)
165 || !EVP_DigestUpdate(hashctx,
166 expanded + EDDSA_448_PRIVATE_BYTES,
167 EDDSA_448_PRIVATE_BYTES)
168 || !EVP_DigestUpdate(hashctx, message, message_len)) {
169 OPENSSL_cleanse(expanded, sizeof(expanded));
170 goto err;
171 }
172 OPENSSL_cleanse(expanded, sizeof(expanded));
173 }
174
175 /* Decode the nonce */
176 {
177 uint8_t nonce[2 * EDDSA_448_PRIVATE_BYTES];
178
179 if (!EVP_DigestFinalXOF(hashctx, nonce, sizeof(nonce)))
180 goto err;
181 curve448_scalar_decode_long(nonce_scalar, nonce, sizeof(nonce));
182 OPENSSL_cleanse(nonce, sizeof(nonce));
183 }
184
185 {
186 /* Scalarmul to create the nonce-point */
187 curve448_scalar_t nonce_scalar_2;
188 curve448_point_t p;
189
190 curve448_scalar_halve(nonce_scalar_2, nonce_scalar);
191 for (c = 2; c < C448_EDDSA_ENCODE_RATIO; c <<= 1)
192 curve448_scalar_halve(nonce_scalar_2, nonce_scalar_2);
193
194 curve448_precomputed_scalarmul(p, curve448_precomputed_base,
195 nonce_scalar_2);
196 curve448_point_mul_by_ratio_and_encode_like_eddsa(nonce_point, p);
197 curve448_point_destroy(p);
198 curve448_scalar_destroy(nonce_scalar_2);
199 }
200
201 {
202 uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES];
203
204 /* Compute the challenge */
205 if (!hash_init_with_dom(hashctx, prehashed, 0, context, context_len)
206 || !EVP_DigestUpdate(hashctx, nonce_point, sizeof(nonce_point))
207 || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES)
208 || !EVP_DigestUpdate(hashctx, message, message_len)
209 || !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge)))
210 goto err;
211
212 curve448_scalar_decode_long(challenge_scalar, challenge,
213 sizeof(challenge));
214 OPENSSL_cleanse(challenge, sizeof(challenge));
215 }
216
217 curve448_scalar_mul(challenge_scalar, challenge_scalar, secret_scalar);
218 curve448_scalar_add(challenge_scalar, challenge_scalar, nonce_scalar);
219
220 OPENSSL_cleanse(signature, EDDSA_448_SIGNATURE_BYTES);
221 memcpy(signature, nonce_point, sizeof(nonce_point));
222 curve448_scalar_encode(&signature[EDDSA_448_PUBLIC_BYTES],
223 challenge_scalar);
224
225 curve448_scalar_destroy(secret_scalar);
226 curve448_scalar_destroy(nonce_scalar);
227 curve448_scalar_destroy(challenge_scalar);
228
229 ret = C448_SUCCESS;
230 err:
231 EVP_MD_CTX_free(hashctx);
232 return ret;
233 }
234
c448_ed448_sign_prehash(uint8_t signature[EDDSA_448_SIGNATURE_BYTES],const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],const uint8_t hash[64],const uint8_t * context,size_t context_len)235 c448_error_t c448_ed448_sign_prehash(
236 uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
237 const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
238 const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
239 const uint8_t hash[64], const uint8_t *context,
240 size_t context_len)
241 {
242 return c448_ed448_sign(signature, privkey, pubkey, hash, 64, 1, context,
243 context_len);
244 }
245
c448_ed448_verify(const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],const uint8_t * message,size_t message_len,uint8_t prehashed,const uint8_t * context,uint8_t context_len)246 c448_error_t c448_ed448_verify(
247 const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
248 const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
249 const uint8_t *message, size_t message_len,
250 uint8_t prehashed, const uint8_t *context,
251 uint8_t context_len)
252 {
253 curve448_point_t pk_point, r_point;
254 c448_error_t error;
255 curve448_scalar_t challenge_scalar;
256 curve448_scalar_t response_scalar;
257 /* Order in little endian format */
258 static const uint8_t order[] = {
259 0xF3, 0x44, 0x58, 0xAB, 0x92, 0xC2, 0x78, 0x23, 0x55, 0x8F, 0xC5, 0x8D,
260 0x72, 0xC2, 0x6C, 0x21, 0x90, 0x36, 0xD6, 0xAE, 0x49, 0xDB, 0x4E, 0xC4,
261 0xE9, 0x23, 0xCA, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
262 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
263 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00
264 };
265 int i;
266
267 /*
268 * Check that s (second 57 bytes of the sig) is less than the order. Both
269 * s and the order are in little-endian format. This can be done in
270 * variable time, since if this is not the case the signature if publicly
271 * invalid.
272 */
273 for (i = EDDSA_448_PUBLIC_BYTES - 1; i >= 0; i--) {
274 if (signature[i + EDDSA_448_PUBLIC_BYTES] > order[i])
275 return C448_FAILURE;
276 if (signature[i + EDDSA_448_PUBLIC_BYTES] < order[i])
277 break;
278 }
279 if (i < 0)
280 return C448_FAILURE;
281
282 error =
283 curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pubkey);
284
285 if (C448_SUCCESS != error)
286 return error;
287
288 error =
289 curve448_point_decode_like_eddsa_and_mul_by_ratio(r_point, signature);
290 if (C448_SUCCESS != error)
291 return error;
292
293 {
294 /* Compute the challenge */
295 EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
296 uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES];
297
298 if (hashctx == NULL
299 || !hash_init_with_dom(hashctx, prehashed, 0, context,
300 context_len)
301 || !EVP_DigestUpdate(hashctx, signature, EDDSA_448_PUBLIC_BYTES)
302 || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES)
303 || !EVP_DigestUpdate(hashctx, message, message_len)
304 || !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge))) {
305 EVP_MD_CTX_free(hashctx);
306 return C448_FAILURE;
307 }
308
309 EVP_MD_CTX_free(hashctx);
310 curve448_scalar_decode_long(challenge_scalar, challenge,
311 sizeof(challenge));
312 OPENSSL_cleanse(challenge, sizeof(challenge));
313 }
314 curve448_scalar_sub(challenge_scalar, curve448_scalar_zero,
315 challenge_scalar);
316
317 curve448_scalar_decode_long(response_scalar,
318 &signature[EDDSA_448_PUBLIC_BYTES],
319 EDDSA_448_PRIVATE_BYTES);
320
321 /* pk_point = -c(x(P)) + (cx + k)G = kG */
322 curve448_base_double_scalarmul_non_secret(pk_point,
323 response_scalar,
324 pk_point, challenge_scalar);
325 return c448_succeed_if(curve448_point_eq(pk_point, r_point));
326 }
327
c448_ed448_verify_prehash(const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],const uint8_t hash[64],const uint8_t * context,uint8_t context_len)328 c448_error_t c448_ed448_verify_prehash(
329 const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
330 const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
331 const uint8_t hash[64], const uint8_t *context,
332 uint8_t context_len)
333 {
334 return c448_ed448_verify(signature, pubkey, hash, 64, 1, context,
335 context_len);
336 }
337
ED448_sign(uint8_t * out_sig,const uint8_t * message,size_t message_len,const uint8_t public_key[57],const uint8_t private_key[57],const uint8_t * context,size_t context_len)338 int ED448_sign(uint8_t *out_sig, const uint8_t *message, size_t message_len,
339 const uint8_t public_key[57], const uint8_t private_key[57],
340 const uint8_t *context, size_t context_len)
341 {
342 return c448_ed448_sign(out_sig, private_key, public_key, message,
343 message_len, 0, context, context_len)
344 == C448_SUCCESS;
345 }
346
ED448_verify(const uint8_t * message,size_t message_len,const uint8_t signature[114],const uint8_t public_key[57],const uint8_t * context,size_t context_len)347 int ED448_verify(const uint8_t *message, size_t message_len,
348 const uint8_t signature[114], const uint8_t public_key[57],
349 const uint8_t *context, size_t context_len)
350 {
351 return c448_ed448_verify(signature, public_key, message, message_len, 0,
352 context, (uint8_t)context_len) == C448_SUCCESS;
353 }
354
ED448ph_sign(uint8_t * out_sig,const uint8_t hash[64],const uint8_t public_key[57],const uint8_t private_key[57],const uint8_t * context,size_t context_len)355 int ED448ph_sign(uint8_t *out_sig, const uint8_t hash[64],
356 const uint8_t public_key[57], const uint8_t private_key[57],
357 const uint8_t *context, size_t context_len)
358 {
359 return c448_ed448_sign_prehash(out_sig, private_key, public_key, hash,
360 context, context_len) == C448_SUCCESS;
361
362 }
363
ED448ph_verify(const uint8_t hash[64],const uint8_t signature[114],const uint8_t public_key[57],const uint8_t * context,size_t context_len)364 int ED448ph_verify(const uint8_t hash[64], const uint8_t signature[114],
365 const uint8_t public_key[57], const uint8_t *context,
366 size_t context_len)
367 {
368 return c448_ed448_verify_prehash(signature, public_key, hash, context,
369 (uint8_t)context_len) == C448_SUCCESS;
370 }
371
ED448_public_from_private(uint8_t out_public_key[57],const uint8_t private_key[57])372 int ED448_public_from_private(uint8_t out_public_key[57],
373 const uint8_t private_key[57])
374 {
375 return c448_ed448_derive_public_key(out_public_key, private_key)
376 == C448_SUCCESS;
377 }
378