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 */ 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 */ 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 */ 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 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 */ 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 */ 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> 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