Update sjcl and delete custom ripemd160, montgomery, and jacobi

This commit is contained in:
Chris Clark
2015-05-26 10:32:52 -07:00
parent ebbec1954e
commit 50cda426eb
9 changed files with 60 additions and 524 deletions

40
npm-shrinkwrap.json generated
View File

@@ -5,16 +5,16 @@
"node-version": "v0.12.3",
"dependencies": {
"async": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/async/-/async-0.9.0.tgz"
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz"
},
"babel-runtime": {
"version": "5.3.3",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.3.3.tgz",
"version": "5.4.7",
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.4.7.tgz",
"dependencies": {
"core-js": {
"version": "0.9.9",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-0.9.9.tgz"
"version": "0.9.13",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-0.9.13.tgz"
}
}
},
@@ -27,8 +27,8 @@
"resolved": "https://registry.npmjs.org/extend/-/extend-1.2.1.tgz"
},
"lodash": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.8.0.tgz"
"version": "3.9.3",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-3.9.3.tgz"
},
"lru-cache": {
"version": "2.5.2",
@@ -39,24 +39,24 @@
"resolved": "https://registry.npmjs.org/ripple-wallet-generator/-/ripple-wallet-generator-1.0.3.tgz"
},
"sjcl": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.2.tgz"
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/sjcl/-/sjcl-1.0.3.tgz"
},
"ws": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-0.7.1.tgz",
"version": "0.7.2",
"resolved": "https://registry.npmjs.org/ws/-/ws-0.7.2.tgz",
"dependencies": {
"bufferutil": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-1.0.1.tgz",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-1.1.0.tgz",
"dependencies": {
"bindings": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
},
"nan": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-1.6.2.tgz"
"version": "1.8.4",
"resolved": "https://registry.npmjs.org/nan/-/nan-1.8.4.tgz"
}
}
},
@@ -69,16 +69,16 @@
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.1.tgz"
},
"utf-8-validate": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-1.0.1.tgz",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/utf-8-validate/-/utf-8-validate-1.1.0.tgz",
"dependencies": {
"bindings": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz"
},
"nan": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-1.6.2.tgz"
"version": "1.8.4",
"resolved": "https://registry.npmjs.org/nan/-/nan-1.8.4.tgz"
}
}
}

View File

@@ -21,7 +21,7 @@
"lodash": "^3.1.0",
"lru-cache": "~2.5.0",
"ripple-wallet-generator": "^1.0.3",
"sjcl": "^1.0.2",
"sjcl": "^1.0.3",
"ws": "~0.7.1"
},
"devDependencies": {

View File

@@ -1,11 +1,8 @@
'use strict';
require('./sjcl-ecc-pointextras.js');
require('./sjcl-secp256k1.js');
require('./sjcl-ripemd160.js');
require('./sjcl-extramath.js');
require('./sjcl-montgomery.js');
require('./sjcl-validecc.js');
require('./sjcl-ecdsa-canonical.js');
require('./sjcl-ecdsa-der.js');
require('./sjcl-ecdsa-recoverablepublickey.js');
require('./sjcl-jacobi.js');

View File

@@ -125,7 +125,7 @@ function recoverPublicKeyPointFromSignature(curve, signature_r, signature_s,
// Conversion
var alpha = x.mul(x).mul(x).add(curve.a.mul(x)).add(curve.b).mod(
field_modulus);
var beta = alpha.powermodMontgomery(FIELD_MODULUS_PLUS_ONE_DIVIDED_BY_FOUR,
var beta = alpha.powermod(FIELD_MODULUS_PLUS_ONE_DIVIDED_BY_FOUR,
field_modulus);
// If beta is even but y isn't or

View File

@@ -1,56 +0,0 @@
/* eslint new-cap: [2, {newIsCapExceptions: ["bn"]}] */
'use strict';
var sjcl = require('sjcl');
sjcl.bn.prototype.jacobi = function(that) {
var self = this;
that = new sjcl.bn(that);
if (that.sign() === -1) {
return undefined;
}
// 1. If a = 0 then return(0).
if (self.equals(0)) {
return 0;
}
// 2. If a = 1 then return(1).
if (self.equals(1)) {
return 1;
}
var s = 0;
// 3. Write a = 2^e * a1, where a1 is odd.
var e = 0;
while (!self.testBit(e)) {
e++;
}
var a1 = self.shiftRight(e);
// 4. If e is even then set s ← 1.
if ((e & 1) === 0) {
s = 1;
} else {
var residue = that.modInt(8);
if (residue === 1 || residue === 7) {
// Otherwise set s ← 1 if n ≡ 1 or 7 (mod 8)
s = 1;
} else if (residue === 3 || residue === 5) {
// Or set s ← 1 if n ≡ 3 or 5 (mod 8).
s = -1;
}
}
// 5. If n ≡ 3 (mod 4) and a1 ≡ 3 (mod 4) then set s ← s.
if (that.modInt(4) === 3 && a1.modInt(4) === 3) {
s = -s;
}
if (a1.equals(1)) {
return s;
}
return s * that.mod(a1).jacobi(a1);
};

View File

@@ -1,160 +0,0 @@
/* eslint-disable */
/* this is implemented in sjcl, but has not yet been released as of v1.0.2 */
var sjcl = require('sjcl');
sjcl.bn.prototype.invDigit = function ()
{
var radixMod = 1 + this.radixMask;
if (this.limbs.length < 1) return 0;
var x = this.limbs[0];
if ((x&1) == 0) return 0;
var y = x&3; // y == 1/x mod 2^2
y = (y*(2-(x&0xf)*y))&0xf; // y == 1/x mod 2^4
y = (y*(2-(x&0xff)*y))&0xff; // y == 1/x mod 2^8
y = (y*(2-(((x&0xffff)*y)&0xffff)))&0xffff; // y == 1/x mod 2^16
// last step - calculate inverse mod DV directly;
// assumes 16 < radixMod <= 32 and assumes ability to handle 48-bit ints
y = (y*(2-x*y%radixMod))%radixMod; // y == 1/x mod 2^dbits
// we really want the negative inverse, and -DV < y < DV
return (y>0)?radixMod-y:-y;
};
// returns bit length of the integer x
function nbits(x) {
var r = 1, t;
if((t=x>>>16) != 0) { x = t; r += 16; }
if((t=x>>8) != 0) { x = t; r += 8; }
if((t=x>>4) != 0) { x = t; r += 4; }
if((t=x>>2) != 0) { x = t; r += 2; }
if((t=x>>1) != 0) { x = t; r += 1; }
return r;
}
// JSBN-style add and multiply for SJCL w/ 24 bit radix
sjcl.bn.prototype.am = function (i,x,w,j,c,n) {
var xl = x&0xfff, xh = x>>12;
while (--n >= 0) {
var l = this.limbs[i]&0xfff;
var h = this.limbs[i++]>>12;
var m = xh*l+h*xl;
l = xl*l+((m&0xfff)<<12)+w.limbs[j]+c;
c = (l>>24)+(m>>12)+xh*h;
w.limbs[j++] = l&0xffffff;
}
return c;
}
var Montgomery = function (m)
{
this.m = m;
this.mt = m.limbs.length;
this.mt2 = this.mt * 2;
this.mp = m.invDigit();
this.mpl = this.mp&0x7fff;
this.mph = this.mp>>15;
this.um = (1<<(m.radix-15))-1;
};
Montgomery.prototype.reduce = function (x)
{
var radixMod = x.radixMask + 1;
while (x.limbs.length <= this.mt2) // pad x so am has enough room later
x.limbs[x.limbs.length] = 0;
for (var i = 0; i < this.mt; ++i) {
// faster way of calculating u0 = x[i]*mp mod 2^radix
var j = x.limbs[i]&0x7fff;
var u0 = (j*this.mpl+(((j*this.mph+(x.limbs[i]>>15)*this.mpl)&this.um)<<15))&x.radixMask;
// use am to combine the multiply-shift-add into one call
j = i+this.mt;
x.limbs[j] += this.m.am(0,u0,x,i,0,this.mt);
// propagate carry
while (x.limbs[j] >= radixMod) { x.limbs[j] -= radixMod; x.limbs[++j]++; }
}
x.trim();
x = x.shiftRight(this.mt * this.m.radix);
if (x.greaterEquals(this.m)) x = x.sub(this.m);
return x.trim().normalize().reduce();
};
Montgomery.prototype.square = function (x)
{
return this.reduce(x.square());
};
Montgomery.prototype.multiply = function (x, y)
{
return this.reduce(x.mul(y));
};
Montgomery.prototype.convert = function (x)
{
return x.abs().shiftLeft(this.mt * this.m.radix).mod(this.m);
};
Montgomery.prototype.revert = function (x)
{
return this.reduce(x.copy());
};
sjcl.bn.prototype.powermodMontgomery = function (e, m)
{
var i = e.bitLength(), k, r = new this._class(1);
if (i <= 0) return r;
else if (i < 18) k = 1;
else if (i < 48) k = 3;
else if (i < 144) k = 4;
else if (i < 768) k = 5;
else k = 6;
if (i < 8 || !m.testBit(0)) {
// For small exponents and even moduli, use a simple square-and-multiply
// algorithm.
return this.powermod(e, m);
}
var z = new Montgomery(m);
e.trim().normalize();
// precomputation
var g = new Array(), n = 3, k1 = k-1, km = (1<<k)-1;
g[1] = z.convert(this);
if (k > 1) {
var g2 = z.square(g[1]);
while (n <= km) {
g[n] = z.multiply(g2, g[n-2]);
n += 2;
}
}
var j = e.limbs.length-1, w, is1 = true, r2 = new this._class(), t;
i = nbits(e.limbs[j])-1;
while (j >= 0) {
if (i >= k1) w = (e.limbs[j]>>(i-k1))&km;
else {
w = (e.limbs[j]&((1<<(i+1))-1))<<(k1-i);
if (j > 0) w |= e.limbs[j-1]>>(this.radix+i-k1);
}
n = k;
while ((w&1) == 0) { w >>= 1; --n; }
if ((i -= n) < 0) { i += this.radix; --j; }
if (is1) { // ret == 1, don't bother squaring or multiplying it
r = g[w].copy();
is1 = false;
} else {
while (n > 1) { r2 = z.square(r); r = z.square(r2); n -= 2; }
if (n > 0) r2 = z.square(r); else { t = r; r = r2; r2 = t; }
r = z.multiply(r2,g[w]);
}
while (j >= 0 && (e.limbs[j]&(1<<i)) == 0) {
r2 = z.square(r); t = r; r = r2; r2 = t;
if (--i < 0) { i = this.radix-1; --j; }
}
}
return z.revert(r);
}

View File

@@ -1,211 +0,0 @@
/* eslint-disable */
/* this is implemented in sjcl, but has not yet been released as of v1.0.2 */
var sjcl = require('sjcl');
/** @fileOverview Javascript RIPEMD-160 implementation.
*
* @author Artem S Vybornov <vybornov@gmail.com>
*/
(function() {
/**
* Context for a RIPEMD-160 operation in progress.
* @constructor
* @class RIPEMD, 160 bits.
*/
sjcl.hash.ripemd160 = function (hash) {
if (hash) {
this._h = hash._h.slice(0);
this._buffer = hash._buffer.slice(0);
this._length = hash._length;
} else {
this.reset();
}
};
/**
* Hash a string or an array of words.
* @static
* @param {bitArray|String} data the data to hash.
* @return {bitArray} The hash value, an array of 5 big-endian words.
*/
sjcl.hash.ripemd160.hash = function (data) {
return (new sjcl.hash.ripemd160()).update(data).finalize();
};
sjcl.hash.ripemd160.prototype = {
/**
* Reset the hash state.
* @return this
*/
reset: function () {
this._h = _h0.slice(0);
this._buffer = [];
this._length = 0;
return this;
},
/**
* Reset the hash state.
* @param {bitArray|String} data the data to hash.
* @return this
*/
update: function (data) {
if ( typeof data === "string" )
data = sjcl.codec.utf8String.toBits(data);
var i, b = this._buffer = sjcl.bitArray.concat(this._buffer, data),
ol = this._length,
nl = this._length = ol + sjcl.bitArray.bitLength(data);
for (i = 512+ol & -512; i <= nl; i+= 512) {
var words = b.splice(0,16);
for ( var w = 0; w < 16; ++w )
words[w] = _cvt(words[w]);
_block.call( this, words );
}
return this;
},
/**
* Complete hashing and output the hash value.
* @return {bitArray} The hash value, an array of 5 big-endian words.
*/
finalize: function () {
var b = sjcl.bitArray.concat( this._buffer, [ sjcl.bitArray.partial(1,1) ] ),
l = ( this._length + 1 ) % 512,
z = ( l > 448 ? 512 : 448 ) - l % 448,
zp = z % 32;
if ( zp > 0 )
b = sjcl.bitArray.concat( b, [ sjcl.bitArray.partial(zp,0) ] )
for ( ; z >= 32; z -= 32 )
b.push(0);
b.push( _cvt( this._length | 0 ) );
b.push( _cvt( Math.floor(this._length / 0x100000000) ) );
while ( b.length ) {
var words = b.splice(0,16);
for ( var w = 0; w < 16; ++w )
words[w] = _cvt(words[w]);
_block.call( this, words );
}
var h = this._h;
this.reset();
for ( var w = 0; w < 5; ++w )
h[w] = _cvt(h[w]);
return h;
}
};
var _h0 = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];
var _k1 = [ 0x00000000, 0x5a827999, 0x6ed9eba1, 0x8f1bbcdc, 0xa953fd4e ];
var _k2 = [ 0x50a28be6, 0x5c4dd124, 0x6d703ef3, 0x7a6d76e9, 0x00000000 ];
for ( var i = 4; i >= 0; --i ) {
for ( var j = 1; j < 16; ++j ) {
_k1.splice(i,0,_k1[i]);
_k2.splice(i,0,_k2[i]);
}
}
var _r1 = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13 ];
var _r2 = [ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11 ];
var _s1 = [ 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6 ];
var _s2 = [ 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 ];
function _f0(x,y,z) {
return x ^ y ^ z;
};
function _f1(x,y,z) {
return (x & y) | (~x & z);
};
function _f2(x,y,z) {
return (x | ~y) ^ z;
};
function _f3(x,y,z) {
return (x & z) | (y & ~z);
};
function _f4(x,y,z) {
return x ^ (y | ~z);
};
function _rol(n,l) {
return (n << l) | (n >>> (32-l));
}
function _cvt(n) {
return ( (n & 0xff << 0) << 24 )
| ( (n & 0xff << 8) << 8 )
| ( (n & 0xff << 16) >>> 8 )
| ( (n & 0xff << 24) >>> 24 );
}
function _block(X) {
var A1 = this._h[0], B1 = this._h[1], C1 = this._h[2], D1 = this._h[3], E1 = this._h[4],
A2 = this._h[0], B2 = this._h[1], C2 = this._h[2], D2 = this._h[3], E2 = this._h[4];
var j = 0, T;
for ( ; j < 16; ++j ) {
T = _rol( A1 + _f0(B1,C1,D1) + X[_r1[j]] + _k1[j], _s1[j] ) + E1;
A1 = E1; E1 = D1; D1 = _rol(C1,10); C1 = B1; B1 = T;
T = _rol( A2 + _f4(B2,C2,D2) + X[_r2[j]] + _k2[j], _s2[j] ) + E2;
A2 = E2; E2 = D2; D2 = _rol(C2,10); C2 = B2; B2 = T; }
for ( ; j < 32; ++j ) {
T = _rol( A1 + _f1(B1,C1,D1) + X[_r1[j]] + _k1[j], _s1[j] ) + E1;
A1 = E1; E1 = D1; D1 = _rol(C1,10); C1 = B1; B1 = T;
T = _rol( A2 + _f3(B2,C2,D2) + X[_r2[j]] + _k2[j], _s2[j] ) + E2;
A2 = E2; E2 = D2; D2 = _rol(C2,10); C2 = B2; B2 = T; }
for ( ; j < 48; ++j ) {
T = _rol( A1 + _f2(B1,C1,D1) + X[_r1[j]] + _k1[j], _s1[j] ) + E1;
A1 = E1; E1 = D1; D1 = _rol(C1,10); C1 = B1; B1 = T;
T = _rol( A2 + _f2(B2,C2,D2) + X[_r2[j]] + _k2[j], _s2[j] ) + E2;
A2 = E2; E2 = D2; D2 = _rol(C2,10); C2 = B2; B2 = T; }
for ( ; j < 64; ++j ) {
T = _rol( A1 + _f3(B1,C1,D1) + X[_r1[j]] + _k1[j], _s1[j] ) + E1;
A1 = E1; E1 = D1; D1 = _rol(C1,10); C1 = B1; B1 = T;
T = _rol( A2 + _f1(B2,C2,D2) + X[_r2[j]] + _k2[j], _s2[j] ) + E2;
A2 = E2; E2 = D2; D2 = _rol(C2,10); C2 = B2; B2 = T; }
for ( ; j < 80; ++j ) {
T = _rol( A1 + _f4(B1,C1,D1) + X[_r1[j]] + _k1[j], _s1[j] ) + E1;
A1 = E1; E1 = D1; D1 = _rol(C1,10); C1 = B1; B1 = T;
T = _rol( A2 + _f0(B2,C2,D2) + X[_r2[j]] + _k2[j], _s2[j] ) + E2;
A2 = E2; E2 = D2; D2 = _rol(C2,10); C2 = B2; B2 = T; }
T = this._h[1] + C1 + D2;
this._h[1] = this._h[2] + D1 + E2;
this._h[2] = this._h[3] + E1 + A2;
this._h[3] = this._h[4] + A1 + B2;
this._h[4] = this._h[0] + B1 + C2;
this._h[0] = T;
}
})();

View File

@@ -1,47 +0,0 @@
var assert = require('assert');
var sjcl = require('ripple-lib').sjcl;
describe('SJCL Jacobi', function() {
it('(15/13) = -1', function () {
var jac = new sjcl.bn(15).jacobi(13);
assert.strictEqual(jac, -1);
});
it('(4/97) = 1', function () {
var jac = new sjcl.bn(4).jacobi(97);
assert.strictEqual(jac, 1);
});
it('(17/17) = 0', function () {
var jac = new sjcl.bn(17).jacobi(17);
assert.strictEqual(jac, 0);
});
it('(34/17) = 0', function () {
var jac = new sjcl.bn(34).jacobi(17);
assert.strictEqual(jac, 0);
});
it('(19/45) = 1', function () {
var jac = new sjcl.bn(19).jacobi(45);
assert.strictEqual(jac, 1);
});
it('(8/21) = -1', function () {
var jac = new sjcl.bn(8).jacobi(21);
assert.strictEqual(jac, -1);
});
it('(5/21) = 1', function () {
var jac = new sjcl.bn(5).jacobi(21);
assert.strictEqual(jac, 1);
});
it('(1001/9907) = -1', function () {
var jac = new sjcl.bn(1001).jacobi(9907);
assert.strictEqual(jac, -1);
});
it('(1236/20003) = 1', function () {
var jac = new sjcl.bn(1236).jacobi(20003);
assert.strictEqual(jac, 1);
});
it('With huge numbers', function () {
var jac = new sjcl.bn("217033ffbc5a462201407027104916c5e7bf09f2b0c926f7c5cb20858be29d92e7fe67080eeb268fcbc2bc44d9cecfe1d3acbb302111eba355a8b769ed4bdbf773d37dca47e2293c173ff4f84b38f4e84bfad7cc1a913d70e11cf664a95575b80ec9d10123289b402ad2c71c70f2dc28360262d3d703faa964c741a711e4eebd324d659601dd14564fcd8c5908bbf8c97cf3ff82f083da3005848b48cb545b31be2039cca1d67714f32d32b3228c1a659415ee6c138ca274f789006a90a9a41bbc3934b84c78948eae8351f45696fa716b1328561f4c3bbb44ac73112c291b6b4587365e44fa09d583fb8074eb35bf947231e500c0d2c79c5fb957e50e84f6c9").jacobi("c7f1bc1dfb1be82d244aef01228c1409c198894eca9e21430f1669b4aa3864c9f37f3d51b2b4ba1ab9e80f59d267fda1521e88b05117993175e004543c6e3611242f24432ce8efa3b81f0ff660b4f91c5d52f2511a6f38181a7bf9abeef72db056508bbb4eeb5f65f161dd2d5b439655d2ae7081fcc62fdcb281520911d96700c85cdaf12e7d1f15b55ade867240722425198d4ce39019550c4c8a921fc231d3e94297688c2d77cd68ee8fdeda38b7f9a274701fef23b4eaa6c1a9c15b2d77f37634930386fc20ec291be95aed9956801e1c76601b09c413ad915ff03bfdc0b6b233686ae59e8caf11750b509ab4e57ee09202239baee3d6e392d1640185e1cd");
assert.strictEqual(jac, -1);
});
});
// vim:sw=2:sts=2:ts=8:et

View File

@@ -1,15 +1,28 @@
var assert = require('assert');
var sjcl = require('ripple-lib').sjcl;
/* eslint-disable max-len */
/* eslint new-cap: [2, {newIsCapExceptions: ["bn"]}] */
'use strict';
const assert = require('assert');
const sjcl = require('ripple-lib').sjcl;
// fix normalize bug in scjl:
// https://github.com/bitwiseshiftleft/sjcl/pull/221
function normalizeFix(bn) {
while (bn.limbs.length > 0 && bn.limbs[bn.limbs.length - 1] === 0) {
bn.limbs.pop();
}
return bn;
}
function testExp(vec) {
var actual = new sjcl.bn(vec.g).powermodMontgomery(new sjcl.bn(vec.e),
new sjcl.bn(vec.m));
assert.strictEqual(actual.toString(), new sjcl.bn(vec.r).toString());
const actual = normalizeFix(new sjcl.bn(vec.g).powermod(
new sjcl.bn(vec.e), new sjcl.bn(vec.m)));
const expected = new sjcl.bn(vec.r);
assert.strictEqual(actual.toString(), expected.toString());
}
describe('SJCL Montgomery Exponentiation', function() {
describe('powermod', function() {
it('test 1', function () {
it('test 1', function() {
testExp({
g: 2,
e: 3,
@@ -17,15 +30,15 @@ describe('SJCL Montgomery Exponentiation', function() {
r: 2
});
});
it('test 2', function () {
it('test 2', function() {
testExp({
g: 2,
e: "10000000000000000000000000",
e: '10000000000000000000000000',
m: 1337,
r: 1206
});
});
it('test 3', function () {
it('test 3', function() {
testExp({
g: 17,
e: 90,
@@ -33,15 +46,15 @@ describe('SJCL Montgomery Exponentiation', function() {
r: 28445204336
});
});
it('test 4', function () {
it('test 4', function() {
testExp({
g: 2,
e: "0x844A000000000000000000000",
e: '0x844A000000000000000000000',
m: 13,
r: 9
});
});
it('test 5', function () {
it('test 5', function() {
testExp({
g: 2,
e: 0x1010,
@@ -49,36 +62,36 @@ describe('SJCL Montgomery Exponentiation', function() {
r: 59
});
});
it('test 6', function () {
it('test 6', function() {
testExp({
g: 2,
e: "43207437777777877617151",
e: '43207437777777877617151',
m: 13,
r: 2
});
});
it('test 7', function () {
it('test 7', function() {
testExp({
g: 2,
e: "389274238947216444871600001871964319565192765874149",
e: '389274238947216444871600001871964319565192765874149',
m: 117,
r: 44
});
});
it('test 8', function () {
it('test 8', function() {
testExp({
g: 2,
e: "89457115510016156219817846189181057618965150496979174671534084187",
m: "1897166415676096761",
r: "16840615e646a4c5c8d"
e: '89457115510016156219817846189181057618965150496979174671534084187',
m: '1897166415676096761',
r: '16840615e646a4c5c8d'
});
});
it('test 9', function () {
it('test 9', function() {
testExp({
g: "4c3399bebab284bc7f9056efe17ea39db324ffa1d52dc1542eb16a749570789359f192535b7bcb514b36be9cdb4fb2a6ba3ad6b4248034e9a1d2a8612cd9d885242b4f679524121b74f79d7db14859fccde1c0dfe6ef002dcbc777ab5fcf4432",
e: "000322e6b6dafe138ccd6a991977d19",
m: "a5091daa41997943e3c98469e93377f668d05d8059bc53f72aaacdac3729a3070dc7439a5171160bf9ec2826b7191b03b0e84b28e14dd376de35d29a96f686666e053ab62a41ebc2b5f52e8cf06254100fd153a1cda4485f170c39c54689e52d",
r: "554336ea044782d29f091117cfeaeee2334b4242bd7428d0bba3ce5325781dc219e891e54698cb0193ffe7c6fc07f1808f6685e64b6a082815f6afd2e16c7a61316b5e3e59cd8b3984d5a76c8e173f8615f7dceac0c99e27e4abfb1278dfa67f"
g: '4c3399bebab284bc7f9056efe17ea39db324ffa1d52dc1542eb16a749570789359f192535b7bcb514b36be9cdb4fb2a6ba3ad6b4248034e9a1d2a8612cd9d885242b4f679524121b74f79d7db14859fccde1c0dfe6ef002dcbc777ab5fcf4432',
e: '000322e6b6dafe138ccd6a991977d19',
m: 'a5091daa41997943e3c98469e93377f668d05d8059bc53f72aaacdac3729a3070dc7439a5171160bf9ec2826b7191b03b0e84b28e14dd376de35d29a96f686666e053ab62a41ebc2b5f52e8cf06254100fd153a1cda4485f170c39c54689e52d',
r: '554336ea044782d29f091117cfeaeee2334b4242bd7428d0bba3ce5325781dc219e891e54698cb0193ffe7c6fc07f1808f6685e64b6a082815f6afd2e16c7a61316b5e3e59cd8b3984d5a76c8e173f8615f7dceac0c99e27e4abfb1278dfa67f'
});
});
});