Merge pull request #9 from ryanxcharles/feature/compressed-public-keys

Save private keys in base58check encoded format
This commit is contained in:
Ryan X. Charles 2014-01-02 06:32:37 -08:00
commit 013778d0f0
4 changed files with 75 additions and 6 deletions

View File

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

View File

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

15
test/PrivateKey.js Normal file
View File

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

View File

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