add tests for BIP32

This commit is contained in:
Manuel Araoz 2014-04-29 14:37:37 -03:00
parent 6cf690afcc
commit ac719345e8
3 changed files with 33 additions and 20 deletions

View File

@ -26,7 +26,7 @@ module.exports = function(grunt) {
tasks: ['markdown'] tasks: ['markdown']
}, },
scripts: { scripts: {
files: ['**/*.js', '**/*.html', '!**/node_modules/**', '!browser/bundle.js', '!browser/testdata.js', '!browser/vendor-bundle.js'], files: ['**/*.js', '**/*.html', '!**/node_modules/**', '!browser/bundle.js', '!browser/testdata.js', '!browser/vendor-bundle.js', '!docs/**'],
tasks: ['shell'], tasks: ['shell'],
}, },
}, },

View File

@ -7,8 +7,8 @@ var SecureRandom = imports.SecureRandom || require('./SecureRandom');
var bignum = imports.bignum || require('./Bignum'); var bignum = imports.bignum || require('./Bignum');
var networks = require('../networks'); var networks = require('../networks');
var secp256k1_n = new bignum("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16); var secp256k1_n = new bignum('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16);
var secp256k1_Gx = new bignum("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16); var secp256k1_Gx = new bignum('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16);
/* /*
random new BIP32: new BIP32(); random new BIP32: new BIP32();
@ -20,9 +20,9 @@ var BIP32 = function(bytes) {
bytes = 'livenet'; bytes = 'livenet';
this.version = networks['livenet'].bip32privateVersion; this.version = networks['livenet'].bip32privateVersion;
} }
else if (bytes == 'testnet') else if (bytes == 'testnet') {
this.version = networks['testnet'].bip32privateVersion; this.version = networks['testnet'].bip32privateVersion;
}
if (bytes == 'livenet' || bytes == 'testnet') { if (bytes == 'livenet' || bytes == 'testnet') {
this.depth = 0x00; this.depth = 0x00;
this.parentFingerprint = new Buffer([0, 0, 0, 0]); this.parentFingerprint = new Buffer([0, 0, 0, 0]);
@ -37,7 +37,7 @@ var BIP32 = function(bytes) {
} }
// decode base58 // decode base58
if (typeof bytes === "string") { if (typeof bytes === 'string') {
var decoded = base58.decode(bytes); var decoded = base58.decode(bytes);
if (decoded.length != 82) if (decoded.length != 82)
throw new Error('Not enough data, expected 82 and received '+decoded.length); throw new Error('Not enough data, expected 82 and received '+decoded.length);
@ -47,7 +47,7 @@ var BIP32 = function(bytes) {
var hash = coinUtil.sha256(coinUtil.sha256(bytes)); var hash = coinUtil.sha256(coinUtil.sha256(bytes));
if (hash[0] != checksum[0] || hash[1] != checksum[1] || hash[2] != checksum[2] || hash[3] != checksum[3]) { if (hash[0] != checksum[0] || hash[1] != checksum[1] || hash[2] != checksum[2] || hash[3] != checksum[3]) {
throw new Error("Invalid checksum"); throw new Error('Invalid checksum');
} }
} }
@ -63,7 +63,7 @@ BIP32.seed = function(bytes, network) {
bytes = new Buffer(bytes, 'hex'); //if not buffer, assume hex bytes = new Buffer(bytes, 'hex'); //if not buffer, assume hex
if (bytes.length < 128/8) if (bytes.length < 128/8)
return false; //need more entropy return false; //need more entropy
var hash = coinUtil.sha512hmac(bytes, new Buffer("Bitcoin seed")); var hash = coinUtil.sha512hmac(bytes, new Buffer('Bitcoin seed'));
var bip32 = new BIP32(null); var bip32 = new BIP32(null);
bip32.depth = 0x00; bip32.depth = 0x00;
@ -85,7 +85,7 @@ BIP32.seed = function(bytes, network) {
BIP32.prototype.initFromBytes = function(bytes) { BIP32.prototype.initFromBytes = function(bytes) {
// Both pub and private extended keys are 78 bytes // Both pub and private extended keys are 78 bytes
if(bytes.length != 78) throw new Error("not enough data"); if(bytes.length != 78) throw new Error('not enough data');
this.version = u32(bytes.slice(0, 4)); this.version = u32(bytes.slice(0, 4));
this.depth = u8(bytes.slice(4, 5)); this.depth = u8(bytes.slice(4, 5));
@ -116,7 +116,7 @@ BIP32.prototype.initFromBytes = function(bytes) {
this.pubKeyHash = coinUtil.sha256ripe160(this.eckey.public); this.pubKeyHash = coinUtil.sha256ripe160(this.eckey.public);
this.hasPrivateKey = false; this.hasPrivateKey = false;
} else { } else {
throw new Error("Invalid key"); throw new Error('Invalid key');
} }
this.buildExtendedPublicKey(); this.buildExtendedPublicKey();
@ -137,7 +137,7 @@ BIP32.prototype.buildExtendedPublicKey = function() {
v = networks['testnet'].bip32publicVersion; v = networks['testnet'].bip32publicVersion;
break; break;
default: default:
throw new Error("Unknown version"); throw new Error('Unknown version');
} }
// Version // Version
@ -158,15 +158,16 @@ BIP32.prototype.buildExtendedPublicKey = function() {
} }
BIP32.prototype.extendedPublicKeyString = function(format) { BIP32.prototype.extendedPublicKeyString = function(format) {
if (format === undefined || format === "base58") { if (format === undefined || format === 'base58') {
var hash = coinUtil.sha256(coinUtil.sha256(this.extendedPublicKey)); var hash = coinUtil.sha256(coinUtil.sha256(this.extendedPublicKey));
var checksum = hash.slice(0, 4); var checksum = hash.slice(0, 4);
var data = Buffer.concat([this.extendedPublicKey, checksum]); var data = Buffer.concat([this.extendedPublicKey, checksum]);
return base58.encode(data); return base58.encode(data);
} else if (format === "hex") { } else if (format === 'hex') {
alert('calc'+this.extendedPublicKey.toString('hex'));
return this.extendedPublicKey.toString('hex');; return this.extendedPublicKey.toString('hex');;
} else { } else {
throw new Error("bad format"); throw new Error('bad format');
} }
} }
@ -194,15 +195,15 @@ BIP32.prototype.buildExtendedPrivateKey = function() {
} }
BIP32.prototype.extendedPrivateKeyString = function(format) { BIP32.prototype.extendedPrivateKeyString = function(format) {
if (format === undefined || format === "base58") { if (format === undefined || format === 'base58') {
var hash = coinUtil.sha256(coinUtil.sha256(this.extendedPrivateKey)); var hash = coinUtil.sha256(coinUtil.sha256(this.extendedPrivateKey));
var checksum = hash.slice(0, 4); var checksum = hash.slice(0, 4);
var data = Buffer.concat([this.extendedPrivateKey, checksum]); var data = Buffer.concat([this.extendedPrivateKey, checksum]);
return base58.encode(data); return base58.encode(data);
} else if (format === "hex") { } else if (format === 'hex') {
return this.extendedPrivateKey.toString('hex'); return this.extendedPrivateKey.toString('hex');
} else { } else {
throw new Error("bad format"); throw new Error('bad format');
} }
} }
@ -219,7 +220,7 @@ BIP32.prototype.derive = function(path) {
var c = e[i]; var c = e[i];
if (i == 0 ) { if (i == 0 ) {
if (c != 'm') throw new Error("invalid path"); if (c != 'm') throw new Error('invalid path');
continue; continue;
} }
@ -250,7 +251,7 @@ BIP32.prototype.deriveChild = function(i) {
this.version == networks['testnet'].bip32privateVersion ); this.version == networks['testnet'].bip32privateVersion );
if (usePrivate && (!this.hasPrivateKey || !isPrivate)) if (usePrivate && (!this.hasPrivateKey || !isPrivate))
throw new Error("Cannot do private key derivation without private key"); throw new Error('Cannot do private key derivation without private key');
var ret = null; var ret = null;
if (this.hasPrivateKey) { if (this.hasPrivateKey) {
@ -323,7 +324,7 @@ BIP32.prototype.deriveChild = function(i) {
function uint(f, size) { function uint(f, size) {
if (f.length < size) if (f.length < size)
throw new Error("not enough data"); throw new Error('not enough data');
var n = 0; var n = 0;
for (var i = 0; i < size; i++) { for (var i = 0; i < size; i++) {
n *= 256; n *= 256;

View File

@ -291,7 +291,19 @@ describe('BIP32', function() {
bip32.extendedPrivateKeyString().should.equal(vector2_m_private); bip32.extendedPrivateKeyString().should.equal(vector2_m_private);
bip32.extendedPublicKeyString().should.equal(vector2_m_public); bip32.extendedPublicKeyString().should.equal(vector2_m_public);
}); });
});
describe('testnet', function() {
it('should initialize a new BIP32 correctly from a random BIP32', function() {
var b1 = new BIP32('testnet');
var b2 = new BIP32(b1.extendedPublicKeyString());
b2.extendedPublicKeyString().should.equal(b1.extendedPublicKeyString());
});
it('should generate valid ext pub key for testnet', function() {
var b = new BIP32('testnet');
b.extendedPublicKeyString().substring(0,4).should.equal('tpub');
});
}); });
}); });