Comparing version 2.0.6 to 3.0.0
{ | ||
"name": "bip32", | ||
"version": "2.0.6", | ||
"version": "3.0.0", | ||
"description": "A BIP32 compatible library", | ||
@@ -44,3 +44,2 @@ "keywords": [ | ||
"create-hmac": "^1.1.7", | ||
"tiny-secp256k1": "^1.1.3", | ||
"typeforce": "^1.11.5", | ||
@@ -53,2 +52,3 @@ "wif": "^2.0.6" | ||
"tape": "^4.13.2", | ||
"tiny-secp256k1": "^2.1.0", | ||
"tslint": "^6.1.0", | ||
@@ -55,0 +55,0 @@ "typescript": "3.3.3333" |
# bip32 | ||
[![Build Status](https://travis-ci.org/bitcoinjs/bip32.png?branch=master)](https://travis-ci.org/bitcoinjs/bip32) | ||
[![Github CI](https://github.com/bitcoinjs/bip32/actions/workflows/main_ci.yml/badge.svg)](https://github.com/bitcoinjs/bip32/actions/workflows/main_ci.yml) [![NPM](https://img.shields.io/npm/v/bip32.svg)](https://www.npmjs.org/package/bip32) [![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) | ||
[![NPM](https://img.shields.io/npm/v/bip32.svg)](https://www.npmjs.org/package/bip32) | ||
[![code style: prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg?style=flat-square)](https://github.com/prettier/prettier) | ||
A [BIP32](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki) compatible library written in TypeScript with transpiled JavaScript committed to git. | ||
@@ -16,4 +12,8 @@ | ||
``` typescript | ||
import * as bip32 from 'bip32'; | ||
import BIP32Factory from 'bip32'; | ||
import * as ecc from 'tiny-secp256k1'; | ||
import { BIP32Interface } from 'bip32'; | ||
// You must wrap a tiny-secp256k1 compatible implementation | ||
const bip32 = BIP32Factory(ecc); | ||
let node: BIP32Interface = bip32.fromBase58('xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi'); | ||
@@ -28,7 +28,12 @@ | ||
``` javascript | ||
let bip32 = require('bip32') | ||
let node = bip32.fromBase58('xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi') | ||
let BIP32Factory = require('bip32').default | ||
// tiny-secp256k1 v2 is ES module and must be imported, not required | ||
// (This requires v14 of node or greater) | ||
// But as long as you implement the interface, any library is fine | ||
import('tiny-secp256k1').then(ecc => BIP32Factory(ecc)).then(bip32 => { | ||
let node = bip32.fromBase58('xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi') | ||
let child = node.derivePath('m/0/0') | ||
// ... | ||
let child = node.derivePath('m/0/0') | ||
// ... | ||
}) | ||
``` | ||
@@ -35,0 +40,0 @@ |
554
src/bip32.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const crypto = require("./crypto"); | ||
const testecc_1 = require("./testecc"); | ||
const bs58check = require('bs58check'); | ||
const ecc = require('tiny-secp256k1'); | ||
const typeforce = require('typeforce'); | ||
const wif = require('wif'); | ||
const UINT256_TYPE = typeforce.BufferN(32); | ||
const NETWORK_TYPE = typeforce.compile({ | ||
wif: typeforce.UInt8, | ||
bip32: { | ||
public: typeforce.UInt32, | ||
private: typeforce.UInt32, | ||
}, | ||
}); | ||
const BITCOIN = { | ||
messagePrefix: '\x18Bitcoin Signed Message:\n', | ||
bech32: 'bc', | ||
bip32: { | ||
public: 0x0488b21e, | ||
private: 0x0488ade4, | ||
}, | ||
pubKeyHash: 0x00, | ||
scriptHash: 0x05, | ||
wif: 0x80, | ||
}; | ||
const HIGHEST_BIT = 0x80000000; | ||
const UINT31_MAX = Math.pow(2, 31) - 1; | ||
function BIP32Path(value) { | ||
return (typeforce.String(value) && value.match(/^(m\/)?(\d+'?\/)*\d+'?$/) !== null); | ||
} | ||
function UInt31(value) { | ||
return typeforce.UInt32(value) && value <= UINT31_MAX; | ||
} | ||
class BIP32 { | ||
constructor(__D, __Q, chainCode, network, __DEPTH = 0, __INDEX = 0, __PARENT_FINGERPRINT = 0x00000000) { | ||
this.__D = __D; | ||
this.__Q = __Q; | ||
this.chainCode = chainCode; | ||
this.network = network; | ||
this.__DEPTH = __DEPTH; | ||
this.__INDEX = __INDEX; | ||
this.__PARENT_FINGERPRINT = __PARENT_FINGERPRINT; | ||
typeforce(NETWORK_TYPE, network); | ||
this.lowR = false; | ||
function default_1(ecc) { | ||
testecc_1.testEcc(ecc); | ||
const UINT256_TYPE = typeforce.BufferN(32); | ||
const NETWORK_TYPE = typeforce.compile({ | ||
wif: typeforce.UInt8, | ||
bip32: { | ||
public: typeforce.UInt32, | ||
private: typeforce.UInt32, | ||
}, | ||
}); | ||
const BITCOIN = { | ||
messagePrefix: '\x18Bitcoin Signed Message:\n', | ||
bech32: 'bc', | ||
bip32: { | ||
public: 0x0488b21e, | ||
private: 0x0488ade4, | ||
}, | ||
pubKeyHash: 0x00, | ||
scriptHash: 0x05, | ||
wif: 0x80, | ||
}; | ||
const HIGHEST_BIT = 0x80000000; | ||
const UINT31_MAX = Math.pow(2, 31) - 1; | ||
function BIP32Path(value) { | ||
return (typeforce.String(value) && value.match(/^(m\/)?(\d+'?\/)*\d+'?$/) !== null); | ||
} | ||
get depth() { | ||
return this.__DEPTH; | ||
function UInt31(value) { | ||
return typeforce.UInt32(value) && value <= UINT31_MAX; | ||
} | ||
get index() { | ||
return this.__INDEX; | ||
} | ||
get parentFingerprint() { | ||
return this.__PARENT_FINGERPRINT; | ||
} | ||
get publicKey() { | ||
if (this.__Q === undefined) | ||
this.__Q = ecc.pointFromScalar(this.__D, true); | ||
return this.__Q; | ||
} | ||
get privateKey() { | ||
return this.__D; | ||
} | ||
get identifier() { | ||
return crypto.hash160(this.publicKey); | ||
} | ||
get fingerprint() { | ||
return this.identifier.slice(0, 4); | ||
} | ||
get compressed() { | ||
return true; | ||
} | ||
// Private === not neutered | ||
// Public === neutered | ||
isNeutered() { | ||
return this.__D === undefined; | ||
} | ||
neutered() { | ||
return fromPublicKeyLocal(this.publicKey, this.chainCode, this.network, this.depth, this.index, this.parentFingerprint); | ||
} | ||
toBase58() { | ||
const network = this.network; | ||
const version = !this.isNeutered() | ||
? network.bip32.private | ||
: network.bip32.public; | ||
const buffer = Buffer.allocUnsafe(78); | ||
// 4 bytes: version bytes | ||
buffer.writeUInt32BE(version, 0); | ||
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, .... | ||
buffer.writeUInt8(this.depth, 4); | ||
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key) | ||
buffer.writeUInt32BE(this.parentFingerprint, 5); | ||
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized. | ||
// This is encoded in big endian. (0x00000000 if master key) | ||
buffer.writeUInt32BE(this.index, 9); | ||
// 32 bytes: the chain code | ||
this.chainCode.copy(buffer, 13); | ||
// 33 bytes: the public key or private key data | ||
if (!this.isNeutered()) { | ||
// 0x00 + k for private keys | ||
buffer.writeUInt8(0, 45); | ||
this.privateKey.copy(buffer, 46); | ||
// 33 bytes: the public key | ||
class BIP32 { | ||
constructor(__D, __Q, chainCode, network, __DEPTH = 0, __INDEX = 0, __PARENT_FINGERPRINT = 0x00000000) { | ||
this.__D = __D; | ||
this.__Q = __Q; | ||
this.chainCode = chainCode; | ||
this.network = network; | ||
this.__DEPTH = __DEPTH; | ||
this.__INDEX = __INDEX; | ||
this.__PARENT_FINGERPRINT = __PARENT_FINGERPRINT; | ||
typeforce(NETWORK_TYPE, network); | ||
this.lowR = false; | ||
} | ||
else { | ||
// X9.62 encoding for public keys | ||
this.publicKey.copy(buffer, 45); | ||
get depth() { | ||
return this.__DEPTH; | ||
} | ||
return bs58check.encode(buffer); | ||
} | ||
toWIF() { | ||
if (!this.privateKey) | ||
throw new TypeError('Missing private key'); | ||
return wif.encode(this.network.wif, this.privateKey, true); | ||
} | ||
// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions | ||
derive(index) { | ||
typeforce(typeforce.UInt32, index); | ||
const isHardened = index >= HIGHEST_BIT; | ||
const data = Buffer.allocUnsafe(37); | ||
// Hardened child | ||
if (isHardened) { | ||
if (this.isNeutered()) | ||
throw new TypeError('Missing private key for hardened child key'); | ||
// data = 0x00 || ser256(kpar) || ser32(index) | ||
data[0] = 0x00; | ||
this.privateKey.copy(data, 1); | ||
data.writeUInt32BE(index, 33); | ||
// Normal child | ||
get index() { | ||
return this.__INDEX; | ||
} | ||
else { | ||
// data = serP(point(kpar)) || ser32(index) | ||
// = serP(Kpar) || ser32(index) | ||
this.publicKey.copy(data, 0); | ||
data.writeUInt32BE(index, 33); | ||
get parentFingerprint() { | ||
return this.__PARENT_FINGERPRINT; | ||
} | ||
const I = crypto.hmacSHA512(this.chainCode, data); | ||
const IL = I.slice(0, 32); | ||
const IR = I.slice(32); | ||
// if parse256(IL) >= n, proceed with the next value for i | ||
if (!ecc.isPrivate(IL)) | ||
return this.derive(index + 1); | ||
// Private parent key -> private child key | ||
let hd; | ||
if (!this.isNeutered()) { | ||
// ki = parse256(IL) + kpar (mod n) | ||
const ki = ecc.privateAdd(this.privateKey, IL); | ||
// In case ki == 0, proceed with the next value for i | ||
if (ki == null) | ||
return this.derive(index + 1); | ||
hd = fromPrivateKeyLocal(ki, IR, this.network, this.depth + 1, index, this.fingerprint.readUInt32BE(0)); | ||
// Public parent key -> public child key | ||
get publicKey() { | ||
if (this.__Q === undefined) | ||
this.__Q = Buffer.from(ecc.pointFromScalar(this.__D, true)); | ||
return this.__Q; | ||
} | ||
else { | ||
// Ki = point(parse256(IL)) + Kpar | ||
// = G*IL + Kpar | ||
const Ki = ecc.pointAddScalar(this.publicKey, IL, true); | ||
// In case Ki is the point at infinity, proceed with the next value for i | ||
if (Ki === null) | ||
get privateKey() { | ||
return this.__D; | ||
} | ||
get identifier() { | ||
return crypto.hash160(this.publicKey); | ||
} | ||
get fingerprint() { | ||
return this.identifier.slice(0, 4); | ||
} | ||
get compressed() { | ||
return true; | ||
} | ||
// Private === not neutered | ||
// Public === neutered | ||
isNeutered() { | ||
return this.__D === undefined; | ||
} | ||
neutered() { | ||
return fromPublicKeyLocal(this.publicKey, this.chainCode, this.network, this.depth, this.index, this.parentFingerprint); | ||
} | ||
toBase58() { | ||
const network = this.network; | ||
const version = !this.isNeutered() | ||
? network.bip32.private | ||
: network.bip32.public; | ||
const buffer = Buffer.allocUnsafe(78); | ||
// 4 bytes: version bytes | ||
buffer.writeUInt32BE(version, 0); | ||
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, .... | ||
buffer.writeUInt8(this.depth, 4); | ||
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key) | ||
buffer.writeUInt32BE(this.parentFingerprint, 5); | ||
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized. | ||
// This is encoded in big endian. (0x00000000 if master key) | ||
buffer.writeUInt32BE(this.index, 9); | ||
// 32 bytes: the chain code | ||
this.chainCode.copy(buffer, 13); | ||
// 33 bytes: the public key or private key data | ||
if (!this.isNeutered()) { | ||
// 0x00 + k for private keys | ||
buffer.writeUInt8(0, 45); | ||
this.privateKey.copy(buffer, 46); | ||
// 33 bytes: the public key | ||
} | ||
else { | ||
// X9.62 encoding for public keys | ||
this.publicKey.copy(buffer, 45); | ||
} | ||
return bs58check.encode(buffer); | ||
} | ||
toWIF() { | ||
if (!this.privateKey) | ||
throw new TypeError('Missing private key'); | ||
return wif.encode(this.network.wif, this.privateKey, true); | ||
} | ||
// https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#child-key-derivation-ckd-functions | ||
derive(index) { | ||
typeforce(typeforce.UInt32, index); | ||
const isHardened = index >= HIGHEST_BIT; | ||
const data = Buffer.allocUnsafe(37); | ||
// Hardened child | ||
if (isHardened) { | ||
if (this.isNeutered()) | ||
throw new TypeError('Missing private key for hardened child key'); | ||
// data = 0x00 || ser256(kpar) || ser32(index) | ||
data[0] = 0x00; | ||
this.privateKey.copy(data, 1); | ||
data.writeUInt32BE(index, 33); | ||
// Normal child | ||
} | ||
else { | ||
// data = serP(point(kpar)) || ser32(index) | ||
// = serP(Kpar) || ser32(index) | ||
this.publicKey.copy(data, 0); | ||
data.writeUInt32BE(index, 33); | ||
} | ||
const I = crypto.hmacSHA512(this.chainCode, data); | ||
const IL = I.slice(0, 32); | ||
const IR = I.slice(32); | ||
// if parse256(IL) >= n, proceed with the next value for i | ||
if (!ecc.isPrivate(IL)) | ||
return this.derive(index + 1); | ||
hd = fromPublicKeyLocal(Ki, IR, this.network, this.depth + 1, index, this.fingerprint.readUInt32BE(0)); | ||
// Private parent key -> private child key | ||
let hd; | ||
if (!this.isNeutered()) { | ||
// ki = parse256(IL) + kpar (mod n) | ||
const ki = Buffer.from(ecc.privateAdd(this.privateKey, IL)); | ||
// In case ki == 0, proceed with the next value for i | ||
if (ki == null) | ||
return this.derive(index + 1); | ||
hd = fromPrivateKeyLocal(ki, IR, this.network, this.depth + 1, index, this.fingerprint.readUInt32BE(0)); | ||
// Public parent key -> public child key | ||
} | ||
else { | ||
// Ki = point(parse256(IL)) + Kpar | ||
// = G*IL + Kpar | ||
const Ki = Buffer.from(ecc.pointAddScalar(this.publicKey, IL, true)); | ||
// In case Ki is the point at infinity, proceed with the next value for i | ||
if (Ki === null) | ||
return this.derive(index + 1); | ||
hd = fromPublicKeyLocal(Ki, IR, this.network, this.depth + 1, index, this.fingerprint.readUInt32BE(0)); | ||
} | ||
return hd; | ||
} | ||
return hd; | ||
} | ||
deriveHardened(index) { | ||
typeforce(UInt31, index); | ||
// Only derives hardened private keys by default | ||
return this.derive(index + HIGHEST_BIT); | ||
} | ||
derivePath(path) { | ||
typeforce(BIP32Path, path); | ||
let splitPath = path.split('/'); | ||
if (splitPath[0] === 'm') { | ||
if (this.parentFingerprint) | ||
throw new TypeError('Expected master, got child'); | ||
splitPath = splitPath.slice(1); | ||
deriveHardened(index) { | ||
typeforce(UInt31, index); | ||
// Only derives hardened private keys by default | ||
return this.derive(index + HIGHEST_BIT); | ||
} | ||
return splitPath.reduce((prevHd, indexStr) => { | ||
let index; | ||
if (indexStr.slice(-1) === `'`) { | ||
index = parseInt(indexStr.slice(0, -1), 10); | ||
return prevHd.deriveHardened(index); | ||
derivePath(path) { | ||
typeforce(BIP32Path, path); | ||
let splitPath = path.split('/'); | ||
if (splitPath[0] === 'm') { | ||
if (this.parentFingerprint) | ||
throw new TypeError('Expected master, got child'); | ||
splitPath = splitPath.slice(1); | ||
} | ||
return splitPath.reduce((prevHd, indexStr) => { | ||
let index; | ||
if (indexStr.slice(-1) === `'`) { | ||
index = parseInt(indexStr.slice(0, -1), 10); | ||
return prevHd.deriveHardened(index); | ||
} | ||
else { | ||
index = parseInt(indexStr, 10); | ||
return prevHd.derive(index); | ||
} | ||
}, this); | ||
} | ||
sign(hash, lowR) { | ||
if (!this.privateKey) | ||
throw new Error('Missing private key'); | ||
if (lowR === undefined) | ||
lowR = this.lowR; | ||
if (lowR === false) { | ||
return Buffer.from(ecc.sign(hash, this.privateKey)); | ||
} | ||
else { | ||
index = parseInt(indexStr, 10); | ||
return prevHd.derive(index); | ||
let sig = Buffer.from(ecc.sign(hash, this.privateKey)); | ||
const extraData = Buffer.alloc(32, 0); | ||
let counter = 0; | ||
// if first try is lowR, skip the loop | ||
// for second try and on, add extra entropy counting up | ||
while (sig[0] > 0x7f) { | ||
counter++; | ||
extraData.writeUIntLE(counter, 0, 6); | ||
sig = Buffer.from(ecc.sign(hash, this.privateKey, extraData)); | ||
} | ||
return sig; | ||
} | ||
}, this); | ||
} | ||
signSchnorr(hash) { | ||
if (!this.privateKey) | ||
throw new Error('Missing private key'); | ||
if (!ecc.signSchnorr) | ||
throw new Error('signSchnorr not supported by ecc library'); | ||
return Buffer.from(ecc.signSchnorr(hash, this.privateKey)); | ||
} | ||
verify(hash, signature) { | ||
return ecc.verify(hash, this.publicKey, signature); | ||
} | ||
verifySchnorr(hash, signature) { | ||
if (!ecc.verifySchnorr) | ||
throw new Error('verifySchnorr not supported by ecc library'); | ||
return ecc.verifySchnorr(hash, this.publicKey.subarray(1, 33), signature); | ||
} | ||
} | ||
sign(hash, lowR) { | ||
if (!this.privateKey) | ||
throw new Error('Missing private key'); | ||
if (lowR === undefined) | ||
lowR = this.lowR; | ||
if (lowR === false) { | ||
return ecc.sign(hash, this.privateKey); | ||
function fromBase58(inString, network) { | ||
const buffer = bs58check.decode(inString); | ||
if (buffer.length !== 78) | ||
throw new TypeError('Invalid buffer length'); | ||
network = network || BITCOIN; | ||
// 4 bytes: version bytes | ||
const version = buffer.readUInt32BE(0); | ||
if (version !== network.bip32.private && version !== network.bip32.public) | ||
throw new TypeError('Invalid network version'); | ||
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ... | ||
const depth = buffer[4]; | ||
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key) | ||
const parentFingerprint = buffer.readUInt32BE(5); | ||
if (depth === 0) { | ||
if (parentFingerprint !== 0x00000000) | ||
throw new TypeError('Invalid parent fingerprint'); | ||
} | ||
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized. | ||
// This is encoded in MSB order. (0x00000000 if master key) | ||
const index = buffer.readUInt32BE(9); | ||
if (depth === 0 && index !== 0) | ||
throw new TypeError('Invalid index'); | ||
// 32 bytes: the chain code | ||
const chainCode = buffer.slice(13, 45); | ||
let hd; | ||
// 33 bytes: private key data (0x00 + k) | ||
if (version === network.bip32.private) { | ||
if (buffer.readUInt8(45) !== 0x00) | ||
throw new TypeError('Invalid private key'); | ||
const k = buffer.slice(46, 78); | ||
hd = fromPrivateKeyLocal(k, chainCode, network, depth, index, parentFingerprint); | ||
// 33 bytes: public key data (0x02 + X or 0x03 + X) | ||
} | ||
else { | ||
let sig = ecc.sign(hash, this.privateKey); | ||
const extraData = Buffer.alloc(32, 0); | ||
let counter = 0; | ||
// if first try is lowR, skip the loop | ||
// for second try and on, add extra entropy counting up | ||
while (sig[0] > 0x7f) { | ||
counter++; | ||
extraData.writeUIntLE(counter, 0, 6); | ||
sig = ecc.signWithEntropy(hash, this.privateKey, extraData); | ||
} | ||
return sig; | ||
const X = buffer.slice(45, 78); | ||
hd = fromPublicKeyLocal(X, chainCode, network, depth, index, parentFingerprint); | ||
} | ||
return hd; | ||
} | ||
verify(hash, signature) { | ||
return ecc.verify(hash, this.publicKey, signature); | ||
function fromPrivateKey(privateKey, chainCode, network) { | ||
return fromPrivateKeyLocal(privateKey, chainCode, network); | ||
} | ||
} | ||
function fromBase58(inString, network) { | ||
const buffer = bs58check.decode(inString); | ||
if (buffer.length !== 78) | ||
throw new TypeError('Invalid buffer length'); | ||
network = network || BITCOIN; | ||
// 4 bytes: version bytes | ||
const version = buffer.readUInt32BE(0); | ||
if (version !== network.bip32.private && version !== network.bip32.public) | ||
throw new TypeError('Invalid network version'); | ||
// 1 byte: depth: 0x00 for master nodes, 0x01 for level-1 descendants, ... | ||
const depth = buffer[4]; | ||
// 4 bytes: the fingerprint of the parent's key (0x00000000 if master key) | ||
const parentFingerprint = buffer.readUInt32BE(5); | ||
if (depth === 0) { | ||
if (parentFingerprint !== 0x00000000) | ||
throw new TypeError('Invalid parent fingerprint'); | ||
function fromPrivateKeyLocal(privateKey, chainCode, network, depth, index, parentFingerprint) { | ||
typeforce({ | ||
privateKey: UINT256_TYPE, | ||
chainCode: UINT256_TYPE, | ||
}, { privateKey, chainCode }); | ||
network = network || BITCOIN; | ||
if (!ecc.isPrivate(privateKey)) | ||
throw new TypeError('Private key not in range [1, n)'); | ||
return new BIP32(privateKey, undefined, chainCode, network, depth, index, parentFingerprint); | ||
} | ||
// 4 bytes: child number. This is the number i in xi = xpar/i, with xi the key being serialized. | ||
// This is encoded in MSB order. (0x00000000 if master key) | ||
const index = buffer.readUInt32BE(9); | ||
if (depth === 0 && index !== 0) | ||
throw new TypeError('Invalid index'); | ||
// 32 bytes: the chain code | ||
const chainCode = buffer.slice(13, 45); | ||
let hd; | ||
// 33 bytes: private key data (0x00 + k) | ||
if (version === network.bip32.private) { | ||
if (buffer.readUInt8(45) !== 0x00) | ||
throw new TypeError('Invalid private key'); | ||
const k = buffer.slice(46, 78); | ||
hd = fromPrivateKeyLocal(k, chainCode, network, depth, index, parentFingerprint); | ||
// 33 bytes: public key data (0x02 + X or 0x03 + X) | ||
function fromPublicKey(publicKey, chainCode, network) { | ||
return fromPublicKeyLocal(publicKey, chainCode, network); | ||
} | ||
else { | ||
const X = buffer.slice(45, 78); | ||
hd = fromPublicKeyLocal(X, chainCode, network, depth, index, parentFingerprint); | ||
function fromPublicKeyLocal(publicKey, chainCode, network, depth, index, parentFingerprint) { | ||
typeforce({ | ||
publicKey: typeforce.BufferN(33), | ||
chainCode: UINT256_TYPE, | ||
}, { publicKey, chainCode }); | ||
network = network || BITCOIN; | ||
// verify the X coordinate is a point on the curve | ||
if (!ecc.isPoint(publicKey)) | ||
throw new TypeError('Point is not on the curve'); | ||
return new BIP32(undefined, publicKey, chainCode, network, depth, index, parentFingerprint); | ||
} | ||
return hd; | ||
function fromSeed(seed, network) { | ||
typeforce(typeforce.Buffer, seed); | ||
if (seed.length < 16) | ||
throw new TypeError('Seed should be at least 128 bits'); | ||
if (seed.length > 64) | ||
throw new TypeError('Seed should be at most 512 bits'); | ||
network = network || BITCOIN; | ||
const I = crypto.hmacSHA512(Buffer.from('Bitcoin seed', 'utf8'), seed); | ||
const IL = I.slice(0, 32); | ||
const IR = I.slice(32); | ||
return fromPrivateKey(IL, IR, network); | ||
} | ||
return { | ||
fromSeed, | ||
fromBase58, | ||
fromPublicKey, | ||
fromPrivateKey, | ||
}; | ||
} | ||
exports.fromBase58 = fromBase58; | ||
function fromPrivateKey(privateKey, chainCode, network) { | ||
return fromPrivateKeyLocal(privateKey, chainCode, network); | ||
} | ||
exports.fromPrivateKey = fromPrivateKey; | ||
function fromPrivateKeyLocal(privateKey, chainCode, network, depth, index, parentFingerprint) { | ||
typeforce({ | ||
privateKey: UINT256_TYPE, | ||
chainCode: UINT256_TYPE, | ||
}, { privateKey, chainCode }); | ||
network = network || BITCOIN; | ||
if (!ecc.isPrivate(privateKey)) | ||
throw new TypeError('Private key not in range [1, n)'); | ||
return new BIP32(privateKey, undefined, chainCode, network, depth, index, parentFingerprint); | ||
} | ||
function fromPublicKey(publicKey, chainCode, network) { | ||
return fromPublicKeyLocal(publicKey, chainCode, network); | ||
} | ||
exports.fromPublicKey = fromPublicKey; | ||
function fromPublicKeyLocal(publicKey, chainCode, network, depth, index, parentFingerprint) { | ||
typeforce({ | ||
publicKey: typeforce.BufferN(33), | ||
chainCode: UINT256_TYPE, | ||
}, { publicKey, chainCode }); | ||
network = network || BITCOIN; | ||
// verify the X coordinate is a point on the curve | ||
if (!ecc.isPoint(publicKey)) | ||
throw new TypeError('Point is not on the curve'); | ||
return new BIP32(undefined, publicKey, chainCode, network, depth, index, parentFingerprint); | ||
} | ||
function fromSeed(seed, network) { | ||
typeforce(typeforce.Buffer, seed); | ||
if (seed.length < 16) | ||
throw new TypeError('Seed should be at least 128 bits'); | ||
if (seed.length > 64) | ||
throw new TypeError('Seed should be at most 512 bits'); | ||
network = network || BITCOIN; | ||
const I = crypto.hmacSHA512(Buffer.from('Bitcoin seed', 'utf8'), seed); | ||
const IL = I.slice(0, 32); | ||
const IR = I.slice(32); | ||
return fromPrivateKey(IL, IR, network); | ||
} | ||
exports.fromSeed = fromSeed; | ||
exports.default = default_1; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var bip32_1 = require("./bip32"); | ||
exports.fromSeed = bip32_1.fromSeed; | ||
exports.fromBase58 = bip32_1.fromBase58; | ||
exports.fromPublicKey = bip32_1.fromPublicKey; | ||
exports.fromPrivateKey = bip32_1.fromPrivateKey; | ||
exports.default = bip32_1.default; |
@@ -33,7 +33,23 @@ /// <reference types="node" /> | ||
verify(hash: Buffer, signature: Buffer): boolean; | ||
signSchnorr(hash: Buffer): Buffer; | ||
verifySchnorr(hash: Buffer, signature: Buffer): boolean; | ||
} | ||
export declare function fromBase58(inString: string, network?: Network): BIP32Interface; | ||
export declare function fromPrivateKey(privateKey: Buffer, chainCode: Buffer, network?: Network): BIP32Interface; | ||
export declare function fromPublicKey(publicKey: Buffer, chainCode: Buffer, network?: Network): BIP32Interface; | ||
export declare function fromSeed(seed: Buffer, network?: Network): BIP32Interface; | ||
export interface BIP32API { | ||
fromSeed(seed: Buffer, network?: Network): BIP32Interface; | ||
fromBase58(inString: string, network?: Network): BIP32Interface; | ||
fromPublicKey(publicKey: Buffer, chainCode: Buffer, network?: Network): BIP32Interface; | ||
fromPrivateKey(privateKey: Buffer, chainCode: Buffer, network?: Network): BIP32Interface; | ||
} | ||
export interface TinySecp256k1Interface { | ||
isPoint(p: Uint8Array): boolean; | ||
isPrivate(d: Uint8Array): boolean; | ||
pointFromScalar(d: Uint8Array, compressed?: boolean): Uint8Array | null; | ||
pointAddScalar(p: Uint8Array, tweak: Uint8Array, compressed?: boolean): Uint8Array | null; | ||
privateAdd(d: Uint8Array, tweak: Uint8Array): Uint8Array | null; | ||
sign(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array; | ||
signSchnorr?(h: Uint8Array, d: Uint8Array, e?: Uint8Array): Uint8Array; | ||
verify(h: Uint8Array, Q: Uint8Array, signature: Uint8Array, strict?: boolean): boolean; | ||
verifySchnorr?(h: Uint8Array, Q: Uint8Array, signature: Uint8Array): boolean; | ||
} | ||
export default function (ecc: TinySecp256k1Interface): BIP32API; | ||
export {}; |
@@ -1,1 +0,1 @@ | ||
export { BIP32Interface, fromSeed, fromBase58, fromPublicKey, fromPrivateKey, } from './bip32'; | ||
export { default, BIP32Interface, BIP32API, TinySecp256k1Interface, } from './bip32'; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
23910
6
11
442
41
6
- Removedtiny-secp256k1@^1.1.3
- Removedbindings@1.5.0(transitive)
- Removedbn.js@4.12.0(transitive)
- Removedbrorand@1.1.0(transitive)
- Removedelliptic@6.5.7(transitive)
- Removedfile-uri-to-path@1.0.0(transitive)
- Removedhash.js@1.1.7(transitive)
- Removedhmac-drbg@1.0.1(transitive)
- Removedminimalistic-assert@1.0.1(transitive)
- Removedminimalistic-crypto-utils@1.0.1(transitive)
- Removednan@2.20.0(transitive)
- Removedtiny-secp256k1@1.1.6(transitive)