|
|
@ -7,8 +7,8 @@ var SecureRandom = imports.SecureRandom || require('./SecureRandom'); |
|
|
|
var bignum = imports.bignum || require('./Bignum'); |
|
|
|
var networks = require('../networks'); |
|
|
|
|
|
|
|
var secp256k1_n = new bignum("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", 16); |
|
|
|
var secp256k1_Gx = new bignum("79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", 16); |
|
|
|
var secp256k1_n = new bignum('FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141', 16); |
|
|
|
var secp256k1_Gx = new bignum('79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798', 16); |
|
|
|
|
|
|
|
/* |
|
|
|
random new BIP32: new BIP32(); |
|
|
@ -20,9 +20,9 @@ var BIP32 = function(bytes) { |
|
|
|
bytes = 'livenet'; |
|
|
|
this.version = networks['livenet'].bip32privateVersion; |
|
|
|
} |
|
|
|
else if (bytes == 'testnet') |
|
|
|
else if (bytes == 'testnet') { |
|
|
|
this.version = networks['testnet'].bip32privateVersion; |
|
|
|
|
|
|
|
} |
|
|
|
if (bytes == 'livenet' || bytes == 'testnet') { |
|
|
|
this.depth = 0x00; |
|
|
|
this.parentFingerprint = new Buffer([0, 0, 0, 0]); |
|
|
@ -37,17 +37,17 @@ var BIP32 = function(bytes) { |
|
|
|
} |
|
|
|
|
|
|
|
// decode base58
|
|
|
|
if (typeof bytes === "string") { |
|
|
|
if (typeof bytes === 'string') { |
|
|
|
var decoded = base58.decode(bytes); |
|
|
|
if (decoded.length != 82) |
|
|
|
throw new Error("Not enough data"); |
|
|
|
throw new Error('Not enough data, expected 82 and received '+decoded.length); |
|
|
|
var checksum = decoded.slice(78, 82); |
|
|
|
bytes = decoded.slice(0, 78); |
|
|
|
|
|
|
|
var hash = coinUtil.sha256(coinUtil.sha256(bytes)); |
|
|
|
|
|
|
|
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
|
|
|
|
if (bytes.length < 128/8) |
|
|
|
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); |
|
|
|
bip32.depth = 0x00; |
|
|
@ -85,7 +85,7 @@ BIP32.seed = function(bytes, network) { |
|
|
|
|
|
|
|
BIP32.prototype.initFromBytes = function(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.depth = u8(bytes.slice(4, 5)); |
|
|
@ -116,7 +116,7 @@ BIP32.prototype.initFromBytes = function(bytes) { |
|
|
|
this.pubKeyHash = coinUtil.sha256ripe160(this.eckey.public); |
|
|
|
this.hasPrivateKey = false; |
|
|
|
} else { |
|
|
|
throw new Error("Invalid key"); |
|
|
|
throw new Error('Invalid key'); |
|
|
|
} |
|
|
|
|
|
|
|
this.buildExtendedPublicKey(); |
|
|
@ -137,7 +137,7 @@ BIP32.prototype.buildExtendedPublicKey = function() { |
|
|
|
v = networks['testnet'].bip32publicVersion; |
|
|
|
break; |
|
|
|
default: |
|
|
|
throw new Error("Unknown version"); |
|
|
|
throw new Error('Unknown version'); |
|
|
|
} |
|
|
|
|
|
|
|
// Version
|
|
|
@ -158,15 +158,15 @@ BIP32.prototype.buildExtendedPublicKey = function() { |
|
|
|
} |
|
|
|
|
|
|
|
BIP32.prototype.extendedPublicKeyString = function(format) { |
|
|
|
if (format === undefined || format === "base58") { |
|
|
|
if (format === undefined || format === 'base58') { |
|
|
|
var hash = coinUtil.sha256(coinUtil.sha256(this.extendedPublicKey)); |
|
|
|
var checksum = hash.slice(0, 4); |
|
|
|
var data = Buffer.concat([this.extendedPublicKey, checksum]); |
|
|
|
return base58.encode(data); |
|
|
|
} else if (format === "hex") { |
|
|
|
} else if (format === 'hex') { |
|
|
|
return this.extendedPublicKey.toString('hex');; |
|
|
|
} else { |
|
|
|
throw new Error("bad format"); |
|
|
|
throw new Error('bad format'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -194,15 +194,15 @@ BIP32.prototype.buildExtendedPrivateKey = function() { |
|
|
|
} |
|
|
|
|
|
|
|
BIP32.prototype.extendedPrivateKeyString = function(format) { |
|
|
|
if (format === undefined || format === "base58") { |
|
|
|
if (format === undefined || format === 'base58') { |
|
|
|
var hash = coinUtil.sha256(coinUtil.sha256(this.extendedPrivateKey)); |
|
|
|
var checksum = hash.slice(0, 4); |
|
|
|
var data = Buffer.concat([this.extendedPrivateKey, checksum]); |
|
|
|
return base58.encode(data); |
|
|
|
} else if (format === "hex") { |
|
|
|
} else if (format === 'hex') { |
|
|
|
return this.extendedPrivateKey.toString('hex'); |
|
|
|
} else { |
|
|
|
throw new Error("bad format"); |
|
|
|
throw new Error('bad format'); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
@ -219,7 +219,7 @@ BIP32.prototype.derive = function(path) { |
|
|
|
var c = e[i]; |
|
|
|
|
|
|
|
if (i == 0 ) { |
|
|
|
if (c != 'm') throw new Error("invalid path"); |
|
|
|
if (c != 'm') throw new Error('invalid path'); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
@ -250,7 +250,7 @@ BIP32.prototype.deriveChild = function(i) { |
|
|
|
this.version == networks['testnet'].bip32privateVersion ); |
|
|
|
|
|
|
|
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; |
|
|
|
if (this.hasPrivateKey) { |
|
|
@ -323,7 +323,7 @@ BIP32.prototype.deriveChild = function(i) { |
|
|
|
|
|
|
|
function uint(f, size) { |
|
|
|
if (f.length < size) |
|
|
|
throw new Error("not enough data"); |
|
|
|
throw new Error('not enough data'); |
|
|
|
var n = 0; |
|
|
|
for (var i = 0; i < size; i++) { |
|
|
|
n *= 256; |
|
|
|