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.
This commit is contained in:
Ryan X. Charles 2014-03-27 18:59:47 -04:00
parent 5c21866fe2
commit 91181de234
2 changed files with 82 additions and 17 deletions

View File

@ -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;
}

75
Point.js Normal file
View File

@ -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);