1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- // BarrettMu, a class for performing Barrett modular reduction computations in
- // JavaScript.
- //
- // Requires BigInt.js.
- //
- // Copyright 2004-2005 David Shapiro.
- //
- // You may use, re-use, abuse, copy, and modify this code to your liking, but
- // please keep this header.
- //
- // Thanks!
- //
- // Dave Shapiro
- // dave@ohdave.com
- function BarrettMu(m)
- {
- this.modulus = biCopy(m);
- this.k = biHighIndex(this.modulus) + 1;
- var b2k = new BigInt();
- b2k.digits[2 * this.k] = 1; // b2k = b^(2k)
- this.mu = biDivide(b2k, this.modulus);
- this.bkplus1 = new BigInt();
- this.bkplus1.digits[this.k + 1] = 1; // bkplus1 = b^(k+1)
- this.modulo = BarrettMu_modulo;
- this.multiplyMod = BarrettMu_multiplyMod;
- this.powMod = BarrettMu_powMod;
- }
- function BarrettMu_modulo(x)
- {
- var q1 = biDivideByRadixPower(x, this.k - 1);
- var q2 = biMultiply(q1, this.mu);
- var q3 = biDivideByRadixPower(q2, this.k + 1);
- var r1 = biModuloByRadixPower(x, this.k + 1);
- var r2term = biMultiply(q3, this.modulus);
- var r2 = biModuloByRadixPower(r2term, this.k + 1);
- var r = biSubtract(r1, r2);
- if (r.isNeg) {
- r = biAdd(r, this.bkplus1);
- }
- var rgtem = biCompare(r, this.modulus) >= 0;
- while (rgtem) {
- r = biSubtract(r, this.modulus);
- rgtem = biCompare(r, this.modulus) >= 0;
- }
- return r;
- }
- function BarrettMu_multiplyMod(x, y)
- {
- /*
- x = this.modulo(x);
- y = this.modulo(y);
- */
- var xy = biMultiply(x, y);
- return this.modulo(xy);
- }
- function BarrettMu_powMod(x, y)
- {
- var result = new BigInt();
- result.digits[0] = 1;
- var a = x;
- var k = y;
- while (true) {
- if ((k.digits[0] & 1) != 0) result = this.multiplyMod(result, a);
- k = biShiftRight(k, 1);
- if (k.digits[0] == 0 && biHighIndex(k) == 0) break;
- a = this.multiplyMod(a, a);
- }
- return result;
- }
|