You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
var bn = require('bn.js'); var brorand = require('brorand');
function MillerRabin(rand) { this.rand = rand || new brorand.Rand(); } module.exports = MillerRabin;
MillerRabin.create = function create(rand) { return new MillerRabin(rand); };
MillerRabin.prototype._randbelow = function _randbelow(n) { var len = n.bitLength(); var min_bytes = Math.ceil(len / 8);
// Generage random bytes until a number less than n is found.
// This ensures that 0..n-1 have an equal probability of being selected.
do var a = new bn(this.rand.generate(min_bytes)); while (a.cmp(n) >= 0);
return a; };
MillerRabin.prototype._randrange = function _randrange(start, stop) { // Generate a random number greater than or equal to start and less than stop.
var size = stop.sub(start); return start.add(this._randbelow(size)); };
MillerRabin.prototype.test = function test(n, k, cb) { var len = n.bitLength(); var red = bn.mont(n); var rone = new bn(1).toRed(red);
if (!k) k = Math.max(1, (len / 48) | 0);
// Find d and s, (n - 1) = (2 ^ s) * d;
var n1 = n.subn(1); for (var s = 0; !n1.testn(s); s++) {} var d = n.shrn(s);
var rn1 = n1.toRed(red);
var prime = true; for (; k > 0; k--) { var a = this._randrange(new bn(2), n1); if (cb) cb(a);
var x = a.toRed(red).redPow(d); if (x.cmp(rone) === 0 || x.cmp(rn1) === 0) continue;
for (var i = 1; i < s; i++) { x = x.redSqr();
if (x.cmp(rone) === 0) return false; if (x.cmp(rn1) === 0) break; }
if (i === s) return false; }
return prime; };
MillerRabin.prototype.getDivisor = function getDivisor(n, k) { var len = n.bitLength(); var red = bn.mont(n); var rone = new bn(1).toRed(red);
if (!k) k = Math.max(1, (len / 48) | 0);
// Find d and s, (n - 1) = (2 ^ s) * d;
var n1 = n.subn(1); for (var s = 0; !n1.testn(s); s++) {} var d = n.shrn(s);
var rn1 = n1.toRed(red);
for (; k > 0; k--) { var a = this._randrange(new bn(2), n1);
var g = n.gcd(a); if (g.cmpn(1) !== 0) return g;
var x = a.toRed(red).redPow(d); if (x.cmp(rone) === 0 || x.cmp(rn1) === 0) continue;
for (var i = 1; i < s; i++) { x = x.redSqr();
if (x.cmp(rone) === 0) return x.fromRed().subn(1).gcd(n); if (x.cmp(rn1) === 0) break; }
if (i === s) { x = x.redSqr(); return x.fromRed().subn(1).gcd(n); } }
return false; };
|