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