496 lines
18 KiB
JavaScript
496 lines
18 KiB
JavaScript
var assert = require('assert');
|
|
var bignum = require('../');
|
|
|
|
exports.create = function () {
|
|
assert.eql(bignum(1337).toString(), '1337');
|
|
assert.eql(bignum('1337').toString(), '1337');
|
|
assert.eql(new bignum('100').toString(), '100');
|
|
assert.eql(
|
|
new bignum('55555555555555555555555555').toString(),
|
|
'55555555555555555555555555'
|
|
);
|
|
|
|
assert.eql(Number(bignum('1e+100').toString()), 1e+100);
|
|
assert.eql(bignum('1e+100').bitLength(), 333);
|
|
assert.eql(Number(bignum('1.23e+45').toString()), 1.23e+45);
|
|
for (var i = 0; i < 10; i++) {
|
|
assert.eql(
|
|
bignum('1.23456e+' + i).toString(),
|
|
Math.floor(1.23456 * Math.pow(10,i))
|
|
);
|
|
}
|
|
|
|
assert.eql(bignum('1.23e-45').toString(), '0');
|
|
|
|
assert.throws(function() { bignum(undefined); });
|
|
assert.throws(function() { bignum(null); });
|
|
};
|
|
|
|
exports.add = function () {
|
|
for (var i = -10; i < 10; i++) {
|
|
for (var j = -10; j < 10; j++) {
|
|
var is = i.toString();
|
|
var js = j.toString();
|
|
var ks = (i + j).toString();
|
|
assert.eql(bignum(i).add(j).toString(), ks);
|
|
assert.eql(bignum(i).add(js).toString(), ks);
|
|
assert.eql(bignum(i).add(bignum(j)).toString(), ks);
|
|
assert.eql(bignum.add(i, j).toString(), ks);
|
|
}
|
|
}
|
|
|
|
assert.eql(
|
|
bignum(
|
|
'201781752444966478956292456789265633588628356858680927185287861892'
|
|
+ '9889675589272409635031813235465496971529430565627918846694860512'
|
|
+ '1492948268400884893722767401972695174353441'
|
|
).add(
|
|
'939769862972759638577945343130228368606420083646071622223953046277'
|
|
+ '3784500359975110887672142614667937014937371109558223563373329424'
|
|
+ '0624814097369771481147215472578762824607080'
|
|
).toString(),
|
|
'1141551615417726117534237799919494002195048440504752549409240908170367'
|
|
+ '41759492475205227039558501334339864668016751861424100681899362117762'
|
|
+ '365770656374869982874551457998960521'
|
|
);
|
|
};
|
|
|
|
exports.sub = function () {
|
|
for (var i = -10; i < 10; i++) {
|
|
for (var j = -10; j < 10; j++) {
|
|
var is = i.toString();
|
|
var js = j.toString();
|
|
var ks = (i - j).toString();
|
|
assert.eql(bignum(i).sub(j).toString(), ks);
|
|
assert.eql(bignum(i).sub(js).toString(), ks);
|
|
assert.eql(bignum(i).sub(bignum(j)).toString(), ks);
|
|
assert.eql(bignum.sub(i, j).toString(), ks);
|
|
}
|
|
}
|
|
|
|
assert.eql(
|
|
bignum(
|
|
'635849762218952604062459342660379446997761295162166888134051068531'
|
|
+ '9813941775949841573516110003093332652267534768664621969514455380'
|
|
+ '8051168706779408804756208386011014197185296'
|
|
).sub(
|
|
'757617343536280696839135295661092954931163607913400460585109207644'
|
|
+ '7966483882748233585856350085641718822741649072106343655764769889'
|
|
+ '6399869016678013515043471880323279258685478'
|
|
).toString(),
|
|
'-121767581317328092776675953000713507933402312751233572451058139112815'
|
|
+ '25421067983920123402400825483861704741143034417216862503145088348700'
|
|
+ '309898604710287263494312265061500182'
|
|
);
|
|
};
|
|
|
|
exports.mul = function () {
|
|
for (var i = -10; i < 10; i++) {
|
|
for (var j = -10; j < 10; j++) {
|
|
var is = i.toString();
|
|
var js = j.toString();
|
|
var ks = (i * j).toString();
|
|
assert.eql(bignum(i).mul(j).toString(), ks);
|
|
assert.eql(bignum(i).mul(js).toString(), ks);
|
|
assert.eql(bignum(i).mul(bignum(j)).toString(), ks);
|
|
assert.eql(bignum.mul(i, j).toString(), ks);
|
|
}
|
|
}
|
|
|
|
assert.eql(
|
|
bignum(
|
|
'433593290010590489671135819286259593426549306666324008679782084292'
|
|
+ '2446494189019075159822930571858728009485237489829138626896756141'
|
|
+ '8738958337632249177044975686477011571044266'
|
|
).mul(
|
|
'127790264841901718791915669264129510947625523373763053776083279450'
|
|
+ '3886212911067061184379695097643279217271150419129022856601771338'
|
|
+ '794256383410400076210073482253089544155377'
|
|
).toString(),
|
|
'5540900136412485758752141142221047463857522755277604708501015732755989'
|
|
+ '17659432099233635577634197309727815375309484297883528869192732141328'
|
|
+ '99346769031695550850320602049507618052164677667378189154076988316301'
|
|
+ '23719953859959804490669091769150047414629675184805332001182298088891'
|
|
+ '58079529848220802017396422115936618644438110463469902675126288489182'
|
|
+ '82'
|
|
);
|
|
|
|
assert.eql(
|
|
bignum('10000000000000000000000000000').mul(-123).toString(),
|
|
'-1230000000000000000000000000000'
|
|
);
|
|
};
|
|
|
|
exports.div = function () {
|
|
for (var i = -10; i < 10; i++) {
|
|
for (var j = -10; j < 10; j++) {
|
|
var is = i.toString();
|
|
var js = j.toString();
|
|
var round = ((i/j) < 0) ? Math.ceil : Math.floor;
|
|
var ks = round(i / j).toString();
|
|
if (ks.match(/^-?\d+$/)) { // ignore exceptions
|
|
assert.eql(bignum(i).div(j).toString(), ks);
|
|
assert.eql(bignum(i).div(js).toString(), ks);
|
|
assert.eql(bignum(i).div(bignum(j)).toString(), ks);
|
|
assert.eql(bignum.div(i, j).toString(), ks);
|
|
}
|
|
}
|
|
}
|
|
|
|
assert.eql(
|
|
bignum(
|
|
'433593290010590489671135819286259593426549306666324008679782084292'
|
|
+ '2446494189019075159822930571858728009485237489829138626896756141'
|
|
+ '8738958337632249177044975686477011571044266'
|
|
).div(
|
|
'127790264841901718791915669264129510947625523373763053776083279450'
|
|
+ '3886212911067061184379695097643279217271150419129022856601771338'
|
|
+ '794256383410400076210073482253089544155377'
|
|
).toString(),
|
|
'33'
|
|
);
|
|
};
|
|
|
|
exports.abs = function () {
|
|
assert.eql(
|
|
bignum(
|
|
'433593290010590489671135819286259593426549306666324008679782084292'
|
|
+ '2446494189019075159822930571858728009485237489829138626896756141'
|
|
+ '8738958337632249177044975686477011571044266'
|
|
).abs().toString(),
|
|
'4335932900105904896711358192862595934265493066663240086797820842922446'
|
|
+ '49418901907515982293057185872800948523748982913862689675614187389583'
|
|
+ '37632249177044975686477011571044266'
|
|
);
|
|
|
|
assert.eql(
|
|
bignum(
|
|
'-43359329001059048967113581928625959342654930666632400867978208429'
|
|
+ '2244649418901907515982293057185872800948523748982913862689675614'
|
|
+ '18738958337632249177044975686477011571044266'
|
|
).abs().toString(),
|
|
'4335932900105904896711358192862595934265493066663240086797820842922446'
|
|
+ '49418901907515982293057185872800948523748982913862689675614187389583'
|
|
+ '37632249177044975686477011571044266'
|
|
);
|
|
};
|
|
|
|
exports.neg = function () {
|
|
assert.eql(
|
|
bignum(
|
|
'433593290010590489671135819286259593426549306666324008679782084292'
|
|
+ '2446494189019075159822930571858728009485237489829138626896756141'
|
|
+ '8738958337632249177044975686477011571044266'
|
|
).neg().toString(),
|
|
'-433593290010590489671135819286259593426549306666324008679782084292244'
|
|
+ '64941890190751598229305718587280094852374898291386268967561418738958'
|
|
+ '337632249177044975686477011571044266'
|
|
);
|
|
|
|
assert.eql(
|
|
bignum(
|
|
'-43359329001059048967113581928625959342654930666632400867978208429'
|
|
+ '2244649418901907515982293057185872800948523748982913862689675614'
|
|
+ '18738958337632249177044975686477011571044266'
|
|
).neg().toString(),
|
|
'4335932900105904896711358192862595934265493066663240086797820842922446'
|
|
+ '49418901907515982293057185872800948523748982913862689675614187389583'
|
|
+ '37632249177044975686477011571044266'
|
|
);
|
|
};
|
|
|
|
exports.mod = function () {
|
|
for (var i = 0; i < 10; i++) {
|
|
for (var j = 0; j < 10; j++) {
|
|
var is = i.toString();
|
|
var js = j.toString();
|
|
if (!isNaN(i % j)) {
|
|
var ks = (i % j).toString();
|
|
assert.eql(bignum(i).mod(j).toString(), ks);
|
|
assert.eql(bignum(i).mod(js).toString(), ks);
|
|
assert.eql(bignum(i).mod(bignum(j)).toString(), ks);
|
|
assert.eql(bignum.mod(i, j).toString(), ks);
|
|
}
|
|
}
|
|
}
|
|
|
|
assert.eql(
|
|
bignum('486541542410442549118519277483401413')
|
|
.mod('1802185856709793916115771381388554')
|
|
.toString()
|
|
,
|
|
'1753546955507985683376775889880387'
|
|
);
|
|
};
|
|
|
|
exports.cmp = function () {
|
|
for (var i = -10; i <= 10; i++) {
|
|
var bi = bignum(i);
|
|
|
|
for (var j = -10; j <= 10; j++) {
|
|
[ j, bignum(j) ].forEach(function (jj) {
|
|
assert.eql(bi.lt(jj), i < j);
|
|
assert.eql(bi.le(jj), i <= j);
|
|
assert.eql(bi.eq(jj), i === j);
|
|
assert.eql(bi.ne(jj), i !== j);
|
|
assert.eql(bi.gt(jj), i > j);
|
|
assert.eql(bi.ge(jj), i >= j);
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
exports.powm = function () {
|
|
var twos = [ 2, '2', bignum(2), bignum('2') ]
|
|
var tens = [ 100000, '100000', bignum(100000), bignum(100000) ];
|
|
twos.forEach(function (two) {
|
|
tens.forEach(function (t) {
|
|
assert.eql(
|
|
bignum('111111111').powm(two, t).toString(),
|
|
'54321'
|
|
);
|
|
});
|
|
});
|
|
|
|
assert.eql(
|
|
bignum('624387628734576238746587435')
|
|
.powm(2732, '457676874367586')
|
|
.toString()
|
|
,
|
|
'335581885073251'
|
|
);
|
|
};
|
|
|
|
exports.pow = function () {
|
|
[ 2, '2', bignum(2), bignum('2') ].forEach(function (two) {
|
|
assert.eql(
|
|
bignum('111111111').pow(two).toString(),
|
|
'12345678987654321'
|
|
);
|
|
});
|
|
|
|
assert.eql(
|
|
bignum('3487438743234789234879').pow(22).toString(),
|
|
'861281136448465709000943928980299119292959327175552412961995332536782980636409994680542395362634321718164701236369695670918217801815161694902810780084448291245512671429670376051205638247649202527956041058237646154753587769450973231275642223337064356190945030999709422512682440247294915605076918925272414789710234097768366414400280590151549041536921814066973515842848197905763447515344747881160891303219471850554054186959791307149715821010152303317328860351766337716947079041'
|
|
);
|
|
};
|
|
|
|
exports.and = function () {
|
|
for (var i = 0; i < 256; i += 7) {
|
|
for (var j = 0; j < 256; j += 7) {
|
|
var is = i.toString();
|
|
var js = j.toString();
|
|
var ks = (i & j).toString();
|
|
assert.eql(bignum(i).and(j).toString(), ks);
|
|
assert.eql(bignum(i).and(js).toString(), ks);
|
|
assert.eql(bignum(i).and(bignum(j)).toString(), ks);
|
|
assert.eql(bignum.and(i, j).toString(), ks);
|
|
}
|
|
}
|
|
assert.eql(bignum.and(bignum('111111', 16), bignum('111111', 16)).toString(16), '111111');
|
|
assert.eql(bignum.and(bignum('111110', 16), bignum('111111', 16)).toString(16), '111110');
|
|
assert.eql(bignum.and(bignum('111112', 16), bignum('111111', 16)).toString(16), '111110');
|
|
assert.eql(bignum.and(bignum('111121', 16), bignum('111111', 16)).toString(16), '111101');
|
|
assert.eql(bignum.and(bignum('111131', 16), bignum('111111', 16)).toString(16), '111111');
|
|
};
|
|
|
|
exports.or = function () {
|
|
for (var i = 0; i < 256; i += 7) {
|
|
for (var j = 0; j < 256; j += 7) {
|
|
var is = i.toString();
|
|
var js = j.toString();
|
|
var ks = (i | j).toString();
|
|
assert.eql(bignum(i).or(j).toString(), ks);
|
|
assert.eql(bignum(i).or(js).toString(), ks);
|
|
assert.eql(bignum(i).or(bignum(j)).toString(), ks);
|
|
assert.eql(bignum.or(i, j).toString(), ks);
|
|
}
|
|
}
|
|
assert.eql(bignum.or(bignum('111111', 16), bignum('111111', 16)).toString(16), '111111');
|
|
assert.eql(bignum.or(bignum('111110', 16), bignum('111111', 16)).toString(16), '111111');
|
|
assert.eql(bignum.or(bignum('111112', 16), bignum('111111', 16)).toString(16), '111113');
|
|
assert.eql(bignum.or(bignum('111121', 16), bignum('111111', 16)).toString(16), '111131');
|
|
};
|
|
|
|
exports.xor = function () {
|
|
for (var i = 0; i < 256; i += 7) {
|
|
for (var j = 0; j < 256; j += 7) {
|
|
var is = i.toString();
|
|
var js = j.toString();
|
|
var ks = (i ^ j).toString();
|
|
assert.eql(bignum(i).xor(j).toString(), ks);
|
|
assert.eql(bignum(i).xor(js).toString(), ks);
|
|
assert.eql(bignum(i).xor(bignum(j)).toString(), ks);
|
|
assert.eql(bignum.xor(i, j).toString(), ks);
|
|
}
|
|
}
|
|
assert.eql(bignum.xor(bignum('111111', 16), bignum('111111', 16)).toString(), 0);
|
|
assert.eql(bignum.xor(bignum('111110', 16), bignum('111111', 16)).toString(), 1);
|
|
assert.eql(bignum.xor(bignum('111112', 16), bignum('111111', 16)).toString(), 3);
|
|
assert.eql(bignum.xor(bignum('111121', 16), bignum('111111', 16)).toString(), 0x30);
|
|
};
|
|
|
|
exports.rand = function () {
|
|
for (var i = 1; i < 1000; i++) {
|
|
var x = bignum(i).rand().toNumber();
|
|
assert.ok(0 <= x && x < i);
|
|
|
|
var y = bignum(i).rand(i + 10).toNumber();
|
|
assert.ok(i <= y && y < i + 10);
|
|
|
|
var z = bignum.rand(i, i + 10).toNumber();
|
|
assert.ok(i <= z && z < i + 10);
|
|
}
|
|
};
|
|
|
|
exports.primes = function () {
|
|
var ps = { 2 : true, 3 : true, 5 : true, 7 : true };
|
|
for (var i = 0; i <= 10; i++) {
|
|
assert.eql(bignum(i).probPrime(), ps[i] ? true : false);
|
|
}
|
|
|
|
var ns = {
|
|
2 : 3,
|
|
3 : 5,
|
|
15313 : 15319,
|
|
222919 : 222931,
|
|
611939 : 611951,
|
|
334214459 : '334214467',
|
|
961748927 : '961748941',
|
|
9987704933 : '9987704953',
|
|
};
|
|
|
|
Object.keys(ns).forEach(function (n) {
|
|
assert.eql(
|
|
bignum(n).nextPrime().toString(),
|
|
ns[n].toString()
|
|
);
|
|
});
|
|
|
|
var uniques = [
|
|
'3', '11', '37', '101', '9091', '9901', '333667', '909091', '99990001',
|
|
'999999000001', '9999999900000001', '909090909090909091',
|
|
'1111111111111111111', '11111111111111111111111',
|
|
'900900900900990990990991',
|
|
];
|
|
|
|
var wagstaff = [
|
|
'3', '11', '43', '683', '2731', '43691', '174763', '2796203',
|
|
'715827883', '2932031007403', '768614336404564651',
|
|
'201487636602438195784363', '845100400152152934331135470251',
|
|
'56713727820156410577229101238628035243',
|
|
];
|
|
|
|
var big = [
|
|
'4669523849932130508876392554713407521319117239637943224980015676156491',
|
|
'54875133386847519273109693154204970395475080920935355580245252923343305939004903',
|
|
'204005728266090048777253207241416669051476369216501266754813821619984472224780876488344279',
|
|
'2074722246773485207821695222107608587480996474721117292752992589912196684750549658310084416732550077',
|
|
'5628290459057877291809182450381238927697314822133923421169378062922140081498734424133112032854812293',
|
|
];
|
|
|
|
[ uniques, wagstaff, big ].forEach(function (xs) {
|
|
xs.forEach(function (x) {
|
|
var p = bignum(x).probPrime();
|
|
assert.ok(p === true || p === 'maybe');
|
|
});
|
|
});
|
|
};
|
|
|
|
exports.invertm = function () {
|
|
// numbers from http://www.itl.nist.gov/fipspubs/fip186.htm appendix 5
|
|
var q = bignum('b20db0b101df0c6624fc1392ba55f77d577481e5', 16);
|
|
var k = bignum('79577ddcaafddc038b865b19f8eb1ada8a2838c6', 16);
|
|
var kinv = k.invertm(q);
|
|
assert.eql(kinv.toString(16), '2784e3d672d972a74e22c67f4f4f726ecc751efa');
|
|
};
|
|
|
|
exports.shift = function () {
|
|
assert.eql(bignum(37).shiftLeft(2).toString(), (37 << 2).toString()); // 148
|
|
assert.eql(bignum(37).shiftRight(2).toString(), (37 >> 2).toString()); // 9
|
|
|
|
assert.equal(
|
|
bignum(2).pow(Math.pow(2,10)).shiftRight(4).toString(),
|
|
bignum(2).pow(Math.pow(2,10)).div(16).toString()
|
|
);
|
|
};
|
|
|
|
exports.mod = function () {
|
|
assert.eql(bignum(55555).mod(2).toString(), '1');
|
|
assert.eql(
|
|
bignum('1234567').mod(
|
|
bignum('4321')
|
|
).toNumber(),
|
|
1234567 % 4321
|
|
);
|
|
};
|
|
|
|
exports.endian = function () {
|
|
var a = bignum(0x0102030405);
|
|
assert.eql(a.toBuffer({ endian: 'big', size: 2 }).toString('hex'), '000102030405');
|
|
assert.eql(a.toBuffer({ endian: 'little', size: 2 }).toString('hex'), '010003020504');
|
|
|
|
var b = bignum(0x0102030405);
|
|
assert.eql(a.toBuffer({ endian: 'big', size: 'auto' }).toString('hex'), '0102030405');
|
|
assert.eql(a.toBuffer({ endian: 'little', size: 'auto' }).toString('hex'), '0504030201');
|
|
|
|
var c = new Buffer("000102030405", 'hex');
|
|
assert.eql(bignum.fromBuffer(c, { endian: 'big', size: 'auto'}).toString(16), "0102030405");
|
|
assert.eql(bignum.fromBuffer(c, { endian: 'little', size: 'auto'}).toString(16), "050403020100");
|
|
};
|
|
|
|
exports.bitlength = function () {
|
|
var bl = bignum(
|
|
'433593290010590489671135819286259593426549306666324008679782084292'
|
|
+ '2446494189019075159822930571858728009485237489829138626896756141'
|
|
+ '873895833763224917704497568647701157104426'
|
|
).bitLength();
|
|
|
|
assert.equal(bl > 0, true);
|
|
};
|
|
|
|
exports.gcd = function () {
|
|
var b1 = bignum('234897235923342343242');
|
|
var b2 = bignum('234790237101762305340234');
|
|
var expected = bignum('6');
|
|
assert.equal(b1.gcd(b2).toString(), expected.toString());
|
|
};
|
|
|
|
exports.jacobi = function () {
|
|
// test case from p. 134 of D. R. Stinson
|
|
var b1 = bignum('7411');
|
|
var b2 = bignum('9283');
|
|
assert.equal(b1.jacobi(b2), -1);
|
|
|
|
// test case from p. 132 of D. R. Stinson
|
|
b1 = bignum('6278');
|
|
b2 = bignum('9975');
|
|
assert.equal(b1.jacobi(b2), -1);
|
|
|
|
// test case from p. 74 of Men. Oorsh. Vans.
|
|
b1 = bignum('158');
|
|
b2 = bignum('235');
|
|
assert.equal(b1.jacobi(b2), -1);
|
|
|
|
// test case from p. 216 of Kumanduri Romero
|
|
b1 = bignum('4');
|
|
b2 = bignum('7');
|
|
assert.equal(b1.jacobi(b2), 1);
|
|
|
|
// test case from p. 363 of K. R. Rosen
|
|
b1 = bignum('68');
|
|
b2 = bignum('111');
|
|
assert.equal(b1.jacobi(b2), 1);
|
|
};
|
|
|
|
if (process.argv[1] === __filename) {
|
|
assert.eql = assert.deepEqual;
|
|
Object.keys(exports).forEach(function (ex) {
|
|
exports[ex]();
|
|
});
|
|
|
|
if ("function" === typeof gc) {
|
|
gc();
|
|
}
|
|
}
|