diff --git a/PrivateKey.js b/PrivateKey.js index 2e55af6..decc9c7 100644 --- a/PrivateKey.js +++ b/PrivateKey.js @@ -3,8 +3,11 @@ require('classtool'); function ClassSpec(b) { var superclass = b.superclass || require('./util/VersionedData').class(); - function PrivateKey() { + //compressed is true if public key is compressed; false otherwise + function PrivateKey(version, buf, compressed) { PrivateKey.super(this, arguments); + if (compressed !== undefined) + this.compressed(compressed); }; PrivateKey.superclass = superclass; @@ -13,11 +16,52 @@ function ClassSpec(b) { PrivateKey.prototype.validate = function() { this.doAsBinary(function() { PrivateKey.super(this, 'validate', arguments); - if (this.data.length < 32 || this.data.length > 33) + if (this.data.length < 32 || (this.data.length > 1+32 && !this.compressed()) || (this.data.length==1+32+1 && this.data[1+32+1-1]!=1) || this.data.length>1+32+1) throw new Error('invalid data length'); }); }; + // get or set the payload data (as a Buffer object) + // overloaded from VersionedData + PrivateKey.prototype.payload = function(data) { + if(data) { + this.doAsBinary(function() {data.copy(this.data,1);}); + return data; + } + var buf=this.as('binary'); + if (buf.length==1+32+1) + return buf.slice(1,1+32); + else if (buf.length==1+32) + return buf.slice(1); + }; + + // get or set whether the corresponding public key is compressed + PrivateKey.prototype.compressed = function(compressed) { + if (compressed !== undefined) { + this.doAsBinary(function(){ + var len=1+32+1; + if (compressed) { + var data=new Buffer(len); + this.data.copy(data); + this.data=data; + this.data[len-1]=1; + } else { + this.data=this.data.slice(0,len-1); + } + }); + } + else { + var len=1+32+1; + var data=this.as('binary'); + if (data.length==len && data[len-1]==1) + return true; + else if (data.length==len-1) + return false; + else + throw new Error('invalid private key'); + } + }; + return PrivateKey; }; module.defineClass(ClassSpec); diff --git a/WalletKey.js b/WalletKey.js index 1fb8c23..0958509 100644 --- a/WalletKey.js +++ b/WalletKey.js @@ -4,6 +4,7 @@ function ClassSpec(b) { var coinUtil = require('./util/util'); var timeUtil = require('./util/time'); var KeyModule = require('./Key'); + var PrivateKey = require('./PrivateKey').class(); var Address = require('./Address').class(); function WalletKey(cfg) { @@ -21,9 +22,10 @@ function ClassSpec(b) { var pubKey = this.privKey.public.toString('hex'); var pubKeyHash = coinUtil.sha256ripe160(this.privKey.public); var addr = new Address(this.network.addressPubkey, pubKeyHash); + var priv = new PrivateKey(this.network.keySecret, this.privKey.private, this.privKey.compressed); var obj = { created: this.created, - priv: this.privKey.private.toString('hex'), + priv: priv.toString(), pub: pubKey, addr: addr.toString(), }; @@ -34,10 +36,18 @@ function ClassSpec(b) { WalletKey.prototype.fromObj = function(obj) { this.created = obj.created; this.privKey = new KeyModule.Key(); - this.privKey.private = new Buffer(obj.priv, 'hex'); + if (obj.priv.length==64) { + this.privKey.private = new Buffer(obj.priv,'hex'); + this.privKey.compressed = true; + } + else { + var priv = new PrivateKey(obj.priv); + this.privKey.private = new Buffer(priv.payload()); + this.privKey.compressed = priv.compressed(); + } + this.privKey.regenerateSync(); }; return WalletKey; }; module.defineClass(ClassSpec); - diff --git a/test/PrivateKey.js b/test/PrivateKey.js new file mode 100644 index 0000000..2bfae56 --- /dev/null +++ b/test/PrivateKey.js @@ -0,0 +1,15 @@ +var assert = require('assert'); +var PrivateKey = require('../PrivateKey').class(); +var networks = require('../networks'); + +describe('PrivateKey', function(){ + describe('#as', function(){ + it('should convert hex testnet private key with compressed public key to base58check format', function() { + var hex='b9f4892c9e8282028fea1d2667c4dc5213564d41fc5783896a0d843fc15089f3'; + var buf=new Buffer(hex,'hex'); + var result='cTpB4YiyKiBcPxnefsDpbnDxFDffjqJob8wGCEDXxgQ7zQoMXJdH'; + var privkey=new PrivateKey(networks.testnet.keySecret,buf,true); + assert.equal(privkey.as('base58'),result); + }); + }); +}); diff --git a/test/basic.js b/test/basic.js index 3b0f6ff..1ed1148 100644 --- a/test/basic.js +++ b/test/basic.js @@ -56,7 +56,7 @@ function test_decode_priv(b58, payload, isTestnet, isCompressed) var privkey = new PrivateKey(b58); assert.equal(version, privkey.version()); - assert.equal(buf.toString(), privkey.payload().toString()); + assert.equal(buf_pl.toString(), privkey.payload().toString()); } function test_decode_pub(b58, payload, isTestnet, addrType)