diff --git a/bigint/bigint.c b/bigint/bigint.c index d83edb6..7dd841b 100644 --- a/bigint/bigint.c +++ b/bigint/bigint.c @@ -164,29 +164,8 @@ void bigint_sub_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){ return; } if(r<0){ - for(i=0; iwordv[i] - b->wordv[i] - borrow; - if(t<1){ - borrow = 0; - dest->wordv[i]=(uint8_t)(-t); - }else{ - borrow = -1; - dest->wordv[i]=(uint8_t)(-t); - } - } - for(;iwordv[i] + borrow; - if(t<1){ - borrow = 0; - dest->wordv[i]=(uint8_t)t; - }else{ - borrow = -1; - dest->wordv[i]=(uint8_t)t; - } - } + bigint_sub_u(dest, b, a); SET_NEG(dest); - dest->length_B = i; - bigint_adjust(dest); }else{ for(i=0; iwordv[i] - b->wordv[i] - borrow; @@ -224,12 +203,6 @@ int8_t bigint_cmp_u(const bigint_t* a, const bigint_t* b){ if(a->length_B < b->length_B){ return -1; } - if(GET_FBS(a) > GET_FBS(b)){ - return 1; - } - if(GET_FBS(a) < GET_FBS(b)){ - return -1; - } if(a->length_B==0){ return 0; } @@ -304,6 +277,9 @@ void bigint_sub_s(bigint_t* dest, const bigint_t* a, const bigint_t* b){ int8_t bigint_cmp_s(const bigint_t* a, const bigint_t* b){ uint8_t s; + if(a->length_B==0 && b->length_B==0){ + return 0; + } s = GET_SIGN(a)?2:0; s |= GET_SIGN(b)?1:0; switch(s){ @@ -369,15 +345,11 @@ void bigint_shiftright(bigint_t* a, uint16_t shift){ byteshift = shift/8; bitshift = shift&7; if(byteshift >= a->length_B){ /* we would shift out more than we have */ - a->length_B=0; - a->wordv[0] = 0; - SET_FBS(a, 0); + bigint_set_zero(a); return; } if(byteshift == a->length_B-1 && bitshift>GET_FBS(a)){ - a->length_B=0; - a->wordv[0] = 0; - SET_FBS(a, 0); + bigint_set_zero(a); return; } if(byteshift){ @@ -419,6 +391,14 @@ void bigint_set_zero(bigint_t* a){ /* using the Karatsuba-Algorithm */ /* x*y = (xh*yh)*b**2n + ((xh+xl)*(yh+yl) - xh*yh - xl*yl)*b**n + yh*yl */ void bigint_mul_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){ + if(dest==a || dest==b){ + bigint_t d; + uint8_t d_b[a->length_B+b->length_B]; + d.wordv = d_b; + bigint_mul_u(&d, a, b); + bigint_copy(dest, &d); + return; + } if(a->length_B==0 || b->length_B==0){ bigint_set_zero(dest); return; @@ -493,7 +473,7 @@ void bigint_mul_u(bigint_t* dest, const bigint_t* a, const bigint_t* b){ bigint_mul_u(dest, &xl, &yl); /* dest <= xl*yl */ bigint_add_u(&tmp2, &xh, &xl); /* tmp2 <= xh+xl */ bigint_add_u(&tmp, &yh, &yl); /* tmp <= yh+yl */ - bigint_mul_u(&m, &tmp2, &tmp); /* m <= tmp*tmp */ + bigint_mul_u(&m, &tmp2, &tmp); /* m <= tmp2*tmp */ bigint_mul_u(&tmp, &xh, &yh); /* h <= xh*yh */ bigint_sub_u(&m, &m, dest); /* m <= m-dest */ bigint_sub_u(&m, &m, &tmp); /* m <= m-h */ @@ -544,6 +524,14 @@ void bigint_square(bigint_t* dest, const bigint_t* a){ bigint_adjust(dest); return; } + if(dest==a){ + bigint_t d; + uint8_t d_b[a->length_B*2]; + d.wordv = d_b; + bigint_square(&d, a); + bigint_copy(dest, &d); + return; + } uint16_t n; n=(a->length_B+1)/2; bigint_t xh, xl, tmp; /* x-high, x-low, temp */ @@ -609,20 +597,282 @@ void bigint_sub_u_bitscale(bigint_t* a, const bigint_t* b, uint16_t bitscale){ void bigint_reduce(bigint_t* a, const bigint_t* r){ uint8_t rfbs = GET_FBS(r); +/* + cli_putstr_P(PSTR("\r\nreduce ")); + bigint_print_hex(a); + cli_putstr_P(PSTR(" % ")); + bigint_print_hex(r); + cli_putstr_P(PSTR("\r\n")); +*/ + if(r->length_B==0){ return; } while(a->length_B > r->length_B){ bigint_sub_u_bitscale(a, r, (a->length_B-r->length_B)*8+GET_FBS(a)-rfbs-1); } - while(GET_FBS(a) > rfbs+1){ + + while((GET_FBS(a) > rfbs+1) && (a->length_B == r->length_B)){ bigint_sub_u_bitscale(a, r, GET_FBS(a)-rfbs-1); } + while(bigint_cmp_u(a,r)>=0){ bigint_sub_u(a,a,r); } bigint_adjust(a); } + +/******************************************************************************/ + +/* calculate dest = a**exp % r */ +/* using square&multiply */ +void bigint_expmod_u(bigint_t* dest, const bigint_t* a, const bigint_t* exp, const bigint_t* r){ + bigint_t tmp, tmp2, x; + uint8_t x_b[MAX(r->length_B, a->length_B)], tmp_b[r->length_B*2], tmp2_b[r->length_B*2]; + int16_t i; + uint8_t j; + x.wordv = x_b; + tmp.wordv = tmp_b; + tmp2.wordv = tmp2_b; + bigint_copy(&x, a); + bigint_reduce(&x, r); + bigint_copy(&tmp, &x); + if(a->length_B==0 || exp->length_B==0 || r->length_B==0){ + return; + } + i=exp->length_B-1; + if(exp->wordv[i]!=1){ + for(j=1<<(GET_FBS(exp)-1); j>0; j>>=1){ + // cli_putc('Q'); + bigint_square(&tmp2, &tmp); + bigint_reduce(&tmp2, r); + if(exp->wordv[i]&j){ + // cli_putc('M'); + bigint_mul_u(&tmp, &tmp2, &x); + bigint_reduce(&tmp, r); + }else{ + bigint_copy(&tmp, &tmp2); + } + } + } + for(--i; i>=0; --i){ + for(j=0x80; j>0; j>>=1){ +// cli_putc('q'); + bigint_square(&tmp2, &tmp); + bigint_reduce(&tmp2, r); + if(exp->wordv[i]&j){ +// cli_putc('m'); + bigint_mul_u(&tmp, &tmp2, &x); + bigint_reduce(&tmp, r); + }else{ + bigint_copy(&tmp, &tmp2); + } + } + } +// cli_putstr_P(PSTR("\r\n")); + bigint_copy(dest, &tmp); +} +#define DEBUG 0 +/******************************************************************************/ +/* gcd <-- gcd(x,y) a*x+b*y=gcd */ +void bigint_gcdext(bigint_t* gcd, bigint_t* a, bigint_t* b, const bigint_t* x, const bigint_t* y){ + bigint_t g, x_, y_, u, v, a_, b_, c_, d_; + volatile uint16_t i=0; + if(x->length_B==0 || y->length_B==0){ + return; + } + while(x->wordv[i]==0 && y->wordv[i]==0){ + ++i; + } + uint8_t g_b[i+2], x_b[x->length_B-i], y_b[y->length_B-i]; + uint8_t u_b[x->length_B-i], v_b[y->length_B-i]; + uint8_t a_b[y->length_B+2], c_b[y->length_B+2]; + uint8_t b_b[x->length_B+2], d_b[x->length_B+2]; + + g.wordv = g_b; + x_.wordv = x_b; + y_.wordv = y_b; + memset(g_b, 0, i); + g_b[i]=1; + g.length_B = i+1; + g.info=0; + x_.info = y_.info = 0; + x_.length_B = x->length_B-i; + y_.length_B = y->length_B-i; + memcpy(x_.wordv, x->wordv+i, x_.length_B); + memcpy(y_.wordv, y->wordv+i, y_.length_B); + for(i=0; (x_.wordv[0]&(1<=v ...")); + cli_putstr_P(PSTR("\r\nDBG: (30) a = ")); + bigint_print_hex(&a_); + cli_putstr_P(PSTR("\r\nDBG: (30) b = ")); + bigint_print_hex(&b_); + cli_putstr_P(PSTR("\r\nDBG: (30) c = ")); + bigint_print_hex(&c_); + cli_putstr_P(PSTR("\r\nDBG: (30) d = ")); + bigint_print_hex(&d_); +#endif + if(bigint_cmp_u(&u, &v)>=0){ + bigint_sub_u(&u, &u, &v); + bigint_sub_s(&a_, &a_, &c_); + bigint_sub_s(&b_, &b_, &d_); + }else{ + bigint_sub_u(&v, &v, &u); + bigint_sub_s(&c_, &c_, &a_); + bigint_sub_s(&d_, &d_, &b_); + } +#if DEBUG + if(GET_SIGN(&u)){ + cli_putstr_P(PSTR("\r\nDBG: u negative! u = ")); + bigint_print_hex(&u); + } + if(GET_SIGN(&v)){ + cli_putstr_P(PSTR("\r\nDBG: v negative! v = ")); + bigint_print_hex(&v); + } +#endif +/* + cli_putstr_P(PSTR("\r\nDBG: (2) a = ")); + bigint_print_hex(&a_); + cli_putstr_P(PSTR("\r\nDBG: (2) b = ")); + bigint_print_hex(&b_); + cli_putstr_P(PSTR("\r\nDBG: (2) c = ")); + bigint_print_hex(&c_); + cli_putstr_P(PSTR("\r\nDBG: (2) d = ")); + bigint_print_hex(&d_); +*/ + }while(u.length_B); + if(gcd){ + bigint_mul_s(gcd, &v, &g); + } + if(a){ + bigint_copy(a, &c_); + } + if(b){ + bigint_copy(b, &d_); + } +} + +/******************************************************************************/ + +void bigint_inverse(bigint_t* dest, bigint_t* a, bigint_t* m){ + bigint_gcdext(NULL, dest, NULL, a, m); + while(dest->info&BIGINT_NEG_MASK){ + bigint_add_s(dest, dest, m); + } +} + + + + + + + + + + + + + + + + + + + + + + diff --git a/bigint/bigint.h b/bigint/bigint.h index d8dfb14..7a7702f 100644 --- a/bigint/bigint.h +++ b/bigint/bigint.h @@ -59,6 +59,10 @@ void bigint_mul_s(bigint_t* dest, const bigint_t* a, const bigint_t* b); void bigint_square(bigint_t* dest, const bigint_t* a); void bigint_sub_u_bitscale(bigint_t* a, const bigint_t* b, uint16_t bitscale); void bigint_reduce(bigint_t* a, const bigint_t* r); +void bigint_expmod_u(bigint_t* dest, const bigint_t* a, const bigint_t* exp, const bigint_t* r); +void bigint_gcdext(bigint_t* gcd, bigint_t* a, bigint_t* b, const bigint_t* x, const bigint_t* y); +void bigint_inverse(bigint_t* dest, bigint_t* a, bigint_t* m); + /******************************************************************************/ #endif /*BIGINT_H_*/ diff --git a/bigint/bigint_io.c b/bigint/bigint_io.c index 1a2b12c..221c61c 100644 --- a/bigint/bigint_io.c +++ b/bigint/bigint_io.c @@ -18,19 +18,26 @@ */ #include "cli.h" +#include "hexdigit_tab.h" #include "bigint.h" +#include #include #include void bigint_print_hex(const bigint_t* a){ + if(a->length_B==0){ + cli_putc('0'); + return; + } if(a->info&BIGINT_NEG_MASK){ cli_putc('-'); } // cli_putc((a->info&BIGINT_NEG_MASK)?'-':'+'); /* print sign */ - if(a->length_B!=0){ + if(a->wordv[a->length_B-1]<0x10){ + cli_putc(pgm_read_byte(hexdigit_tab_uc_P+a->wordv[a->length_B-1])); + cli_hexdump_rev(a->wordv, a->length_B-1); + } else { cli_hexdump_rev(a->wordv, a->length_B); - }else{ - cli_putc('0'); } } diff --git a/host/bigint_test.rb b/host/bigint_test.rb index 71f1195..eabaec5 100644 --- a/host/bigint_test.rb +++ b/host/bigint_test.rb @@ -61,6 +61,56 @@ def readconfigfile(fname, conf) return conf end +################################################################################ +# expmod # +################################################################################ + +def expmod(base, power, mod) + result = 1 + while power > 0 + result = (result * base) % mod if power & 1 == 1 + base = (base * base) % mod + power >>= 1; + end + return result +end + +################################################################################ +# gcdext # +################################################################################ + +def gcdext(x,y) + g=1 + while(x&1==0 && y&1==0) do + x>>=1 + y>>=1 + g<<=1 + end + u=x; v=y; a=1; b=0; c=0; d=1 + begin + while(u&1==0) do + if(a%2==1 || b%2==1) + a += y + b -= x + end + u>>=1; a>>=1; b>>=1 + end + while(v&1==0) do + if(c%2==1 || d%2==1) + c += y + d -= x + end + v>>=1; c>>=1; d>>=1; + end + if(u>=v) + u -= v; a-=c; b-=d + else + v -= u; c-=a; d-=b + end + end while(u!=0) + return[g*v, c, d] +end + ################################################################################ # reset_system # ################################################################################ @@ -189,7 +239,7 @@ def mul_test(a,b) $logfile.printf("[pass]: %s\n", line) return true else - $logfile.printf("[fail (%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (c_==a+b)?"":"c",line) + $logfile.printf("[fail (%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (c_==a*b)?"":"c",line) $logfile.printf(" ; should %s * %s = %s\n", a.to_s(16), b.to_s(16), (a*b).to_s(16)) return false end @@ -259,15 +309,17 @@ def reduce_test(a,b) end end while not /[\s]*enter b:[\s]*/.match(line) $sp.print(b.to_s(16)+" ") + line='' begin - line = $sp.gets() - line = "" if line==nil + line_tmp = $sp.gets() + line_tmp = '' if line_tmp==nil + line += line_tmp puts("DBG got: "+line) if $debug if /^Error:.*/.match(line) puts line return false end - end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]*)/.match(line) + end while not m=/[\s]*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/.match(line) a_ = m[1].to_i(16) b_ = m[2].to_i(16) c_ = m[3].to_i(16) @@ -276,13 +328,134 @@ def reduce_test(a,b) $logfile.printf("[pass]: %s\n", line) return true else - $logfile.printf("[fail (%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (c_==a+b)?"":"c",line) + $logfile.printf("[fail (%s%s%s)]: %s", (a==a_)?"":"a", (b==b_)?"":"b", (c_==a%b)?"":"c",line) $logfile.printf(" ; should %s %% %s = %s\n", a.to_s(16), b.to_s(16), (a%b).to_s(16)) return false end return false end +################################################################################ +# expmod_test # +################################################################################ + +def expmod_test(a,b,c) + begin + line = $sp.gets() + line = "" if line==nil + puts("DBG got: "+line) if $debug + if /^Error:.*/.match(line) + puts line + return false + end + end while not /[\s]*enter a:[\s]*/.match(line) + $sp.print(a.to_s(16)+" ") + begin + line = $sp.gets() + line = "" if line==nil + puts("DBG got: "+line) if $debug + if /^Error:.*/.match(line) + puts line + return false + end + end while not /[\s]*enter b:[\s]*/.match(line) + $sp.print(b.to_s(16)+" ") + begin + line = $sp.gets() + line = "" if line==nil + puts("DBG got: "+line) if $debug + if /^Error:.*/.match(line) + puts line + return false + end + end while not /[\s]*enter c:[\s]*/.match(line) + $sp.print(c.to_s(16)+" ") + line='' + begin + line_tmp = $sp.gets() + line_tmp = '' if line_tmp==nil + line += line_tmp + puts("DBG got: "+line) if $debug + if /^Error:.*/.match(line) + puts line + return false + end + end while not m=/[\s]*([+-]?[0-9a-fA-F]*)\*\*([+-]?[0-9a-fA-F]*)[\s]+%[\s]+([+-]?[0-9a-fA-F]*)[\s]*=[\s]*([+-]?[0-9a-fA-F]+)/.match(line) + a_ = m[1].to_i(16) + b_ = m[2].to_i(16) + c_ = m[3].to_i(16) + d_ = m[4].to_i(16) + line.chomp! + if(a_== a && b_ == b && c_ == c && d_ ==expmod(a,b,c) ) + $logfile.printf("[pass]: %s\n", line) + return true + else + $logfile.printf("[fail (%s%s%s%s)]: %s", (a==a_)?'':'a', (b==b_)?'':'b', (c_==c)?'':'c', (d_==expmod(a,b,c))?'':'d',line) + $logfile.printf(" ; should %s**%s %% %s = %s\n", a.to_s(16), b.to_s(16), c.to_s(16), expmod(a,b,c).to_s(16)) + return false + end + return false +end + +################################################################################ +# gcdext_test # +################################################################################ + +def gcdext_test(a,b) + begin + line = $sp.gets() + line = "" if line==nil + puts("DBG got: "+line) if $debug + if /^Error:.*/.match(line) + puts line + return false + end + end while not /[\s]*enter a:[\s]*/.match(line) + $sp.print(a.to_s(16)+" ") + begin + line = $sp.gets() + line = "" if line==nil + puts("DBG got: "+line) if $debug + if /^Error:.*/.match(line) + puts line + return false + end + end while not /[\s]*enter b:[\s]*/.match(line) + $sp.print(b.to_s(16)+" ") + line='' + begin + line_tmp = $sp.gets() + line_tmp = '' if line_tmp==nil + line = '' if line.end_with?('\n') + line += line_tmp + puts("DBG got: "+line) if $debug + if /^Error:.*/.match(line) + puts line + return false + end + end while not m=/gcdext\([\s]*([+-]?[0-9a-fA-F]*)[\s]*,[\s]*([+-]?[0-9a-fA-F]*)[\s]*\)[\s]*=> a = ([+-]?[0-9a-fA-F]+); b = ([+-]?[0-9a-fA-F]+); gcd = ([+-]?[0-9a-fA-F]+)/.match(line) + a_ = m[1].to_i(16) + b_ = m[2].to_i(16) + c_ = m[3].to_i(16) + d_ = m[4].to_i(16) + e_ = m[5].to_i(16) + line.chomp! + line.gsub!("\r",'') + line.gsub!("\n",'') + ref = gcdext(a,b) + if(a_== a && b_ == b && c_ == ref[1] && d_ == ref[2] && e_== ref[0]) + $logfile.printf("[pass]: %s\n", line) + return true + else + $logfile.printf("[fail (%s%s%s%s%s)]: %s", (a==a_)?'':'a', (b==b_)?'':'b', + (c_==ref[1])?'':'c', (d_==ref[2])?'':'d', (e_==ref[0])?'':'e', line) + $logfile.printf(" ; should gcdext( %s, %s) => a = %s; b = %s; gcd = %s\n", + a.to_s(16), b.to_s(16), ref[1].to_s(16), ref[2].to_s(16), ref[0].to_s(16)) + return false + end + return false +end + ################################################################################ # run_test_add # ################################################################################ @@ -398,6 +571,65 @@ def run_test_reduce(skip=0) end while length_a_B<4096/8 end +################################################################################ +# run_test_expmod # +################################################################################ + +def run_test_expmod(skip=0) + length_a_B = skip+1 + length_b_B = skip+1 + length_c_B = skip+1 + begin + $size = length_a_B + (0..16).each do |i| + a = rand(256**length_a_B) + b = rand(256**length_b_B)+1 + c = rand(256**length_c_B)+1 + v = expmod_test(a, b, c) + screen_progress(v) + end + (0..16).each do |i| + b_size = rand(length_b_B+1) + a = rand(256**length_a_B) + b = rand(256**b_size)+1 + c = rand(256**b_size)+1 + v = expmod_test(a, b, c) + screen_progress(v) + end + length_a_B += 1 + length_b_B += 1 + end while length_a_B<4096/8 +end + +################################################################################ +# run_test_gcdext # +################################################################################ + +def run_test_gcdext(skip=0) + length_a_B = skip+1 + length_b_B = skip+1 + begin + $size = length_a_B + (0..16).each do |i| + a = rand(256**length_a_B) + b = rand(256**length_a_B)+1 + v = gcdext_test(a, b) + $logfile.flush() + screen_progress(v) + end + (0..16).each do |i| + b_size = rand(length_b_B+1) + a = rand(256**length_a_B) + b = rand(256**b_size)+1 + v = gcdext_test(a, b) + $logfile.flush() + screen_progress(v) + end + length_a_B += 1 + length_b_B += 1 + end while length_a_B<4096/8 +end + ################################################################################ # MAIN # ################################################################################ @@ -472,11 +704,15 @@ tests['a'] = proc {|x| run_test_add(x) } tests['m'] = proc {|x| run_test_mul(x) } tests['s'] = proc {|x| run_test_square(x) } tests['r'] = proc {|x| run_test_reduce(x) } +tests['e'] = proc {|x| run_test_expmod(x) } +tests['g'] = proc {|x| run_test_gcdext(x) } init_str = Hash.new init_str['a'] = 'add-test' init_str['m'] = 'mul-test' init_str['s'] = 'square-test' init_str['r'] = 'reduce-test' +init_str['e'] = 'expmod-test' +init_str['g'] = 'gcdext-test' srand(0xdeadbeef) @@ -491,7 +727,7 @@ if opts['a'] end end else - 'amsr'.each_char do |x| + 'amsre'.each_char do |x| if tests[x] puts init_str[x] init_system(init_str[x]) diff --git a/test_src/main-bigint-test.c b/test_src/main-bigint-test.c index 85bcb09..5b65d9e 100644 --- a/test_src/main-bigint-test.c +++ b/test_src/main-bigint-test.c @@ -164,7 +164,7 @@ void test_square_bigint(void){ } void test_reduce_bigint(void){ - bigint_t a, b, c; + bigint_t a, b; cli_putstr_P(PSTR("\r\nreduce test\r\n")); for(;;){ cli_putstr_P(PSTR("\r\nenter a:")); @@ -190,6 +190,97 @@ void test_reduce_bigint(void){ free(b.wordv); } } +/* d = a**b % c */ +void test_expmod_bigint(void){ + bigint_t a, b, c, d; + uint8_t *d_b; + cli_putstr_P(PSTR("\r\nreduce test\r\n")); + for(;;){ + cli_putstr_P(PSTR("\r\nenter a:")); + if(bigint_read_hex_echo(&a)){ + cli_putstr_P(PSTR("\r\n end expmod test")); + return; + } + cli_putstr_P(PSTR("\r\nenter b:")); + if(bigint_read_hex_echo(&b)){ + free(a.wordv); + cli_putstr_P(PSTR("\r\n end expmod test")); + return; + } + cli_putstr_P(PSTR("\r\nenter c:")); + if(bigint_read_hex_echo(&c)){ + free(a.wordv); + free(b.wordv); + cli_putstr_P(PSTR("\r\n end expmod test")); + return; + } + d_b = malloc(c.length_B); + if(d_b==NULL){ + cli_putstr_P(PSTR("\n\rERROR: Out of memory!")); + free(a.wordv); + free(b.wordv); + free(c.wordv); + continue; + } + d.wordv = d_b; + cli_putstr_P(PSTR("\r\n ")); + bigint_print_hex(&a); + cli_putstr_P(PSTR("**")); + bigint_print_hex(&b); + cli_putstr_P(PSTR(" % ")); + bigint_print_hex(&c); + cli_putstr_P(PSTR(" = ")); + bigint_expmod_u(&d, &a, &b, &c); + bigint_print_hex(&d); + cli_putstr_P(PSTR("\r\n")); + free(a.wordv); + free(b.wordv); + free(c.wordv); + free(d.wordv); + + } +} + +void test_gcdext_bigint(void){ + bigint_t a, b, c, d, e; + cli_putstr_P(PSTR("\r\ngcdext test\r\n")); + for(;;){ + cli_putstr_P(PSTR("\r\nenter a:")); + if(bigint_read_hex_echo(&a)){ + cli_putstr_P(PSTR("\r\n end gcdext test")); + return; + } + cli_putstr_P(PSTR("\r\nenter b:")); + if(bigint_read_hex_echo(&b)){ + free(a.wordv); + cli_putstr_P(PSTR("\r\n end gcdext test")); + return; + } + c.wordv = malloc((a.length_Bb.length_B)?a.length_B:b.length_B); + e.wordv = malloc(1+(a.length_B>b.length_B)?a.length_B:b.length_B); + + cli_putstr_P(PSTR("\r\n gcdext( ")); + bigint_print_hex(&a); + cli_putstr_P(PSTR(", ")); + bigint_print_hex(&b); + cli_putstr_P(PSTR(") => ")); + bigint_gcdext(&c, &d, &e, &a, &b); + cli_putstr_P(PSTR("a = ")); + bigint_print_hex(&d); + cli_putstr_P(PSTR("; b = ")); + bigint_print_hex(&e); + cli_putstr_P(PSTR("; gcd = ")); + bigint_print_hex(&c); + + cli_putstr_P(PSTR("\r\n")); + free(a.wordv); + free(b.wordv); + free(c.wordv); + free(d.wordv); + free(e.wordv); + } +} void test_simple(void){ bigint_t a, b, c; @@ -317,6 +408,39 @@ void test_reduce_simple(void){ bigint_print_hex(&c); } +/* gcdext( B5DDAD, 6CBBC2) */ +/* gcdext( CD319349, 9EFD76CC) */ +/* gcdext( 1609000771, 6FAC577D72) */ +/* */ +void test_gcdext_simple(void){ + bigint_t a, b, c, d, e; + + uint8_t a_b[5] = {0x71, 0x07, 0x00, 0x09, 0x16}; + uint8_t b_b[5] = {0x72, 0x7D, 0x57, 0xAC, 0X6F}; + uint8_t c_b[6], d_b[6], e_b[6]; + a.wordv=a_b; + a.length_B = 5; + a.info=0x00; + bigint_adjust(&a); + b.wordv=b_b; + b.length_B = 5; + b.info=0x00; + bigint_adjust(&b); + c.wordv = c_b; + d.wordv = d_b; + e.wordv = e_b; + bigint_gcdext(&c, &d, &e, &a, &b); + cli_putstr_P(PSTR("\r\n test: gcd( ")); + bigint_print_hex(&a); + cli_putstr_P(PSTR(", ")); + bigint_print_hex(&b); + cli_putstr_P(PSTR(") => a = ")); + bigint_print_hex(&d); + cli_putstr_P(PSTR("; b = ")); + bigint_print_hex(&e); + cli_putstr_P(PSTR("; gcd = ")); + bigint_print_hex(&c); +} void testrun_performance_bigint(void){ @@ -330,6 +454,8 @@ const char add_test_str[] PROGMEM = "add-test"; const char mul_test_str[] PROGMEM = "mul-test"; const char square_test_str[] PROGMEM = "square-test"; const char reduce_test_str[] PROGMEM = "reduce-test"; +const char expmod_test_str[] PROGMEM = "expmod-test"; +const char gcdext_test_str[] PROGMEM = "gcdext-test"; const char quick_test_str[] PROGMEM = "quick-test"; const char performance_str[] PROGMEM = "performance"; const char echo_str[] PROGMEM = "echo"; @@ -339,7 +465,9 @@ cmdlist_entry_t cmdlist[] PROGMEM = { { mul_test_str, NULL, test_mul_bigint }, { square_test_str, NULL, test_square_bigint }, { reduce_test_str, NULL, test_reduce_bigint }, - { quick_test_str, NULL, test_reduce_simple }, + { expmod_test_str, NULL, test_expmod_bigint }, + { gcdext_test_str, NULL, test_gcdext_bigint }, + { quick_test_str, NULL, test_gcdext_simple }, { echo_test_str, NULL, test_echo_bigint }, { performance_str, NULL, testrun_performance_bigint }, { echo_str, (void*)1, (void_fpt)echo_ctrl },