Skip to content

Commit

Permalink
Move depth, index, parentFingerprint to constructor
Browse files Browse the repository at this point in the history
  • Loading branch information
junderw committed Mar 19, 2019
1 parent a5b40d2 commit fe4dc02
Show file tree
Hide file tree
Showing 2 changed files with 120 additions and 45 deletions.
51 changes: 28 additions & 23 deletions src/bip32.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,25 @@ function UInt31(value) {
return typeforce.UInt32(value) && value <= UINT31_MAX;
}
class BIP32 {
constructor(__D, __Q, chainCode, network) {
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 = 0;
this.index = 0;
this.parentFingerprint = 0x00000000;
this.__DEPTH = __DEPTH;
this.__INDEX = __INDEX;
this.__PARENT_FINGERPRINT = __PARENT_FINGERPRINT;
typeforce(NETWORK_TYPE, network);
}
get depth() {
return this.__DEPTH;
}
get index() {
return this.__INDEX;
}
get parentFingerprint() {
return this.__PARENT_FINGERPRINT;
}
get publicKey() {
if (this.__Q === undefined)
this.__Q = ecc.pointFromScalar(this.__D, true);
Expand All @@ -59,11 +68,7 @@ class BIP32 {
return this.__D === undefined;
}
neutered() {
const neutered = fromPublicKey(this.publicKey, this.chainCode, this.network);
neutered.depth = this.depth;
neutered.index = this.index;
neutered.parentFingerprint = this.parentFingerprint;
return neutered;
return fromPublicKeyLocal(this.publicKey, this.chainCode, this.network, this.depth, this.index, this.parentFingerprint);
}
toBase58() {
const network = this.network;
Expand Down Expand Up @@ -135,7 +140,7 @@ class BIP32 {
// In case ki == 0, proceed with the next value for i
if (ki == null)
return this.derive(index + 1);
hd = fromPrivateKey(ki, IR, this.network);
hd = fromPrivateKeyLocal(ki, IR, this.network, this.depth + 1, index, this.fingerprint.readUInt32BE(0));
// Public parent key -> public child key
}
else {
Expand All @@ -145,11 +150,8 @@ class BIP32 {
// In case Ki is the point at infinity, proceed with the next value for i
if (Ki === null)
return this.derive(index + 1);
hd = fromPublicKey(Ki, IR, this.network);
hd = fromPublicKeyLocal(Ki, IR, this.network, this.depth + 1, index, this.fingerprint.readUInt32BE(0));
}
hd.depth = this.depth + 1;
hd.index = index;
hd.parentFingerprint = this.fingerprint.readUInt32BE(0);
return hd;
}
deriveHardened(index) {
Expand Down Expand Up @@ -214,31 +216,35 @@ function fromBase58(inString, network) {
if (buffer.readUInt8(45) !== 0x00)
throw new TypeError('Invalid private key');
const k = buffer.slice(46, 78);
hd = fromPrivateKey(k, chainCode, network);
hd = fromPrivateKeyLocal(k, chainCode, network, depth, index, parentFingerprint);
// 33 bytes: public key data (0x02 + X or 0x03 + X)
}
else {
const X = buffer.slice(45, 78);
hd = fromPublicKey(X, chainCode, network);
hd = fromPublicKeyLocal(X, chainCode, network, depth, index, parentFingerprint);
}
hd.depth = depth;
hd.index = index;
hd.parentFingerprint = parentFingerprint;
return hd;
}
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);
return new BIP32(privateKey, undefined, chainCode, network, depth, index, parentFingerprint);
}
exports.fromPrivateKey = fromPrivateKey;
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,
Expand All @@ -247,9 +253,8 @@ function fromPublicKey(publicKey, chainCode, network) {
// 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);
return new BIP32(undefined, publicKey, chainCode, network, depth, index, parentFingerprint);
}
exports.fromPublicKey = fromPublicKey;
function fromSeed(seed, network) {
typeforce(typeforce.Buffer, seed);
if (seed.length < 16)
Expand Down
114 changes: 92 additions & 22 deletions ts-src/bip32.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,30 @@ export interface BIP32Interface {
}

class BIP32 implements BIP32Interface {
depth = 0;
index = 0;
parentFingerprint = 0x00000000;

constructor(
private __D: Buffer | undefined,
private __Q: Buffer | undefined,
public chainCode: Buffer,
public network: Network,
private __DEPTH = 0,
private __INDEX = 0,
private __PARENT_FINGERPRINT = 0x00000000,
) {
typeforce(NETWORK_TYPE, network);
}

get depth(): number {
return this.__DEPTH;
}

get index(): number {
return this.__INDEX;
}

get parentFingerprint(): number {
return this.__PARENT_FINGERPRINT;
}

get publicKey(): Buffer {
if (this.__Q === undefined) this.__Q = ecc.pointFromScalar(this.__D, true);
return this.__Q!;
Expand All @@ -105,15 +116,14 @@ class BIP32 implements BIP32Interface {
}

neutered(): BIP32Interface {
const neutered = fromPublicKey(
return fromPublicKeyLocal(
this.publicKey,
this.chainCode,
this.network,
this.depth,
this.index,
this.parentFingerprint,
);
neutered.depth = this.depth;
neutered.index = this.index;
neutered.parentFingerprint = this.parentFingerprint;
return neutered;
}

toBase58(): string {
Expand Down Expand Up @@ -200,7 +210,14 @@ class BIP32 implements BIP32Interface {
// In case ki == 0, proceed with the next value for i
if (ki == null) return this.derive(index + 1);

hd = fromPrivateKey(ki, IR, this.network);
hd = fromPrivateKeyLocal(
ki,
IR,
this.network,
this.depth + 1,
index,
this.fingerprint.readUInt32BE(0),
);

// Public parent key -> public child key
} else {
Expand All @@ -211,12 +228,16 @@ class BIP32 implements BIP32Interface {
// In case Ki is the point at infinity, proceed with the next value for i
if (Ki === null) return this.derive(index + 1);

hd = fromPublicKey(Ki, IR, this.network);
hd = fromPublicKeyLocal(
Ki,
IR,
this.network,
this.depth + 1,
index,
this.fingerprint.readUInt32BE(0),
);
}

hd.depth = this.depth + 1;
hd.index = index;
hd.parentFingerprint = this.fingerprint.readUInt32BE(0);
return hd;
}

Expand Down Expand Up @@ -292,33 +313,55 @@ export function fromBase58(

// 32 bytes: the chain code
const chainCode = buffer.slice(13, 45);
let hd;
let hd: BIP32Interface;

// 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 = fromPrivateKey(k, chainCode, network);
hd = fromPrivateKeyLocal(
k,
chainCode,
network,
depth,
index,
parentFingerprint,
);

// 33 bytes: public key data (0x02 + X or 0x03 + X)
} else {
const X = buffer.slice(45, 78);

hd = fromPublicKey(X, chainCode, network);
hd = fromPublicKeyLocal(
X,
chainCode,
network,
depth,
index,
parentFingerprint,
);
}

hd.depth = depth;
hd.index = index;
hd.parentFingerprint = parentFingerprint;
return hd;
}

export function fromPrivateKey(
privateKey: Buffer,
chainCode: Buffer,
network?: Network,
): BIP32Interface {
return fromPrivateKeyLocal(privateKey, chainCode, network);
}

function fromPrivateKeyLocal(
privateKey: Buffer,
chainCode: Buffer,
network?: Network,
depth?: number,
index?: number,
parentFingerprint?: number,
): BIP32Interface {
typeforce(
{
Expand All @@ -331,13 +374,32 @@ export function fromPrivateKey(

if (!ecc.isPrivate(privateKey))
throw new TypeError('Private key not in range [1, n)');
return new BIP32(privateKey, undefined, chainCode, network);
return new BIP32(
privateKey,
undefined,
chainCode,
network,
depth,
index,
parentFingerprint,
);
}

export function fromPublicKey(
publicKey: Buffer,
chainCode: Buffer,
network?: Network,
): BIP32Interface {
return fromPublicKeyLocal(publicKey, chainCode, network);
}

function fromPublicKeyLocal(
publicKey: Buffer,
chainCode: Buffer,
network?: Network,
depth?: number,
index?: number,
parentFingerprint?: number,
): BIP32Interface {
typeforce(
{
Expand All @@ -350,7 +412,15 @@ export function fromPublicKey(

// 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);
return new BIP32(
undefined,
publicKey,
chainCode,
network,
depth,
index,
parentFingerprint,
);
}

export function fromSeed(seed: Buffer, network?: Network): BIP32Interface {
Expand Down

0 comments on commit fe4dc02

Please sign in to comment.