diff --git a/packages/hd/package.json b/packages/hd/package.json index 5e6dab3f1..bcd092af7 100644 --- a/packages/hd/package.json +++ b/packages/hd/package.json @@ -25,7 +25,6 @@ "@ckb-lumos/crypto": "0.23.0", "bn.js": "^5.1.3", "elliptic": "^6.5.4", - "scrypt-js": "^3.0.1", "uuid": "^8.3.0" }, "repository": { diff --git a/packages/hd/src/keystore.ts b/packages/hd/src/keystore.ts index 179d11c7c..bbf3244a9 100644 --- a/packages/hd/src/keystore.ts +++ b/packages/hd/src/keystore.ts @@ -1,8 +1,7 @@ import { v4 as uuid } from "uuid"; import { bytes } from "@ckb-lumos/codec"; import { HexString } from "@ckb-lumos/base"; -import { ctr, keccak256, randomBytes } from "@ckb-lumos/crypto"; -import { syncScrypt } from "scrypt-js"; +import { ctr, scrypt, keccak256, randomBytes } from "@ckb-lumos/crypto"; import { ExtendedPrivateKey } from "./extended_key"; const { bytify, concat, hexify } = bytes; @@ -143,14 +142,12 @@ export default class Keystore { r: DEFAULT_SCRIPT_PARAM_r, p: DEFAULT_SCRIPT_PARAM_p, }; - const derivedKey = syncScrypt( - new TextEncoder().encode(password), - salt, - kdfparams.n, - kdfparams.r, - kdfparams.p, - kdfparams.dklen - ); + const derivedKey = scrypt(new TextEncoder().encode(password), salt, { + N: kdfparams.n, + r: kdfparams.r, + p: kdfparams.p, + dkLen: kdfparams.dklen, + }); // DO NOT remove the Uint8Array.from call below. // Without calling Uint8Array.from to make a copy of iv, @@ -209,13 +206,15 @@ export default class Keystore { derivedKey(password: string): Uint8Array { const { kdfparams } = this.crypto; - return syncScrypt( + return scrypt( new TextEncoder().encode(password), bytify("0x" + kdfparams.salt), - kdfparams.n, - kdfparams.r, - kdfparams.p, - kdfparams.dklen + { + N: kdfparams.n, + r: kdfparams.r, + p: kdfparams.p, + dkLen: kdfparams.dklen, + } ); } diff --git a/packages/hd/tests/keystore.test.ts b/packages/hd/tests/keystore.test.ts index da3b69b5c..88c47d2de 100644 --- a/packages/hd/tests/keystore.test.ts +++ b/packages/hd/tests/keystore.test.ts @@ -55,24 +55,56 @@ test("load and check password, loads private key", (t) => { * MAC: 2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097 * Cipher key: fac192ceb5fd772906bea3e118a69e8b */ +// This case does NOT work with @crpyto/hashes/scrypt because N is not less than 2^(128 * r / 8) +// const json = { +// crypto: { +// cipher: "aes-128-ctr", +// cipherparams: { +// iv: "83dbcc02d8ccb40e466191a123791e0e", +// }, +// ciphertext: +// "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", +// kdf: "scrypt", +// kdfparams: { +// dklen: 32, +// n: 262144, // 2^18 Scrypt: N must be larger than 1, a power of 2, less than 2^(128 * r / 8) and less than 2^32 +// r: 1, +// p: 8, +// salt: "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19", +// }, +// mac: "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097", +// }, +// id: "3198bc9c-6672-5ab3-d995-4942343ae5b6", +// version: 3, +// }; test("load test vector keystore", (t) => { + // const privateKey = "0xe8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35"; + // const chainCode = "0x873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508"; + // const keystore = KeyStore.create( + // new ExtendedPrivateKey(privateKey, chainCode), + // 'testpassword', + // { + // iv: bytify("0x8f7097ee22add66106055bf3e241fece"), + // salt: bytify("0x481ead5b0311079d2adcd74f32e3db3bdc5f447bc2217ad8164d2d7ead19079f") + // } + // ); const json = { crypto: { cipher: "aes-128-ctr", cipherparams: { - iv: "83dbcc02d8ccb40e466191a123791e0e", + iv: "8f7097ee22add66106055bf3e241fece", }, ciphertext: - "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", + "28b4e6295dca3079d2e0d661517dd18ee7fe0b6a816ef7398d1828e10dfff57480107d30e1e4a73d30a7e0c46584f8f7f66ca38c13fb6fddc22abfe07f3ab0fb", kdf: "scrypt", kdfparams: { dklen: 32, - n: 262144, - p: 8, - r: 1, - salt: "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19", + n: 262144, // 2^18 + r: 8, + p: 1, + salt: "481ead5b0311079d2adcd74f32e3db3bdc5f447bc2217ad8164d2d7ead19079f", }, - mac: "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097", + mac: "87e41a279a32c206579738a051801b3532749682a34fe914e3f487622b0c7b2a", }, id: "3198bc9c-6672-5ab3-d995-4942343ae5b6", version: 3, @@ -81,11 +113,11 @@ test("load test vector keystore", (t) => { t.true(keystore.checkPassword("testpassword")); t.deepEqual( keystore.decrypt("testpassword"), - "0x7a28b5ba57c53603b0b07b56bba752f7784bf506fa95edc395f5cf6c7514fe9d" + "0xe8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508" ); t.deepEqual( hexify(keystore.derivedKey("testpassword")), - "0xfac192ceb5fd772906bea3e118a69e8bbb5cc24229e20d8766fd298291bba6bd" + "0xdc0b555db92835c5a417a6c7229a0c3a228c91ff1b22580ee2c368a8aed33140" ); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 333d2d44e..972600268 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -471,9 +471,6 @@ importers: elliptic: specifier: ^6.5.4 version: 6.5.5 - scrypt-js: - specifier: ^3.0.1 - version: 3.0.1 uuid: specifier: ^8.3.0 version: 8.3.2 @@ -14777,10 +14774,6 @@ packages: ajv-formats: 2.1.1(ajv@8.13.0) ajv-keywords: 5.1.0(ajv@8.13.0) - /scrypt-js@3.0.1: - resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} - dev: false - /search-insights@2.13.0: resolution: {integrity: sha512-Orrsjf9trHHxFRuo9/rzm0KIWmgzE8RMlZMzuhZOJ01Rnz3D0YBAe+V6473t6/H6c7irs6Lt48brULAiRWb3Vw==} dev: false