Rename decaf_448_* to curve448_*
[openssl.git] / crypto / ec / curve448 / eddsa.c
1 /**
2  * @file ed448goldilocks/eddsa.c
3  * @author Mike Hamburg
4  *
5  * @copyright
6  *   Copyright (c) 2015-2016 Cryptography Research, Inc.  \n
7  *   Released under the MIT License.  See LICENSE.txt for license information.
8  *
9  * @cond internal
10  * @brief EdDSA routines.
11  *
12  * @warning This file was automatically generated in Python.
13  * Please do not edit it.
14  */
15 #include <openssl/crypto.h>
16
17 #include "word.h"
18 #include "ed448.h"
19 #include "shake.h"
20 #include <string.h>
21
22 #define API_NAME "decaf_448"
23
24 #define hash_ctx_t   decaf_shake256_ctx_t
25 #define hash_init    decaf_shake256_init
26 #define hash_update  decaf_shake256_update
27 #define hash_final   decaf_shake256_final
28 #define hash_destroy decaf_shake256_destroy
29 #define hash_hash    decaf_shake256_hash
30
31 #define NO_CONTEXT DECAF_EDDSA_448_SUPPORTS_CONTEXTLESS_SIGS
32 #define EDDSA_USE_SIGMA_ISOGENY 0
33 #define COFACTOR 4
34 #define EDDSA_PREHASH_BYTES 64
35
36 #if NO_CONTEXT
37 const uint8_t NO_CONTEXT_POINTS_HERE = 0;
38 const uint8_t * const DECAF_ED448_NO_CONTEXT = &NO_CONTEXT_POINTS_HERE;
39 #endif
40
41 /* EDDSA_BASE_POINT_RATIO = 1 or 2
42  * Because EdDSA25519 is not on E_d but on the isogenous E_sigma_d,
43  * its base point is twice ours.
44  */
45 #define EDDSA_BASE_POINT_RATIO (1+EDDSA_USE_SIGMA_ISOGENY) /* TODO: remove */
46
47 static void clamp (
48     uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES]
49 ) {
50     /* Blarg */
51     secret_scalar_ser[0] &= -COFACTOR;
52     uint8_t hibit = (1<<0)>>1;
53     if (hibit == 0) {
54         secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES - 1] = 0;
55         secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES - 2] |= 0x80;
56     } else {
57         secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES - 1] &= hibit-1;
58         secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES - 1] |= hibit;
59     }
60 }
61
62 static void hash_init_with_dom(
63     hash_ctx_t hash,
64     uint8_t prehashed,
65     uint8_t for_prehash,
66     const uint8_t *context,
67     uint8_t context_len
68 ) {
69     hash_init(hash);
70
71 #if NO_CONTEXT
72     if (context_len == 0 && context == DECAF_ED448_NO_CONTEXT) {
73         (void)prehashed;
74         (void)for_prehash;
75         (void)context;
76         (void)context_len;
77         return;
78     }
79 #endif
80     const char *dom_s = "SigEd448";
81     const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len};
82     hash_update(hash,(const unsigned char *)dom_s, strlen(dom_s));
83     hash_update(hash,dom,2);
84     hash_update(hash,context,context_len);
85 }
86
87 void decaf_ed448_prehash_init (
88     hash_ctx_t hash
89 ) {
90     hash_init(hash);
91 }
92
93 /* In this file because it uses the hash */
94 void decaf_ed448_convert_private_key_to_x448 (
95     uint8_t x[DECAF_X448_PRIVATE_BYTES],
96     const uint8_t ed[DECAF_EDDSA_448_PRIVATE_BYTES]
97 ) {
98     /* pass the private key through hash_hash function */
99     /* and keep the first DECAF_X448_PRIVATE_BYTES bytes */
100     hash_hash(
101         x,
102         DECAF_X448_PRIVATE_BYTES,
103         ed,
104         DECAF_EDDSA_448_PRIVATE_BYTES
105     );
106 }
107     
108 void decaf_ed448_derive_public_key (
109     uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES],
110     const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES]
111 ) {
112     /* only this much used for keygen */
113     uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES];
114     
115     hash_hash(
116         secret_scalar_ser,
117         sizeof(secret_scalar_ser),
118         privkey,
119         DECAF_EDDSA_448_PRIVATE_BYTES
120     );
121     clamp(secret_scalar_ser);
122         
123     curve448_scalar_t secret_scalar;
124     curve448_scalar_decode_long(secret_scalar, secret_scalar_ser, sizeof(secret_scalar_ser));
125     
126     /* Since we are going to mul_by_cofactor during encoding, divide by it here.
127      * However, the EdDSA base point is not the same as the decaf base point if
128      * the sigma isogeny is in use: the EdDSA base point is on Etwist_d/(1-d) and
129      * the decaf base point is on Etwist_d, and when converted it effectively
130      * picks up a factor of 2 from the isogenies.  So we might start at 2 instead of 1. 
131      */
132     for (unsigned int c=1; c<DECAF_448_EDDSA_ENCODE_RATIO; c <<= 1) {
133         curve448_scalar_halve(secret_scalar,secret_scalar);
134     }
135     
136     curve448_point_t p;
137     curve448_precomputed_scalarmul(p,curve448_precomputed_base,secret_scalar);
138     
139     curve448_point_mul_by_ratio_and_encode_like_eddsa(pubkey, p);
140         
141     /* Cleanup */
142     curve448_scalar_destroy(secret_scalar);
143     curve448_point_destroy(p);
144     OPENSSL_cleanse(secret_scalar_ser, sizeof(secret_scalar_ser));
145 }
146
147 void decaf_ed448_sign (
148     uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES],
149     const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES],
150     const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES],
151     const uint8_t *message,
152     size_t message_len,
153     uint8_t prehashed,
154     const uint8_t *context,
155     uint8_t context_len
156 ) {
157     curve448_scalar_t secret_scalar;
158     hash_ctx_t hash;
159     {
160         /* Schedule the secret key */
161         struct {
162             uint8_t secret_scalar_ser[DECAF_EDDSA_448_PRIVATE_BYTES];
163             uint8_t seed[DECAF_EDDSA_448_PRIVATE_BYTES];
164         } __attribute__((packed)) expanded;
165         hash_hash(
166             (uint8_t *)&expanded,
167             sizeof(expanded),
168             privkey,
169             DECAF_EDDSA_448_PRIVATE_BYTES
170         );
171         clamp(expanded.secret_scalar_ser);   
172         curve448_scalar_decode_long(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser));
173     
174         /* Hash to create the nonce */
175         hash_init_with_dom(hash,prehashed,0,context,context_len);
176         hash_update(hash,expanded.seed,sizeof(expanded.seed));
177         hash_update(hash,message,message_len);
178         OPENSSL_cleanse(&expanded, sizeof(expanded));
179     }
180     
181     /* Decode the nonce */
182     curve448_scalar_t nonce_scalar;
183     {
184         uint8_t nonce[2*DECAF_EDDSA_448_PRIVATE_BYTES];
185         hash_final(hash,nonce,sizeof(nonce));
186         curve448_scalar_decode_long(nonce_scalar, nonce, sizeof(nonce));
187         OPENSSL_cleanse(nonce, sizeof(nonce));
188     }
189     
190     uint8_t nonce_point[DECAF_EDDSA_448_PUBLIC_BYTES] = {0};
191     {
192         /* Scalarmul to create the nonce-point */
193         curve448_scalar_t nonce_scalar_2;
194         curve448_scalar_halve(nonce_scalar_2,nonce_scalar);
195         for (unsigned int c = 2; c < DECAF_448_EDDSA_ENCODE_RATIO; c <<= 1) {
196             curve448_scalar_halve(nonce_scalar_2,nonce_scalar_2);
197         }
198         
199         curve448_point_t p;
200         curve448_precomputed_scalarmul(p,curve448_precomputed_base,nonce_scalar_2);
201         curve448_point_mul_by_ratio_and_encode_like_eddsa(nonce_point, p);
202         curve448_point_destroy(p);
203         curve448_scalar_destroy(nonce_scalar_2);
204     }
205     
206     curve448_scalar_t challenge_scalar;
207     {
208         /* Compute the challenge */
209         hash_init_with_dom(hash,prehashed,0,context,context_len);
210         hash_update(hash,nonce_point,sizeof(nonce_point));
211         hash_update(hash,pubkey,DECAF_EDDSA_448_PUBLIC_BYTES);
212         hash_update(hash,message,message_len);
213         uint8_t challenge[2*DECAF_EDDSA_448_PRIVATE_BYTES];
214         hash_final(hash,challenge,sizeof(challenge));
215         hash_destroy(hash);
216         curve448_scalar_decode_long(challenge_scalar,challenge,sizeof(challenge));
217         OPENSSL_cleanse(challenge,sizeof(challenge));
218     }
219     
220     curve448_scalar_mul(challenge_scalar,challenge_scalar,secret_scalar);
221     curve448_scalar_add(challenge_scalar,challenge_scalar,nonce_scalar);
222     
223     OPENSSL_cleanse(signature,DECAF_EDDSA_448_SIGNATURE_BYTES);
224     memcpy(signature,nonce_point,sizeof(nonce_point));
225     curve448_scalar_encode(&signature[DECAF_EDDSA_448_PUBLIC_BYTES],challenge_scalar);
226     
227     curve448_scalar_destroy(secret_scalar);
228     curve448_scalar_destroy(nonce_scalar);
229     curve448_scalar_destroy(challenge_scalar);
230 }
231
232
233 void decaf_ed448_sign_prehash (
234     uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES],
235     const uint8_t privkey[DECAF_EDDSA_448_PRIVATE_BYTES],
236     const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES],
237     const decaf_ed448_prehash_ctx_t hash,
238     const uint8_t *context,
239     uint8_t context_len
240 ) {
241     uint8_t hash_output[EDDSA_PREHASH_BYTES];
242     {
243         decaf_ed448_prehash_ctx_t hash_too;
244         memcpy(hash_too,hash,sizeof(hash_too));
245         hash_final(hash_too,hash_output,sizeof(hash_output));
246         hash_destroy(hash_too);
247     }
248
249     decaf_ed448_sign(signature,privkey,pubkey,hash_output,sizeof(hash_output),1,context,context_len);
250     OPENSSL_cleanse(hash_output,sizeof(hash_output));
251 }
252
253 decaf_error_t decaf_ed448_verify (
254     const uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES],
255     const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES],
256     const uint8_t *message,
257     size_t message_len,
258     uint8_t prehashed,
259     const uint8_t *context,
260     uint8_t context_len
261 ) { 
262     curve448_point_t pk_point, r_point;
263     decaf_error_t error = curve448_point_decode_like_eddsa_and_mul_by_ratio(pk_point,pubkey);
264     if (DECAF_SUCCESS != error) { return error; }
265     
266     error = curve448_point_decode_like_eddsa_and_mul_by_ratio(r_point,signature);
267     if (DECAF_SUCCESS != error) { return error; }
268     
269     curve448_scalar_t challenge_scalar;
270     {
271         /* Compute the challenge */
272         hash_ctx_t hash;
273         hash_init_with_dom(hash,prehashed,0,context,context_len);
274         hash_update(hash,signature,DECAF_EDDSA_448_PUBLIC_BYTES);
275         hash_update(hash,pubkey,DECAF_EDDSA_448_PUBLIC_BYTES);
276         hash_update(hash,message,message_len);
277         uint8_t challenge[2*DECAF_EDDSA_448_PRIVATE_BYTES];
278         hash_final(hash,challenge,sizeof(challenge));
279         hash_destroy(hash);
280         curve448_scalar_decode_long(challenge_scalar,challenge,sizeof(challenge));
281         OPENSSL_cleanse(challenge,sizeof(challenge));
282     }
283     curve448_scalar_sub(challenge_scalar, curve448_scalar_zero, challenge_scalar);
284     
285     curve448_scalar_t response_scalar;
286     curve448_scalar_decode_long(
287         response_scalar,
288         &signature[DECAF_EDDSA_448_PUBLIC_BYTES],
289         DECAF_EDDSA_448_PRIVATE_BYTES
290     );
291     
292     for (unsigned c=1; c<DECAF_448_EDDSA_DECODE_RATIO; c<<=1) {
293         curve448_scalar_add(response_scalar,response_scalar,response_scalar);
294     }
295     
296     
297     /* pk_point = -c(x(P)) + (cx + k)G = kG */
298     curve448_base_double_scalarmul_non_secret(
299         pk_point,
300         response_scalar,
301         pk_point,
302         challenge_scalar
303     );
304     return decaf_succeed_if(curve448_point_eq(pk_point,r_point));
305 }
306
307
308 decaf_error_t decaf_ed448_verify_prehash (
309     const uint8_t signature[DECAF_EDDSA_448_SIGNATURE_BYTES],
310     const uint8_t pubkey[DECAF_EDDSA_448_PUBLIC_BYTES],
311     const decaf_ed448_prehash_ctx_t hash,
312     const uint8_t *context,
313     uint8_t context_len
314 ) {
315     decaf_error_t ret;
316     
317     uint8_t hash_output[EDDSA_PREHASH_BYTES];
318     {
319         decaf_ed448_prehash_ctx_t hash_too;
320         memcpy(hash_too,hash,sizeof(hash_too));
321         hash_final(hash_too,hash_output,sizeof(hash_output));
322         hash_destroy(hash_too);
323     }
324     
325     ret = decaf_ed448_verify(signature,pubkey,hash_output,sizeof(hash_output),1,context,context_len);
326     
327     return ret;
328 }