1 /* main-bigint-test.c */
3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2008, 2009, 2010 Daniel Otte (daniel.otte@rub.de)
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/>.
24 #include "main-test-common.h"
27 #include "noekeon_prng.h"
29 #include "bigint_io.h"
31 #include "performance_test.h"
33 char* algo_name = "BigInt";
35 /*****************************************************************************
36 * additional validation-functions *
37 *****************************************************************************/
38 void test_echo_bigint(void){
40 cli_putstr_P(PSTR("\r\necho test\r\n"));
42 cli_putstr_P(PSTR("\r\nenter hex number:"));
43 if(bigint_read_hex_echo(&a)){
44 cli_putstr_P(PSTR("\r\n end echo test"));
47 cli_putstr_P(PSTR("\r\necho: "));
49 cli_putstr_P(PSTR("\r\n"));
54 void test_add_bigint(void){
56 cli_putstr_P(PSTR("\r\nadd test\r\n"));
58 cli_putstr_P(PSTR("\r\nenter a:"));
59 if(bigint_read_hex_echo(&a)){
60 cli_putstr_P(PSTR("\r\n end add test"));
63 cli_putstr_P(PSTR("\r\nenter b:"));
64 if(bigint_read_hex_echo(&b)){
66 cli_putstr_P(PSTR("\r\n end add test"));
69 cli_putstr_P(PSTR("\r\n "));
71 cli_putstr_P(PSTR(" + "));
73 cli_putstr_P(PSTR(" = "));
75 c_b = malloc(((a.length_W>b.length_W)?a.length_W:b.length_W)+2);
77 cli_putstr_P(PSTR("\n\rERROR: Out of memory!"));
83 bigint_add_s(&c, &a, &b);
85 cli_putstr_P(PSTR("\r\n"));
92 void test_add_scale_bigint(void){
95 cli_putstr_P(PSTR("\r\nadd-scale test\r\n"));
97 cli_putstr_P(PSTR("\r\nenter a:"));
98 if(bigint_read_hex_echo(&a)){
99 cli_putstr_P(PSTR("\r\n end add-scale test"));
102 cli_putstr_P(PSTR("\r\nenter b:"));
103 if(bigint_read_hex_echo(&b)){
104 cli_putstr_P(PSTR("\r\n end add-scale test"));
107 cli_putstr_P(PSTR("\r\nenter scale:"));
110 cli_getsn_cecho(str, 7);
114 if(bigint_read_hex_echo(&scale)){
116 cli_putstr_P(PSTR("\r\n end add test"));
121 c_b = malloc(((a.length_W>(b.length_W+scale))?a.length_W:(b.length_W+scale))+2);
123 cli_putstr_P(PSTR("\n\rERROR: Out of memory!"));
130 bigint_add_scale_u(&c, &b, scale);
131 cli_putstr_P(PSTR("\r\n "));
132 bigint_print_hex(&a);
133 cli_putstr_P(PSTR(" + "));
134 bigint_print_hex(&b);
135 cli_putstr_P(PSTR("<<8*"));
136 cli_hexdump_rev(&scale, 2);
137 cli_putstr_P(PSTR(" = "));
138 bigint_print_hex(&c);
139 cli_putstr_P(PSTR("\r\n"));
146 void test_mul_bigint(void){
148 cli_putstr_P(PSTR("\r\nmul test\r\n"));
150 cli_putstr_P(PSTR("\r\nenter a:"));
151 if(bigint_read_hex_echo(&a)){
152 cli_putstr_P(PSTR("\r\n end mul test"));
155 cli_putstr_P(PSTR("\r\nenter b:"));
156 if(bigint_read_hex_echo(&b)){
158 cli_putstr_P(PSTR("\r\n end mul test"));
161 cli_putstr_P(PSTR("\r\n "));
162 bigint_print_hex(&a);
163 cli_putstr_P(PSTR(" * "));
164 bigint_print_hex(&b);
165 cli_putstr_P(PSTR(" = "));
167 c_b = malloc((((a.length_W>b.length_W)?a.length_W:b.length_W)+1)*2);
169 cli_putstr_P(PSTR("\n\rERROR: Out of memory!"));
175 bigint_mul_s(&c, &a, &b);
176 bigint_print_hex(&c);
177 cli_putstr_P(PSTR("\r\n"));
184 void test_square_bigint(void){
186 cli_putstr_P(PSTR("\r\nsquare test\r\n"));
188 cli_putstr_P(PSTR("\r\nenter a:"));
189 if(bigint_read_hex_echo(&a)){
190 cli_putstr_P(PSTR("\r\n end square test"));
193 cli_putstr_P(PSTR("\r\n "));
194 bigint_print_hex(&a);
195 cli_putstr_P(PSTR("**2 = "));
197 c_b = malloc(a.length_W*2);
199 cli_putstr_P(PSTR("\n\rERROR: Out of memory!"));
204 bigint_square(&c, &a);
205 bigint_print_hex(&c);
206 cli_putstr_P(PSTR("\r\n"));
212 void test_reduce_bigint(void){
214 cli_putstr_P(PSTR("\r\nreduce test\r\n"));
216 cli_putstr_P(PSTR("\r\nenter a:"));
217 if(bigint_read_hex_echo(&a)){
218 cli_putstr_P(PSTR("\r\n end reduce test"));
221 cli_putstr_P(PSTR("\r\nenter b:"));
222 if(bigint_read_hex_echo(&b)){
224 cli_putstr_P(PSTR("\r\n end reduce test"));
227 cli_putstr_P(PSTR("\r\n "));
228 bigint_print_hex(&a);
229 cli_putstr_P(PSTR(" % "));
230 bigint_print_hex(&b);
231 cli_putstr_P(PSTR(" = "));
232 bigint_reduce(&a, &b);
233 bigint_print_hex(&a);
234 cli_putstr_P(PSTR("\r\n"));
240 void test_expmod_bigint(void){
243 cli_putstr_P(PSTR("\r\nreduce test\r\n"));
245 cli_putstr_P(PSTR("\r\nenter a:"));
246 if(bigint_read_hex_echo(&a)){
247 cli_putstr_P(PSTR("\r\n end expmod test"));
250 cli_putstr_P(PSTR("\r\nenter b:"));
251 if(bigint_read_hex_echo(&b)){
253 cli_putstr_P(PSTR("\r\n end expmod test"));
256 cli_putstr_P(PSTR("\r\nenter c:"));
257 if(bigint_read_hex_echo(&c)){
260 cli_putstr_P(PSTR("\r\n end expmod test"));
263 d_b = malloc(c.length_W);
265 cli_putstr_P(PSTR("\n\rERROR: Out of memory!"));
272 cli_putstr_P(PSTR("\r\n "));
273 bigint_print_hex(&a);
274 cli_putstr_P(PSTR("**"));
275 bigint_print_hex(&b);
276 cli_putstr_P(PSTR(" % "));
277 bigint_print_hex(&c);
278 cli_putstr_P(PSTR(" = "));
279 bigint_expmod_u(&d, &a, &b, &c);
280 bigint_print_hex(&d);
281 cli_putstr_P(PSTR("\r\n"));
290 void test_gcdext_bigint(void){
291 bigint_t a, b, c, d, e;
292 cli_putstr_P(PSTR("\r\ngcdext test\r\n"));
294 cli_putstr_P(PSTR("\r\nenter a:"));
295 if(bigint_read_hex_echo(&a)){
296 cli_putstr_P(PSTR("\r\n end gcdext test"));
299 cli_putstr_P(PSTR("\r\nenter b:"));
300 if(bigint_read_hex_echo(&b)){
302 cli_putstr_P(PSTR("\r\n end gcdext test"));
305 c.wordv = malloc((a.length_W<b.length_W)?a.length_W:b.length_W);
306 d.wordv = malloc(1+(a.length_W>b.length_W)?a.length_W:b.length_W);
307 e.wordv = malloc(1+(a.length_W>b.length_W)?a.length_W:b.length_W);
309 cli_putstr_P(PSTR("\r\n gcdext( "));
310 bigint_print_hex(&a);
311 cli_putstr_P(PSTR(", "));
312 bigint_print_hex(&b);
313 cli_putstr_P(PSTR(") => "));
314 bigint_gcdext(&c, &d, &e, &a, &b);
315 cli_putstr_P(PSTR("a = "));
316 bigint_print_hex(&d);
317 cli_putstr_P(PSTR("; b = "));
318 bigint_print_hex(&e);
319 cli_putstr_P(PSTR("; gcd = "));
320 bigint_print_hex(&c);
322 cli_putstr_P(PSTR("\r\n"));
331 void test_simple(void){
333 uint8_t a_b[1], b_b[1], c_b[2];
341 bigint_add_u(&c, &a, &b);
342 cli_putstr_P(PSTR("\r\n 1+2="));
343 bigint_print_hex(&c);
346 void test_mul_simple(void){
348 uint8_t a_b[5] = {0x79, 0x36, 0x9e, 0x72, 0xec};
349 uint8_t b_b[5] = {0x4a, 0x47, 0x0d, 0xec, 0xfd};
358 bigint_mul_s(&c, &a, &b);
359 cli_putstr_P(PSTR("\r\n test: "));
360 bigint_print_hex(&c);
364 // -3d1d 6db7 8251 f371 * -7a18 3791 d18b b7c5 = 1d25ce4fdf93390f8d6c709f4d711cf5
365 // -20538248dece6d29068d * 400b1411b874f81394c6 = -81646b193d95136a6fedb73cee6d30c39fb950e
366 // -BC8B 7D53 4921 853D * 0DDA 6044 00CE DDE6 = -a33eb0c5847db8837589c22db395dce
367 void test_mul_simple(void){
370 // uint8_t a_b[10] = {0x8d, 0x06, 0x29, 0x6d, 0xce, 0xde, 0x48, 0x82, 0x53, 0x20};
371 // uint8_t b_b[10] = {0xc6, 0x94, 0x13, 0xf8, 0x74, 0xb8, 0x11, 0x14, 0x0b, 0x40};
372 uint8_t a_b[8] = {0x3d, 0x85, 0x21, 0x49, 0x53, 0x7d, 0x8b, 0xbc};
373 uint8_t b_b[8] = {0xe6, 0xdd, 0xce, 0x00, 0x44, 0x60, 0xda, 0x0d};
384 bigint_mul_s(&c, &a, &b);
385 cli_putstr_P(PSTR("\r\n test: "));
386 bigint_print_hex(&a);
387 cli_putstr_P(PSTR(" * "));
388 bigint_print_hex(&b);
389 cli_putstr_P(PSTR(" = "));
390 bigint_print_hex(&c);
393 // f4 b86a 2220 0774 437d 70e6 **2 = e9f00f29ca1c876a7a682bd1e04f6925caffd6660ea4
395 const uint8_t square_test_data[] PROGMEM = {
396 0xA0, 0x3C, 0x23, 0x9F, 0x7A, 0xFC, 0x60, 0xEB, 0x96, 0xC2, 0xA8, 0xAC, 0xC3, 0xC9, 0x9E, 0xEC,
397 0x4A, 0xF0, 0x1C, 0xB2, 0x36, 0x68, 0xD6, 0x4D, 0x3E, 0x4F, 0x8E, 0x55, 0xEA, 0x52, 0x46, 0x68,
398 0x6E, 0x18, 0x88, 0x37, 0x03, 0x70, 0xBD, 0x01, 0x60, 0xE2, 0xD6, 0x12, 0xA0, 0x0E, 0xD2, 0x72,
399 0x0D, 0x9D, 0x9F, 0x03, 0xC5, 0x81, 0xCA, 0x6E, 0x88, 0x1E, 0xF5, 0xD8, 0x14, 0x15, 0x30, 0xEB,
400 0x28, 0x7C, 0x80, 0x07, 0x34, 0x05, 0x5D, 0xAA, 0xDC, 0xA8, 0xAA, 0x88, 0xC5, 0xE5, 0xC9, 0xFE,
401 0x9C, 0xA1, 0xCE, 0xC2, 0x09, 0x0D, 0xC4, 0xC8, 0xD3, 0xE7, 0x3A, 0xF3, 0xEF, 0xDF, 0xAE, 0x07,
402 0xEC, 0xC7, 0x83, 0x50, 0x9F, 0x6D, 0xB9, 0x28, 0x77, 0xC0, 0xFE, 0x69, 0xB2, 0x2E, 0x55, 0x90,
403 0x50, 0xED, 0xE0, 0xA1, 0x4D, 0x3D, 0x38, 0xC9, 0x0E, 0xCD, 0x04, 0x3B, 0x64, 0x3F, 0x56, 0xC5,
404 0xC3, 0x9E, 0x89, 0x81, 0x44, 0x60, 0xBA, 0x8E, 0x88, 0xA4, 0xA3, 0x42, 0x7B, 0x06, 0x93, 0x1C,
405 0x6B, 0x04, 0x29, 0xF9, 0xDD, 0xFF, 0xB0, 0x48, 0x2F, 0x6D, 0xD1, 0x0F, 0x7D, 0xA6, 0x26, 0xD8,
406 0xEF, 0x5E, 0x04, 0x18, 0xD1, 0x61, 0x46, 0x37, 0x87, 0xE2, 0x97, 0xDF, 0x10, 0xB4, 0x9A, 0x39,
407 0xB1, 0xD0, 0xCA, 0x91, 0x48, 0x1E, 0x5D, 0xA1, 0x38, 0x89, 0x02, 0xC1, 0x49, 0x86, 0xB7, 0xAE,
408 0x69, 0x20, 0xFA, 0x0E, 0x39, 0xDA, 0xA5, 0xEF, 0x7F, 0xB2, 0x81, 0xB8, 0xC0, 0x3A, 0xF8, 0xDB,
409 0xBC, 0x45, 0xF6, 0xDA, 0xCD, 0xBE, 0x27, 0xBE, 0xF6, 0x20, 0x79, 0xF3, 0xC3, 0xC8, 0xFF, 0x85,
410 0x43, 0x9F, 0xB1, 0x9B, 0x72, 0x88, 0xDD, 0xA4, 0x0D, 0xFC, 0xC6, 0xB5, 0x74, 0x67, 0x29, 0xF5
414 void test_square_simple(void){
417 uint8_t a_b[11] = {0xe6, 0x70, 0x7d, 0x43, 0x74, 0x07, 0x20, 0x22, 0x6a, 0xb8, 0xf4};
424 bigint_square(&c, &a);
425 cli_putstr_P(PSTR("\r\n test: "));
426 bigint_print_hex(&a);
427 cli_putstr_P(PSTR("**2 = "));
428 bigint_print_hex(&c);
431 // [fail (c)]: A862 % 2752 = 0D1A ; should a862 % 2752 = b1a
432 void test_reduce_simple(void){
435 uint8_t a_b[2] = {0x62, 0xA8};
436 uint8_t b_b[2] = {0x52, 0x27};
448 bigint_reduce(&c, &b);
449 cli_putstr_P(PSTR("\r\n test: "));
450 bigint_print_hex(&a);
451 cli_putstr_P(PSTR(" % "));
452 bigint_print_hex(&b);
453 cli_putstr_P(PSTR(" = "));
454 bigint_print_hex(&c);
457 /* gcdext( B5DDAD, 6CBBC2) */
458 /* gcdext( CD319349, 9EFD76CC) */
459 /* gcdext( 1609000771, 6FAC577D72) */
461 void test_gcdext_simple(void){
462 bigint_t a, b, c, d, e;
464 uint8_t a_b[5] = {0x71, 0x07, 0x00, 0x09, 0x16};
465 uint8_t b_b[5] = {0x72, 0x7D, 0x57, 0xAC, 0X6F};
466 uint8_t c_b[6], d_b[6], e_b[6];
478 bigint_gcdext(&c, &d, &e, &a, &b);
479 cli_putstr_P(PSTR("\r\n test: gcd( "));
480 bigint_print_hex(&a);
481 cli_putstr_P(PSTR(", "));
482 bigint_print_hex(&b);
483 cli_putstr_P(PSTR(") => a = "));
484 bigint_print_hex(&d);
485 cli_putstr_P(PSTR("; b = "));
486 bigint_print_hex(&e);
487 cli_putstr_P(PSTR("; gcd = "));
488 bigint_print_hex(&c);
491 void testrun_performance_bigint(void){
494 /*****************************************************************************
496 *****************************************************************************/
498 const char echo_test_str[] PROGMEM = "echo-test";
499 const char add_test_str[] PROGMEM = "add-test";
500 const char add_scale_test_str[] PROGMEM = "add-scale-test";
501 const char mul_test_str[] PROGMEM = "mul-test";
502 const char square_test_str[] PROGMEM = "square-test";
503 const char reduce_test_str[] PROGMEM = "reduce-test";
504 const char expmod_test_str[] PROGMEM = "expmod-test";
505 const char gcdext_test_str[] PROGMEM = "gcdext-test";
506 const char quick_test_str[] PROGMEM = "quick-test";
507 const char performance_str[] PROGMEM = "performance";
508 const char echo_str[] PROGMEM = "echo";
510 const cmdlist_entry_t cmdlist[] PROGMEM = {
511 { add_test_str, NULL, test_add_bigint },
512 { add_scale_test_str, NULL, test_add_scale_bigint },
513 { mul_test_str, NULL, test_mul_bigint },
514 { square_test_str, NULL, test_square_bigint },
515 { reduce_test_str, NULL, test_reduce_bigint },
516 { expmod_test_str, NULL, test_expmod_bigint },
517 { gcdext_test_str, NULL, test_gcdext_bigint },
518 { quick_test_str, NULL, test_gcdext_simple },
519 { echo_test_str, NULL, test_echo_bigint },
520 { performance_str, NULL, testrun_performance_bigint },
521 { echo_str, (void*)1, (void_fpt)echo_ctrl },
529 welcome_msg(algo_name);
530 cmd_interface(cmdlist);