3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2006-2015 Daniel Otte (bg@nerilex.org)
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
26 #include "main-test-common.h"
29 #include "noekeon_prng.h"
31 #include "bigint_io.h"
32 #include "nist_p192.h"
34 #include "ecdsa_sign.h"
36 #include "hfal_sha1.h"
37 #include "hfal_sha224.h"
38 #include "hfal_sha256.h"
39 #include "hfal_sha384.h"
40 #include "hfal_sha512.h"
41 #include "hfal-basic.h"
43 #include "performance_test.h"
44 #include "hfal_sha1.h"
45 #include "base64_enc.h"
46 #include "base64_dec.h"
48 char *algo_name = "ECDSA";
50 /*****************************************************************************
51 * additional validation-functions *
52 *****************************************************************************/
54 uint8_t prng_get_byte(void){
58 const hfdesc_t *hash_select(void){
59 const hfdesc_t *hashes[] = { &sha1_desc, &sha224_desc, &sha256_desc, &sha384_desc, &sha512_desc };
62 printf_P(PSTR("Please select one of the following hash functions:\n"));
63 for(index = 0; index < sizeof(hashes) / sizeof(hashes[0]); ++index){
64 printf_P(PSTR(" %c: %S\n"), index + 'a', pgm_read_word(&(hashes[index]->name)));
67 printf_P(PSTR("[a]: "));
68 selection = getchar();
70 if(selection == '\n' || selection == '\r'){
76 }while(selection > sizeof(hashes) / sizeof(hashes[0]));
77 return hashes[selection];
80 uint8_t convert_hexchar_to_value(char a){
84 if(a >= 'a' && a <= 'f'){
87 if(a >= 'A' && a <= 'F'){
94 uint8_t convert_hex_to_byte(char a, char b){
95 return (convert_hexchar_to_value(a) << 4) | convert_hexchar_to_value(b);
98 void *hash_message(hfdesc_t *hash_function){
99 uint8_t *block, *hash_value;
102 if(hash_function == NULL){
105 block = malloc(hfal_hash_getBlocksize(hash_function) / 8);
109 hash_value = malloc(hfal_hash_getHashsize(hash_function) / 8);
110 if(hash_value == NULL){
114 hfal_hash_init(hash_function, &ctx);
119 hfal_hash_lastBlock(&ctx, block, index * 8);
125 printf_P(PSTR("*** invalid ***\n"));
126 hfal_hash_free(&ctx);
132 block[index++] = convert_hex_to_byte(a, b);
133 if(index == hfal_hash_getBlocksize(hash_function) / 8){
134 hfal_hash_nextBlock(&ctx, block);
137 hfal_hash_ctx2hash(hash_value, &ctx);
138 hfal_hash_free(&ctx);
143 void testrun_performance_invert_bigint(void){
144 printf_P(PSTR("\n=== performance measurement (invert) ===\n"));
148 bigint_word_t v_w[192 / BIGINT_WORD_SIZE];
149 bigint_word_t a_w[192 / BIGINT_WORD_SIZE];
154 for(j = 0; j < 32; ++j){
155 for(i = 0; i < 192 / BIGINT_WORD_SIZE; ++i){
156 ((uint8_t*)v_w)[i] = random();
158 v.length_W = 192 / BIGINT_WORD_SIZE;
162 for(i = 0; i < 16; ++i){
165 bigint_inverse(&a, &v, &nist_curve_p192_p);
175 printf_P(PSTR(" invert costs %"PRIu32" cycles\n"), (uint32_t)time);
178 void testrun_performance_multiply_bigint(void){
179 printf_P(PSTR("\n=== performance measurement (invert) ===\n"));
181 uint64_t time_a = 0, time_b = 0;
184 bigint_word_t v_w[192 * 2 / BIGINT_WORD_SIZE];
185 bigint_word_t a_w[192 / BIGINT_WORD_SIZE];
186 bigint_word_t b_w[192 / BIGINT_WORD_SIZE];
192 for(j = 0; j < 32; ++j){
193 for(i = 0; i < 192 / BIGINT_WORD_SIZE; ++i){
194 ((uint8_t*)a_w)[i] = random();
196 a.length_W = 192 / BIGINT_WORD_SIZE;
200 for(i = 0; i < 192 / BIGINT_WORD_SIZE; ++i){
201 ((uint8_t*)b_w)[i] = random();
203 b.length_W = 192 / BIGINT_WORD_SIZE;
207 for(i = 0; i < 16; ++i){
210 bigint_mul_u(&v,&a, &b);
217 bigint_reduce_p192(&v);
233 printf_P(PSTR(" multiply costs %7"PRIu32" cycles\n"), (uint32_t)time_a);
234 printf_P(PSTR(" multiply + reduce costs %7"PRIu32" cycles\n"), (uint32_t)time_b);
237 void testrun_performance_reduce_bigint(void){
238 printf_P(PSTR("\n=== performance measurement (reduce) ===\n"));
241 bigint_word_t v_w[192 * 2 / BIGINT_WORD_SIZE];
242 bigint_word_t a_w[192 * 2 / BIGINT_WORD_SIZE];
243 bigint_word_t b_w[192 * 2 / BIGINT_WORD_SIZE];
244 uint32_t time_a, time_b;
246 int16_t faster_percent;
248 for(j = 0; j < 32; ++j){
250 for(i = 0; i < 192 * 2 / BIGINT_WORD_SIZE; ++i){
251 ((uint8_t*)v_w)[i] = random();
253 v.length_W = 192 * 2 / BIGINT_WORD_SIZE;
258 // printf_P(PSTR("candidate:\n"));
259 // bigint_print_hex(&v);
264 // printf_P(PSTR("\n going to test optimized version: ...\n"));
267 for(i = 0; i < 16; ++i){
271 bigint_reduce_p192(&a);
273 time_a += stopTimer();
275 // printf_P(PSTR(" took: %"PRIu32" cycles\nresult:"), time);
276 // bigint_print_hex(&a);
279 // printf_P(PSTR("\n going to test not-optimized version: ...\n"));
282 for(i = 0; i < 16; ++i){
286 bigint_reduce(&b, &nist_curve_p192_p);
288 time_b += stopTimer();
290 // printf_P(PSTR(" took: %"PRIu32" cycles\nresult:"), time);
291 // bigint_print_hex(&b);
293 time_diff = time_b - time_a;
294 faster_percent = (time_diff * 100) / time_b;
296 printf_P(PSTR(" delta: %7"PRId32" (%3"PRId16"%%) :-"), time_diff, faster_percent);
297 if(bigint_cmp_u(&a, &b)){
298 printf_P(PSTR("(\n"));
300 printf_P(PSTR(")\n"));
306 uint8_t ecc_affine_point_alloc(ecc_affine_point_t *p, uint16_t length_b){
307 size_t len = (length_b + BIGINT_WORD_SIZE - 1)/ BIGINT_WORD_SIZE;
308 if (! (p->x.wordv = malloc(len))){
311 if (! (p->y.wordv = malloc(len))){
318 void ecc_affine_point_free(ecc_affine_point_t *p){
324 void testrun_square(void){
325 bigint_word_t a_w[] = {
326 0x82, 0x6f, 0x79, 0x39, 0x47, 0x06, 0x26, 0x9f,
327 0x4b, 0xe2, 0x15, 0x61, 0x6f, 0xa1, 0xd4, 0x0c,
328 0x1f, 0x24, 0x3a, 0xd4, 0xc2, 0x6d, 0xe8, 0xb6
331 bigint_word_t b_w[2 * 192 / BIGINT_WORD_SIZE];
335 a.length_W = sizeof(a_w);
342 printf_P(PSTR("\n a = "));
343 bigint_print_hex(&a);
344 bigint_square(&b, &a);
345 printf_P(PSTR("\n a^2 = "));
346 bigint_print_hex(&b);
347 bigint_reduce_p192(&b);
348 printf_P(PSTR("\n a^2 %% p = "));
349 bigint_print_hex(&b);
357 0: b3cfed2634516540528622e16c396c229e50bbdf773f8423
358 1: b6e86dc2d43a241f0cd4a16f6115e24b9f26064739796f82
359 2: 563f557e41731f268f82fe81c8fed959600dd46649ebeeee
360 3: 5e45169bd87475db886b8a7833bb0845f5b011a7ce0c1766
361 4: 4abf34c505a73308a804dcefacbd8f7b10b59fa6ac6421a
363 uint8_t test_point_x_w[] = {
364 0x23, 0x84, 0x3f, 0x77, 0xdf, 0xbb, 0x50, 0x9e,
365 0x22, 0x6c, 0x39, 0x6c, 0xe1, 0x22, 0x86, 0x52,
366 0x40, 0x65, 0x51, 0x34, 0x26, 0xed, 0xcf, 0xb3
369 uint8_t test_point_y_w[] = {
370 0x82, 0x6f, 0x79, 0x39, 0x47, 0x06, 0x26, 0x9f,
371 0x4b, 0xe2, 0x15, 0x61, 0x6f, 0xa1, 0xd4, 0x0c,
372 0x1f, 0x24, 0x3a, 0xd4, 0xc2, 0x6d, 0xe8, 0xb6
375 uint8_t test_point_z1_w[] = {
376 0xee, 0xee, 0xeb, 0x49, 0x66, 0xd4, 0x0d, 0x60,
377 0x59, 0xd9, 0xfe, 0xc8, 0x81, 0xfe, 0x82, 0x8f,
378 0x26, 0x1f, 0x73, 0x41, 0x7e, 0x55, 0x3f, 0x56
381 uint8_t test_point_z2_w[] = {
382 0x66, 0x17, 0x0c, 0xce, 0xa7, 0x11, 0xb0, 0xf5,
383 0x45, 0x08, 0xbb, 0x33, 0x78, 0x8a, 0x6b, 0x88,
384 0xdb, 0x75, 0x74, 0xd8, 0x9b, 0x16, 0x45, 0x5e
387 uint8_t test_point_z3_w[] = {
388 0x1a, 0x42, 0xc6, 0x6a, 0xfa, 0x59, 0x0b, 0xb1,
389 0xf7, 0xd8, 0xcb, 0xfa, 0xce, 0x4d, 0x80, 0x8a,
390 0x30, 0x73, 0x5a, 0x50, 0x4c, 0xf3, 0xab, 0x04
393 ecc_combi_point_t test_point = {
396 .wordv = test_point_x_w,
397 .length_W = sizeof(test_point_x_w),
401 .wordv = test_point_y_w,
402 .length_W = sizeof(test_point_y_w),
406 .wordv = test_point_z1_w,
407 .length_W = sizeof(test_point_z1_w),
411 .wordv = test_point_z2_w,
412 .length_W = sizeof(test_point_z2_w),
416 .wordv = test_point_z3_w,
417 .length_W = sizeof(test_point_z3_w),
422 void testrun_genkey2(void){
423 ecc_chudnovsky_point_t q;
424 ecc_affine_point_t qa;
426 printf_P(PSTR("\n== testing key generation (2) ==\n"));
428 if(ecc_chudnovsky_point_alloc(&q, 192)){
429 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
432 if(ecc_affine_point_alloc(&qa, 192)){
433 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
437 ecc_chudnovsky_point_print(&test_point.chudnovsky);
438 ecc_chudnovsky_to_affine_point(&qa, &test_point.chudnovsky, &nist_curve_p192);
439 printf_P(PSTR("\n Qx: "));
440 bigint_print_hex(&qa.x);
441 printf_P(PSTR("\n Qy: "));
442 bigint_print_hex(&qa.y);
443 printf_P(PSTR("\n================\n"));
444 ecc_chudnovsky_point_double_sp(&q, &test_point.chudnovsky, &nist_curve_p192);
445 ecc_chudnovsky_point_print(&q);
447 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
449 printf_P(PSTR("\n Qx: "));
450 bigint_print_hex(&qa.x);
451 printf_P(PSTR("\n Qy: "));
452 bigint_print_hex(&qa.y);
457 void testrun_genkey1(void){
458 ecc_chudnovsky_point_t q;
459 ecc_affine_point_t qa;
462 // e5ce89a34adddf25ff3bf1ffe6803f57d0220de3118798ea
463 0xea, 0x98, 0x87, 0x11, 0xe3, 0x0d, 0x22, 0xd0,
464 0x57, 0x3f, 0x80, 0xe6, 0xff, 0xf1, 0x3b, 0xff,
465 0x25, 0xdf, 0xdd, 0x4a, 0xa3, 0x89, 0xce, 0xe5
469 .length_W = sizeof(k_w),
474 printf_P(PSTR("\n== testing key generation ==\n"));
476 if(ecc_chudnovsky_point_alloc(&q, 192)){
477 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
480 if(ecc_affine_point_alloc(&qa, 192)){
481 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
485 printf_P(PSTR(" k: "));
486 bigint_print_hex(&k);
487 ecc_chudnovsky_multiplication(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
488 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
490 printf_P(PSTR("\n Qx: "));
491 bigint_print_hex(&qa.x);
492 printf_P(PSTR("\n Qy: "));
493 bigint_print_hex(&qa.y);
496 ecc_affine_point_free(&qa);
497 ecc_chudnovsky_point_free(&q);
500 void testrun_genkey3(void){
501 ecc_chudnovsky_point_t q;
502 ecc_affine_point_t qa;
505 0xb2, 0x51, 0x97, 0xc3, 0x7c, 0x61, 0xf8, 0x8f,
506 0x19, 0x91, 0xcc, 0x67, 0xb5, 0x1c, 0x34, 0x23,
507 0xff, 0x13, 0xad, 0x14, 0x57, 0x43, 0x14, 0x7d
511 .length_W = sizeof(k_w),
516 printf_P(PSTR("\n== testing key generation ==\n"));
518 if(ecc_chudnovsky_point_alloc(&q, 192)){
519 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
522 if(ecc_affine_point_alloc(&qa, 192)){
523 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
527 printf_P(PSTR(" k: "));
528 bigint_print_hex(&k);
529 ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
530 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
532 printf_P(PSTR("\n Qx: "));
533 bigint_print_hex(&qa.x);
534 printf_P(PSTR("\n Qy: "));
535 bigint_print_hex(&qa.y);
538 ecc_affine_point_free(&qa);
539 ecc_chudnovsky_point_free(&q);
543 void testrun_genkey(void){
544 ecc_chudnovsky_point_t q;
545 ecc_affine_point_t qa;
550 printf_P(PSTR("\n== testing key generation ==\n"));
552 printf_P(PSTR("enter secret key d: "));
553 bigint_read_hex_echo(&k);
556 if(ecc_chudnovsky_point_alloc(&q, 192)){
557 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
560 if(ecc_affine_point_alloc(&qa, 192)){
561 ecc_chudnovsky_point_free(&q);
562 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
566 printf_P(PSTR("(naf) k: "));
567 bigint_print_hex(&k);
570 r = ecc_chudnovsky_naf_multiplication(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
573 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
575 printf_P(PSTR("\n Qx: "));
576 bigint_print_hex(&qa.x);
577 printf_P(PSTR("\n Qy: "));
578 bigint_print_hex(&qa.y);
579 printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);
581 printf_P(PSTR("(d&a) k: "));
582 bigint_print_hex(&k);
585 r = ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
588 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
590 printf_P(PSTR("\n Qx: "));
591 bigint_print_hex(&qa.x);
592 printf_P(PSTR("\n Qy: "));
593 bigint_print_hex(&qa.y);
594 printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);
596 ecc_chudnovsky_point_free(&q);
597 ecc_affine_point_free(&qa);
601 3128D2B4 B1C96B14 36F8DE99 FFFFFFFF FFFFFFFF FFFFFFFF 99DEF836 146BC9B1 B4D22831
602 --------------------------------------------------------------
604 78916860 32FD8057 F636B44B 1F47CCE5 64D25099 23A7465A
605 --------------------------------------------------------------
607 78916860 32FD8057 F636B44B 1F47CCE5 64D25099 23A7465B
609 FBA2AAC6 47884B50 4EB8CD5A 0A1287BA BCC62163 F606A9A2
611 DAE6D4CC 05EF4F27 D79EE38B 71C9C8EF 4865D988 50D84AA5
614 void testrun_interm(void){
615 ecc_chudnovsky_point_t q;
616 ecc_affine_point_t qa;
621 printf_P(PSTR("\n== testing key generation ==\n"));
623 printf_P(PSTR("enter secret key d: "));
624 bigint_read_hex_echo(&k);
627 if(ecc_chudnovsky_point_alloc(&q, 192)){
628 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
631 if(ecc_affine_point_alloc(&qa, 192)){
632 ecc_chudnovsky_point_free(&q);
633 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
637 printf_P(PSTR("(naf) k: "));
638 bigint_print_hex(&k);
641 r = ecc_chudnovsky_naf_multiplication(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
644 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
646 printf_P(PSTR("\n Qx: "));
647 bigint_print_hex(&qa.x);
648 printf_P(PSTR("\n Qy: "));
649 bigint_print_hex(&qa.y);
650 printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);
652 printf_P(PSTR("(d&a) k: "));
653 bigint_print_hex(&k);
656 r = ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
659 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
661 printf_P(PSTR("\n Qx: "));
662 bigint_print_hex(&qa.x);
663 printf_P(PSTR("\n Qy: "));
664 bigint_print_hex(&qa.y);
665 printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);
667 ecc_chudnovsky_point_free(&q);
668 ecc_affine_point_free(&qa);
675 const uint8_t ecdsa_test_1_msg[] PROGMEM = {
677 0xcf, 0x71, 0xa0, 0xe4, 0xce, 0x59, 0x43, 0x11,
678 0x77, 0x88, 0x50, 0x87, 0x53, 0x78, 0xd0, 0xee,
679 0xa3, 0xc0, 0x32, 0xa4, 0xbc, 0xc0, 0xdc, 0x1c,
680 0xf2, 0x9d, 0x01, 0xb9, 0xc5, 0x10, 0x78, 0x9c,
681 0xd5, 0x2f, 0xc3, 0x8c, 0x74, 0xe6, 0xa4, 0x27,
682 0x87, 0xd0, 0xf2, 0x7c, 0xe2, 0x93, 0x20, 0x7a,
683 0xfd, 0xd0, 0x11, 0x7a, 0xcc, 0x71, 0xb9, 0x16,
684 0x63, 0x06, 0xce, 0x56, 0xf1, 0xa7, 0xf1, 0xc6,
685 0x0a, 0x9d, 0x68, 0x7d, 0x12, 0x5e, 0xb0, 0x7e,
686 0x26, 0xe5, 0x51, 0xdc, 0x14, 0x0e, 0x8a, 0x04,
687 0xaf, 0xa2, 0xa1, 0x6f, 0x98, 0xb5, 0x1b, 0xa9,
688 0x18, 0x96, 0xbf, 0x32, 0x0f, 0xd4, 0xd6, 0xf1,
689 0xa4, 0x4b, 0x46, 0xf3, 0x3d, 0xae, 0x39, 0xcc,
690 0x24, 0xf0, 0x4a, 0x5d, 0x86, 0x0c, 0xb1, 0x4f,
691 0x6b, 0x6e, 0x8a, 0x69, 0x73, 0xb4, 0x9f, 0xd2,
692 0xa7, 0xbc, 0xeb, 0x48, 0xd7, 0x48, 0xf7, 0xeb
694 0xeb, 0xf7, 0x48, 0xd7, 0x48, 0xeb, 0xbc, 0xa7,
695 0xd2, 0x9f, 0xb4, 0x73, 0x69, 0x8a, 0x6e, 0x6b,
696 0x4f, 0xb1, 0x0c, 0x86, 0x5d, 0x4a, 0xf0, 0x24,
697 0xcc, 0x39, 0xae, 0x3d, 0xf3, 0x46, 0x4b, 0xa4,
698 0xf1, 0xd6, 0xd4, 0x0f, 0x32, 0xbf, 0x96, 0x18,
699 0xa9, 0x1b, 0xb5, 0x98, 0x6f, 0xa1, 0xa2, 0xaf,
700 0x04, 0x8a, 0x0e, 0x14, 0xdc, 0x51, 0xe5, 0x26,
701 0x7e, 0xb0, 0x5e, 0x12, 0x7d, 0x68, 0x9d, 0x0a,
702 0xc6, 0xf1, 0xa7, 0xf1, 0x56, 0xce, 0x06, 0x63,
703 0x16, 0xb9, 0x71, 0xcc, 0x7a, 0x11, 0xd0, 0xfd,
704 0x7a, 0x20, 0x93, 0xe2, 0x7c, 0xf2, 0xd0, 0x87,
705 0x27, 0xa4, 0xe6, 0x74, 0x8c, 0xc3, 0x2f, 0xd5,
706 0x9c, 0x78, 0x10, 0xc5, 0xb9, 0x01, 0x9d, 0xf2,
707 0x1c, 0xdc, 0xc0, 0xbc, 0xa4, 0x32, 0xc0, 0xa3,
708 0xee, 0xd0, 0x78, 0x53, 0x87, 0x50, 0x88, 0x77,
709 0x11, 0x43, 0x59, 0xce, 0xe4, 0xa0, 0x71, 0xcf
713 * d = e14f37b3d1374ff8b03f41b9b3fdd2f0ebccf275d660d7f3
716 const uint8_t ecdsa_test_1_d[] PROGMEM = {
717 0xf3, 0xd7, 0x60, 0xd6, 0x75, 0xf2, 0xcc, 0xeb,
718 0xf0, 0xd2, 0xfd, 0xb3, 0xb9, 0x41, 0x3f, 0xb0,
719 0xf8, 0x4f, 0x37, 0xd1, 0xb3, 0x37, 0x4f, 0xe1
723 * k = cb0abc7043a10783684556fb12c4154d57bc31a289685f25
726 const uint8_t ecdsa_test_1_k[] PROGMEM = {
727 0x25, 0x5f, 0x68, 0x89, 0xa2, 0x31, 0xbc, 0x57,
728 0x4d, 0x15, 0xc4, 0x12, 0xfb, 0x56, 0x45, 0x68,
729 0x83, 0x07, 0xa1, 0x43, 0x70, 0xbc, 0x0a, 0xcb
732 void hash_mem_P(const hfdesc_t *hfdesc, void *dest, const void *msg, uint16_t msg_len_b){
733 uint16_t blocksize = hfal_hash_getBlocksize(hfdesc);
734 uint8_t block[blocksize / 8];
736 hfal_hash_init(hfdesc, &ctx);
737 while(msg_len_b > blocksize){
738 memcpy_P(block, msg, blocksize / 8);
739 msg = (uint8_t*)msg + blocksize / 8;
740 msg_len_b -= blocksize;
741 hfal_hash_nextBlock(&ctx, block);
743 memcpy_P(block, msg, (msg_len_b + 7) / 8);
744 hfal_hash_lastBlock(&ctx, block, msg_len_b);
745 hfal_hash_ctx2hash(dest, &ctx);
746 hfal_hash_free(&ctx);
749 const uint8_t ecdsa_test_2_msg[] PROGMEM = {
750 0x66, 0xa2, 0x51, 0x3d, 0x7b, 0x60, 0x45, 0xe5,
751 0x66, 0x79, 0xb0, 0x32, 0xca, 0xd4, 0x5f, 0xb1,
752 0x82, 0x28, 0x9c, 0xa7, 0x6a, 0x88, 0xc0, 0x6d,
753 0x78, 0xc8, 0x5f, 0x3d, 0xd3, 0x80, 0x45, 0x90,
754 0x20, 0x5b, 0x73, 0xa7, 0x84, 0x24, 0x9a, 0x0a,
755 0x0c, 0x8b, 0xf2, 0xf2, 0x21, 0x45, 0xd1, 0x05,
756 0x21, 0x9b, 0x48, 0x0d, 0x74, 0x60, 0x7c, 0x02,
757 0xb8, 0xa6, 0xb6, 0xb4, 0x59, 0x25, 0x9e, 0x4f,
758 0xdf, 0xe2, 0xbd, 0xb4, 0xab, 0x22, 0x38, 0x01,
759 0x75, 0x35, 0x29, 0x1d, 0x7a, 0xc1, 0xab, 0xda,
760 0x66, 0xc4, 0xf6, 0xdc, 0xea, 0x9e, 0x5d, 0x0b,
761 0xf0, 0x5a, 0x93, 0x06, 0xf3, 0x33, 0xb0, 0x0e,
762 0x56, 0x34, 0x2f, 0x75, 0x53, 0x40, 0x21, 0x1a,
763 0xc2, 0x94, 0xac, 0x21, 0xa7, 0xc2, 0xb2, 0x67,
764 0x12, 0xb8, 0x79, 0x95, 0x1b, 0x2e, 0x23, 0xf6,
765 0x48, 0x7e, 0x4d, 0x39, 0x89, 0x9f, 0xe3, 0x74
768 const uint8_t ecdsa_test_2_d[] PROGMEM = {
769 0xeb, 0x8e, 0x9f, 0x04, 0x7d, 0xb5, 0x9a, 0x80,
770 0x34, 0x6f, 0xcd, 0xf1, 0xcc, 0x33, 0xbb, 0x78,
771 0xbe, 0xc6, 0xb8, 0x76, 0xaf, 0x9f, 0x4b, 0x69
774 const uint8_t ecdsa_test_2_k[] PROGMEM = {
775 0x8e, 0xd5, 0x00, 0x34, 0x08, 0x09, 0x60, 0x36,
776 0x2e, 0xfe, 0x16, 0xd0, 0x53, 0x37, 0xa2, 0xf5,
777 0x47, 0xfa, 0x11, 0xbc, 0xb1, 0xc2, 0xe8, 0x41
781 void test_sign1(void){
782 bigint_word_t d_w[sizeof(ecdsa_test_1_d)];
783 uint8_t rnd[sizeof(ecdsa_test_1_k)];
786 const hfdesc_t *hash_desc;
788 ecdsa_signature_t sign;
794 memcpy_P(rnd, ecdsa_test_1_k, sizeof(ecdsa_test_1_k));
795 memcpy_P(d_w, ecdsa_test_1_d, sizeof(ecdsa_test_1_d));
796 d.length_W = (sizeof(ecdsa_test_1_d) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
800 hash_desc = &sha1_desc; //hash_select();
801 hash = malloc(hfal_hash_getHashsize(hash_desc) / 8);
803 printf_P(PSTR("DBG: XXX <%S %s %d>\n"), PSTR(__FILE__), __func__, __LINE__);
805 hash_mem_P(hash_desc, hash, ecdsa_test_1_msg, sizeof(ecdsa_test_1_msg) * 8);
806 printf_P(PSTR("msg hash: "));
807 cli_hexdump(hash, hfal_hash_getHashsize(hash_desc) / 8);
810 ecc_affine_point_alloc(&q.affine, nist_curve_p192_p.length_W * sizeof(bigint_word_t));
811 // ecc_chudnovsky_point_alloc(&q.chudnovsky, nist_curve_p192_p.length_W * sizeof(bigint_word_t));
812 // ctx.basepoint = &nist_curve_p192_basepoint.chudnovsky;
813 ctx.basepoint = &nist_curve_p192_basepoint.affine;
815 ctx.curve = &nist_curve_p192;
818 bigint_print_hex(&d);
819 printf_P(PSTR("\n Gx: "));
820 bigint_print_hex(&nist_curve_p192_basepoint.affine.x);
821 printf_P(PSTR("\n Gy: "));
822 bigint_print_hex(&nist_curve_p192_basepoint.affine.y);
824 // r = ecc_chudnovsky_multiplication(&q.chudnovsky, &d, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
827 printf_P(PSTR("ERROR: ecc_chudnovsky_multiplication() returned: %"PRIu8"\n"), r);
829 // r = ecc_chudnovsky_to_affine_point(&q.affine, &q.chudnovsky, &nist_curve_p192);
831 printf_P(PSTR("ERROR: ecc_chudnovsky_to_affine_point() returned: %"PRIu8"\n"), r);
834 printf_P(PSTR("\n Qx: "));
835 bigint_print_hex(&q.affine.x);
836 printf_P(PSTR("\n Qy: "));
837 bigint_print_hex(&q.affine.y);
841 ecdsa_signature_alloc(&sign, sizeof(ecdsa_test_1_d) * sizeof(bigint_word_t));
843 r = ecdsa_sign_hash(&sign, hash, hfal_hash_getHashsize(hash_desc) / 8, &ctx, rnd);
845 printf_P(PSTR("ERROR: ecdsa_sign_message() returned: %"PRIu8"\n"), r);
847 printf_P(PSTR(" r: "));
848 bigint_print_hex(&sign.r);
849 printf_P(PSTR("\n s: "));
850 bigint_print_hex(&sign.s);
853 ecdsa_signature_free(&sign);
854 ecc_chudnovsky_point_free(&q.chudnovsky);
859 void test_sign1(void){
860 bigint_word_t d_w[sizeof(ecdsa_test_1_d)];
861 uint8_t rnd[sizeof(ecdsa_test_1_k)];
864 const hfdesc_t *hash_desc;
866 ecdsa_signature_t sign;
872 memcpy_P(rnd, ecdsa_test_1_k, sizeof(ecdsa_test_1_k));
873 memcpy_P(d_w, ecdsa_test_1_d, sizeof(ecdsa_test_1_d));
874 d.length_W = (sizeof(ecdsa_test_1_d) + sizeof(bigint_word_t) - 1) / sizeof(bigint_word_t);
878 hash_desc = &sha1_desc; //hash_select();
879 hash = malloc(hfal_hash_getHashsize(hash_desc) / 8);
881 printf_P(PSTR("DBG: XXX <%S %s %d>\n"), PSTR(__FILE__), __func__, __LINE__);
883 hash_mem_P(hash_desc, hash, ecdsa_test_1_msg, sizeof(ecdsa_test_1_msg) * 8);
884 printf_P(PSTR("msg hash: "));
885 cli_hexdump(hash, hfal_hash_getHashsize(hash_desc) / 8);
888 ecc_chudnovsky_point_alloc(&q.chudnovsky, nist_curve_p192_p.length_W * sizeof(bigint_word_t));
889 ctx.basepoint = &nist_curve_p192_basepoint.chudnovsky;
891 ctx.curve = &nist_curve_p192;
894 bigint_print_hex(&d);
895 printf_P(PSTR("\n Gx: "));
896 bigint_print_hex(&nist_curve_p192_basepoint.affine.x);
897 printf_P(PSTR("\n Gy: "));
898 bigint_print_hex(&nist_curve_p192_basepoint.affine.y);
900 r = ecc_chudnovsky_multiplication(&q.chudnovsky, &d, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
902 printf_P(PSTR("ERROR: ecc_chudnovsky_multiplication() returned: %"PRIu8"\n"), r);
904 r = ecc_chudnovsky_to_affine_point(&q.affine, &q.chudnovsky, &nist_curve_p192);
906 printf_P(PSTR("ERROR: ecc_chudnovsky_to_affine_point() returned: %"PRIu8"\n"), r);
909 printf_P(PSTR("\n Qx: "));
910 bigint_print_hex(&q.affine.x);
911 printf_P(PSTR("\n Qy: "));
912 bigint_print_hex(&q.affine.y);
916 ecdsa_signature_alloc(&sign, sizeof(ecdsa_test_1_d) * sizeof(bigint_word_t));
918 r = ecdsa_sign_hash(&sign, hash, hfal_hash_getHashsize(hash_desc) / 8, &ctx, rnd);
920 printf_P(PSTR("ERROR: ecdsa_sign_message() returned: %"PRIu8"\n"), r);
922 printf_P(PSTR(" r: "));
923 bigint_print_hex(&sign.r);
924 printf_P(PSTR("\n s: "));
925 bigint_print_hex(&sign.s);
928 ecdsa_signature_free(&sign);
929 ecc_chudnovsky_point_free(&q.chudnovsky);
934 void test_sign2(void){
935 bigint_word_t d_w[sizeof(ecdsa_test_2_d)];
936 uint8_t rnd[sizeof(ecdsa_test_2_k)];
939 const hfdesc_t *hash_desc;
941 ecdsa_signature_t sign;
947 memcpy_P(rnd, ecdsa_test_2_k, sizeof(ecdsa_test_2_k));
948 memcpy_P(d_w, ecdsa_test_2_d, sizeof(ecdsa_test_2_d) * sizeof(bigint_word_t));
949 d.length_W = sizeof(ecdsa_test_2_d) / sizeof(bigint_word_t);
953 hash_desc = &sha224_desc; //hash_select();
954 hash = malloc(hfal_hash_getHashsize(hash_desc) / 8);
956 printf_P(PSTR("DBG: XXX <%S %s %d>\n"), PSTR(__FILE__), __func__, __LINE__);
958 hash_mem_P(hash_desc, hash, ecdsa_test_2_msg, sizeof(ecdsa_test_1_msg) * 8);
959 printf_P(PSTR("msg hash: "));
960 cli_hexdump(hash, hfal_hash_getHashsize(hash_desc) / 8);
963 ecc_chudnovsky_point_alloc(&q.chudnovsky, nist_curve_p192_p.length_W * sizeof(bigint_word_t));
964 ctx.basepoint = &nist_curve_p192_basepoint.chudnovsky;
966 ctx.curve = &nist_curve_p192;
969 bigint_print_hex(&d);
970 printf_P(PSTR("\n Gx: "));
971 bigint_print_hex(&nist_curve_p192_basepoint.affine.x);
972 printf_P(PSTR("\n Gy: "));
973 bigint_print_hex(&nist_curve_p192_basepoint.affine.y);
975 r = ecc_chudnovsky_multiplication(&q.chudnovsky, &d, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
977 printf_P(PSTR("ERROR: ecc_chudnovsky_multiplication() returned: %"PRIu8"\n"), r);
979 r = ecc_chudnovsky_to_affine_point(&q.affine, &q.chudnovsky, &nist_curve_p192);
981 printf_P(PSTR("ERROR: ecc_chudnovsky_to_affine_point() returned: %"PRIu8"\n"), r);
984 printf_P(PSTR("\n Qx: "));
985 bigint_print_hex(&q.affine.x);
986 printf_P(PSTR("\n Qy: "));
987 bigint_print_hex(&q.affine.y);
991 ecdsa_signature_alloc(&sign, sizeof(ecdsa_test_2_d) * sizeof(bigint_word_t));
993 r = ecdsa_sign_hash(&sign, hash, hfal_hash_getHashsize(hash_desc) / 8, &ctx, rnd);
995 printf_P(PSTR("ERROR: ecdsa_sign_message() returned: %"PRIu8"\n"), r);
997 printf_P(PSTR(" r: "));
998 bigint_print_hex(&sign.r);
999 printf_P(PSTR("\n s: "));
1000 bigint_print_hex(&sign.s);
1003 ecdsa_signature_free(&sign);
1004 ecc_chudnovsky_point_free(&q.chudnovsky);
1006 /*****************************************************************************
1008 *****************************************************************************/
1010 const char echo_test_str[] PROGMEM = "echo-test";
1011 const char reset_prng_str[] PROGMEM = "reset-prng";
1012 const char quick_test_str[] PROGMEM = "quick-test";
1013 const char performance_reduce_str[] PROGMEM = "performance_reduce";
1014 const char performance_invert_str[] PROGMEM = "performance_invert";
1015 const char performance_multiply_str[] PROGMEM = "performance_multiply";
1016 const char genkey1_str[] PROGMEM = "genkey1";
1017 const char genkey2_str[] PROGMEM = "genkey2";
1018 const char genkey3_str[] PROGMEM = "genkey3";
1019 const char genkey_str[] PROGMEM = "genkey";
1020 const char testsign1_str[] PROGMEM = "testsign1";
1021 const char testsign2_str[] PROGMEM = "testsign2";
1022 const char square_str[] PROGMEM = "square";
1023 const char echo_str[] PROGMEM = "echo";
1025 const const cmdlist_entry_t cmdlist[] PROGMEM = {
1026 // { reset_prng_str, NULL, reset_prng },
1027 // { quick_test_str, NULL, quick_test },
1028 { square_str, NULL, testrun_square },
1029 { genkey_str, NULL, testrun_genkey },
1030 { genkey1_str, NULL, testrun_genkey1 },
1031 { genkey2_str, NULL, testrun_genkey2 },
1032 { genkey3_str, NULL, testrun_genkey3 },
1033 { testsign1_str, NULL, test_sign1 },
1034 { testsign2_str, NULL, test_sign2 },
1035 { performance_reduce_str, NULL, testrun_performance_reduce_bigint },
1036 { performance_invert_str, NULL, testrun_performance_invert_bigint },
1037 { performance_multiply_str, NULL, testrun_performance_multiply_bigint },
1038 { echo_str, (void*)1, (void_fpt)echo_ctrl },
1039 { NULL, NULL, NULL }
1047 welcome_msg(algo_name);
1048 r = cmd_interface(cmdlist);
1049 printf("r = %"PRId8"\n", r);
1050 cli_putstr_P(PSTR("\r\nHello!\r\n"));