From 91181de234a2403474eab838b2f6b2b31015e749 Mon Sep 17 00:00:00 2001 From: "Ryan X. Charles" Date: Thu, 27 Mar 2014 18:59:47 -0400 Subject: [PATCH] add new Point class and update BIP32 to use it The Point class will ultimately be an all purpose tool for dealing with points on the secp256k1 tool. For now, it just needs to have the ability to add two points together, and work both in node and the browser, so that it can be used for BIP32. --- BIP32.js | 24 ++++++------------ Point.js | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+), 17 deletions(-) create mode 100644 Point.js diff --git a/BIP32.js b/BIP32.js index 6efb73a..878a1ac 100644 --- a/BIP32.js +++ b/BIP32.js @@ -2,6 +2,7 @@ var imports = require('soop').imports(); var base58 = imports.base58 || require('base58-native').base58; var coinUtil = imports.coinUtil || require('./util/util'); var Key = imports.Key || require('./Key'); +var Point = imports.Point || require('./Point'); var bignum = imports.bignum || require('bignum'); var crypto = require('crypto'); var networks = require('./networks'); @@ -266,31 +267,20 @@ BIP32.prototype.derive_child = function(i) { var ir = hash.slice(32, 64); // Ki = (IL + kpar)*G = IL*G + Kpar - var key = new Key(); - key.private = il.toBuffer({size: 32}); - key.regenerateSync(); - key.compressed = false; + var ilGkey = new Key(); + ilGkey.private = il.toBuffer({size: 32}); + ilGkey.regenerateSync(); + var ilG = Point.fromKey(ilGkey); var oldkey = new Key(); oldkey.public = this.eckey.public; - oldkey.compressed = false; - var newpub = Key.addUncompressed(key.public, oldkey.public); - - var eckey = new Key(); - eckey.compressed = false; - eckey.public = newpub; - if (eckey.public === null) { - console.log('invalid public key'); - return this.derive_child(i+1); - } - eckey.compressed = true; + var Kpar = Point.fromKey(oldkey); + var newpub = Point.add(ilG, Kpar).toKey().public; ret = new BIP32(); ret.chain_code = new Buffer(ir); var eckey = new Key(); - eckey.compressed = false; eckey.public = newpub; - eckey.compressed = true; ret.eckey = eckey; ret.has_private_key = false; } diff --git a/Point.js b/Point.js new file mode 100644 index 0000000..b028e37 --- /dev/null +++ b/Point.js @@ -0,0 +1,75 @@ +var imports = require('soop').imports(); +var Key = imports.Key || require('./Key'); +var bignum = imports.bignum || require('bignum'); + +//a point on the secp256k1 curve +//x and y are bignums +var Point = function(x, y) { + this.x = x; + this.y = y; +}; + +Point.add = function(p1, p2) { + + //node + if (process.versions) { + var key1 = p1.toKey(); + key1.compressed = false; + var key2 = p2.toKey(); + key2.compressed = false; + var pubKey = Key.addUncompressed(key1.public, key2.public); + var key = new Key(); + key.compressed = false; + key.public = pubKey; + key.compressed = true; + return Point.fromKey(key); + } + + //browser + else { + } + +}; + +//convert the public key of a Key into a Point +Point.fromKey = function(key) { + + //node + if (process.versions) { + var point = new Point(); + var pubKeyBuf = new Buffer(key.public); + var key2 = new Key(); + key2.compressed = key.compressed; + key2.public = pubKeyBuf; + key2.compressed = false; + point.x = bignum.fromBuffer(key2.public.slice(1, 33), {size: 32}); + point.y = bignum.fromBuffer(key2.public.slice(33, 65), {size: 32}); + return point; + } + + //browser + else { + } +}; + +//convert the Point into the Key containing a compressed public key +Point.prototype.toKey = function() { + + //node + if (process.versions) { + var xbuf = this.x.toBuffer({size: 32}); + var ybuf = this.y.toBuffer({size: 32}); + var key = new Key(); + key.compressed = false; + var prefix = new Buffer([0x04]); + key.public = Buffer.concat([prefix, xbuf, ybuf]); //this is probably wrong + key.compressed = true; + return key; + } + + //browser + else { + } +}; + +module.exports = require('soop')(Point);