void powermodg(giant x, giant n, giant g) /* x becomes x^n (mod g). */ { int len, pos; giant scratch2 = popg(); gtog(x, scratch2); itog(1, x); len = bitlen(n); pos = 0; while (1) { if (bitval(n, pos++)) { mulg(scratch2, x); modg(g, x); } if (pos >= len) break; squareg(scratch2); modg(g, scratch2); } pushg(1); }
static int jacobi_symbol(giant a, curveParams *cp) /* Standard Jacobi symbol (a/cp->basePrime). basePrime must be odd, positive. */ { int t = 1, u; giant t5 = borrowGiant(cp->maxDigits); giant t6 = borrowGiant(cp->maxDigits); giant t7 = borrowGiant(cp->maxDigits); int rtn; gtog(a, t5); feemod(cp, t5); gtog(cp->basePrime, t6); while(!isZero(t5)) { u = (t6->n[0]) & 7; while((t5->n[0] & 1) == 0) { gshiftright(1, t5); if((u==3) || (u==5)) t = -t; } gtog(t5, t7); gtog(t6, t5); gtog(t7, t6); u = (t6->n[0]) & 3; if(((t5->n[0] & 3) == 3) && ((u & 3) == 3)) t = -t; modg(t6, t5); } if(isone(t6)) { rtn = t; } else { rtn = 0; } returnGiant(t5); returnGiant(t6); returnGiant(t7); return rtn; }
void main( void ) { giant x = newgiant(INFINITY), y = newgiant(INFINITY), p = newgiant(INFINITY), r = newgiant(100); int j; printf("Give two integers x, y on separate lines:\n"); gin(x); gin(y); gtog(y, p); /* p := y */ mulg(x, p); printf("y * x = "); gout(p); gtog(y, p); subg(x, p); printf("y - x = "); gout(p); gtog(y, p); addg(x, p); printf("y + x = "); gout(p); gtog(y, p); divg(x, p); printf("y div x = "); gout(p); gtog(y, p); modg(x, p); printf("y mod x = "); gout(p); gtog(y, p); gcdg(x, p); printf("GCD(x, y) = "); gout(p); /* Next, test which of x, y is greater. */ if (gcompg(x, y) < 0 ) printf("y is greater\n"); else if (gcompg(x,y) == 0) printf("x, y equal\n"); else printf("x is greater\n"); /* Next, we see how a giant struct is comprised. * We make a random, bipolar number of about 100 * digits in base 65536. */ for (j=0; j < 100; j++) { /* Fill 100 digits randomly. */ r->n[j] = (unsigned short)rand(); } r->sign = 100 * (1 - 2*(rand()%2)); /* Next, don't forget to check for leading zero digits, * even though such are unlikely. */ j = abs(r->sign) - 1; while ((r->n[j] == 0) && (j > 0)) { --j; } r->sign = (j+1) * ((r->sign > 0) ? 1: -1); printf("The random number: "); gout(r); /* Next, compare a large-FFT multiply with a standard, * grammar-school multiply. */ itog(1, x); gshiftleft(65536, x); iaddg(1, x); itog(5, y); gshiftleft(30000, y); itog(1, p); subg(p, y); /* Now we multiply (2^65536 + 1)*(5*(2^30000) - 1). */ gtog(y, p); mulg(x, p); /* Actually invokes FFT method because bit lengths of x, y are sufficiently large. */ printf("High digit of (2^65536 + 1)*(5*(2^30000) - 1) via FFT mul: %d\n", (int) p->n[abs(p->sign)-1]); fflush(stdout); gtog(y, p); grammarmulg(x, p); /* Grammar-school method. */ printf("High digit via grammar-school mul: %d\n", (int) p->n[abs(p->sign)-1]); fflush(stdout); /* Next, perform Fermat test for pseudoprimality. */ printf("Give prime candidate p:\n"); gin(p); gtog(p, y); itog(1, x); subg(x, y); itog(2, x); powermodg(x, y, p); if (isone(x)) printf("p is probably prime.\n"); else printf("p is composite.\n"); }
int binvg(giant p, giant x) { modg(p, x); return(binvaux(p,x)); }