1 /*
2 * Copyright (C) 2021 - This file is part of libecc project
3 *
4 * Authors:
5 * Ryad BENADJILA <ryadbenadjila@gmail.com>
6 * Arnaud EBALARD <arnaud.ebalard@ssi.gouv.fr>
7 *
8 * This software is licensed under a dual BSD and GPL v2 license.
9 * See LICENSE file at the root folder of the project.
10 */
11 #include "kcdsa.h"
12
13 /* We include the rand external dependency because we have to generate
14 * some random data for the nonces.
15 */
16 #include <libecc/external_deps/rand.h>
17 /* We include the printf external dependency for printf output */
18 #include <libecc/external_deps/print.h>
19 /* We include our common helpers */
20 #include "../common/common.h"
21
22 /*
23 * The purpose of this example is to implement the KCDSA signature scheme
24 * based on libecc arithmetic primitives, as described in the ISO14888-3
25 * standard.
26 *
27 * XXX: Please be aware that libecc has been designed for Elliptic
28 * Curve cryptography, and as so the arithmetic primitives are
29 * not optimized for big numbers >= 1024 bits usually used for KCDSA.
30 * Additionnaly, a hard limit of our NN values makes it impossible
31 * to exceed ~5300 bits in the best case (words of size 64 bits).
32 *
33 * All in all, please see this as a proof of concept.
34 * Use it at your own risk!
35 *
36 * !! DISCLAIMER !!
37 * ================
38 *
39 * Althoug some efforts have been made to secure this implementation
40 * of KCDSA (e.g. by protecting the private key and nonces using constant
41 * time and blinding WHEN activated with BLINDING=1), please consider this
42 * code as a proof of concept and use it at your own risk.
43 *
44 * All-in-all, this piece of code can be useful in some contexts, or risky to
45 * use in other sensitive ones where advanced side-channels or fault attacks
46 * have to be considered. Use this KCDSA code knowingly and at your own risk!
47 *
48 */
49
50 /* NOTE: since KCDSA is very similar to DSA, we reuse some of our DSA
51 * primitives to factorize some code. Also, KCDSA private and public keys
52 * have the exact same type as DSA keys.
53 */
54
55 /* Import a KCDSA private key from buffers */
kcdsa_import_priv_key(kcdsa_priv_key * priv,const u8 * p,u16 plen,const u8 * q,u16 qlen,const u8 * g,u16 glen,const u8 * x,u16 xlen)56 int kcdsa_import_priv_key(kcdsa_priv_key *priv, const u8 *p, u16 plen,
57 const u8 *q, u16 qlen,
58 const u8 *g, u16 glen,
59 const u8 *x, u16 xlen)
60 {
61 return dsa_import_priv_key(priv, p, plen, q, qlen, g, glen, x, xlen);
62 }
63
64 /* Import a KCDSA public key from buffers */
kcdsa_import_pub_key(kcdsa_pub_key * pub,const u8 * p,u16 plen,const u8 * q,u16 qlen,const u8 * g,u16 glen,const u8 * y,u16 ylen)65 int kcdsa_import_pub_key(kcdsa_pub_key *pub, const u8 *p, u16 plen,
66 const u8 *q, u16 qlen,
67 const u8 *g, u16 glen,
68 const u8 *y, u16 ylen)
69 {
70 return dsa_import_pub_key(pub, p, plen, q, qlen, g, glen, y, ylen);
71 }
72
73
74
75 /* Compute a KCDSA public key from a private key.
76 * The public key is computed using modular exponentiation of the generator
77 * with the private key inverse.
78 */
kcdsa_compute_pub_from_priv(kcdsa_pub_key * pub,const kcdsa_priv_key * priv)79 int kcdsa_compute_pub_from_priv(kcdsa_pub_key *pub, const kcdsa_priv_key *priv)
80 {
81 int ret;
82 kcdsa_priv_key priv_;
83
84 MUST_HAVE((priv != NULL), ret, err);
85
86 ret = local_memcpy(&priv_, priv, sizeof(kcdsa_priv_key)); EG(ret, err);
87 /* Replace the x of the private key by its inverse */
88 ret = nn_modinv_fermat(&(priv_.x), &(priv_.x), &(priv_.q)); EG(ret, err);
89
90 /* Use the DSA computation with the computed inverse x */
91 ret = dsa_compute_pub_from_priv(pub, &priv_);
92
93 err:
94 IGNORE_RET_VAL(local_memset(&priv_, 0, sizeof(kcdsa_priv_key)));
95
96 return ret;
97 }
98
99
buf_lshift(u8 * buf,u16 buflen,u16 shift)100 ATTRIBUTE_WARN_UNUSED_RET static int buf_lshift(u8 *buf, u16 buflen, u16 shift)
101 {
102 u16 i;
103 int ret;
104
105 MUST_HAVE((buf != NULL), ret, err);
106
107 if (shift > buflen) {
108 shift = buflen;
109 }
110
111 /* Start by shifting all trailing bytes to the left ... */
112 for (i = shift; i < buflen; i++) {
113 buf[i - shift] = buf[i];
114 }
115
116 /* Let's now zeroize the end of the buffer ... */
117 for (i = 1; i <= shift; i++) {
118 buf[buflen - i] = 0;
119 }
120
121 ret = 0;
122
123 err:
124 return ret;
125 }
126
127 /* Generate a KCDSA signature
128 */
kcdsa_sign(const kcdsa_priv_key * priv,const u8 * msg,u32 msglen,const u8 * nonce,u16 noncelen,u8 * sig,u16 siglen,gen_hash_alg_type kcdsa_hash)129 int kcdsa_sign(const kcdsa_priv_key *priv, const u8 *msg, u32 msglen,
130 const u8 *nonce, u16 noncelen,
131 u8 *sig, u16 siglen, gen_hash_alg_type kcdsa_hash)
132 {
133 int ret, iszero;
134 u16 curr_rlen, curr_siglen;
135 /* alpha is the bit length of p, beta is the bit length of q */
136 bitcnt_t alpha, beta;
137 /* Length of the hash function (hlen is "gamma") */
138 u8 hlen, block_size;
139 nn_src_t p, q, g, x;
140 /* The public key for the witness */
141 kcdsa_pub_key pub;
142 nn_src_t y;
143 /* The nonce and its protected version */
144 nn k, k_;
145 /* r, s, pi */
146 nn r, s;
147 nn_t pi;
148 /* This is a bit too much for stack space, but we need it for
149 * the computation of "pi" I2BS representation ...
150 */
151 u8 pi_buf[NN_USABLE_MAX_BYTE_LEN];
152 /* hash context */
153 gen_hash_context hash_ctx;
154 u8 hash[MAX_DIGEST_SIZE];
155 #ifdef USE_SIG_BLINDING
156 /* b is the blinding mask */
157 nn b;
158 b.magic = WORD(0);
159 #endif /* USE_SIG_BLINDING */
160 k.magic = k_.magic = r.magic = s.magic = WORD(0);
161
162 /* Sanity checks */
163 MUST_HAVE((priv != NULL) && (msg != NULL) && (sig != NULL), ret, err);
164
165 ret = local_memset(&pub, 0, sizeof(kcdsa_pub_key)); EG(ret, err);
166 ret = local_memset(hash, 0, sizeof(hash)); EG(ret, err);
167 ret = local_memset(pi_buf, 0, sizeof(pi_buf)); EG(ret, err);
168
169 /* Make things more readable */
170 p = &(priv->p);
171 q = &(priv->q);
172 g = &(priv->g);
173 x = &(priv->x);
174
175 /* Sanity checks */
176 ret = nn_check_initialized(p); EG(ret, err);
177 ret = nn_check_initialized(q); EG(ret, err);
178 ret = nn_check_initialized(g); EG(ret, err);
179 ret = nn_check_initialized(x); EG(ret, err);
180
181 /* Let alpha be the bit length of p */
182 ret = nn_bitlen(p, &alpha); EG(ret, err);
183 /* Let beta be the bit length of q */
184 ret = nn_bitlen(q, &beta); EG(ret, err);
185 /* Get the hash sizes (8*"gamma") */
186 ret = gen_hash_get_hash_sizes(kcdsa_hash, &hlen, &block_size); EG(ret, err);
187 MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err);
188
189 /* Sanity check on the signature length:
190 * If "gamma" <= beta, length of R is "gamma", else length of R
191 * The signature size is either "gamma" + beta or 2 * beta
192 */
193 if(hlen <= (u16)BYTECEIL(beta)){
194 curr_rlen = hlen;
195 }
196 else{
197 curr_rlen = (u16)BYTECEIL(beta);
198 }
199 curr_siglen = (u16)(curr_rlen + BYTECEIL(beta));
200 MUST_HAVE((siglen == curr_siglen), ret, err);
201
202 /* Compute our public key for the witness */
203 ret = kcdsa_compute_pub_from_priv(&pub, priv); EG(ret, err);
204 y = &(pub.y);
205
206 restart:
207 /* If the nonce is imposed, use it. Else get a random modulo q */
208 if(nonce != NULL){
209 ret = _os2ip(&k, nonce, noncelen); EG(ret, err);
210 }
211 else{
212 ret = nn_get_random_mod(&k, q); EG(ret, err);
213 }
214
215 /* Fix the MSB of our scalar */
216 ret = nn_copy(&k_, &k); EG(ret, err);
217 #ifdef USE_SIG_BLINDING
218 /* Blind the scalar */
219 ret = _blind_scalar(&k_, q, &k_); EG(ret, err);
220 #endif /* USE_SIG_BLINDING */
221 ret = _fix_scalar_msb(&k_, q, &k_); EG(ret, err);
222 /* Use r as aliasing for pi to save some space */
223 pi = &r;
224 /* pi = (g**k mod p) */
225 ret = nn_init(pi, 0); EG(ret, err);
226 /* Exponentiation modulo p */
227 ret = nn_mod_pow(pi, g, &k_, p); EG(ret, err);
228
229 /* Compute I2BS(alpha, pi)
230 */
231 MUST_HAVE((sizeof(pi_buf) >= (u16)BYTECEIL(alpha)), ret, err);
232 ret = _i2osp(pi, pi_buf, (u16)BYTECEIL(alpha)); EG(ret, err);
233
234 if(hlen <= (u16)BYTECEIL(beta)){
235 unsigned int i;
236 /* r = h(I2BS(alpha, pi)) */
237 ret = gen_hash_init(&hash_ctx, kcdsa_hash); EG(ret, err);
238 ret = gen_hash_update(&hash_ctx, pi_buf, (u16)BYTECEIL(alpha), kcdsa_hash); EG(ret, err);
239 /* Export r result of the hash function in sig */
240 ret = gen_hash_final(&hash_ctx, sig, kcdsa_hash); EG(ret, err);
241 /* Compute v */
242 MUST_HAVE((block_size <= (u16)BYTECEIL(alpha)), ret, err);
243 ret = _i2osp(y, pi_buf, (u16)BYTECEIL(alpha)); EG(ret, err);
244 ret = buf_lshift(pi_buf, (u16)BYTECEIL(alpha), (u16)(BYTECEIL(alpha) - block_size)); EG(ret, err);
245 ret = gen_hash_init(&hash_ctx, kcdsa_hash); EG(ret, err);
246 ret = gen_hash_update(&hash_ctx, pi_buf, block_size, kcdsa_hash); EG(ret, err);
247 ret = gen_hash_update(&hash_ctx, msg, msglen, kcdsa_hash); EG(ret, err);
248 ret = gen_hash_final(&hash_ctx, hash, kcdsa_hash); EG(ret, err);
249 for(i = 0; i < hlen; i++){
250 hash[i] = (hash[i] ^ sig[i]);
251 }
252 ret = _os2ip(&s, hash, hlen); EG(ret, err);
253 }
254 else{
255 unsigned int i;
256 /* h(I2BS(alpha, pi)) */
257 ret = gen_hash_init(&hash_ctx, kcdsa_hash); EG(ret, err);
258 ret = gen_hash_update(&hash_ctx, pi_buf, (u16)BYTECEIL(alpha), kcdsa_hash); EG(ret, err);
259 /* Export r result of the hash function in sig ... */
260 ret = gen_hash_final(&hash_ctx, hash, kcdsa_hash); EG(ret, err);
261 /* ... and proceed with the appropriate tuncation */
262 ret = buf_lshift(hash, hlen, (u16)(hlen - BYTECEIL(beta))); EG(ret, err);
263 ret = local_memcpy(sig, hash, (u16)BYTECEIL(beta)); EG(ret, err);
264 /* Compute v */
265 MUST_HAVE((block_size <= (u16)BYTECEIL(alpha)), ret, err);
266 ret = _i2osp(y, pi_buf, (u16)BYTECEIL(alpha)); EG(ret, err);
267 ret = buf_lshift(pi_buf, (u16)BYTECEIL(alpha), (u16)(BYTECEIL(alpha) - block_size)); EG(ret, err);
268 ret = gen_hash_init(&hash_ctx, kcdsa_hash); EG(ret, err);
269 ret = gen_hash_update(&hash_ctx, pi_buf, block_size, kcdsa_hash); EG(ret, err);
270 ret = gen_hash_update(&hash_ctx, msg, msglen, kcdsa_hash); EG(ret, err);
271 ret = gen_hash_final(&hash_ctx, hash, kcdsa_hash); EG(ret, err);
272 /* ... and proceed with the appropriate tuncation */
273 ret = buf_lshift(hash, hlen, (u16)(hlen - BYTECEIL(beta))); EG(ret, err);
274 for(i = 0; i < (u16)BYTECEIL(beta); i++){
275 hash[i] = (hash[i] ^ sig[i]);
276 }
277 ret = _os2ip(&s, hash, (u16)BYTECEIL(beta)); EG(ret, err);
278 }
279
280 /* Reduce v modulo q */
281 ret = nn_mod(&s, &s, q); EG(ret, err);
282
283 #ifdef USE_SIG_BLINDING
284 /* Note: if we use blinding, v and k are multiplied by
285 * a random value b in ]0,q[ */
286 ret = nn_get_random_mod(&b, q); EG(ret, err);
287 /* Blind r with b */
288 ret = nn_mod_mul(&s, &s, &b, q); EG(ret, err);
289 /* Blind k with b */
290 ret = nn_mod_mul(&k, &k, &b, q); EG(ret, err);
291 /*
292 * In case of blinding, we compute b^-1 with
293 * little Fermat theorem. This will be used to
294 * unblind s.
295 */
296 ret = nn_modinv_fermat(&b, &b, q); EG(ret, err);
297 #endif /* USE_SIG_BLINDING */
298
299 /* Compute s = x (k - v) mod q */
300 ret = nn_mod_sub(&s, &k, &s, q); EG(ret, err);
301 ret = nn_mod_mul(&s, &s, x, q); EG(ret, err);
302
303 #ifdef USE_SIG_BLINDING
304 /* In case of blinding, unblind s */
305 ret = nn_mod_mul(&s, &s, &b, q); EG(ret, err);
306 #endif /* USE_SIG_BLINDING */
307 /* If s is 0, restart the process */
308 ret = nn_iszero(&s, &iszero); EG(ret, err);
309 if (iszero) {
310 goto restart;
311 }
312
313 /* Export s */
314 ret = _i2osp(&s, sig + curr_rlen, (u16)BYTECEIL(beta));
315
316 err:
317 if(ret && (sig != NULL)){
318 IGNORE_RET_VAL(local_memset(sig, 0, siglen));
319 }
320
321 IGNORE_RET_VAL(local_memset(&pub, 0, sizeof(kcdsa_pub_key)));
322
323 nn_uninit(&k);
324 nn_uninit(&k_);
325 #ifdef USE_SIG_BLINDING
326 nn_uninit(&b);
327 #endif
328 nn_uninit(&r);
329 nn_uninit(&s);
330
331 PTR_NULLIFY(pi);
332 PTR_NULLIFY(y);
333 PTR_NULLIFY(p);
334 PTR_NULLIFY(q);
335 PTR_NULLIFY(g);
336 PTR_NULLIFY(x);
337
338 return ret;
339 }
340
341
342
343 /* Verify a KCDSA signature
344 */
kcdsa_verify(const kcdsa_pub_key * pub,const u8 * msg,u32 msglen,const u8 * sig,u16 siglen,gen_hash_alg_type kcdsa_hash)345 int kcdsa_verify(const kcdsa_pub_key *pub, const u8 *msg, u32 msglen,
346 const u8 *sig, u16 siglen, gen_hash_alg_type kcdsa_hash)
347 {
348 int ret, iszero, cmp;
349 u16 curr_rlen, curr_siglen;
350 /* alpha is the bit length of p, beta is the bit length of q */
351 bitcnt_t alpha, beta;
352 /* Length of the hash function */
353 u8 hlen, block_size;
354 nn_src_t p, q, g, y;
355 /* s */
356 nn s;
357 /* u, v and pi */
358 nn u, v, pi;
359 /* This is a bit too much for stack space, but we need it for
360 * the computation of "pi" I2BS representation ...
361 */
362 u8 pi_buf[NN_USABLE_MAX_BYTE_LEN];
363 /* Hash */
364 u8 hash[MAX_DIGEST_SIZE];
365 /* hash context */
366 gen_hash_context hash_ctx;
367 s.magic = v.magic = u.magic = pi.magic = WORD(0);
368
369 /* Sanity checks */
370 MUST_HAVE((pub != NULL) && (msg != NULL) && (sig != NULL), ret, err);
371
372 ret = local_memset(pi_buf, 0, sizeof(pi_buf)); EG(ret, err);
373 ret = local_memset(hash, 0, sizeof(hash)); EG(ret, err);
374
375 /* Make things more readable */
376 p = &(pub->p);
377 q = &(pub->q);
378 g = &(pub->g);
379 y = &(pub->y);
380
381 /* Sanity checks */
382 ret = nn_check_initialized(p); EG(ret, err);
383 ret = nn_check_initialized(q); EG(ret, err);
384 ret = nn_check_initialized(g); EG(ret, err);
385 ret = nn_check_initialized(y); EG(ret, err);
386
387 /* Let alpha be the bit length of p */
388 ret = nn_bitlen(p, &alpha); EG(ret, err);
389 /* Let beta be the bit length of q */
390 ret = nn_bitlen(q, &beta); EG(ret, err);
391 /* Get the hash sizes (8*"gamma") */
392 ret = gen_hash_get_hash_sizes(kcdsa_hash, &hlen, &block_size); EG(ret, err);
393 MUST_HAVE((hlen <= MAX_DIGEST_SIZE), ret, err);
394
395 /* Sanity check on the signature length:
396 * If "gamma" <= beta, length of R is "gamma", else length of R
397 * The signature size is either "gamma" + beta or 2 * beta
398 */
399 if(hlen <= (u16)BYTECEIL(beta)){
400 curr_rlen = hlen;
401 }
402 else{
403 curr_rlen = (u16)BYTECEIL(beta);
404 }
405 curr_siglen = (u16)(curr_rlen + BYTECEIL(beta));
406 MUST_HAVE((siglen == curr_siglen), ret, err);
407
408 /* Extract s */
409 ret = _os2ip(&s, sig + curr_rlen, (u16)(siglen - curr_rlen)); EG(ret, err);
410
411 /* Return an error if s = 0 */
412 ret = nn_iszero(&s, &iszero); EG(ret, err);
413 MUST_HAVE((!iszero), ret, err);
414 /* Check that 0 < s < q */
415 ret = nn_cmp(&s, q, &cmp); EG(ret, err);
416 MUST_HAVE((cmp < 0), ret, err);
417
418 /* Initialize internal variables */
419 ret = nn_init(&u, 0); EG(ret, err);
420 ret = nn_init(&pi, 0); EG(ret, err);
421
422 /* Compute v */
423 if(hlen <= (u16)BYTECEIL(beta)){
424 unsigned int i;
425 /* r is of size hlen */
426 MUST_HAVE((block_size <= (u16)BYTECEIL(alpha)), ret, err);
427 ret = _i2osp(y, pi_buf, (u16)BYTECEIL(alpha)); EG(ret, err);
428 ret = buf_lshift(pi_buf, (u16)BYTECEIL(alpha), (u16)(BYTECEIL(alpha) - block_size)); EG(ret, err);
429 ret = gen_hash_init(&hash_ctx, kcdsa_hash); EG(ret, err);
430 ret = gen_hash_update(&hash_ctx, pi_buf, block_size, kcdsa_hash); EG(ret, err);
431 ret = gen_hash_update(&hash_ctx, msg, msglen, kcdsa_hash); EG(ret, err);
432 ret = gen_hash_final(&hash_ctx, hash, kcdsa_hash); EG(ret, err);
433 for(i = 0; i < hlen; i++){
434 hash[i] = (hash[i] ^ sig[i]);
435 }
436 ret = _os2ip(&v, hash, hlen); EG(ret, err);
437 }
438 else{
439 unsigned int i;
440 /* r is of size beta */
441 MUST_HAVE((block_size <= (u16)BYTECEIL(alpha)), ret, err);
442 ret = _i2osp(y, pi_buf, (u16)BYTECEIL(alpha)); EG(ret, err);
443 ret = buf_lshift(pi_buf, (u16)BYTECEIL(alpha), (u16)(BYTECEIL(alpha) - block_size)); EG(ret, err);
444 ret = gen_hash_init(&hash_ctx, kcdsa_hash); EG(ret, err);
445 ret = gen_hash_update(&hash_ctx, pi_buf, block_size, kcdsa_hash); EG(ret, err);
446 ret = gen_hash_update(&hash_ctx, msg, msglen, kcdsa_hash); EG(ret, err);
447 ret = gen_hash_final(&hash_ctx, hash, kcdsa_hash); EG(ret, err);
448 /* ... and proceed with the appropriate tuncation */
449 ret = buf_lshift(hash, hlen, (u16)(hlen - BYTECEIL(beta))); EG(ret, err);
450 for(i = 0; i < (u16)BYTECEIL(beta); i++){
451 hash[i] = (hash[i] ^ sig[i]);
452 }
453 ret = _os2ip(&v, hash, (u16)BYTECEIL(beta)); EG(ret, err);
454 }
455
456 /* Reduce v modulo q */
457 ret = nn_mod(&v, &v, q); EG(ret, err);
458
459 /* NOTE: no need to use a secure exponentiation here as we only
460 * manipulate public data.
461 */
462 /* Compute (y ** s) mod (p) */
463 ret = _nn_mod_pow_insecure(&u, y, &s, p); EG(ret, err);
464 /* Compute (g ** v) mod (p) */
465 ret = _nn_mod_pow_insecure(&pi, g, &v, p); EG(ret, err);
466 /* Compute (y ** s) (g ** v) mod (p) */
467 ret = nn_mod_mul(&pi, &pi, &u, p); EG(ret, err);
468
469 /* Compute I2BS(alpha, pi)
470 */
471 MUST_HAVE((sizeof(pi_buf) >= (u16)BYTECEIL(alpha)), ret, err);
472 ret = _i2osp(&pi, pi_buf, (u16)BYTECEIL(alpha)); EG(ret, err);
473
474 if(hlen <= (u16)BYTECEIL(beta)){
475 /* r = h(I2BS(alpha, pi)) */
476 ret = gen_hash_init(&hash_ctx, kcdsa_hash); EG(ret, err);
477 ret = gen_hash_update(&hash_ctx, pi_buf, (u16)BYTECEIL(alpha), kcdsa_hash); EG(ret, err);
478 /* Export r result of the hash function in sig */
479 ret = gen_hash_final(&hash_ctx, hash, kcdsa_hash); EG(ret, err);
480 }
481 else{
482 /* h(I2BS(alpha, pi)) */
483 ret = gen_hash_init(&hash_ctx, kcdsa_hash); EG(ret, err);
484 ret = gen_hash_update(&hash_ctx, pi_buf, (u16)BYTECEIL(alpha), kcdsa_hash); EG(ret, err);
485 /* Export r result of the hash function in sig ... */
486 ret = gen_hash_final(&hash_ctx, hash, kcdsa_hash); EG(ret, err);
487 /* ... and proceed with the appropriate tuncation */
488 ret = buf_lshift(hash, hlen, (u16)(hlen - BYTECEIL(beta))); EG(ret, err);
489 }
490
491 /* Now check that r == r' */
492 ret = are_equal(sig, hash, curr_rlen, &cmp); EG(ret, err);
493 ret = (cmp != 1) ? -1 : 0;
494
495 err:
496 nn_uninit(&s);
497 nn_uninit(&u);
498 nn_uninit(&v);
499 nn_uninit(&pi);
500
501 PTR_NULLIFY(p);
502 PTR_NULLIFY(q);
503 PTR_NULLIFY(g);
504 PTR_NULLIFY(y);
505
506 return ret;
507 }
508
509 #ifdef KCDSA
510 #include <libecc/utils/print_buf.h>
main(int argc,char * argv[])511 int main(int argc, char *argv[])
512 {
513 int ret = 0;
514
515 #if 0
516 /* This example is taken from ISO14888-3 KCDSA (Appendix F "Numerical examples" */
517 const u8 p[] = {
518 0x8D, 0xA8, 0xC1, 0xB5, 0xC9, 0x5D, 0x11, 0xBE, 0x46, 0x66, 0x1D, 0xF5, 0x8C, 0x9F, 0x80, 0x3E, 0xB7, 0x29, 0xB8, 0x00, 0xDD, 0x92, 0x75, 0x1B,
519 0x3A, 0x4F, 0x10, 0xC6, 0xA5, 0x44, 0x8E, 0x9F, 0x3B, 0xC0, 0xE9, 0x16, 0xF0, 0x42, 0xE3, 0x99, 0xB3, 0x4A, 0xF9, 0xBE, 0xE5, 0x82, 0xCC, 0xFC,
520 0x3F, 0xF5, 0x00, 0x0C, 0xFF, 0x23, 0x56, 0x94, 0x94, 0x35, 0x1C, 0xFE, 0xA5, 0x52, 0x9E, 0xA3, 0x47, 0xDC, 0xF4, 0x3F, 0x30, 0x2F, 0x58, 0x94,
521 0x38, 0x07, 0x09, 0xEA, 0x2E, 0x1C, 0x41, 0x6B, 0x51, 0xA5, 0xCD, 0xFC, 0x75, 0x93, 0xB1, 0x8B, 0x7E, 0x37, 0x88, 0xD5, 0x1B, 0x9C, 0xC9, 0xAE,
522 0x82, 0x8B, 0x4F, 0x8F, 0xB0, 0x6E, 0x0E, 0x90, 0x57, 0xF7, 0xFA, 0x0F, 0x93, 0xBB, 0x03, 0x97, 0x03, 0x1F, 0xE7, 0xD5, 0x0A, 0x68, 0x28, 0xDA,
523 0x0C, 0x11, 0x60, 0xA0, 0xE6, 0x6D, 0x4E, 0x5D, 0x2A, 0x18, 0xAD, 0x17, 0xA8, 0x11, 0xE7, 0x0B, 0x14, 0xF4, 0xF4, 0x31, 0x1A, 0x02, 0x82, 0x60,
524 0x32, 0x33, 0x44, 0x4F, 0x98, 0x76, 0x3C, 0x5A, 0x1E, 0x82, 0x9C, 0x76, 0x4C, 0xF3, 0x6A, 0xDB, 0x56, 0x98, 0x0B, 0xD4, 0xC5, 0x4B, 0xBE, 0x29,
525 0x7E, 0x79, 0x02, 0x28, 0x42, 0x92, 0xD7, 0x5C, 0xA3, 0x60, 0x0F, 0xF4, 0x59, 0x31, 0x0B, 0x09, 0x29, 0x1C, 0xBE, 0xFB, 0xC7, 0x21, 0x52, 0x8A,
526 0x13, 0x40, 0x3B, 0x8B, 0x93, 0xB7, 0x11, 0xC3, 0x03, 0xA2, 0x18, 0x2B, 0x6E, 0x63, 0x97, 0xE0, 0x83, 0x38, 0x0B, 0xF2, 0x88, 0x6A, 0xF3, 0xB9,
527 0xAF, 0xCC, 0x9F, 0x50, 0x55, 0xD8, 0xB7, 0x13, 0x6C, 0x0E, 0xBD, 0x08, 0xC5, 0xCF, 0x0B, 0x38, 0x88, 0x8C, 0xD1, 0x15, 0x72, 0x78, 0x7F, 0x6D,
528 0xF3, 0x84, 0xC9, 0x7C, 0x91, 0xB5, 0x8C, 0x31, 0xDE, 0xE5, 0x65, 0x5E, 0xCB, 0xF3, 0xFA, 0x53,
529 };
530
531 const u8 q[] = {
532 0x86, 0x4F, 0x18, 0x84, 0x1E, 0xC1, 0x03, 0xCD, 0xFD, 0x1B, 0xE7, 0xFE, 0xE5, 0x46, 0x50, 0xF2, 0x2A, 0x3B, 0xB9, 0x97, 0x53, 0x7F, 0x32, 0xCC,
533 0x79, 0xA5, 0x1F, 0x53,
534 };
535
536 const u8 g[] = {
537 0x0E, 0x9B, 0xE1, 0xF8, 0x7A, 0x41, 0x4D, 0x16, 0x7A, 0x9A, 0x5A, 0x96, 0x8B, 0x07, 0x9E, 0x4A, 0xD3, 0x85, 0xA3, 0x57, 0x3E, 0xDB, 0x21, 0xAA,
538 0x67, 0xA6, 0xF6, 0x1C, 0x0D, 0x00, 0xC1, 0x4A, 0x7A, 0x22, 0x50, 0x44, 0xB6, 0xE9, 0xEB, 0x03, 0x68, 0xC1, 0xEB, 0x57, 0xB2, 0x4B, 0x45, 0xCD,
539 0x85, 0x4F, 0xD9, 0x3C, 0x1B, 0x2D, 0xFB, 0x0A, 0x3E, 0xA3, 0x02, 0xD2, 0x36, 0x7E, 0x4E, 0xC7, 0x2F, 0x6E, 0x7E, 0xE8, 0xEA, 0x7F, 0x80, 0x02,
540 0xF7, 0x70, 0x4E, 0x99, 0x0B, 0x95, 0x4F, 0x25, 0xBA, 0xDA, 0x8D, 0xA6, 0x2B, 0xAE, 0xB6, 0xF0, 0x69, 0x53, 0xC0, 0xC8, 0x51, 0x04, 0xAD, 0x03,
541 0xF3, 0x66, 0x18, 0xF7, 0x6C, 0x62, 0xF4, 0xEC, 0xF3, 0x48, 0x01, 0x83, 0x69, 0x85, 0x0A, 0x56, 0x17, 0xC9, 0x99, 0xDB, 0xE6, 0x8B, 0xA1, 0x7D,
542 0x5B, 0xC7, 0x25, 0x56, 0x74, 0xEF, 0x48, 0x39, 0x22, 0xC6, 0xA3, 0xF9, 0x9D, 0x3C, 0x3C, 0x6F, 0x35, 0x88, 0x96, 0xC4, 0xE6, 0x3C, 0x60, 0x5E,
543 0xE7, 0xDB, 0x16, 0xFC, 0xBD, 0x9B, 0xE3, 0x54, 0xE2, 0x81, 0xF7, 0xFE, 0x78, 0x13, 0xD0, 0x54, 0x27, 0xED, 0x19, 0x12, 0xB5, 0xC7, 0x65, 0x3A,
544 0x16, 0x7B, 0x94, 0x34, 0x91, 0x47, 0xEE, 0xAF, 0x85, 0xCC, 0x9C, 0xE2, 0xE8, 0x16, 0x61, 0xF3, 0x21, 0x51, 0x2D, 0x5D, 0x2C, 0x05, 0x80, 0xB0,
545 0x3D, 0x17, 0x04, 0xEE, 0xF2, 0x31, 0x7F, 0x45, 0x18, 0x5C, 0x82, 0x58, 0x38, 0x7E, 0x7E, 0xC9, 0x79, 0xC0, 0x47, 0x07, 0xEF, 0x54, 0x62, 0x41,
546 0x27, 0x84, 0xAF, 0xE4, 0x1A, 0x7B, 0x45, 0xC8, 0x3B, 0x9C, 0xBE, 0x48, 0xF9, 0x12, 0x7C, 0xB4, 0x40, 0x0B, 0xE9, 0xE9, 0x6A, 0xC5, 0xDE, 0x17,
547 0xF2, 0xC9, 0xDE, 0xA3, 0x5E, 0x37, 0x34, 0xE7, 0x9B, 0x64, 0x67, 0x3F, 0x85, 0x68, 0x1C, 0x4E,
548 };
549
550 const u8 x[] = {
551 0x2F, 0x19, 0x91, 0xC1, 0xAF, 0x40, 0x18, 0x72, 0x8A, 0x5A, 0x43, 0x1B, 0x9B, 0x54, 0x59, 0xDF, 0xB1, 0x6F, 0x6D, 0x25, 0x67, 0x97, 0xFE, 0x57,
552 0x0E, 0xC6, 0xBC, 0x65,
553 };
554
555 const u8 y[] = {
556 0x04, 0xED, 0xE5, 0xC6, 0x7E, 0xA2, 0x92, 0x97, 0xA8, 0xCA, 0xCB, 0x6B, 0xDE, 0x6F, 0x46, 0x66, 0xAE, 0xA2, 0x7D, 0x10, 0x3D, 0xD1, 0xE9, 0xE9,
557 0x58, 0x2F, 0x76, 0xA2, 0xF2, 0x2B, 0x8B, 0x1B, 0x32, 0x23, 0x0B, 0xC5, 0x8F, 0x06, 0xB7, 0x68, 0xF8, 0x10, 0x2B, 0x49, 0xFA, 0x1C, 0xAE, 0x5E,
558 0x18, 0x92, 0x14, 0x94, 0x7F, 0x62, 0x39, 0xB6, 0xC6, 0xCE, 0x7C, 0x9B, 0xC2, 0xD2, 0x30, 0xE8, 0x9A, 0x40, 0xBE, 0xE2, 0xC3, 0x3A, 0x88, 0x61,
559 0xFD, 0x4F, 0x7D, 0x35, 0xB7, 0x88, 0xFE, 0x95, 0xB2, 0xD5, 0x88, 0x5D, 0x8C, 0x8F, 0xAE, 0xA8, 0x1C, 0x90, 0xBE, 0x4C, 0xEE, 0x27, 0x84, 0xE3,
560 0x35, 0x77, 0xA7, 0x1D, 0x3B, 0x7F, 0x08, 0x5D, 0x71, 0xE9, 0xA1, 0xD4, 0x78, 0x15, 0xC7, 0x3F, 0xA0, 0x87, 0xAC, 0xAA, 0xB9, 0xFC, 0xB5, 0x65,
561 0x5A, 0xC9, 0x57, 0x0E, 0x68, 0x52, 0xBE, 0x7C, 0x9C, 0x0A, 0xEC, 0xEA, 0x8B, 0xD9, 0xAA, 0x75, 0xA4, 0x4F, 0xC3, 0x14, 0x7F, 0x73, 0x3E, 0x90,
562 0x6A, 0xDB, 0x0F, 0xD7, 0x6D, 0x61, 0x35, 0x61, 0xB1, 0xDB, 0x36, 0x4B, 0xBD, 0xC9, 0xAF, 0xD3, 0xCE, 0x8F, 0x5F, 0x17, 0xE3, 0xE7, 0x12, 0x03,
563 0x4A, 0x99, 0x93, 0x50, 0x80, 0x59, 0xFA, 0x52, 0x44, 0x1F, 0xA9, 0x0D, 0xDF, 0xE9, 0xA0, 0xF2, 0xA0, 0xB9, 0x19, 0x2F, 0xE2, 0x22, 0x0C, 0x08,
564 0x1B, 0xD0, 0xC0, 0xF0, 0xE0, 0x7C, 0xB5, 0xF1, 0xEE, 0x4F, 0xF4, 0x05, 0x23, 0x59, 0x1F, 0x17, 0x8A, 0x4F, 0xC7, 0xCB, 0x50, 0x65, 0xF6, 0xA3,
565 0x82, 0x16, 0xE9, 0xA0, 0x99, 0xC2, 0x05, 0xB2, 0x9B, 0x87, 0x46, 0xD8, 0x65, 0xE1, 0xAF, 0x6D, 0x90, 0x3E, 0x5A, 0x13, 0x80, 0x04, 0x91, 0x0B,
566 0x70, 0xEB, 0x5B, 0x84, 0xEE, 0xD9, 0x76, 0x0E, 0xA6, 0x05, 0x78, 0xBF, 0x08, 0x85, 0x28, 0x98,
567 };
568
569 const u8 msg[] = "This is a test message for KCDSA usage!";
570
571 const u8 nonce[] = {
572 0x49, 0x56, 0x19, 0x94, 0xFD, 0x2B, 0xAD, 0x5E, 0x41, 0x0C, 0xA1, 0xC1, 0x5C, 0x3F, 0xD3, 0xF1, 0x2E, 0x70, 0x26, 0x3F, 0x28, 0x20, 0xAD, 0x5C,
573 0x56, 0x6D, 0xED, 0x80,
574 };
575 u8 sig[28*2] = { 0 };
576 gen_hash_alg_type kcdsa_hash = HASH_SHA224;
577 #endif
578
579 #if 0
580 /* This example is taken from ISO14888-3 KCDSA (Appendix F "Numerical examples" */
581 const u8 p[] = {
582 0x8D, 0xA8, 0xC1, 0xB5, 0xC9, 0x5D, 0x11, 0xBE, 0x46, 0x66, 0x1D, 0xF5, 0x8C, 0x9F, 0x80, 0x3E, 0xB7, 0x29, 0xB8, 0x00, 0xDD, 0x92, 0x75, 0x1B,
583 0x3A, 0x4F, 0x10, 0xC6, 0xA5, 0x44, 0x8E, 0x9F, 0x3B, 0xC0, 0xE9, 0x16, 0xF0, 0x42, 0xE3, 0x99, 0xB3, 0x4A, 0xF9, 0xBE, 0xE5, 0x82, 0xCC, 0xFC,
584 0x3F, 0xF5, 0x00, 0x0C, 0xFF, 0x23, 0x56, 0x94, 0x94, 0x35, 0x1C, 0xFE, 0xA5, 0x52, 0x9E, 0xA3, 0x47, 0xDC, 0xF4, 0x3F, 0x30, 0x2F, 0x58, 0x94,
585 0x38, 0x07, 0x09, 0xEA, 0x2E, 0x1C, 0x41, 0x6B, 0x51, 0xA5, 0xCD, 0xFC, 0x75, 0x93, 0xB1, 0x8B, 0x7E, 0x37, 0x88, 0xD5, 0x1B, 0x9C, 0xC9, 0xAE,
586 0x82, 0x8B, 0x4F, 0x8F, 0xB0, 0x6E, 0x0E, 0x90, 0x57, 0xF7, 0xFA, 0x0F, 0x93, 0xBB, 0x03, 0x97, 0x03, 0x1F, 0xE7, 0xD5, 0x0A, 0x68, 0x28, 0xDA,
587 0x0C, 0x11, 0x60, 0xA0, 0xE6, 0x6D, 0x4E, 0x5D, 0x2A, 0x18, 0xAD, 0x17, 0xA8, 0x11, 0xE7, 0x0B, 0x14, 0xF4, 0xF4, 0x31, 0x1A, 0x02, 0x82, 0x60,
588 0x32, 0x33, 0x44, 0x4F, 0x98, 0x76, 0x3C, 0x5A, 0x1E, 0x82, 0x9C, 0x76, 0x4C, 0xF3, 0x6A, 0xDB, 0x56, 0x98, 0x0B, 0xD4, 0xC5, 0x4B, 0xBE, 0x29,
589 0x7E, 0x79, 0x02, 0x28, 0x42, 0x92, 0xD7, 0x5C, 0xA3, 0x60, 0x0F, 0xF4, 0x59, 0x31, 0x0B, 0x09, 0x29, 0x1C, 0xBE, 0xFB, 0xC7, 0x21, 0x52, 0x8A,
590 0x13, 0x40, 0x3B, 0x8B, 0x93, 0xB7, 0x11, 0xC3, 0x03, 0xA2, 0x18, 0x2B, 0x6E, 0x63, 0x97, 0xE0, 0x83, 0x38, 0x0B, 0xF2, 0x88, 0x6A, 0xF3, 0xB9,
591 0xAF, 0xCC, 0x9F, 0x50, 0x55, 0xD8, 0xB7, 0x13, 0x6C, 0x0E, 0xBD, 0x08, 0xC5, 0xCF, 0x0B, 0x38, 0x88, 0x8C, 0xD1, 0x15, 0x72, 0x78, 0x7F, 0x6D,
592 0xF3, 0x84, 0xC9, 0x7C, 0x91, 0xB5, 0x8C, 0x31, 0xDE, 0xE5, 0x65, 0x5E, 0xCB, 0xF3, 0xFA, 0x53,
593 };
594
595 const u8 q[] = {
596 0x86, 0x4F, 0x18, 0x84, 0x1E, 0xC1, 0x03, 0xCD, 0xFD, 0x1B, 0xE7, 0xFE, 0xE5, 0x46, 0x50, 0xF2, 0x2A, 0x3B, 0xB9, 0x97, 0x53, 0x7F, 0x32, 0xCC,
597 0x79, 0xA5, 0x1F, 0x53,
598 };
599
600 const u8 g[] = {
601 0x0E, 0x9B, 0xE1, 0xF8, 0x7A, 0x41, 0x4D, 0x16, 0x7A, 0x9A, 0x5A, 0x96, 0x8B, 0x07, 0x9E, 0x4A, 0xD3, 0x85, 0xA3, 0x57, 0x3E, 0xDB, 0x21, 0xAA,
602 0x67, 0xA6, 0xF6, 0x1C, 0x0D, 0x00, 0xC1, 0x4A, 0x7A, 0x22, 0x50, 0x44, 0xB6, 0xE9, 0xEB, 0x03, 0x68, 0xC1, 0xEB, 0x57, 0xB2, 0x4B, 0x45, 0xCD,
603 0x85, 0x4F, 0xD9, 0x3C, 0x1B, 0x2D, 0xFB, 0x0A, 0x3E, 0xA3, 0x02, 0xD2, 0x36, 0x7E, 0x4E, 0xC7, 0x2F, 0x6E, 0x7E, 0xE8, 0xEA, 0x7F, 0x80, 0x02,
604 0xF7, 0x70, 0x4E, 0x99, 0x0B, 0x95, 0x4F, 0x25, 0xBA, 0xDA, 0x8D, 0xA6, 0x2B, 0xAE, 0xB6, 0xF0, 0x69, 0x53, 0xC0, 0xC8, 0x51, 0x04, 0xAD, 0x03,
605 0xF3, 0x66, 0x18, 0xF7, 0x6C, 0x62, 0xF4, 0xEC, 0xF3, 0x48, 0x01, 0x83, 0x69, 0x85, 0x0A, 0x56, 0x17, 0xC9, 0x99, 0xDB, 0xE6, 0x8B, 0xA1, 0x7D,
606 0x5B, 0xC7, 0x25, 0x56, 0x74, 0xEF, 0x48, 0x39, 0x22, 0xC6, 0xA3, 0xF9, 0x9D, 0x3C, 0x3C, 0x6F, 0x35, 0x88, 0x96, 0xC4, 0xE6, 0x3C, 0x60, 0x5E,
607 0xE7, 0xDB, 0x16, 0xFC, 0xBD, 0x9B, 0xE3, 0x54, 0xE2, 0x81, 0xF7, 0xFE, 0x78, 0x13, 0xD0, 0x54, 0x27, 0xED, 0x19, 0x12, 0xB5, 0xC7, 0x65, 0x3A,
608 0x16, 0x7B, 0x94, 0x34, 0x91, 0x47, 0xEE, 0xAF, 0x85, 0xCC, 0x9C, 0xE2, 0xE8, 0x16, 0x61, 0xF3, 0x21, 0x51, 0x2D, 0x5D, 0x2C, 0x05, 0x80, 0xB0,
609 0x3D, 0x17, 0x04, 0xEE, 0xF2, 0x31, 0x7F, 0x45, 0x18, 0x5C, 0x82, 0x58, 0x38, 0x7E, 0x7E, 0xC9, 0x79, 0xC0, 0x47, 0x07, 0xEF, 0x54, 0x62, 0x41,
610 0x27, 0x84, 0xAF, 0xE4, 0x1A, 0x7B, 0x45, 0xC8, 0x3B, 0x9C, 0xBE, 0x48, 0xF9, 0x12, 0x7C, 0xB4, 0x40, 0x0B, 0xE9, 0xE9, 0x6A, 0xC5, 0xDE, 0x17,
611 0xF2, 0xC9, 0xDE, 0xA3, 0x5E, 0x37, 0x34, 0xE7, 0x9B, 0x64, 0x67, 0x3F, 0x85, 0x68, 0x1C, 0x4E,
612 };
613
614 const u8 x[] = {
615 0x2F, 0x19, 0x91, 0xC1, 0xAF, 0x40, 0x18, 0x72, 0x8A, 0x5A, 0x43, 0x1B, 0x9B, 0x54, 0x59, 0xDF, 0xB1, 0x6F, 0x6D, 0x25, 0x67, 0x97, 0xFE, 0x57,
616 0x0E, 0xC6, 0xBC, 0x65,
617 };
618
619 const u8 y[] = {
620 0x04, 0xED, 0xE5, 0xC6, 0x7E, 0xA2, 0x92, 0x97, 0xA8, 0xCA, 0xCB, 0x6B, 0xDE, 0x6F, 0x46, 0x66, 0xAE, 0xA2, 0x7D, 0x10, 0x3D, 0xD1, 0xE9, 0xE9,
621 0x58, 0x2F, 0x76, 0xA2, 0xF2, 0x2B, 0x8B, 0x1B, 0x32, 0x23, 0x0B, 0xC5, 0x8F, 0x06, 0xB7, 0x68, 0xF8, 0x10, 0x2B, 0x49, 0xFA, 0x1C, 0xAE, 0x5E,
622 0x18, 0x92, 0x14, 0x94, 0x7F, 0x62, 0x39, 0xB6, 0xC6, 0xCE, 0x7C, 0x9B, 0xC2, 0xD2, 0x30, 0xE8, 0x9A, 0x40, 0xBE, 0xE2, 0xC3, 0x3A, 0x88, 0x61,
623 0xFD, 0x4F, 0x7D, 0x35, 0xB7, 0x88, 0xFE, 0x95, 0xB2, 0xD5, 0x88, 0x5D, 0x8C, 0x8F, 0xAE, 0xA8, 0x1C, 0x90, 0xBE, 0x4C, 0xEE, 0x27, 0x84, 0xE3,
624 0x35, 0x77, 0xA7, 0x1D, 0x3B, 0x7F, 0x08, 0x5D, 0x71, 0xE9, 0xA1, 0xD4, 0x78, 0x15, 0xC7, 0x3F, 0xA0, 0x87, 0xAC, 0xAA, 0xB9, 0xFC, 0xB5, 0x65,
625 0x5A, 0xC9, 0x57, 0x0E, 0x68, 0x52, 0xBE, 0x7C, 0x9C, 0x0A, 0xEC, 0xEA, 0x8B, 0xD9, 0xAA, 0x75, 0xA4, 0x4F, 0xC3, 0x14, 0x7F, 0x73, 0x3E, 0x90,
626 0x6A, 0xDB, 0x0F, 0xD7, 0x6D, 0x61, 0x35, 0x61, 0xB1, 0xDB, 0x36, 0x4B, 0xBD, 0xC9, 0xAF, 0xD3, 0xCE, 0x8F, 0x5F, 0x17, 0xE3, 0xE7, 0x12, 0x03,
627 0x4A, 0x99, 0x93, 0x50, 0x80, 0x59, 0xFA, 0x52, 0x44, 0x1F, 0xA9, 0x0D, 0xDF, 0xE9, 0xA0, 0xF2, 0xA0, 0xB9, 0x19, 0x2F, 0xE2, 0x22, 0x0C, 0x08,
628 0x1B, 0xD0, 0xC0, 0xF0, 0xE0, 0x7C, 0xB5, 0xF1, 0xEE, 0x4F, 0xF4, 0x05, 0x23, 0x59, 0x1F, 0x17, 0x8A, 0x4F, 0xC7, 0xCB, 0x50, 0x65, 0xF6, 0xA3,
629 0x82, 0x16, 0xE9, 0xA0, 0x99, 0xC2, 0x05, 0xB2, 0x9B, 0x87, 0x46, 0xD8, 0x65, 0xE1, 0xAF, 0x6D, 0x90, 0x3E, 0x5A, 0x13, 0x80, 0x04, 0x91, 0x0B,
630 0x70, 0xEB, 0x5B, 0x84, 0xEE, 0xD9, 0x76, 0x0E, 0xA6, 0x05, 0x78, 0xBF, 0x08, 0x85, 0x28, 0x98,
631 };
632
633 const u8 msg[] = "This is a test message for KCDSA usage!";
634
635 const u8 nonce[] = {
636 0x49, 0x56, 0x19, 0x94, 0xFD, 0x2B, 0xAD, 0x5E, 0x41, 0x0C, 0xA1, 0xC1, 0x5C, 0x3F, 0xD3, 0xF1, 0x2E, 0x70, 0x26, 0x3F, 0x28, 0x20, 0xAD, 0x5C,
637 0x56, 0x6D, 0xED, 0x80,
638 };
639 u8 sig[28*2] = { 0 };
640 gen_hash_alg_type kcdsa_hash = HASH_SHA256;
641 #endif
642
643 #if 1
644 /* This example is taken from ISO14888-3 KCDSA (Appendix F "Numerical examples" */
645 const u8 p[] = {
646 0xCB, 0xAE, 0xAC, 0xE3, 0x67, 0x7E, 0x98, 0xAD, 0xB2, 0xE4, 0x9C, 0x00, 0x2B, 0x8B, 0x0F, 0x43, 0x41, 0x43, 0xB4, 0x66, 0x51, 0x58, 0x39, 0xBF,
647 0x81, 0x3B, 0x09, 0x7D, 0x2D, 0x1E, 0xE6, 0x81, 0x50, 0x08, 0xC2, 0x7A, 0x34, 0x15, 0xBC, 0x22, 0x31, 0x60, 0x98, 0x74, 0x5E, 0x58, 0x44, 0xF3,
648 0x3E, 0xCC, 0x88, 0x87, 0xC1, 0x6D, 0xFB, 0x1C, 0xFB, 0x77, 0xDC, 0x4C, 0x3F, 0x35, 0x71, 0xCC, 0xEE, 0xFD, 0x42, 0x91, 0x8F, 0x6C, 0x48, 0xC3,
649 0x70, 0x2A, 0xB6, 0xEF, 0x09, 0x19, 0xB7, 0xE8, 0x40, 0x2F, 0xC8, 0x9B, 0x35, 0xD0, 0x9A, 0x0E, 0x50, 0x40, 0xE3, 0x09, 0x1E, 0xE4, 0x67, 0x4B,
650 0xE8, 0x91, 0x93, 0x3C, 0x10, 0x07, 0xE0, 0x17, 0xED, 0xD4, 0x08, 0x18, 0x7E, 0x41, 0x14, 0xB6, 0xBE, 0x55, 0x48, 0xD7, 0x8D, 0xB5, 0x8B, 0x84,
651 0x84, 0x75, 0xA4, 0x22, 0x62, 0xD7, 0xEB, 0x79, 0x5F, 0x08, 0xD1, 0x61, 0x10, 0x55, 0xEF, 0xEA, 0x8A, 0x6A, 0xEB, 0x20, 0xEB, 0x0F, 0x1C, 0x22,
652 0xF0, 0x02, 0xA2, 0xE8, 0x19, 0x5B, 0xCB, 0xBA, 0x83, 0x0B, 0x84, 0x61, 0x35, 0x31, 0xBD, 0xD9, 0xEC, 0x71, 0xE5, 0xA9, 0x7A, 0x9D, 0xCC, 0xC6,
653 0x5D, 0x61, 0x17, 0xB8, 0x5D, 0x0C, 0xA6, 0x6C, 0x3F, 0xDA, 0xA3, 0x47, 0x6E, 0x97, 0xAD, 0xCD, 0x05, 0xA1, 0xF4, 0x90, 0x2B, 0xD0, 0x4B, 0x92,
654 0xF4, 0x00, 0xC4, 0x2B, 0xA0, 0xC9, 0x94, 0x0A, 0x32, 0x60, 0x04, 0x43, 0x3B, 0x6D, 0x30, 0x01, 0x28, 0xBF, 0x93, 0x0F, 0x48, 0x4E, 0xAA, 0x63,
655 0x02, 0xCD, 0x7A, 0x31, 0x9E, 0xE5, 0xE5, 0x61, 0xA1, 0x2A, 0x36, 0x25, 0x59, 0x40, 0x20, 0xC2, 0x40, 0xDB, 0xA3, 0xBE, 0xBD, 0x8A, 0x47, 0x51,
656 0x58, 0x41, 0xF1, 0x98, 0xEB, 0xE4, 0x32, 0x18, 0x26, 0x39, 0x61, 0x6F, 0x6A, 0x7F, 0x9B, 0xD7, 0x43, 0x4F, 0x05, 0x34, 0x8F, 0x7F, 0x1D, 0xB3,
657 0x11, 0x5A, 0x9F, 0xEE, 0xBA, 0x98, 0x4A, 0x2B, 0x73, 0x78, 0x43, 0x34, 0xDE, 0x77, 0x37, 0xEE, 0x37, 0x04, 0x53, 0x5F, 0xCA, 0x2F, 0x49, 0x04,
658 0xCB, 0x4A, 0xD5, 0x8F, 0x17, 0x2F, 0x26, 0x48, 0xE1, 0xD6, 0x2D, 0x05, 0x85, 0x39, 0xAC, 0x78, 0x3D, 0x03, 0x2D, 0x18, 0x33, 0xD2, 0xB9, 0xAA,
659 0xD9, 0x69, 0x82, 0xC9, 0x69, 0x2E, 0x0D, 0xDB, 0xB6, 0x61, 0x55, 0x08, 0x83, 0xED, 0x66, 0xF7, 0xAA, 0x8B, 0xCE, 0x8F, 0xF0, 0x66, 0x3A, 0x0A,
660 0xDD, 0xA2, 0x26, 0xC7, 0xBD, 0x0E, 0x06, 0xDF, 0xC7, 0x25, 0x94, 0xA3, 0x87, 0xC6, 0x76, 0xA3, 0xCA, 0x06, 0xA3, 0x00, 0x62, 0xBE, 0x1D, 0x85,
661 0xF2, 0x3E, 0x3E, 0x02, 0xC4, 0xD6, 0x5E, 0x06, 0x1B, 0x61, 0x9B, 0x04, 0xE8, 0x3A, 0x31, 0x8E, 0xC5, 0x5E, 0xCA, 0x06, 0x9E, 0xB8, 0x56, 0x03,
662 };
663
664 const u8 q[] = {
665 0xC2, 0xA8, 0xCA, 0xF4, 0x87, 0x18, 0x00, 0x79, 0x66, 0xF2, 0xEC, 0x13, 0x4E, 0xAB, 0xA3, 0xCB, 0xB0, 0x7F, 0x31, 0xA8, 0xF2, 0x66, 0x7A, 0xCB,
666 0x5D, 0x9B, 0x87, 0x2F, 0xA7, 0x60, 0xA4, 0x01,
667 };
668
669 const u8 g[] = {
670 0x17, 0xA1, 0xC1, 0x67, 0xAF, 0x83, 0x6C, 0xC8, 0x51, 0x49, 0xBE, 0x43, 0x63, 0xF1, 0xBB, 0x4F, 0x00, 0x10, 0x84, 0x8F, 0xC9, 0xB6, 0x78, 0xB4,
671 0xE0, 0x26, 0xF1, 0xF3, 0x87, 0x13, 0x37, 0x49, 0xA4, 0xB1, 0xBB, 0xA4, 0xC2, 0x32, 0x52, 0xA4, 0xC8, 0x6F, 0x31, 0xE2, 0x1E, 0x8A, 0xCA, 0xCB,
672 0x4E, 0x33, 0xAD, 0x89, 0xB7, 0xC3, 0xD7, 0x9A, 0x54, 0x09, 0x26, 0x8B, 0xFB, 0xA8, 0x2B, 0x45, 0x81, 0x4E, 0x43, 0x52, 0x0C, 0x09, 0xD6, 0x31,
673 0x61, 0x3F, 0xA3, 0x5D, 0xB9, 0xCA, 0xF1, 0x8F, 0x79, 0x1C, 0x27, 0x29, 0xA4, 0xB0, 0x14, 0xBC, 0x79, 0xA8, 0x5A, 0x90, 0xCD, 0x54, 0x10, 0x37,
674 0x11, 0x9E, 0xCC, 0xDE, 0x07, 0x78, 0x86, 0x3F, 0xFC, 0xB9, 0xC2, 0x59, 0x31, 0xFC, 0xD3, 0x3A, 0x67, 0x06, 0xE5, 0xFE, 0x1F, 0x49, 0x5B, 0xB8,
675 0xBC, 0xB3, 0xD0, 0xEE, 0xC9, 0xB6, 0xD5, 0xA9, 0x37, 0x31, 0x27, 0xA2, 0x12, 0x1E, 0x37, 0xD9, 0x8A, 0x84, 0x03, 0x30, 0x25, 0x8D, 0xBF, 0xCE,
676 0xE7, 0xE0, 0x6F, 0x81, 0x5B, 0x69, 0xC1, 0x6C, 0x5D, 0x17, 0x28, 0x9C, 0x4C, 0xC3, 0x7E, 0x71, 0x9B, 0x85, 0x62, 0x98, 0xD4, 0xE1, 0x57, 0x4E,
677 0x4F, 0x4F, 0x85, 0x15, 0xBA, 0xF9, 0xA8, 0x50, 0xD1, 0x1D, 0xDA, 0x09, 0x55, 0xBC, 0x30, 0xFA, 0x5B, 0x16, 0x79, 0x2D, 0x67, 0x3A, 0x3B, 0x1F,
678 0x41, 0x51, 0x2F, 0xC3, 0xEB, 0x89, 0x45, 0x2D, 0x51, 0x50, 0x9F, 0x97, 0x4D, 0x87, 0x8B, 0x48, 0x2D, 0x2A, 0xD2, 0xED, 0x32, 0xBE, 0x19, 0x05,
679 0x6F, 0x57, 0x45, 0x04, 0x2B, 0xFF, 0x80, 0x4F, 0xB7, 0x48, 0x27, 0x96, 0x61, 0x2B, 0x74, 0x6F, 0xE8, 0xD7, 0x0A, 0x83, 0x8C, 0xC6, 0xF4, 0x96,
680 0xDD, 0x0F, 0xFC, 0x3D, 0x95, 0xC1, 0xE0, 0xB1, 0x98, 0x18, 0x4D, 0x73, 0x52, 0x36, 0x56, 0xA0, 0x64, 0x31, 0xBC, 0x52, 0x5C, 0x2B, 0xC1, 0x61,
681 0x97, 0x29, 0xE8, 0xC0, 0x88, 0xF6, 0xDF, 0x91, 0x56, 0x45, 0xE0, 0x60, 0x92, 0x2A, 0x4A, 0xF3, 0xED, 0xD6, 0x30, 0x47, 0xC7, 0xB6, 0x07, 0x7C,
682 0x66, 0x7C, 0x07, 0xD8, 0x8E, 0xB0, 0x0F, 0x4C, 0xFE, 0x59, 0xD3, 0x2E, 0x5F, 0x54, 0x50, 0x12, 0xC5, 0x66, 0x51, 0x6B, 0x78, 0x74, 0xFB, 0x3D,
683 0xAE, 0xD5, 0x14, 0x03, 0x31, 0xF2, 0x95, 0x28, 0xB3, 0x0F, 0xC8, 0xB8, 0xA9, 0x37, 0x1C, 0x28, 0x18, 0x01, 0x7B, 0x09, 0x53, 0xA8, 0x4F, 0xFC,
684 0x9F, 0xBF, 0xF8, 0x4B, 0x64, 0xBF, 0x02, 0x38, 0xAA, 0x7E, 0x2A, 0xF2, 0xEC, 0xAD, 0xC1, 0x5A, 0x1C, 0x06, 0xDA, 0xDC, 0xF1, 0xF2, 0xE7, 0xB1,
685 0x24, 0x0A, 0x5E, 0x64, 0x5A, 0x64, 0x69, 0xC9, 0xB0, 0x02, 0x21, 0x5D, 0x9A, 0x91, 0xC2, 0xA4, 0xED, 0x2F, 0xB5, 0x47, 0xA9, 0x42, 0xD7, 0x77,
686 };
687
688 const u8 x[] = {
689 0x7C, 0x28, 0x56, 0x9A, 0x94, 0xB4, 0x6F, 0xA7, 0x45, 0xC8, 0xD3, 0x06, 0xAD, 0x7D, 0xC1, 0x89, 0x96, 0xCE, 0x04, 0x6E, 0xEB, 0xE0, 0x43, 0x83,
690 0x83, 0x91, 0xC2, 0x32, 0x07, 0x8D, 0xB0, 0x5A,
691 };
692
693 const u8 y[] = {
694 0x25, 0x74, 0xE1, 0x0E, 0x80, 0x6F, 0x1C, 0x42, 0x58, 0xF7, 0xCF, 0x8F, 0xA4, 0xA6, 0xCF, 0x2B, 0xEB, 0x17, 0x7D, 0xBE, 0x60, 0xE4, 0xEC, 0x17,
695 0xDF, 0x21, 0xDC, 0xDB, 0xA7, 0x20, 0x73, 0xF6, 0x55, 0x65, 0x50, 0x6D, 0xA3, 0xDF, 0x98, 0xD5, 0xA6, 0xC8, 0xEE, 0xE6, 0x1B, 0x6B, 0x5D, 0x88,
696 0xB9, 0x8C, 0x47, 0xC2, 0xB2, 0xF6, 0xFC, 0x6F, 0x50, 0x4F, 0xA4, 0xFB, 0xC7, 0xF4, 0x11, 0xE2, 0x3E, 0xAA, 0x3B, 0x18, 0x7A, 0x35, 0x3D, 0xAE,
697 0xD4, 0x15, 0x33, 0xA9, 0x55, 0x8A, 0xB9, 0x32, 0x0A, 0x15, 0x4C, 0xAE, 0xCC, 0x54, 0x4E, 0x43, 0x00, 0x08, 0x88, 0x9A, 0x2C, 0x89, 0x93, 0x73,
698 0xEC, 0x75, 0xA2, 0x4C, 0xFF, 0x26, 0x24, 0x7C, 0xF2, 0x97, 0xD2, 0x93, 0x74, 0x7E, 0xCC, 0x05, 0xB3, 0x48, 0x36, 0x47, 0xA8, 0x7B, 0xCB, 0xB8,
699 0xD4, 0x50, 0x00, 0x92, 0x09, 0xF5, 0xE4, 0x49, 0xA0, 0x0A, 0x65, 0x9B, 0x63, 0x7C, 0xE1, 0x39, 0xCF, 0x64, 0x87, 0xAC, 0xA7, 0x0F, 0x9C, 0x00,
700 0xCB, 0x67, 0x0C, 0x7F, 0x3B, 0x95, 0xBF, 0xD7, 0xCF, 0x23, 0x6A, 0x0A, 0x6F, 0x3C, 0x93, 0xBE, 0x8D, 0x9C, 0xF5, 0x91, 0xC9, 0xD3, 0x06, 0x86,
701 0x94, 0x15, 0xB1, 0xAA, 0x97, 0x26, 0x4B, 0x90, 0x41, 0x67, 0x85, 0x0A, 0x47, 0x94, 0xC7, 0x80, 0xBE, 0x45, 0x27, 0xDF, 0xFE, 0xB6, 0x7B, 0xE6,
702 0xE6, 0x67, 0x86, 0xC5, 0xCC, 0xE0, 0x37, 0x8C, 0xCB, 0x49, 0x92, 0x0D, 0x85, 0x55, 0x58, 0xF4, 0xDA, 0xC4, 0xC4, 0x2F, 0x92, 0xDD, 0x22, 0x9B,
703 0x48, 0x3B, 0x22, 0x57, 0xDB, 0x0C, 0xE3, 0x5D, 0xC7, 0x37, 0xF9, 0x80, 0x1A, 0x26, 0x1A, 0x02, 0xBD, 0xF7, 0x18, 0xC2, 0xFD, 0x4D, 0x69, 0xC5,
704 0x2E, 0x0D, 0x97, 0x12, 0xB4, 0x2C, 0x48, 0x97, 0xBA, 0xE7, 0xC6, 0x84, 0xD3, 0xD3, 0x5B, 0xC5, 0x72, 0x6C, 0xE8, 0x99, 0x26, 0x96, 0xB0, 0x44,
705 0xD7, 0x22, 0xAF, 0xBA, 0x78, 0xEF, 0xA8, 0x58, 0xC4, 0xD1, 0x0F, 0x19, 0x72, 0x11, 0x2C, 0xE8, 0xFF, 0xD3, 0x97, 0x92, 0x49, 0xBF, 0x14, 0xE4,
706 0x9D, 0x8E, 0x0D, 0x9A, 0xCB, 0x1B, 0x0A, 0x9C, 0xA9, 0x0D, 0x05, 0x51, 0x18, 0x03, 0x84, 0x5D, 0x7C, 0x67, 0x0B, 0xCF, 0x1B, 0x06, 0x64, 0x97,
707 0xA7, 0x74, 0x3B, 0x08, 0xA2, 0x19, 0xE7, 0x64, 0xEA, 0x0A, 0x3A, 0x2A, 0x61, 0x76, 0x61, 0xC1, 0x6A, 0x37, 0x2F, 0xE0, 0x58, 0xB5, 0x47, 0xA2,
708 0x8B, 0x62, 0x6E, 0xCF, 0x44, 0x22, 0x22, 0xE1, 0x8E, 0xEF, 0x48, 0x7C, 0xC1, 0x01, 0xDB, 0xFB, 0x71, 0x5B, 0xC3, 0x3A, 0xB8, 0x59, 0x28, 0xEC,
709 0xF0, 0xBD, 0x4D, 0xEA, 0x30, 0xF2, 0x50, 0xA6, 0xA5, 0xC8, 0x61, 0x78, 0x83, 0xEA, 0x0F, 0x87, 0x3E, 0x7A, 0x46, 0x51, 0x98, 0xC4, 0x64, 0x4B,
710 };
711
712 const u8 msg[] = "This is a test message for KCDSA usage!";
713
714 const u8 nonce[] = {
715 0x83, 0xF3, 0x00, 0x8F, 0xCE, 0xBA, 0xE5, 0x7E, 0xC7, 0xA6, 0x4A, 0x3A, 0xF7, 0xEE, 0x6E, 0xE1, 0x9C, 0xC1, 0x97, 0xA6, 0xD5, 0xEB, 0xA3, 0xA5,
716 0xB3, 0xEF, 0x79, 0xB2, 0xF8, 0xF3, 0xDD, 0x53,
717 };
718 u8 sig[32*2] = { 0 };
719 gen_hash_alg_type kcdsa_hash = HASH_SHA256;
720 #endif
721
722 kcdsa_priv_key priv;
723 kcdsa_pub_key pub;
724 kcdsa_pub_key pub2;
725
726 FORCE_USED_VAR(argc);
727 FORCE_USED_VAR(argv);
728
729 /* Sanity check on size for DSA.
730 * NOTE: the double parentheses are here to handle -Wunreachable-code
731 */
732 if((NN_USABLE_MAX_BIT_LEN) < (4096)){
733 ext_printf("Error: you seem to have compiled libecc with usable NN size < 4096, not suitable for DSA.\n");
734 ext_printf(" => Please recompile libecc with EXTRA_CFLAGS=\"-DUSER_NN_BIT_LEN=4096\"\n");
735 ext_printf(" This will increase usable NN for proper DSA up to 4096 bits.\n");
736 ext_printf(" Then recompile the current examples with the same EXTRA_CFLAGS=\"-DUSER_NN_BIT_LEN=4096\" flag and execute again!\n");
737 /* NOTE: ret = 0 here to pass self tests even if the library is not compatible */
738 ret = 0;
739 goto err;
740 }
741
742
743 ret = kcdsa_import_priv_key(&priv, p, sizeof(p), q, sizeof(q), g, sizeof(g), x, sizeof(x)); EG(ret, err);
744 ret = kcdsa_import_pub_key(&pub, p, sizeof(p), q, sizeof(q), g, sizeof(g), y, sizeof(y)); EG(ret, err);
745 ret = kcdsa_compute_pub_from_priv(&pub2, &priv); EG(ret, err);
746
747 nn_print("y", &(pub2.y));
748
749 ret = kcdsa_sign(&priv, msg, sizeof(msg)-1, nonce, sizeof(nonce), sig, sizeof(sig), kcdsa_hash); EG(ret, err);
750
751 buf_print("sig", sig, sizeof(sig));
752
753 ret = kcdsa_verify(&pub, msg, sizeof(msg)-1, sig, sizeof(sig), kcdsa_hash);
754 ext_printf("Signature result %d\n", ret);
755
756 err:
757 return ret;
758 }
759 #endif
760