/* global describe, it */ var assert = require('assert'); var BN = require('../').BN; describe('BN.js/Reduction context', function () { function testMethod (name, fn) { describe(name + ' method', function () { it('should support add, iadd, sub, isub operations', function () { var p = new BN(257); var m = fn(p); var a = new BN(123).toRed(m); var b = new BN(231).toRed(m); assert.equal(a.redAdd(b).fromRed().toString(10), '97'); assert.equal(a.redSub(b).fromRed().toString(10), '149'); assert.equal(b.redSub(a).fromRed().toString(10), '108'); assert.equal(a.clone().redIAdd(b).fromRed().toString(10), '97'); assert.equal(a.clone().redISub(b).fromRed().toString(10), '149'); assert.equal(b.clone().redISub(a).fromRed().toString(10), '108'); }); it('should support pow and mul operations', function () { var p192 = new BN( 'fffffffffffffffffffffffffffffffeffffffffffffffff', 16); var m = fn(p192); var a = new BN(123); var b = new BN(231); var c = a.toRed(m).redMul(b.toRed(m)).fromRed(); assert(c.cmp(a.mul(b).mod(p192)) === 0); assert.equal(a.toRed(m).redPow(new BN(3)).fromRed() .cmp(a.sqr().mul(a)), 0); assert.equal(a.toRed(m).redPow(new BN(4)).fromRed() .cmp(a.sqr().sqr()), 0); assert.equal(a.toRed(m).redPow(new BN(8)).fromRed() .cmp(a.sqr().sqr().sqr()), 0); assert.equal(a.toRed(m).redPow(new BN(9)).fromRed() .cmp(a.sqr().sqr().sqr().mul(a)), 0); assert.equal(a.toRed(m).redPow(new BN(17)).fromRed() .cmp(a.sqr().sqr().sqr().sqr().mul(a)), 0); assert.equal( a.toRed(m).redPow(new BN('deadbeefabbadead', 16)).fromRed() .toString(16), '3aa0e7e304e320b68ef61592bcb00341866d6fa66e11a4d6'); }); it('should sqrtm numbers', function () { var p = new BN(263); var m = fn(p); var q = new BN(11).toRed(m); var qr = q.redSqrt(); assert.equal(qr.redSqr().cmp(q), 0); qr = q.redSqrt(); assert.equal(qr.redSqr().cmp(q), 0); p = new BN( 'fffffffffffffffffffffffffffffffeffffffffffffffff', 16); m = fn(p); q = new BN(13).toRed(m); qr = q.redSqrt(true, p); assert.equal(qr.redSqr().cmp(q), 0); qr = q.redSqrt(false, p); assert.equal(qr.redSqr().cmp(q), 0); // Tonelli-shanks p = new BN(13); m = fn(p); q = new BN(10).toRed(m); assert.equal(q.redSqrt().fromRed().toString(10), '7'); }); it('should invm numbers', function () { var p = new BN(257); var m = fn(p); var a = new BN(3).toRed(m); var b = a.redInvm(); assert.equal(a.redMul(b).fromRed().toString(16), '1'); }); it('should invm numbers (regression)', function () { var p = new BN( 'ffffffff00000001000000000000000000000000ffffffffffffffffffffffff', 16); var a = new BN( 'e1d969b8192fbac73ea5b7921896d6a2263d4d4077bb8e5055361d1f7f8163f3', 16); var m = fn(p); a = a.toRed(m); assert.equal(a.redInvm().fromRed().negative, 0); }); it('should imul numbers', function () { var p = new BN( 'fffffffffffffffffffffffffffffffeffffffffffffffff', 16); var m = fn(p); var a = new BN('deadbeefabbadead', 16); var b = new BN('abbadeadbeefdead', 16); var c = a.mul(b).mod(p); assert.equal(a.toRed(m).redIMul(b.toRed(m)).fromRed().toString(16), c.toString(16)); }); it('should pow(base, 0) == 1', function () { var base = new BN(256).toRed(BN.red('k256')); var exponent = new BN(0); var result = base.redPow(exponent); assert.equal(result.toString(), '1'); }); it('should shl numbers', function () { var base = new BN(256).toRed(BN.red('k256')); var result = base.redShl(1); assert.equal(result.toString(), '512'); }); it('should reduce when converting to red', function () { var p = new BN(257); var m = fn(p); var a = new BN(5).toRed(m); assert.doesNotThrow(function () { var b = a.redISub(new BN(512).toRed(m)); b.redISub(new BN(512).toRed(m)); }); }); it('redNeg and zero value', function () { var a = new BN(0).toRed(BN.red('k256')).redNeg(); assert.equal(a.isZero(), true); }); it('should not allow modulus <= 1', function () { assert.throws(function () { BN.red(new BN(0)); }, /^Error: modulus must be greater than 1$/); assert.throws(function () { BN.red(new BN(1)); }, /^Error: modulus must be greater than 1$/); assert.doesNotThrow(function () { BN.red(new BN(2)); }); }); }); } testMethod('Plain', BN.red); testMethod('Montgomery', BN.mont); describe('Pseudo-Mersenne Primes', function () { it('should reduce numbers mod k256', function () { var p = BN._prime('k256'); assert.equal(p.ireduce(new BN(0xdead)).toString(16), 'dead'); assert.equal(p.ireduce(new BN('deadbeef', 16)).toString(16), 'deadbeef'); var num = new BN('fedcba9876543210fedcba9876543210dead' + 'fedcba9876543210fedcba9876543210dead', 16); var exp = num.mod(p.p).toString(16); assert.equal(p.ireduce(num).toString(16), exp); var regr = new BN('f7e46df64c1815962bf7bc9c56128798' + '3f4fcef9cb1979573163b477eab93959' + '335dfb29ef07a4d835d22aa3b6797760' + '70a8b8f59ba73d56d01a79af9', 16); exp = regr.mod(p.p).toString(16); assert.equal(p.ireduce(regr).toString(16), exp); }); it('should not fail to invm number mod k256', function () { var regr2 = new BN( '6c150c4aa9a8cf1934485d40674d4a7cd494675537bda36d49405c5d2c6f496f', 16); regr2 = regr2.toRed(BN.red('k256')); assert.equal(regr2.redInvm().redMul(regr2).fromRed().cmpn(1), 0); }); it('should correctly square the number', function () { var p = BN._prime('k256').p; var red = BN.red('k256'); var n = new BN('9cd8cb48c3281596139f147c1364a3ed' + 'e88d3f310fdb0eb98c924e599ca1b3c9', 16); var expected = n.sqr().mod(p); var actual = n.toRed(red).redSqr().fromRed(); assert.equal(actual.toString(16), expected.toString(16)); }); it('redISqr should return right result', function () { var n = new BN('30f28939', 16); var actual = n.toRed(BN.red('k256')).redISqr().fromRed(); assert.equal(actual.toString(16), '95bd93d19520eb1'); }); }); it('should avoid 4.1.0 regresion', function () { function bits2int (obits, q) { var bits = new BN(obits); var shift = (obits.length << 3) - q.bitLength(); if (shift > 0) { bits.ishrn(shift); } return bits; } var t = new Buffer('aff1651e4cd6036d57aa8b2a05ccf1a9d5a40166340ecbbdc55' + 'be10b568aa0aa3d05ce9a2fcec9df8ed018e29683c6051cb83e' + '46ce31ba4edb045356a8d0d80b', 'hex'); var g = new BN('5c7ff6b06f8f143fe8288433493e4769c4d988ace5be25a0e24809670' + '716c613d7b0cee6932f8faa7c44d2cb24523da53fbe4f6ec3595892d1' + 'aa58c4328a06c46a15662e7eaa703a1decf8bbb2d05dbe2eb956c142a' + '338661d10461c0d135472085057f3494309ffa73c611f78b32adbb574' + '0c361c9f35be90997db2014e2ef5aa61782f52abeb8bd6432c4dd097b' + 'c5423b285dafb60dc364e8161f4a2a35aca3a10b1c4d203cc76a470a3' + '3afdcbdd92959859abd8b56e1725252d78eac66e71ba9ae3f1dd24871' + '99874393cd4d832186800654760e1e34c09e4d155179f9ec0dc4473f9' + '96bdce6eed1cabed8b6f116f7ad9cf505df0f998e34ab27514b0ffe7', 16); var p = new BN('9db6fb5951b66bb6fe1e140f1d2ce5502374161fd6538df1648218642' + 'f0b5c48c8f7a41aadfa187324b87674fa1822b00f1ecf8136943d7c55' + '757264e5a1a44ffe012e9936e00c1d3e9310b01c7d179805d3058b2a9' + 'f4bb6f9716bfe6117c6b5b3cc4d9be341104ad4a80ad6c94e005f4b99' + '3e14f091eb51743bf33050c38de235567e1b34c3d6a5c0ceaa1a0f368' + '213c3d19843d0b4b09dcb9fc72d39c8de41f1bf14d4bb4563ca283716' + '21cad3324b6a2d392145bebfac748805236f5ca2fe92b871cd8f9c36d' + '3292b5509ca8caa77a2adfc7bfd77dda6f71125a7456fea153e433256' + 'a2261c6a06ed3693797e7995fad5aabbcfbe3eda2741e375404ae25b', 16); var q = new BN('f2c3119374ce76c9356990b465374a17f23f9ed35089bd969f61c6dde' + '9998c1f', 16); var k = bits2int(t, q); var expectedR = '89ec4bb1400eccff8e7d9aa515cd1de7803f2daff09693ee7fd1353e' + '90a68307'; var r = g.toRed(BN.mont(p)).redPow(k).fromRed().mod(q); assert.equal(r.toString(16), expectedR); }); it('K256.split for 512 bits number should return equal numbers', function () { var red = BN.red('k256'); var input = new BN(1).iushln(512).subn(1); assert.equal(input.bitLength(), 512); var output = new BN(0); red.prime.split(input, output); assert.equal(input.cmp(output), 0); }); });
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 19553 | swellard | Move and rename clients | ||
//guest/perforce_software/helix-web-services/main/source/clients/2016.1.0/javascript/node_modules/bn.js/test/red-test.js | |||||
#2 | 19053 | tjuricek |
Rebuild JavaScript Client SDK. The JavaScript client now is a "typed" approach that tends to be similar in approach to the other clients, based on the swagger definition for the platform version. Importantly, client SDK tests are individual scripts (that run under node) that are actually controlled via TestNG. This approach now lets us use a consistent test reporting format so we can at least collect reports from each of the jobs. The documentation is still in progress, that I want to validate as the tests are generated. |
||
#1 | 18810 | tjuricek |
First-pass at JavaScript client SDK. JavaScript requires Node with Gulp to "browserfy" the library. It's the easiest way I found to use the swagger-js project; bundle up a wrapping method. There is no JavaScript reference guide. The swagger-js doesn't really document what they do very well, actually. Overall I'm not particularly impressed by swagger-js, it was hard to even figure out what the right method syntax was. We may want to invest time in doing it better. This required setting CORS response headers, which are currently defaulted to a fairly insecure setting. |