2 * Copyright 2017-2020 The OpenSSL Project Authors. All Rights Reserved.
3 * Copyright 2015-2016 Cryptography Research, Inc.
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
10 * Originally written by Mike Hamburg
13 #include <openssl/crypto.h>
14 #include <openssl/evp.h>
15 #include "crypto/ecx.h"
16 #include "curve448_local.h"
19 #include "internal/numbers.h"
23 static c448_error_t oneshot_hash(OSSL_LIB_CTX *ctx, uint8_t *out, size_t outlen,
24 const uint8_t *in, size_t inlen,
27 EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
28 EVP_MD *shake256 = NULL;
29 c448_error_t ret = C448_FAILURE;
34 shake256 = EVP_MD_fetch(ctx, "SHAKE256", propq);
38 if (!EVP_DigestInit_ex(hashctx, shake256, NULL)
39 || !EVP_DigestUpdate(hashctx, in, inlen)
40 || !EVP_DigestFinalXOF(hashctx, out, outlen))
45 EVP_MD_CTX_free(hashctx);
46 EVP_MD_free(shake256);
50 static void clamp(uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES])
52 secret_scalar_ser[0] &= -COFACTOR;
53 secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 1] = 0;
54 secret_scalar_ser[EDDSA_448_PRIVATE_BYTES - 2] |= 0x80;
57 static c448_error_t hash_init_with_dom(OSSL_LIB_CTX *ctx, EVP_MD_CTX *hashctx,
60 const uint8_t *context,
65 const char dom_s[] = {0x53, 0x69, 0x67, 0x45,
66 0x64, 0x34, 0x34, 0x38, 0x00};
68 const char dom_s[] = "SigEd448";
71 EVP_MD *shake256 = NULL;
73 if (context_len > UINT8_MAX)
76 dom[0] = (uint8_t)(2 - (prehashed == 0 ? 1 : 0)
77 - (for_prehash == 0 ? 1 : 0));
78 dom[1] = (uint8_t)context_len;
80 shake256 = EVP_MD_fetch(ctx, "SHAKE256", propq);
84 if (!EVP_DigestInit_ex(hashctx, shake256, NULL)
85 || !EVP_DigestUpdate(hashctx, dom_s, strlen(dom_s))
86 || !EVP_DigestUpdate(hashctx, dom, sizeof(dom))
87 || !EVP_DigestUpdate(hashctx, context, context_len)) {
88 EVP_MD_free(shake256);
92 EVP_MD_free(shake256);
96 /* In this file because it uses the hash */
97 c448_error_t c448_ed448_convert_private_key_to_x448(
99 uint8_t x[X448_PRIVATE_BYTES],
100 const uint8_t ed [EDDSA_448_PRIVATE_BYTES],
103 /* pass the private key through oneshot_hash function */
104 /* and keep the first X448_PRIVATE_BYTES bytes */
105 return oneshot_hash(ctx, x, X448_PRIVATE_BYTES, ed,
106 EDDSA_448_PRIVATE_BYTES, propq);
109 c448_error_t c448_ed448_derive_public_key(
111 uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
112 const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
115 /* only this much used for keygen */
116 uint8_t secret_scalar_ser[EDDSA_448_PRIVATE_BYTES];
117 curve448_scalar_t secret_scalar;
121 if (!oneshot_hash(ctx, secret_scalar_ser, sizeof(secret_scalar_ser),
123 EDDSA_448_PRIVATE_BYTES,
127 clamp(secret_scalar_ser);
129 curve448_scalar_decode_long(secret_scalar, secret_scalar_ser,
130 sizeof(secret_scalar_ser));
133 * Since we are going to mul_by_cofactor during encoding, divide by it
134 * here. However, the EdDSA base point is not the same as the decaf base
135 * point if the sigma isogeny is in use: the EdDSA base point is on
136 * Etwist_d/(1-d) and the decaf base point is on Etwist_d, and when
137 * converted it effectively picks up a factor of 2 from the isogenies. So
138 * we might start at 2 instead of 1.
140 for (c = 1; c < C448_EDDSA_ENCODE_RATIO; c <<= 1)
141 curve448_scalar_halve(secret_scalar, secret_scalar);
143 curve448_precomputed_scalarmul(p, curve448_precomputed_base, secret_scalar);
145 curve448_point_mul_by_ratio_and_encode_like_eddsa(pubkey, p);
148 curve448_scalar_destroy(secret_scalar);
149 curve448_point_destroy(p);
150 OPENSSL_cleanse(secret_scalar_ser, sizeof(secret_scalar_ser));
155 c448_error_t c448_ed448_sign(
157 uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
158 const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
159 const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
160 const uint8_t *message, size_t message_len,
161 uint8_t prehashed, const uint8_t *context,
162 size_t context_len, const char *propq)
164 curve448_scalar_t secret_scalar;
165 EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
166 c448_error_t ret = C448_FAILURE;
167 curve448_scalar_t nonce_scalar;
168 uint8_t nonce_point[EDDSA_448_PUBLIC_BYTES] = { 0 };
170 curve448_scalar_t challenge_scalar;
177 * Schedule the secret key, First EDDSA_448_PRIVATE_BYTES is serialized
178 * secret scalar,next EDDSA_448_PRIVATE_BYTES bytes is the seed.
180 uint8_t expanded[EDDSA_448_PRIVATE_BYTES * 2];
182 if (!oneshot_hash(ctx, expanded, sizeof(expanded), privkey,
183 EDDSA_448_PRIVATE_BYTES, propq))
186 curve448_scalar_decode_long(secret_scalar, expanded,
187 EDDSA_448_PRIVATE_BYTES);
189 /* Hash to create the nonce */
190 if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context,
192 || !EVP_DigestUpdate(hashctx,
193 expanded + EDDSA_448_PRIVATE_BYTES,
194 EDDSA_448_PRIVATE_BYTES)
195 || !EVP_DigestUpdate(hashctx, message, message_len)) {
196 OPENSSL_cleanse(expanded, sizeof(expanded));
199 OPENSSL_cleanse(expanded, sizeof(expanded));
202 /* Decode the nonce */
204 uint8_t nonce[2 * EDDSA_448_PRIVATE_BYTES];
206 if (!EVP_DigestFinalXOF(hashctx, nonce, sizeof(nonce)))
208 curve448_scalar_decode_long(nonce_scalar, nonce, sizeof(nonce));
209 OPENSSL_cleanse(nonce, sizeof(nonce));
213 /* Scalarmul to create the nonce-point */
214 curve448_scalar_t nonce_scalar_2;
217 curve448_scalar_halve(nonce_scalar_2, nonce_scalar);
218 for (c = 2; c < C448_EDDSA_ENCODE_RATIO; c <<= 1)
219 curve448_scalar_halve(nonce_scalar_2, nonce_scalar_2);
221 curve448_precomputed_scalarmul(p, curve448_precomputed_base,
223 curve448_point_mul_by_ratio_and_encode_like_eddsa(nonce_point, p);
224 curve448_point_destroy(p);
225 curve448_scalar_destroy(nonce_scalar_2);
229 uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES];
231 /* Compute the challenge */
232 if (!hash_init_with_dom(ctx, hashctx, prehashed, 0, context, context_len,
234 || !EVP_DigestUpdate(hashctx, nonce_point, sizeof(nonce_point))
235 || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES)
236 || !EVP_DigestUpdate(hashctx, message, message_len)
237 || !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge)))
240 curve448_scalar_decode_long(challenge_scalar, challenge,
242 OPENSSL_cleanse(challenge, sizeof(challenge));
245 curve448_scalar_mul(challenge_scalar, challenge_scalar, secret_scalar);
246 curve448_scalar_add(challenge_scalar, challenge_scalar, nonce_scalar);
248 OPENSSL_cleanse(signature, EDDSA_448_SIGNATURE_BYTES);
249 memcpy(signature, nonce_point, sizeof(nonce_point));
250 curve448_scalar_encode(&signature[EDDSA_448_PUBLIC_BYTES],
253 curve448_scalar_destroy(secret_scalar);
254 curve448_scalar_destroy(nonce_scalar);
255 curve448_scalar_destroy(challenge_scalar);
259 EVP_MD_CTX_free(hashctx);
263 c448_error_t c448_ed448_sign_prehash(
265 uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
266 const uint8_t privkey[EDDSA_448_PRIVATE_BYTES],
267 const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
268 const uint8_t hash[64], const uint8_t *context,
269 size_t context_len, const char *propq)
271 return c448_ed448_sign(ctx, signature, privkey, pubkey, hash, 64, 1,
272 context, context_len, propq);
275 c448_error_t c448_ed448_verify(
277 const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
278 const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
279 const uint8_t *message, size_t message_len,
280 uint8_t prehashed, const uint8_t *context,
281 uint8_t context_len, const char *propq)
283 curve448_point_t pk_point, r_point;
285 curve448_scalar_t challenge_scalar;
286 curve448_scalar_t response_scalar;
287 /* Order in little endian format */
288 static const uint8_t order[] = {
289 0xF3, 0x44, 0x58, 0xAB, 0x92, 0xC2, 0x78, 0x23, 0x55, 0x8F, 0xC5, 0x8D,
290 0x72, 0xC2, 0x6C, 0x21, 0x90, 0x36, 0xD6, 0xAE, 0x49, 0xDB, 0x4E, 0xC4,
291 0xE9, 0x23, 0xCA, 0x7C, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
292 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
293 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x00
298 * Check that s (second 57 bytes of the sig) is less than the order. Both
299 * s and the order are in little-endian format. This can be done in
300 * variable time, since if this is not the case the signature if publicly
303 for (i = EDDSA_448_PUBLIC_BYTES - 1; i >= 0; i--) {
304 if (signature[i + EDDSA_448_PUBLIC_BYTES] > order[i])
306 if (signature[i + EDDSA_448_PUBLIC_BYTES] < order[i])
313 curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point, pubkey);
315 if (C448_SUCCESS != error)
319 curve448_point_decode_like_eddsa_and_mul_by_ratio(r_point, signature);
320 if (C448_SUCCESS != error)
324 /* Compute the challenge */
325 EVP_MD_CTX *hashctx = EVP_MD_CTX_new();
326 uint8_t challenge[2 * EDDSA_448_PRIVATE_BYTES];
329 || !hash_init_with_dom(ctx, hashctx, prehashed, 0, context,
331 || !EVP_DigestUpdate(hashctx, signature, EDDSA_448_PUBLIC_BYTES)
332 || !EVP_DigestUpdate(hashctx, pubkey, EDDSA_448_PUBLIC_BYTES)
333 || !EVP_DigestUpdate(hashctx, message, message_len)
334 || !EVP_DigestFinalXOF(hashctx, challenge, sizeof(challenge))) {
335 EVP_MD_CTX_free(hashctx);
339 EVP_MD_CTX_free(hashctx);
340 curve448_scalar_decode_long(challenge_scalar, challenge,
342 OPENSSL_cleanse(challenge, sizeof(challenge));
344 curve448_scalar_sub(challenge_scalar, curve448_scalar_zero,
347 curve448_scalar_decode_long(response_scalar,
348 &signature[EDDSA_448_PUBLIC_BYTES],
349 EDDSA_448_PRIVATE_BYTES);
351 /* pk_point = -c(x(P)) + (cx + k)G = kG */
352 curve448_base_double_scalarmul_non_secret(pk_point,
354 pk_point, challenge_scalar);
355 return c448_succeed_if(curve448_point_eq(pk_point, r_point));
358 c448_error_t c448_ed448_verify_prehash(
360 const uint8_t signature[EDDSA_448_SIGNATURE_BYTES],
361 const uint8_t pubkey[EDDSA_448_PUBLIC_BYTES],
362 const uint8_t hash[64], const uint8_t *context,
363 uint8_t context_len, const char *propq)
365 return c448_ed448_verify(ctx, signature, pubkey, hash, 64, 1, context,
369 int ED448_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t *message,
370 size_t message_len, const uint8_t public_key[57],
371 const uint8_t private_key[57], const uint8_t *context,
372 size_t context_len, const char *propq)
374 return c448_ed448_sign(ctx, out_sig, private_key, public_key, message,
375 message_len, 0, context, context_len,propq)
379 int ED448_verify(OSSL_LIB_CTX *ctx, const uint8_t *message, size_t message_len,
380 const uint8_t signature[114], const uint8_t public_key[57],
381 const uint8_t *context, size_t context_len, const char *propq)
383 return c448_ed448_verify(ctx, signature, public_key, message, message_len,
384 0, context, (uint8_t)context_len,
385 propq) == C448_SUCCESS;
388 int ED448ph_sign(OSSL_LIB_CTX *ctx, uint8_t *out_sig, const uint8_t hash[64],
389 const uint8_t public_key[57], const uint8_t private_key[57],
390 const uint8_t *context, size_t context_len, const char *propq)
392 return c448_ed448_sign_prehash(ctx, out_sig, private_key, public_key, hash,
393 context, context_len, propq) == C448_SUCCESS;
397 int ED448ph_verify(OSSL_LIB_CTX *ctx, const uint8_t hash[64],
398 const uint8_t signature[114], const uint8_t public_key[57],
399 const uint8_t *context, size_t context_len, const char *propq)
401 return c448_ed448_verify_prehash(ctx, signature, public_key, hash, context,
402 (uint8_t)context_len, propq) == C448_SUCCESS;
405 int ED448_public_from_private(OSSL_LIB_CTX *ctx, uint8_t out_public_key[57],
406 const uint8_t private_key[57], const char *propq)
408 return c448_ed448_derive_public_key(ctx, out_public_key, private_key, propq)