/* * Some number-theoretic algorithms * * Copyright © 1999 Bart Massey. * All Rights Reserved. See the file COPYING in this directory * for licensing information. * * Bart Massey 1999/1 * * bigpowmod(b,e,m): returns (b**e) mod m * [gcd(a,b): accelerated greatest-common-divisor (built-in)] * extgcd(a,b): extended GCD returns struct coeff * zminv(a,n): inverse of a in Z*n */ namespace Numbers { public int bigpowmod(int b, int e, int m) { if (e == 0) return 1; if (e == 1) return b % m; int tmp = bigpowmod(b, e // 2, m); int tmp2 = (tmp * tmp) % m; if (e % 2 == 0) return tmp2; return (tmp2 * b) % m; } public typedef struct { int d, x, y; } coeff; /* Extended Euclid's Algorithm */ public coeff extgcd(int a, int b) { if (b == 0) return (coeff) { .d = a, .x = 1, .y = 0}; coeff t = extgcd(b, a % b); int x = t.x; t.x = t.y; t.y = x - (a // b) * t.y; return t; } /* multiplicative inverse of a mod n */ public int zminv(int a, int n) { coeff e = extgcd(a, n); if (e.x < 0) return n + e.x; return e.x; } }