Beta 7 with some repo names changed.

This commit is contained in:
Luis Fernando Molina committed 2020-11-15 13:05:19 +01:00
1 parent 0f7b40cca7
commit 963c19493a
3408 files changed
+462217 -15516

No files matched your search

@@ -0,0 +1,255 @@
'use strict';
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var assert = _interopDefault(require('assert'));
var safeBuffer = _interopDefault(require('safe-buffer'));
var bs58check = _interopDefault(require('bs58check'));
var cryptoShim = require("../shims/hdkey-crypto");
var secp256k1Shim = require("../shims/hdkey-secp256k1v3");
var Buffer = safeBuffer.Buffer;
var MASTER_SECRET = Buffer.from('Bitcoin seed', 'utf8');
var HARDENED_OFFSET = 0x80000000;
var LEN = 78;
// Bitcoin hardcoded by default, can use package `coininfo` for others
var BITCOIN_VERSIONS = {private: 0x0488ADE4, public: 0x0488B21E};
function HDKey (versions) {
this.versions = versions || BITCOIN_VERSIONS;
this.depth = 0;
this.index = 0;
this._privateKey = null;
this._publicKey = null;
this.chainCode = null;
this._fingerprint = 0;
this.parentFingerprint = 0;
}
Object.defineProperty(HDKey.prototype, 'fingerprint', { get: function () { return this._fingerprint } });
Object.defineProperty(HDKey.prototype, 'identifier', { get: function () { return this._identifier } });
Object.defineProperty(HDKey.prototype, 'pubKeyHash', { get: function () { return this.identifier } });
Object.defineProperty(HDKey.prototype, 'privateKey', {
get: function () {
return this._privateKey
},
set: function (value) {
assert.equal(value.length, 32, 'Private key must be 32 bytes.');
assert(secp256k1Shim.privateKeyVerify(value) === true, 'Invalid private key');
this._privateKey = value;
this._publicKey = secp256k1Shim.publicKeyCreate(value, true);
this._identifier = hash160(this.publicKey);
this._fingerprint = this._identifier.slice(0, 4).readUInt32BE(0);
}
});
Object.defineProperty(HDKey.prototype, 'publicKey', {
get: function () {
return this._publicKey
},
set: function (value) {
assert(value.length === 33 || value.length === 65, 'Public key must be 33 or 65 bytes.');
assert(secp256k1Shim.publicKeyVerify(value) === true, 'Invalid public key');
this._publicKey = secp256k1Shim.publicKeyConvert(value, true); // force compressed point
this._identifier = hash160(this.publicKey);
this._fingerprint = this._identifier.slice(0, 4).readUInt32BE(0);
this._privateKey = null;
}
});
Object.defineProperty(HDKey.prototype, 'privateExtendedKey', {
get: function () {
if (this._privateKey) return bs58check.encode(serialize(this, this.versions.private, Buffer.concat([Buffer.alloc(1, 0), this.privateKey])))
else return null
}
});
Object.defineProperty(HDKey.prototype, 'publicExtendedKey', {
get: function () {
return bs58check.encode(serialize(this, this.versions.public, this.publicKey))
}
});
HDKey.prototype.derive = function (path) {
if (path === 'm' || path === 'M' || path === "m'" || path === "M'") {
return this
}
var entries = path.split('/');
var hdkey = this;
entries.forEach(function (c, i) {
if (i === 0) {
assert(/^[mM]{1}/.test(c), 'Path must start with "m" or "M"');
return
}
var hardened = (c.length > 1) && (c[c.length - 1] === "'");
var childIndex = parseInt(c, 10); // & (HARDENED_OFFSET - 1)
assert(childIndex < HARDENED_OFFSET, 'Invalid index');
if (hardened) childIndex += HARDENED_OFFSET;
hdkey = hdkey.deriveChild(childIndex);
});
return hdkey
};
HDKey.prototype.deriveChild = function (index) {
var isHardened = index >= HARDENED_OFFSET;
var indexBuffer = Buffer.allocUnsafe(4);
indexBuffer.writeUInt32BE(index, 0);
var data;
if (isHardened) { // Hardened child
assert(this.privateKey, 'Could not derive hardened child key');
var pk = this.privateKey;
var zb = Buffer.alloc(1, 0);
pk = Buffer.concat([zb, pk]);
// data = 0x00 || ser256(kpar) || ser32(index)
data = Buffer.concat([pk, indexBuffer]);
} else { // Normal child
// data = serP(point(kpar)) || ser32(index)
// = serP(Kpar) || ser32(index)
data = Buffer.concat([this.publicKey, indexBuffer]);
}
var I = cryptoShim.createHmac('sha512', this.chainCode).update(data).digest();
var IL = I.slice(0, 32);
var IR = I.slice(32);
var hd = new HDKey(this.versions);
// Private parent key -> private child key
if (this.privateKey) {
// ki = parse256(IL) + kpar (mod n)
try {
hd.privateKey = secp256k1Shim.privateKeyTweakAdd(this.privateKey, IL);
// throw if IL >= n || (privateKey + IL) === 0
} catch (err) {
// In case parse256(IL) >= n or ki == 0, one should proceed with the next value for i
return this.deriveChild(index + 1)
}
// Public parent key -> public child key
} else {
// Ki = point(parse256(IL)) + Kpar
// = G*IL + Kpar
try {
hd.publicKey = secp256k1Shim.publicKeyTweakAdd(this.publicKey, IL, true);
// throw if IL >= n || (g**IL + publicKey) is infinity
} catch (err) {
// In case parse256(IL) >= n or Ki is the point at infinity, one should proceed with the next value for i
return this.deriveChild(index + 1)
}
}
hd.chainCode = IR;
hd.depth = this.depth + 1;
hd.parentFingerprint = this.fingerprint;// .readUInt32BE(0)
hd.index = index;
return hd
};
HDKey.prototype.sign = function (hash) {
return secp256k1Shim.sign(hash, this.privateKey).signature
};
HDKey.prototype.verify = function (hash, signature) {
return secp256k1Shim.verify(hash, signature, this.publicKey)
};
HDKey.prototype.wipePrivateData = function () {
if (this._privateKey) cryptoShim.randomBytes(this._privateKey.length).copy(this._privateKey);
this._privateKey = null;
return this
};
HDKey.prototype.toJSON = function () {
return {
xpriv: this.privateExtendedKey,
xpub: this.publicExtendedKey
}
};
HDKey.fromMasterSeed = function (seedBuffer, versions) {
var I = cryptoShim.createHmac('sha512', MASTER_SECRET).update(seedBuffer).digest();
var IL = I.slice(0, 32);
var IR = I.slice(32);
var hdkey = new HDKey(versions);
hdkey.chainCode = IR;
hdkey.privateKey = IL;
return hdkey
};
HDKey.fromExtendedKey = function (base58key, versions) {
// => version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
versions = versions || BITCOIN_VERSIONS;
var hdkey = new HDKey(versions);
var keyBuffer = bs58check.decode(base58key);
var version = keyBuffer.readUInt32BE(0);
assert(version === versions.private || version === versions.public, 'Version mismatch: does not match private or public');
hdkey.depth = keyBuffer.readUInt8(4);
hdkey.parentFingerprint = keyBuffer.readUInt32BE(5);
hdkey.index = keyBuffer.readUInt32BE(9);
hdkey.chainCode = keyBuffer.slice(13, 45);
var key = keyBuffer.slice(45);
if (key.readUInt8(0) === 0) { // private
assert(version === versions.private, 'Version mismatch: version does not match private');
hdkey.privateKey = key.slice(1); // cut off first 0x0 byte
} else {
assert(version === versions.public, 'Version mismatch: version does not match public');
hdkey.publicKey = key;
}
return hdkey
};
HDKey.fromJSON = function (obj) {
return HDKey.fromExtendedKey(obj.xpriv)
};
function serialize (hdkey, version, key) {
// => version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
var buffer = Buffer.allocUnsafe(LEN);
buffer.writeUInt32BE(version, 0);
buffer.writeUInt8(hdkey.depth, 4);
var fingerprint = hdkey.depth ? hdkey.parentFingerprint : 0x00000000;
buffer.writeUInt32BE(fingerprint, 5);
buffer.writeUInt32BE(hdkey.index, 9);
hdkey.chainCode.copy(buffer, 13);
key.copy(buffer, 45);
return buffer
}
function hash160 (buf) {
var sha = cryptoShim.createHash('sha256').update(buf).digest();
return cryptoShim.createHash('ripemd160').update(sha).digest()
}
HDKey.HARDENED_OFFSET = HARDENED_OFFSET;
var hdkey = HDKey;
module.exports = hdkey;
@@ -0,0 +1,206 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var createHash = _interopDefault(require('create-hash'));
var pbkdf2 = _interopDefault(require('pbkdf2'));
var randombytes = _interopDefault(require('randombytes'));
function unwrapExports (x) {
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}
function createCommonjsModule(fn, module) {
return module = { exports: {} }, fn(module, module.exports), module.exports;
}
var emptyModule = /*#__PURE__*/Object.freeze({
__proto__: null
});
var src = createCommonjsModule(function (module, exports) {
Object.defineProperty(exports, "__esModule", { value: true });
let DEFAULT_WORDLIST = emptyModule._default;
const INVALID_MNEMONIC = 'Invalid mnemonic';
const INVALID_ENTROPY = 'Invalid entropy';
const INVALID_CHECKSUM = 'Invalid mnemonic checksum';
const WORDLIST_REQUIRED = 'A wordlist is required but a default could not be found.\n' +
'Please explicitly pass a 2048 word array explicitly.';
function lpad(str, padString, length) {
while (str.length < length)
str = padString + str;
return str;
}
function binaryToByte(bin) {
return parseInt(bin, 2);
}
function bytesToBinary(bytes) {
return bytes.map(x => lpad(x.toString(2), '0', 8)).join('');
}
function deriveChecksumBits(entropyBuffer) {
const ENT = entropyBuffer.length * 8;
const CS = ENT / 32;
const hash = createHash('sha256')
.update(entropyBuffer)
.digest();
return bytesToBinary([...hash]).slice(0, CS);
}
function salt(password) {
return 'mnemonic' + (password || '');
}
function mnemonicToSeedSync(mnemonic, password) {
const mnemonicBuffer = Buffer.from((mnemonic || '').normalize('NFKD'), 'utf8');
const saltBuffer = Buffer.from(salt((password || '').normalize('NFKD')), 'utf8');
return pbkdf2.pbkdf2Sync(mnemonicBuffer, saltBuffer, 2048, 64, 'sha512');
}
exports.mnemonicToSeedSync = mnemonicToSeedSync;
function mnemonicToSeed(mnemonic, password) {
return new Promise((resolve, reject) => {
try {
const mnemonicBuffer = Buffer.from((mnemonic || '').normalize('NFKD'), 'utf8');
const saltBuffer = Buffer.from(salt((password || '').normalize('NFKD')), 'utf8');
pbkdf2.pbkdf2(mnemonicBuffer, saltBuffer, 2048, 64, 'sha512', (err, data) => {
if (err)
return reject(err);
else
return resolve(data);
});
}
catch (error) {
return reject(error);
}
});
}
exports.mnemonicToSeed = mnemonicToSeed;
function mnemonicToEntropy(mnemonic, wordlist) {
wordlist = wordlist || DEFAULT_WORDLIST;
if (!wordlist) {
throw new Error(WORDLIST_REQUIRED);
}
const words = (mnemonic || '').normalize('NFKD').split(' ');
if (words.length % 3 !== 0)
throw new Error(INVALID_MNEMONIC);
// convert word indices to 11 bit binary strings
const bits = words
.map(word => {
const index = wordlist.indexOf(word);
if (index === -1)
throw new Error(INVALID_MNEMONIC);
return lpad(index.toString(2), '0', 11);
})
.join('');
// split the binary string into ENT/CS
const dividerIndex = Math.floor(bits.length / 33) * 32;
const entropyBits = bits.slice(0, dividerIndex);
const checksumBits = bits.slice(dividerIndex);
// calculate the checksum and compare
const entropyBytes = entropyBits.match(/(.{1,8})/g).map(binaryToByte);
if (entropyBytes.length < 16)
throw new Error(INVALID_ENTROPY);
if (entropyBytes.length > 32)
throw new Error(INVALID_ENTROPY);
if (entropyBytes.length % 4 !== 0)
throw new Error(INVALID_ENTROPY);
const entropy = Buffer.from(entropyBytes);
const newChecksum = deriveChecksumBits(entropy);
if (newChecksum !== checksumBits)
throw new Error(INVALID_CHECKSUM);
return entropy.toString('hex');
}
exports.mnemonicToEntropy = mnemonicToEntropy;
function entropyToMnemonic(entropy, wordlist) {
if (!Buffer.isBuffer(entropy))
entropy = Buffer.from(entropy, 'hex');
wordlist = wordlist || DEFAULT_WORDLIST;
if (!wordlist) {
throw new Error(WORDLIST_REQUIRED);
}
// 128 <= ENT <= 256
if (entropy.length < 16)
throw new TypeError(INVALID_ENTROPY);
if (entropy.length > 32)
throw new TypeError(INVALID_ENTROPY);
if (entropy.length % 4 !== 0)
throw new TypeError(INVALID_ENTROPY);
const entropyBits = bytesToBinary([...entropy]);
const checksumBits = deriveChecksumBits(entropy);
const bits = entropyBits + checksumBits;
const chunks = bits.match(/(.{1,11})/g);
const words = chunks.map(binary => {
const index = binaryToByte(binary);
return wordlist[index];
});
return wordlist[0] === '\u3042\u3044\u3053\u304f\u3057\u3093' // Japanese wordlist
? words.join('\u3000')
: words.join(' ');
}
exports.entropyToMnemonic = entropyToMnemonic;
function generateMnemonic(strength, rng, wordlist) {
strength = strength || 128;
if (strength % 32 !== 0)
throw new TypeError(INVALID_ENTROPY);
rng = rng || randombytes;
return entropyToMnemonic(rng(strength / 8), wordlist);
}
exports.generateMnemonic = generateMnemonic;
function validateMnemonic(mnemonic, wordlist) {
try {
mnemonicToEntropy(mnemonic, wordlist);
}
catch (e) {
return false;
}
return true;
}
exports.validateMnemonic = validateMnemonic;
function setDefaultWordlist(language) {
const result = emptyModule.wordlists[language];
if (result)
DEFAULT_WORDLIST = result;
else
throw new Error('Could not find wordlist for language "' + language + '"');
}
exports.setDefaultWordlist = setDefaultWordlist;
function getDefaultWordlist() {
if (!DEFAULT_WORDLIST)
throw new Error('No Default Wordlist set');
return Object.keys(emptyModule.wordlists).filter(lang => {
if (lang === 'JA' || lang === 'EN')
return false;
return emptyModule.wordlists[lang].every((word, index) => word === DEFAULT_WORDLIST[index]);
})[0];
}
exports.getDefaultWordlist = getDefaultWordlist;
var _wordlists_2 = emptyModule;
exports.wordlists = _wordlists_2.wordlists;
});
var index = unwrapExports(src);
var src_1 = src.mnemonicToSeedSync;
var src_2 = src.mnemonicToSeed;
var src_3 = src.mnemonicToEntropy;
var src_4 = src.entropyToMnemonic;
var src_5 = src.generateMnemonic;
var src_6 = src.validateMnemonic;
var src_7 = src.setDefaultWordlist;
var src_8 = src.getDefaultWordlist;
var src_9 = src.wordlists;
exports.default = index;
exports.entropyToMnemonic = src_4;
exports.generateMnemonic = src_5;
exports.getDefaultWordlist = src_8;
exports.mnemonicToEntropy = src_3;
exports.mnemonicToSeed = src_2;
exports.mnemonicToSeedSync = src_1;
exports.setDefaultWordlist = src_7;
exports.validateMnemonic = src_6;
exports.wordlists = src_9;
@@ -0,0 +1,255 @@
'use strict';
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var assert = _interopDefault(require('assert'));
var safeBuffer = _interopDefault(require('safe-buffer'));
var bs58check = _interopDefault(require('bs58check'));
var cryptoShim = require("../shims/hdkey-crypto");
var secp256k1Shim = require("../shims/hdkey-secp256k1v3");
var Buffer = safeBuffer.Buffer;
var MASTER_SECRET = Buffer.from('Bitcoin seed', 'utf8');
var HARDENED_OFFSET = 0x80000000;
var LEN = 78;
// Bitcoin hardcoded by default, can use package `coininfo` for others
var BITCOIN_VERSIONS = {private: 0x0488ADE4, public: 0x0488B21E};
function HDKey (versions) {
this.versions = versions || BITCOIN_VERSIONS;
this.depth = 0;
this.index = 0;
this._privateKey = null;
this._publicKey = null;
this.chainCode = null;
this._fingerprint = 0;
this.parentFingerprint = 0;
}
Object.defineProperty(HDKey.prototype, 'fingerprint', { get: function () { return this._fingerprint } });
Object.defineProperty(HDKey.prototype, 'identifier', { get: function () { return this._identifier } });
Object.defineProperty(HDKey.prototype, 'pubKeyHash', { get: function () { return this.identifier } });
Object.defineProperty(HDKey.prototype, 'privateKey', {
get: function () {
return this._privateKey
},
set: function (value) {
assert.equal(value.length, 32, 'Private key must be 32 bytes.');
assert(secp256k1Shim.privateKeyVerify(value) === true, 'Invalid private key');
this._privateKey = value;
this._publicKey = secp256k1Shim.publicKeyCreate(value, true);
this._identifier = hash160(this.publicKey);
this._fingerprint = this._identifier.slice(0, 4).readUInt32BE(0);
}
});
Object.defineProperty(HDKey.prototype, 'publicKey', {
get: function () {
return this._publicKey
},
set: function (value) {
assert(value.length === 33 || value.length === 65, 'Public key must be 33 or 65 bytes.');
assert(secp256k1Shim.publicKeyVerify(value) === true, 'Invalid public key');
this._publicKey = secp256k1Shim.publicKeyConvert(value, true); // force compressed point
this._identifier = hash160(this.publicKey);
this._fingerprint = this._identifier.slice(0, 4).readUInt32BE(0);
this._privateKey = null;
}
});
Object.defineProperty(HDKey.prototype, 'privateExtendedKey', {
get: function () {
if (this._privateKey) return bs58check.encode(serialize(this, this.versions.private, Buffer.concat([Buffer.alloc(1, 0), this.privateKey])))
else return null
}
});
Object.defineProperty(HDKey.prototype, 'publicExtendedKey', {
get: function () {
return bs58check.encode(serialize(this, this.versions.public, this.publicKey))
}
});
HDKey.prototype.derive = function (path) {
if (path === 'm' || path === 'M' || path === "m'" || path === "M'") {
return this
}
var entries = path.split('/');
var hdkey = this;
entries.forEach(function (c, i) {
if (i === 0) {
assert(/^[mM]{1}/.test(c), 'Path must start with "m" or "M"');
return
}
var hardened = (c.length > 1) && (c[c.length - 1] === "'");
var childIndex = parseInt(c, 10); // & (HARDENED_OFFSET - 1)
assert(childIndex < HARDENED_OFFSET, 'Invalid index');
if (hardened) childIndex += HARDENED_OFFSET;
hdkey = hdkey.deriveChild(childIndex);
});
return hdkey
};
HDKey.prototype.deriveChild = function (index) {
var isHardened = index >= HARDENED_OFFSET;
var indexBuffer = Buffer.allocUnsafe(4);
indexBuffer.writeUInt32BE(index, 0);
var data;
if (isHardened) { // Hardened child
assert(this.privateKey, 'Could not derive hardened child key');
var pk = this.privateKey;
var zb = Buffer.alloc(1, 0);
pk = Buffer.concat([zb, pk]);
// data = 0x00 || ser256(kpar) || ser32(index)
data = Buffer.concat([pk, indexBuffer]);
} else { // Normal child
// data = serP(point(kpar)) || ser32(index)
// = serP(Kpar) || ser32(index)
data = Buffer.concat([this.publicKey, indexBuffer]);
}
var I = cryptoShim.createHmac('sha512', this.chainCode).update(data).digest();
var IL = I.slice(0, 32);
var IR = I.slice(32);
var hd = new HDKey(this.versions);
// Private parent key -> private child key
if (this.privateKey) {
// ki = parse256(IL) + kpar (mod n)
try {
hd.privateKey = secp256k1Shim.privateKeyTweakAdd(this.privateKey, IL);
// throw if IL >= n || (privateKey + IL) === 0
} catch (err) {
// In case parse256(IL) >= n or ki == 0, one should proceed with the next value for i
return this.deriveChild(index + 1)
}
// Public parent key -> public child key
} else {
// Ki = point(parse256(IL)) + Kpar
// = G*IL + Kpar
try {
hd.publicKey = secp256k1Shim.publicKeyTweakAdd(this.publicKey, IL, true);
// throw if IL >= n || (g**IL + publicKey) is infinity
} catch (err) {
// In case parse256(IL) >= n or Ki is the point at infinity, one should proceed with the next value for i
return this.deriveChild(index + 1)
}
}
hd.chainCode = IR;
hd.depth = this.depth + 1;
hd.parentFingerprint = this.fingerprint;// .readUInt32BE(0)
hd.index = index;
return hd
};
HDKey.prototype.sign = function (hash) {
return secp256k1Shim.sign(hash, this.privateKey).signature
};
HDKey.prototype.verify = function (hash, signature) {
return secp256k1Shim.verify(hash, signature, this.publicKey)
};
HDKey.prototype.wipePrivateData = function () {
if (this._privateKey) cryptoShim.randomBytes(this._privateKey.length).copy(this._privateKey);
this._privateKey = null;
return this
};
HDKey.prototype.toJSON = function () {
return {
xpriv: this.privateExtendedKey,
xpub: this.publicExtendedKey
}
};
HDKey.fromMasterSeed = function (seedBuffer, versions) {
var I = cryptoShim.createHmac('sha512', MASTER_SECRET).update(seedBuffer).digest();
var IL = I.slice(0, 32);
var IR = I.slice(32);
var hdkey = new HDKey(versions);
hdkey.chainCode = IR;
hdkey.privateKey = IL;
return hdkey
};
HDKey.fromExtendedKey = function (base58key, versions) {
// => version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
versions = versions || BITCOIN_VERSIONS;
var hdkey = new HDKey(versions);
var keyBuffer = bs58check.decode(base58key);
var version = keyBuffer.readUInt32BE(0);
assert(version === versions.private || version === versions.public, 'Version mismatch: does not match private or public');
hdkey.depth = keyBuffer.readUInt8(4);
hdkey.parentFingerprint = keyBuffer.readUInt32BE(5);
hdkey.index = keyBuffer.readUInt32BE(9);
hdkey.chainCode = keyBuffer.slice(13, 45);
var key = keyBuffer.slice(45);
if (key.readUInt8(0) === 0) { // private
assert(version === versions.private, 'Version mismatch: version does not match private');
hdkey.privateKey = key.slice(1); // cut off first 0x0 byte
} else {
assert(version === versions.public, 'Version mismatch: version does not match public');
hdkey.publicKey = key;
}
return hdkey
};
HDKey.fromJSON = function (obj) {
return HDKey.fromExtendedKey(obj.xpriv)
};
function serialize (hdkey, version, key) {
// => version(4) || depth(1) || fingerprint(4) || index(4) || chain(32) || key(33)
var buffer = Buffer.allocUnsafe(LEN);
buffer.writeUInt32BE(version, 0);
buffer.writeUInt8(hdkey.depth, 4);
var fingerprint = hdkey.depth ? hdkey.parentFingerprint : 0x00000000;
buffer.writeUInt32BE(fingerprint, 5);
buffer.writeUInt32BE(hdkey.index, 9);
hdkey.chainCode.copy(buffer, 13);
key.copy(buffer, 45);
return buffer
}
function hash160 (buf) {
var sha = cryptoShim.createHash('sha256').update(buf).digest();
return cryptoShim.createHash('ripemd160').update(sha).digest()
}
HDKey.HARDENED_OFFSET = HARDENED_OFFSET;
var hdkey = HDKey;
module.exports = hdkey;