From cb19a54233086c30369c27d103ae2107dafb20c0 Mon Sep 17 00:00:00 2001 From: willclarktech Date: Tue, 15 Sep 2020 13:31:20 +0200 Subject: [PATCH] crypto: Add HdPath type alias --- packages/crypto/src/index.ts | 1 + packages/crypto/src/slip10.spec.ts | 56 +++++++++++++----------------- packages/crypto/src/slip10.ts | 12 +++---- packages/crypto/types/index.d.ts | 1 + packages/crypto/types/slip10.d.ts | 7 ++-- 5 files changed, 36 insertions(+), 41 deletions(-) diff --git a/packages/crypto/src/index.ts b/packages/crypto/src/index.ts index 925865b3..bd19288f 100644 --- a/packages/crypto/src/index.ts +++ b/packages/crypto/src/index.ts @@ -18,6 +18,7 @@ export { Secp256k1, Secp256k1Keypair } from "./secp256k1"; export { ExtendedSecp256k1Signature, Secp256k1Signature } from "./secp256k1signature"; export { Sha1, Sha256, Sha512 } from "./sha"; export { + HdPath, pathToString, stringToPath, Slip10, diff --git a/packages/crypto/src/slip10.spec.ts b/packages/crypto/src/slip10.spec.ts index 52718df8..7dc72565 100644 --- a/packages/crypto/src/slip10.spec.ts +++ b/packages/crypto/src/slip10.spec.ts @@ -1,6 +1,7 @@ import { fromHex } from "@cosmjs/encoding"; import { + HdPath, pathToString, Slip10, Slip10Curve, @@ -22,7 +23,7 @@ describe("Slip10", () => { const seed = fromHex("000102030405060708090a0b0c0d0e0f"); it("can derive path m", () => { - const path: readonly Slip10RawIndex[] = []; + const path: HdPath = []; const derived = Slip10.derivePath(Slip10Curve.Secp256k1, seed, path); expect(derived.chainCode).toEqual( fromHex("873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508"), @@ -33,7 +34,7 @@ describe("Slip10", () => { }); it("can derive path m/0'", () => { - const path: readonly Slip10RawIndex[] = [Slip10RawIndex.hardened(0)]; + const path: HdPath = [Slip10RawIndex.hardened(0)]; const derived = Slip10.derivePath(Slip10Curve.Secp256k1, seed, path); expect(derived.chainCode).toEqual( fromHex("47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141"), @@ -44,7 +45,7 @@ describe("Slip10", () => { }); it("can derive path m/0'/1", () => { - const path: readonly Slip10RawIndex[] = [Slip10RawIndex.hardened(0), Slip10RawIndex.normal(1)]; + const path: HdPath = [Slip10RawIndex.hardened(0), Slip10RawIndex.normal(1)]; const derived = Slip10.derivePath(Slip10Curve.Secp256k1, seed, path); expect(derived.chainCode).toEqual( fromHex("2a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19"), @@ -55,11 +56,7 @@ describe("Slip10", () => { }); it("can derive path m/0'/1/2'", () => { - const path: readonly Slip10RawIndex[] = [ - Slip10RawIndex.hardened(0), - Slip10RawIndex.normal(1), - Slip10RawIndex.hardened(2), - ]; + const path: HdPath = [Slip10RawIndex.hardened(0), Slip10RawIndex.normal(1), Slip10RawIndex.hardened(2)]; const derived = Slip10.derivePath(Slip10Curve.Secp256k1, seed, path); expect(derived.chainCode).toEqual( fromHex("04466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f"), @@ -70,7 +67,7 @@ describe("Slip10", () => { }); it("can derive path m/0'/1/2'/2", () => { - const path: readonly Slip10RawIndex[] = [ + const path: HdPath = [ Slip10RawIndex.hardened(0), Slip10RawIndex.normal(1), Slip10RawIndex.hardened(2), @@ -86,7 +83,7 @@ describe("Slip10", () => { }); it("can derive path m/0'/1/2'/2/1000000000", () => { - const path: readonly Slip10RawIndex[] = [ + const path: HdPath = [ Slip10RawIndex.hardened(0), Slip10RawIndex.normal(1), Slip10RawIndex.hardened(2), @@ -110,7 +107,7 @@ describe("Slip10", () => { ); it("can derive path m", () => { - const path: readonly Slip10RawIndex[] = []; + const path: HdPath = []; const derived = Slip10.derivePath(Slip10Curve.Secp256k1, seed, path); expect(derived.chainCode).toEqual( fromHex("60499f801b896d83179a4374aeb7822aaeaceaa0db1f85ee3e904c4defbd9689"), @@ -121,7 +118,7 @@ describe("Slip10", () => { }); it("can derive path m/0", () => { - const path: readonly Slip10RawIndex[] = [Slip10RawIndex.normal(0)]; + const path: HdPath = [Slip10RawIndex.normal(0)]; const derived = Slip10.derivePath(Slip10Curve.Secp256k1, seed, path); expect(derived.chainCode).toEqual( fromHex("f0909affaa7ee7abe5dd4e100598d4dc53cd709d5a5c2cac40e7412f232f7c9c"), @@ -132,7 +129,7 @@ describe("Slip10", () => { }); it("can derive path m/0/2147483647'", () => { - const path: readonly Slip10RawIndex[] = [Slip10RawIndex.normal(0), Slip10RawIndex.hardened(2147483647)]; + const path: HdPath = [Slip10RawIndex.normal(0), Slip10RawIndex.hardened(2147483647)]; const derived = Slip10.derivePath(Slip10Curve.Secp256k1, seed, path); expect(derived.chainCode).toEqual( fromHex("be17a268474a6bb9c61e1d720cf6215e2a88c5406c4aee7b38547f585c9a37d9"), @@ -143,7 +140,7 @@ describe("Slip10", () => { }); it("can derive path m/0/2147483647'/1", () => { - const path: readonly Slip10RawIndex[] = [ + const path: HdPath = [ Slip10RawIndex.normal(0), Slip10RawIndex.hardened(2147483647), Slip10RawIndex.normal(1), @@ -158,7 +155,7 @@ describe("Slip10", () => { }); it("can derive path m/0/2147483647'/1/2147483646'", () => { - const path: readonly Slip10RawIndex[] = [ + const path: HdPath = [ Slip10RawIndex.normal(0), Slip10RawIndex.hardened(2147483647), Slip10RawIndex.normal(1), @@ -174,7 +171,7 @@ describe("Slip10", () => { }); it("can derive path m/0/2147483647'/1/2147483646'/2", () => { - const path: readonly Slip10RawIndex[] = [ + const path: HdPath = [ Slip10RawIndex.normal(0), Slip10RawIndex.hardened(2147483647), Slip10RawIndex.normal(1), @@ -196,7 +193,7 @@ describe("Slip10", () => { const seed = fromHex("000102030405060708090a0b0c0d0e0f"); it("can derive path m", () => { - const path: readonly Slip10RawIndex[] = []; + const path: HdPath = []; const derived = Slip10.derivePath(Slip10Curve.Ed25519, seed, path); expect(derived.chainCode).toEqual( fromHex("90046a93de5380a72b5e45010748567d5ea02bbf6522f979e05c0d8d8ca9fffb"), @@ -207,7 +204,7 @@ describe("Slip10", () => { }); it("can derive path m/0'", () => { - const path: readonly Slip10RawIndex[] = [Slip10RawIndex.hardened(0)]; + const path: HdPath = [Slip10RawIndex.hardened(0)]; const derived = Slip10.derivePath(Slip10Curve.Ed25519, seed, path); expect(derived.chainCode).toEqual( fromHex("8b59aa11380b624e81507a27fedda59fea6d0b779a778918a2fd3590e16e9c69"), @@ -218,7 +215,7 @@ describe("Slip10", () => { }); it("can derive path m/0'/1'", () => { - const path: readonly Slip10RawIndex[] = [Slip10RawIndex.hardened(0), Slip10RawIndex.hardened(1)]; + const path: HdPath = [Slip10RawIndex.hardened(0), Slip10RawIndex.hardened(1)]; const derived = Slip10.derivePath(Slip10Curve.Ed25519, seed, path); expect(derived.chainCode).toEqual( fromHex("a320425f77d1b5c2505a6b1b27382b37368ee640e3557c315416801243552f14"), @@ -229,7 +226,7 @@ describe("Slip10", () => { }); it("can derive path m/0'/1'/2'", () => { - const path: readonly Slip10RawIndex[] = [ + const path: HdPath = [ Slip10RawIndex.hardened(0), Slip10RawIndex.hardened(1), Slip10RawIndex.hardened(2), @@ -244,7 +241,7 @@ describe("Slip10", () => { }); it("can derive path m/0'/1'/2'/2'", () => { - const path: readonly Slip10RawIndex[] = [ + const path: HdPath = [ Slip10RawIndex.hardened(0), Slip10RawIndex.hardened(1), Slip10RawIndex.hardened(2), @@ -260,7 +257,7 @@ describe("Slip10", () => { }); it("can derive path m/0'/1'/2'/2'/1000000000'", () => { - const path: readonly Slip10RawIndex[] = [ + const path: HdPath = [ Slip10RawIndex.hardened(0), Slip10RawIndex.hardened(1), Slip10RawIndex.hardened(2), @@ -284,7 +281,7 @@ describe("Slip10", () => { ); it("can derive path m", () => { - const path: readonly Slip10RawIndex[] = []; + const path: HdPath = []; const derived = Slip10.derivePath(Slip10Curve.Ed25519, seed, path); expect(derived.chainCode).toEqual( fromHex("ef70a74db9c3a5af931b5fe73ed8e1a53464133654fd55e7a66f8570b8e33c3b"), @@ -295,7 +292,7 @@ describe("Slip10", () => { }); it("can derive path m/0'", () => { - const path: readonly Slip10RawIndex[] = [Slip10RawIndex.hardened(0)]; + const path: HdPath = [Slip10RawIndex.hardened(0)]; const derived = Slip10.derivePath(Slip10Curve.Ed25519, seed, path); expect(derived.chainCode).toEqual( fromHex("0b78a3226f915c082bf118f83618a618ab6dec793752624cbeb622acb562862d"), @@ -306,10 +303,7 @@ describe("Slip10", () => { }); it("can derive path m/0'/2147483647'", () => { - const path: readonly Slip10RawIndex[] = [ - Slip10RawIndex.hardened(0), - Slip10RawIndex.hardened(2147483647), - ]; + const path: HdPath = [Slip10RawIndex.hardened(0), Slip10RawIndex.hardened(2147483647)]; const derived = Slip10.derivePath(Slip10Curve.Ed25519, seed, path); expect(derived.chainCode).toEqual( fromHex("138f0b2551bcafeca6ff2aa88ba8ed0ed8de070841f0c4ef0165df8181eaad7f"), @@ -320,7 +314,7 @@ describe("Slip10", () => { }); it("can derive path m/0'/2147483647'/1'", () => { - const path: readonly Slip10RawIndex[] = [ + const path: HdPath = [ Slip10RawIndex.hardened(0), Slip10RawIndex.hardened(2147483647), Slip10RawIndex.hardened(1), @@ -335,7 +329,7 @@ describe("Slip10", () => { }); it("can derive path m/0'/2147483647'/1'/2147483646'", () => { - const path: readonly Slip10RawIndex[] = [ + const path: HdPath = [ Slip10RawIndex.hardened(0), Slip10RawIndex.hardened(2147483647), Slip10RawIndex.hardened(1), @@ -351,7 +345,7 @@ describe("Slip10", () => { }); it("can derive path m/0'/2147483647'/1'/2147483646'/2'", () => { - const path: readonly Slip10RawIndex[] = [ + const path: HdPath = [ Slip10RawIndex.hardened(0), Slip10RawIndex.hardened(2147483647), Slip10RawIndex.hardened(1), diff --git a/packages/crypto/src/slip10.ts b/packages/crypto/src/slip10.ts index 9f507954..39a0bd8a 100644 --- a/packages/crypto/src/slip10.ts +++ b/packages/crypto/src/slip10.ts @@ -49,16 +49,14 @@ export class Slip10RawIndex extends Uint32 { } } +export type HdPath = readonly Slip10RawIndex[]; + const secp256k1 = new elliptic.ec("secp256k1"); // Universal private key derivation accoring to // https://github.com/satoshilabs/slips/blob/master/slip-0010.md export class Slip10 { - public static derivePath( - curve: Slip10Curve, - seed: Uint8Array, - path: readonly Slip10RawIndex[], - ): Slip10Result { + public static derivePath(curve: Slip10Curve, seed: Uint8Array, path: HdPath): Slip10Result { let result = this.master(curve, seed); for (const rawIndex of path) { result = this.child(curve, result.privkey, result.chainCode, rawIndex); @@ -185,7 +183,7 @@ export class Slip10 { } } -export function pathToString(path: readonly Slip10RawIndex[]): string { +export function pathToString(path: HdPath): string { return path.reduce((current, component): string => { const componentString = component.isHardened() ? `${component.toNumber() - 2 ** 31}'` @@ -194,7 +192,7 @@ export function pathToString(path: readonly Slip10RawIndex[]): string { }, "m"); } -export function stringToPath(input: string): readonly Slip10RawIndex[] { +export function stringToPath(input: string): HdPath { if (!input.startsWith("m")) throw new Error("Path string must start with 'm'"); let rest = input.slice(1); diff --git a/packages/crypto/types/index.d.ts b/packages/crypto/types/index.d.ts index 925865b3..bd19288f 100644 --- a/packages/crypto/types/index.d.ts +++ b/packages/crypto/types/index.d.ts @@ -18,6 +18,7 @@ export { Secp256k1, Secp256k1Keypair } from "./secp256k1"; export { ExtendedSecp256k1Signature, Secp256k1Signature } from "./secp256k1signature"; export { Sha1, Sha256, Sha512 } from "./sha"; export { + HdPath, pathToString, stringToPath, Slip10, diff --git a/packages/crypto/types/slip10.d.ts b/packages/crypto/types/slip10.d.ts index ffd92295..cd90a65f 100644 --- a/packages/crypto/types/slip10.d.ts +++ b/packages/crypto/types/slip10.d.ts @@ -21,8 +21,9 @@ export declare class Slip10RawIndex extends Uint32 { static normal(normalIndex: number): Slip10RawIndex; isHardened(): boolean; } +export declare type HdPath = readonly Slip10RawIndex[]; export declare class Slip10 { - static derivePath(curve: Slip10Curve, seed: Uint8Array, path: readonly Slip10RawIndex[]): Slip10Result; + static derivePath(curve: Slip10Curve, seed: Uint8Array, path: HdPath): Slip10Result; private static master; private static child; /** @@ -36,5 +37,5 @@ export declare class Slip10 { private static isGteN; private static n; } -export declare function pathToString(path: readonly Slip10RawIndex[]): string; -export declare function stringToPath(input: string): readonly Slip10RawIndex[]; +export declare function pathToString(path: HdPath): string; +export declare function stringToPath(input: string): HdPath;