Skip to content

Commit

Permalink
refactor: get rid of ed25519-hd-key
Browse files Browse the repository at this point in the history
  • Loading branch information
jjleng authored and banool committed Sep 15, 2022
1 parent 1b1365e commit 9212214
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 34 deletions.
7 changes: 6 additions & 1 deletion ecosystem/typescript/sdk/jest.config.js
Expand Up @@ -5,7 +5,12 @@ module.exports = {
"^(\\.{1,2}/.*)\\.js$": "$1",
},
testEnvironment: "node",
coveragePathIgnorePatterns: ["generated/*", "transaction_builder/aptos_types/*", "utils/memoize-decorator.ts"],
coveragePathIgnorePatterns: [
"generated/*",
"transaction_builder/aptos_types/*",
"utils/memoize-decorator.ts",
"utils/hd-key.ts",
],
testPathIgnorePatterns: ["dist/*"],
collectCoverage: true,
setupFiles: ["dotenv/config"],
Expand Down
4 changes: 2 additions & 2 deletions ecosystem/typescript/sdk/src/aptos_account.ts
Expand Up @@ -3,8 +3,8 @@

import nacl from "tweetnacl";
import sha3 from "js-sha3";
import { derivePath } from "ed25519-hd-key";
import * as bip39 from "@scure/bip39";
import { derivePath } from "./utils/hd-key";
import { bytesToHex } from "./bytes_to_hex.js";
import { HexString, MaybeHexString } from "./hex_string";
import * as Gen from "./generated/index";
Expand Down Expand Up @@ -66,7 +66,7 @@ export class AptosAccount {

const { key } = derivePath(path, bytesToHex(bip39.mnemonicToSeedSync(normalizeMnemonics)));

return new AptosAccount(new Uint8Array(key));
return new AptosAccount(new HexString(key).toUint8Array());
}

/**
Expand Down
83 changes: 83 additions & 0 deletions ecosystem/typescript/sdk/src/utils/hd-key.ts
@@ -0,0 +1,83 @@
import nacl from "tweetnacl";
import { hmac, sha512 } from "hash.js";
import { bytesToHex } from "../bytes_to_hex";

type Hex = string;
type Path = string;

type Keys = {
key: Hex;
chainCode: Hex;
};

const pathRegex = /^m(\/[0-9]+')+$/;

const replaceDerive = (val: string): string => val.replace("'", "");

const HMAC_KEY = "656432353531392073656564"; // ed25519 seed
const HARDENED_OFFSET = 0x80000000;

export const getMasterKeyFromSeed = (seed: Hex): Keys => {
// @ts-ignore
const h = hmac(sha512, HMAC_KEY, "hex");
const I = h.update(seed, "hex").digest("hex");
const IL = I.slice(0, 64);
const IR = I.slice(64);
return {
key: IL,
chainCode: IR,
};
};

export const CKDPriv = ({ key, chainCode }: Keys, index: number): Keys => {
const indexBuffer = Buffer.allocUnsafe(4);
indexBuffer.writeUInt32BE(index, 0);

const buffer = new ArrayBuffer(4);
new DataView(buffer).setUint32(0, index);
const indexBytes = new Uint8Array(buffer);
const zero = new Uint8Array([0]);
const data = bytesToHex(zero) + key + bytesToHex(indexBytes);

// @ts-ignore
const I = hmac(sha512, chainCode, "hex").update(data, "hex").digest("hex");
const IL = I.slice(0, 64);
const IR = I.slice(64);
return {
key: IL,
chainCode: IR,
};
};

export const getPublicKey = (privateKey: Uint8Array, withZeroByte = true): Uint8Array => {
const keyPair = nacl.sign.keyPair.fromSeed(privateKey);
const signPk = keyPair.secretKey.subarray(32);
const zero = new Uint8Array([0]);
return withZeroByte ? new Uint8Array([...zero, ...signPk]) : signPk;
};

export const isValidPath = (path: string): boolean => {
if (!pathRegex.test(path)) {
return false;
}
return !path
.split("/")
.slice(1)
.map(replaceDerive)
.some(Number.isNaN as any);
};

export const derivePath = (path: Path, seed: Hex, offset = HARDENED_OFFSET): Keys => {
if (!isValidPath(path)) {
throw new Error("Invalid derivation path");
}

const { key, chainCode } = getMasterKeyFromSeed(seed);
const segments = path
.split("/")
.slice(1)
.map(replaceDerive)
.map((el) => parseInt(el, 10));

return segments.reduce((parentKeys, segment) => CKDPriv(parentKeys, segment + offset), { key, chainCode });
};
37 changes: 6 additions & 31 deletions ecosystem/typescript/sdk/yarn.lock
Expand Up @@ -1222,14 +1222,6 @@ ci-info@^3.2.0:
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.3.2.tgz#6d2967ffa407466481c6c90b6e16b3098f080128"
integrity sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==

cipher-base@^1.0.1, cipher-base@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de"
integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==
dependencies:
inherits "^2.0.1"
safe-buffer "^5.0.1"

cjs-module-lexer@^1.0.0:
version "1.2.2"
resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz#9f84ba3244a512f3a54e5277e8eef4c489864e40"
Expand Down Expand Up @@ -2181,14 +2173,13 @@ has@^1.0.3:
dependencies:
function-bind "^1.1.1"

hash-base@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33"
integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==
hash.js@1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42"
integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==
dependencies:
inherits "^2.0.4"
readable-stream "^3.6.0"
safe-buffer "^5.2.0"
inherits "^2.0.3"
minimalistic-assert "^1.0.1"

html-escaper@^2.0.0:
version "2.0.2"
Expand Down Expand Up @@ -3380,14 +3371,6 @@ rimraf@^3.0.0, rimraf@^3.0.2:
dependencies:
glob "^7.1.3"

ripemd160@^2.0.0, ripemd160@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c"
integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==
dependencies:
hash-base "^3.0.0"
inherits "^2.0.1"

rollup@^2.74.1:
version "2.79.0"
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.79.0.tgz#9177992c9f09eb58c5e56cbfa641607a12b57ce2"
Expand Down Expand Up @@ -3424,14 +3407,6 @@ semver@^6.0.0, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==

sha.js@^2.4.0, sha.js@^2.4.8:
version "2.4.11"
resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7"
integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==
dependencies:
inherits "^2.0.1"
safe-buffer "^5.0.1"

shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
Expand Down

0 comments on commit 9212214

Please sign in to comment.