Merge pull request #9 from ryanxcharles/feature/compressed-public-keys
Save private keys in base58check encoded format
This commit is contained in:
commit
013778d0f0
|
@ -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);
|
||||
|
|
14
WalletKey.js
14
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();
|
||||
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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue