diff --git a/index.js b/index.js index 64ce4c147..c245ad6e3 100644 --- a/index.js +++ b/index.js @@ -14,12 +14,12 @@ privsec.base58check = require('./lib/base58check'); privsec.bn = require('./lib/bn'); privsec.constants = require('./lib/constants'); privsec.hash = require('./lib/hash'); +privsec.key = require('./lib/key'); privsec.point = require('./lib/point'); privsec.privkey = require('./lib/privkey'); privsec.pubkey = require('./lib/pubkey'); privsec.random = require('./lib/random'); -//privsec.key = require('lib/key'); //privsec.script = require('lib/script'); //privsec.scriptexec = require('lib/scriptexec'); //privsec.tx = require('lib/tx'); diff --git a/lib/key.js b/lib/key.js new file mode 100644 index 000000000..8bae38ec8 --- /dev/null +++ b/lib/key.js @@ -0,0 +1,46 @@ +var Privkey = require('./privkey'); +var Pubkey = require('./pubkey'); +var Random = require('./random'); +var bn = require('./bn'); +var point = require('./point'); + +function Key(priv, pub) { + this.priv = priv; + this.pub = pub; +}; + +Key.prototype.fromRandom = function() { + do { + var privbuf = Random.getRandomBuffer(32); + this.priv = new Privkey(bn(privbuf)); + var condition = this.priv.n.lt(point.getN()); + } while (!condition); + this.priv2pub(); +}; + +Key.prototype.fromString = function(str) { + var obj = JSON.parse(str); + if (obj.priv) { + this.priv = new Privkey(); + this.priv.fromString(obj.priv); + } + if (obj.pub) { + this.pub = new Pubkey(); + this.pub.fromString(obj.pub); + } +}; + +Key.prototype.priv2pub = function() { + this.pub = new Pubkey(point.getG().mul(this.priv.n)); +}; + +Key.prototype.toString = function() { + var obj = {}; + if (this.priv) + obj.priv = this.priv.toString(); + if (this.pub) + obj.pub = this.pub.toString(); + return JSON.stringify(obj); +}; + +module.exports = Key; diff --git a/lib/privkey.js b/lib/privkey.js index ecb74931c..ed580bf20 100644 --- a/lib/privkey.js +++ b/lib/privkey.js @@ -4,11 +4,12 @@ var constants = require('./constants'); var base58check = require('./base58check'); var Privkey = function(n, network, compressed) { - if (typeof n === 'undefined') - return; - this.setNumber(n); - this.setNetwork(network); - this.setCompressed(compressed); + if (typeof n !== 'undefined') + this.setNumber(n); + if (typeof network !== 'undefined') + this.setNetwork(network); + if (typeof compressed !== 'undefined') + this.setCompressed(compressed); }; Privkey.prototype.setNumber = function(n) { @@ -30,12 +31,14 @@ Privkey.prototype.setCompressed = function(compressed) { }; Privkey.prototype.toWIF = function() { - this.setNetwork(this.network); - this.setCompressed(this.compressed); - var network = this.network; var compressed = this.compressed; + if (typeof this.network === 'undefined') + network = 'mainnet'; + if (typeof this.compressed === 'undefined') + compressed = true; + var privbuf = this.n.toBuffer({size: 32}); var buf; if (compressed) diff --git a/test/test.key.js b/test/test.key.js new file mode 100644 index 000000000..a3caf0a77 --- /dev/null +++ b/test/test.key.js @@ -0,0 +1,100 @@ +var should = require('chai').should(); +var bn = require('../lib/bn'); +var point = require('../lib/point'); +var privkey = require('../lib/privkey'); +var pubkey = require('../lib/pubkey'); +var Key = require('../lib/key'); + +describe('key', function() { + + it('should make a blank key', function() { + var key = new Key(); + should.exist(key); + }); + + it('should make a key with a priv and pub', function() { + var priv = new privkey(); + var pub = new pubkey(); + var key = new Key(priv, pub); + should.exist(key); + should.exist(key.priv); + should.exist(key.pub); + }); + + describe("#fromRandom", function() { + + it('should make a new priv and pub', function() { + var key = new Key(); + key.fromRandom(); + should.exist(key.priv); + should.exist(key.pub); + key.priv.n.gt(bn(0)).should.equal(true); + key.pub.p.getX().gt(bn(0)).should.equal(true); + key.pub.p.getY().gt(bn(0)).should.equal(true); + }); + + }); + + describe("#fromString()", function() { + + it('should recover a key creating with toString', function() { + var key = new Key(); + key.fromRandom(); + var priv = key.priv; + var pub = key.pub; + var str = key.toString(); + key.fromString(str); + should.exist(key.priv); + should.exist(key.pub); + key.priv.toString().should.equal(priv.toString()); + key.pub.toString().should.equal(pub.toString()); + }); + + it('should work with only privkey set', function() { + var key = new Key(); + key.fromRandom(); + key.pub = undefined; + var priv = key.priv; + var str = key.toString(); + key.fromString(str); + should.exist(key.priv); + key.priv.toString().should.equal(priv.toString()); + }); + + it('should work with only pubkey set', function() { + var key = new Key(); + key.fromRandom(); + key.priv = undefined; + var pub = key.pub; + var str = key.toString(); + key.fromString(str); + should.exist(key.pub); + key.pub.toString().should.equal(pub.toString()); + }); + + }); + + describe("#priv2pub", function() { + + it('should convert this known privkey to known pubkey', function() { + var privhex = '906977a061af29276e40bf377042ffbde414e496ae2260bbf1fa9d085637bfff'; + var pubhex = '02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc'; + var key = new Key(); + key.priv = new privkey(bn(new Buffer(privhex, 'hex'))); + key.priv2pub(); + key.pub.toString().should.equal(pubhex); + }); + + }); + + describe("#toString()", function() { + + it('should exist', function() { + var key = new Key(); + key.fromRandom(); + should.exist(key.toString()); + }); + + }); + +});