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