Import Curve 448 support
[openssl.git] / crypto / ec / curve448 / GENERATED / c / ed448goldilocks / 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 "word.h"
16 #include <decaf/ed448.h>
17 #include <decaf/shake.h>
18 #include <decaf/sha512.h>
19 #include <string.h>
20
21 #define API_NAME "decaf_448"
22 #define API_NS(_id) decaf_448_##_id
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     API_NS(scalar_t) secret_scalar;
124     API_NS(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         API_NS(scalar_halve)(secret_scalar,secret_scalar);
134     }
135     
136     API_NS(point_t) p;
137     API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),secret_scalar);
138     
139     API_NS(point_mul_by_ratio_and_encode_like_eddsa)(pubkey, p);
140         
141     /* Cleanup */
142     API_NS(scalar_destroy)(secret_scalar);
143     API_NS(point_destroy)(p);
144     decaf_bzero(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     API_NS(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         API_NS(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         decaf_bzero(&expanded, sizeof(expanded));
179     }
180     
181     /* Decode the nonce */
182     API_NS(scalar_t) nonce_scalar;
183     {
184         uint8_t nonce[2*DECAF_EDDSA_448_PRIVATE_BYTES];
185         hash_final(hash,nonce,sizeof(nonce));
186         API_NS(scalar_decode_long)(nonce_scalar, nonce, sizeof(nonce));
187         decaf_bzero(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         API_NS(scalar_t) nonce_scalar_2;
194         API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar);
195         for (unsigned int c = 2; c < DECAF_448_EDDSA_ENCODE_RATIO; c <<= 1) {
196             API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2);
197         }
198         
199         API_NS(point_t) p;
200         API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2);
201         API_NS(point_mul_by_ratio_and_encode_like_eddsa)(nonce_point, p);
202         API_NS(point_destroy)(p);
203         API_NS(scalar_destroy)(nonce_scalar_2);
204     }
205     
206     API_NS(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         API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge));
217         decaf_bzero(challenge,sizeof(challenge));
218     }
219     
220     API_NS(scalar_mul)(challenge_scalar,challenge_scalar,secret_scalar);
221     API_NS(scalar_add)(challenge_scalar,challenge_scalar,nonce_scalar);
222     
223     decaf_bzero(signature,DECAF_EDDSA_448_SIGNATURE_BYTES);
224     memcpy(signature,nonce_point,sizeof(nonce_point));
225     API_NS(scalar_encode)(&signature[DECAF_EDDSA_448_PUBLIC_BYTES],challenge_scalar);
226     
227     API_NS(scalar_destroy)(secret_scalar);
228     API_NS(scalar_destroy)(nonce_scalar);
229     API_NS(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     decaf_bzero(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     API_NS(point_t) pk_point, r_point;
263     decaf_error_t error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(pk_point,pubkey);
264     if (DECAF_SUCCESS != error) { return error; }
265     
266     error = API_NS(point_decode_like_eddsa_and_mul_by_ratio)(r_point,signature);
267     if (DECAF_SUCCESS != error) { return error; }
268     
269     API_NS(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         API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge));
281         decaf_bzero(challenge,sizeof(challenge));
282     }
283     API_NS(scalar_sub)(challenge_scalar, API_NS(scalar_zero), challenge_scalar);
284     
285     API_NS(scalar_t) response_scalar;
286     API_NS(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         API_NS(scalar_add)(response_scalar,response_scalar,response_scalar);
294     }
295     
296     
297     /* pk_point = -c(x(P)) + (cx + k)G = kG */
298     API_NS(base_double_scalarmul_non_secret)(
299         pk_point,
300         response_scalar,
301         pk_point,
302         challenge_scalar
303     );
304     return decaf_succeed_if(API_NS(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 }