diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 4278d4f7..d02334d6 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -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" } } } diff --git a/package.json b/package.json index c7a440dc..826da3ab 100644 --- a/package.json +++ b/package.json @@ -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": { diff --git a/src/sjcl-custom/index.js b/src/sjcl-custom/index.js index e807b2f4..7c0b9c2f 100644 --- a/src/sjcl-custom/index.js +++ b/src/sjcl-custom/index.js @@ -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'); diff --git a/src/sjcl-custom/sjcl-ecdsa-recoverablepublickey.js b/src/sjcl-custom/sjcl-ecdsa-recoverablepublickey.js index 3de08c3b..468abc5d 100644 --- a/src/sjcl-custom/sjcl-ecdsa-recoverablepublickey.js +++ b/src/sjcl-custom/sjcl-ecdsa-recoverablepublickey.js @@ -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 diff --git a/src/sjcl-custom/sjcl-jacobi.js b/src/sjcl-custom/sjcl-jacobi.js deleted file mode 100644 index c99f62ff..00000000 --- a/src/sjcl-custom/sjcl-jacobi.js +++ /dev/null @@ -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); -}; diff --git a/src/sjcl-custom/sjcl-montgomery.js b/src/sjcl-custom/sjcl-montgomery.js deleted file mode 100644 index f05ffb10..00000000 --- a/src/sjcl-custom/sjcl-montgomery.js +++ /dev/null @@ -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< 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< - */ -(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; -} - -})(); diff --git a/test/sjcl-jacobi-test.js b/test/sjcl-jacobi-test.js deleted file mode 100644 index 78d15f99..00000000 --- a/test/sjcl-jacobi-test.js +++ /dev/null @@ -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 diff --git a/test/sjcl-montgomery.js b/test/sjcl-montgomery.js index cbd1f690..5ec9cbf2 100644 --- a/test/sjcl-montgomery.js +++ b/test/sjcl-montgomery.js @@ -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' }); }); });