diff --git a/lib/browser/Point.js b/lib/browser/Point.js index 4e6aee3..b70b532 100644 --- a/lib/browser/Point.js +++ b/lib/browser/Point.js @@ -3,10 +3,7 @@ var Key = require('./Key'); var bignum = require('bignum'); var assert = require('assert'); -var ECPointFp = require('../../browser/vendor-bundle.js').ECPointFp; -var ECFieldElementFp = require('../../browser/vendor-bundle.js').ECFieldElementFp; -var getSECCurveByName = require('../../browser/vendor-bundle.js').getSECCurveByName; -var BigInteger = require('../../browser/vendor-bundle.js').BigInteger; +var elliptic = require('elliptic'); //a point on the secp256k1 curve //x and y are bignums @@ -16,81 +13,21 @@ var Point = function(x, y) { }; Point.add = function(p1, p2) { - var ecparams = getSECCurveByName('secp256k1'); - - var p1xhex = p1.x.toBuffer({ - size: 32 - }).toString('hex'); - var p1x = new BigInteger(p1xhex, 16); - var p1yhex = p1.y.toBuffer({ - size: 32 - }).toString('hex'); - var p1y = new BigInteger(p1yhex, 16); - var p1px = new ECFieldElementFp(ecparams.getCurve().getQ(), p1x); - var p1py = new ECFieldElementFp(ecparams.getCurve().getQ(), p1y); - var p1p = new ECPointFp(ecparams.getCurve(), p1px, p1py); - - var p2xhex = p2.x.toBuffer({ - size: 32 - }).toString('hex'); - var p2x = new BigInteger(p2xhex, 16); - var p2yhex = p2.y.toBuffer({ - size: 32 - }).toString('hex'); - var p2y = new BigInteger(p2yhex, 16); - var p2px = new ECFieldElementFp(ecparams.getCurve().getQ(), p2x); - var p2py = new ECFieldElementFp(ecparams.getCurve().getQ(), p2y); - var p2p = new ECPointFp(ecparams.getCurve(), p2px, p2py); - - var p = p1p.add(p2p); - - var point = new Point(); - var pointxbuf = new Buffer(p.getX().toBigInteger().toByteArrayUnsigned()); - point.x = bignum.fromBuffer(pointxbuf, { - size: pointxbuf.length - }); - assert(pointxbuf.length <= 32); - var pointybuf = new Buffer(p.getY().toBigInteger().toByteArrayUnsigned()); - assert(pointybuf.length <= 32); - point.y = bignum.fromBuffer(pointybuf, { - size: pointybuf.length - }); - - return point; + var ec = elliptic.curves.secp256k1; + var ecp1 = ec.curve.point(p1.x, p1.y); + var ecp2 = ec.curve.point(p2.x, p2.y); + var ecp3 = ecp1.add(ecp2); + //var p3 = ec.curve.point(ecp3.x, ecp3.y); + var p3 = new Point(ecp3.x, ecp3.y); + return p3; }; -Point.multiply = function(p1, x) { - var x = new BigInteger(x.toString('hex'), 16); - - var ecparams = getSECCurveByName('secp256k1'); - - var p1xhex = p1.x.toBuffer({ - size: 32 - }).toString('hex'); - var p1x = new BigInteger(p1xhex, 16); - var p1yhex = p1.y.toBuffer({ - size: 32 - }).toString('hex'); - var p1y = new BigInteger(p1yhex, 16); - var p1px = new ECFieldElementFp(ecparams.getCurve().getQ(), p1x); - var p1py = new ECFieldElementFp(ecparams.getCurve().getQ(), p1y); - var p1p = new ECPointFp(ecparams.getCurve(), p1px, p1py); - - var p = p1p.multiply(x); - - var point = new Point(); - var pointxbuf = new Buffer(p.getX().toBigInteger().toByteArrayUnsigned()); - point.x = bignum.fromBuffer(pointxbuf, { - size: pointxbuf.length - }); - assert(pointxbuf.length <= 32); - var pointybuf = new Buffer(p.getY().toBigInteger().toByteArrayUnsigned()); - assert(pointybuf.length <= 32); - point.y = bignum.fromBuffer(pointybuf, { - size: pointybuf.length - }); - - return point; +Point.multiply = function(p1, xbuf) { + var ec = elliptic.curves.secp256k1; + var ecp1 = ec.curve.point(p1.x, p1.y); + var ecp = ecp1.mul(xbuf); + var p = new Point(ecp.x, ecp.y); + return p; }; //convert the public key of a Key into a Point diff --git a/package.json b/package.json index 1ce272f..f91be85 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ "mocha": ">=1.15.1", "sjcl": "=1.0.1", "bn.js": "=0.13.2", + "elliptic": "=0.15.7", "bindings": "=1.1.1", "bufferput": "git://github.com/bitpay/node-bufferput.git", "bignum": "=0.6.2", diff --git a/test/test.Point.js b/test/test.Point.js index 9ec2ff7..a17875c 100644 --- a/test/test.Point.js +++ b/test/test.Point.js @@ -68,4 +68,36 @@ describe('Point', function() { point.y.toBuffer({size: 32}).toString('hex').should.equal(ayhex); }); + describe('#multiply', function() { + + it('should multiply this number by 2', function() { + var axhex = "69b154b42ff9452c31251cb341d7db01ad603dc56d64f9c5fb9e7031b89a241d"; + var axbuf = new Buffer(axhex, 'hex'); + var ayhex = "eeedc91342b3c8982c1e676435780fe5f9d62f3f692e8d1512485d77fab35997"; + var aybuf = new Buffer(ayhex, 'hex'); + var a = new Point(bignum.fromBuffer(axbuf, {size: 32}), bignum.fromBuffer(aybuf, {size: 32})); + + var x = new bignum(2); + var xbuf = x.toBuffer({size: 32}); + var mult = Point.multiply(a, xbuf); + mult.x.toBuffer({size: 32}).toString('hex').should.equal('f81b3dcae4eeb504d2898500721ece357767b9564bdf03dce95a3db12de72d3a'); + mult.y.toBuffer({size: 32}).toString('hex').should.equal('e0220ac6e8524ca3f80c2c65a390dacc0371a6875afc8546d621eb20284e5568'); + }); + + it('should multiply this number by 200', function() { + var axhex = "69b154b42ff9452c31251cb341d7db01ad603dc56d64f9c5fb9e7031b89a241d"; + var axbuf = new Buffer(axhex, 'hex'); + var ayhex = "eeedc91342b3c8982c1e676435780fe5f9d62f3f692e8d1512485d77fab35997"; + var aybuf = new Buffer(ayhex, 'hex'); + var a = new Point(bignum.fromBuffer(axbuf, {size: 32}), bignum.fromBuffer(aybuf, {size: 32})); + + var x = new bignum(200); + var xbuf = x.toBuffer({size: 32}); + var mult = Point.multiply(a, xbuf); + mult.x.toBuffer({size: 32}).toString('hex').should.equal('91c03d9104df24f01d69702c680a53a9b46ba49de89ab27819ea02c61229bace'); + mult.y.toBuffer({size: 32}).toString('hex').should.equal('5d2fdbdeab06383f14b2702e893444be5e80af58cecb9a70c1ae22e9daab69c1'); + }); + + }); + });