17dd7cddfSDavid du Colombier #include "os.h"
27dd7cddfSDavid du Colombier #include <mp.h>
37dd7cddfSDavid du Colombier
47dd7cddfSDavid du Colombier #define iseven(a) (((a)->p[0] & 1) == 0)
57dd7cddfSDavid du Colombier
69a747e4fSDavid du Colombier // extended binary gcd
79a747e4fSDavid du Colombier //
89a747e4fSDavid du Colombier // For a anv b it solves, v = gcd(a,b) and finds x and y s.t.
97dd7cddfSDavid du Colombier // ax + by = v
109a747e4fSDavid du Colombier //
119a747e4fSDavid du Colombier // Handbook of Applied Cryptography, Menezes et al, 1997, pg 608.
127dd7cddfSDavid du Colombier void
mpextendedgcd(mpint * a,mpint * b,mpint * v,mpint * x,mpint * y)137dd7cddfSDavid du Colombier mpextendedgcd(mpint *a, mpint *b, mpint *v, mpint *x, mpint *y)
147dd7cddfSDavid du Colombier {
157dd7cddfSDavid du Colombier mpint *u, *A, *B, *C, *D;
167dd7cddfSDavid du Colombier int g;
177dd7cddfSDavid du Colombier
18*59c21d95SDavid du Colombier if(a->sign < 0 || b->sign < 0){
19*59c21d95SDavid du Colombier mpassign(mpzero, v);
20*59c21d95SDavid du Colombier mpassign(mpzero, y);
21*59c21d95SDavid du Colombier mpassign(mpzero, x);
22*59c21d95SDavid du Colombier return;
23*59c21d95SDavid du Colombier }
24*59c21d95SDavid du Colombier
257dd7cddfSDavid du Colombier if(a->top == 0){
267dd7cddfSDavid du Colombier mpassign(b, v);
277dd7cddfSDavid du Colombier mpassign(mpone, y);
287dd7cddfSDavid du Colombier mpassign(mpzero, x);
297dd7cddfSDavid du Colombier return;
307dd7cddfSDavid du Colombier }
317dd7cddfSDavid du Colombier if(b->top == 0){
327dd7cddfSDavid du Colombier mpassign(a, v);
337dd7cddfSDavid du Colombier mpassign(mpone, x);
347dd7cddfSDavid du Colombier mpassign(mpzero, y);
357dd7cddfSDavid du Colombier return;
367dd7cddfSDavid du Colombier }
377dd7cddfSDavid du Colombier
387dd7cddfSDavid du Colombier g = 0;
397dd7cddfSDavid du Colombier a = mpcopy(a);
407dd7cddfSDavid du Colombier b = mpcopy(b);
417dd7cddfSDavid du Colombier
427dd7cddfSDavid du Colombier while(iseven(a) && iseven(b)){
437dd7cddfSDavid du Colombier mpright(a, 1, a);
447dd7cddfSDavid du Colombier mpright(b, 1, b);
457dd7cddfSDavid du Colombier g++;
467dd7cddfSDavid du Colombier }
477dd7cddfSDavid du Colombier
487dd7cddfSDavid du Colombier u = mpcopy(a);
497dd7cddfSDavid du Colombier mpassign(b, v);
507dd7cddfSDavid du Colombier A = mpcopy(mpone);
517dd7cddfSDavid du Colombier B = mpcopy(mpzero);
527dd7cddfSDavid du Colombier C = mpcopy(mpzero);
537dd7cddfSDavid du Colombier D = mpcopy(mpone);
547dd7cddfSDavid du Colombier
557dd7cddfSDavid du Colombier for(;;) {
567dd7cddfSDavid du Colombier // print("%B %B %B %B %B %B\n", u, v, A, B, C, D);
577dd7cddfSDavid du Colombier while(iseven(u)){
587dd7cddfSDavid du Colombier mpright(u, 1, u);
597dd7cddfSDavid du Colombier if(!iseven(A) || !iseven(B)) {
607dd7cddfSDavid du Colombier mpadd(A, b, A);
617dd7cddfSDavid du Colombier mpsub(B, a, B);
627dd7cddfSDavid du Colombier }
637dd7cddfSDavid du Colombier mpright(A, 1, A);
647dd7cddfSDavid du Colombier mpright(B, 1, B);
657dd7cddfSDavid du Colombier }
667dd7cddfSDavid du Colombier
677dd7cddfSDavid du Colombier // print("%B %B %B %B %B %B\n", u, v, A, B, C, D);
687dd7cddfSDavid du Colombier while(iseven(v)){
697dd7cddfSDavid du Colombier mpright(v, 1, v);
707dd7cddfSDavid du Colombier if(!iseven(C) || !iseven(D)) {
717dd7cddfSDavid du Colombier mpadd(C, b, C);
727dd7cddfSDavid du Colombier mpsub(D, a, D);
737dd7cddfSDavid du Colombier }
747dd7cddfSDavid du Colombier mpright(C, 1, C);
757dd7cddfSDavid du Colombier mpright(D, 1, D);
767dd7cddfSDavid du Colombier }
777dd7cddfSDavid du Colombier
787dd7cddfSDavid du Colombier // print("%B %B %B %B %B %B\n", u, v, A, B, C, D);
797dd7cddfSDavid du Colombier if(mpcmp(u, v) >= 0){
807dd7cddfSDavid du Colombier mpsub(u, v, u);
817dd7cddfSDavid du Colombier mpsub(A, C, A);
827dd7cddfSDavid du Colombier mpsub(B, D, B);
837dd7cddfSDavid du Colombier } else {
847dd7cddfSDavid du Colombier mpsub(v, u, v);
857dd7cddfSDavid du Colombier mpsub(C, A, C);
867dd7cddfSDavid du Colombier mpsub(D, B, D);
877dd7cddfSDavid du Colombier }
887dd7cddfSDavid du Colombier
897dd7cddfSDavid du Colombier if(u->top == 0)
907dd7cddfSDavid du Colombier break;
917dd7cddfSDavid du Colombier
927dd7cddfSDavid du Colombier }
937dd7cddfSDavid du Colombier mpassign(C, x);
947dd7cddfSDavid du Colombier mpassign(D, y);
957dd7cddfSDavid du Colombier mpleft(v, g, v);
967dd7cddfSDavid du Colombier
977dd7cddfSDavid du Colombier mpfree(A);
987dd7cddfSDavid du Colombier mpfree(B);
997dd7cddfSDavid du Colombier mpfree(C);
1007dd7cddfSDavid du Colombier mpfree(D);
1017dd7cddfSDavid du Colombier mpfree(u);
1027dd7cddfSDavid du Colombier mpfree(a);
1037dd7cddfSDavid du Colombier mpfree(b);
104*59c21d95SDavid du Colombier
105*59c21d95SDavid du Colombier return;
1067dd7cddfSDavid du Colombier }
107