diff --git a/.changeset/brave-walls-sneeze.md b/.changeset/brave-walls-sneeze.md new file mode 100644 index 00000000..2c2f1895 --- /dev/null +++ b/.changeset/brave-walls-sneeze.md @@ -0,0 +1,5 @@ +--- +"@fleet-sdk/wallet": patch +--- + +Bump `@scure/bip32` to `v2` diff --git a/.changeset/dry-heads-dream.md b/.changeset/dry-heads-dream.md new file mode 100644 index 00000000..c96da851 --- /dev/null +++ b/.changeset/dry-heads-dream.md @@ -0,0 +1,5 @@ +--- +"@fleet-sdk/wallet": patch +--- + +Bump `@scure/bip39` to `v2` diff --git a/.changeset/eight-bugs-tan.md b/.changeset/eight-bugs-tan.md new file mode 100644 index 00000000..a87a4f34 --- /dev/null +++ b/.changeset/eight-bugs-tan.md @@ -0,0 +1,5 @@ +--- +"@fleet-sdk/crypto": patch +--- + +Bump `@scure/base` to `v2` diff --git a/.changeset/shiny-taxes-cry.md b/.changeset/shiny-taxes-cry.md new file mode 100644 index 00000000..1867107f --- /dev/null +++ b/.changeset/shiny-taxes-cry.md @@ -0,0 +1,5 @@ +--- +"@fleet-sdk/wallet": patch +--- + +Bump `@noble/curves` to `v2` diff --git a/.changeset/wacky-towns-stick.md b/.changeset/wacky-towns-stick.md new file mode 100644 index 00000000..6be86dce --- /dev/null +++ b/.changeset/wacky-towns-stick.md @@ -0,0 +1,5 @@ +--- +"@fleet-sdk/crypto": patch +--- + +Bump `@noble/hashes` to `v2` diff --git a/packages/crypto/package.json b/packages/crypto/package.json index 3ac5044e..3300085b 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -37,8 +37,8 @@ }, "dependencies": { "@fleet-sdk/common": "workspace:^", - "@noble/hashes": "^1.8.0", - "@scure/base": "^1.2.6" + "@noble/hashes": "^2.0.1", + "@scure/base": "^2.0.0" }, "files": [ "dist", diff --git a/packages/crypto/src/coders/hex.bench.ts b/packages/crypto/src/coders/hex.bench.ts index 2d7cbd71..48f802ff 100644 --- a/packages/crypto/src/coders/hex.bench.ts +++ b/packages/crypto/src/coders/hex.bench.ts @@ -1,4 +1,4 @@ -import { bytesToHex, hexToBytes } from "@noble/hashes/utils"; +import { bytesToHex, hexToBytes } from "@noble/hashes/utils.js"; import { hex as scureHex } from "@scure/base"; import { bench, describe } from "vitest"; import { regularBoxes, validBoxes } from "../../../_test-vectors/mockedBoxes"; diff --git a/packages/crypto/src/hashes.spec.ts b/packages/crypto/src/hashes.spec.ts index db2e09ea..6e482410 100644 --- a/packages/crypto/src/hashes.spec.ts +++ b/packages/crypto/src/hashes.spec.ts @@ -1,4 +1,4 @@ -import { randomBytes } from "@noble/hashes/utils"; +import { randomBytes } from "@noble/hashes/utils.js"; import { describe, expect, it } from "vitest"; import { hex, utf8 } from "./coders"; import { blake2b, blake2b256, sha256 } from "./hashes"; diff --git a/packages/crypto/src/hashes.ts b/packages/crypto/src/hashes.ts index eaa1e8c8..29e521b6 100644 --- a/packages/crypto/src/hashes.ts +++ b/packages/crypto/src/hashes.ts @@ -1,5 +1,5 @@ -import { blake2b as _blake2b } from "@noble/hashes/blake2b"; -import { sha256 as _sha256 } from "@noble/hashes/sha256"; +import { type Blake2Opts, blake2b as _blake2b } from "@noble/hashes/blake2.js"; +import { sha256 as _sha256 } from "@noble/hashes/sha2.js"; import { hex } from "./coders"; import type { ByteInput } from "./types"; @@ -22,11 +22,17 @@ export function blake2b(message: ByteInput, options?: Blake2bOptions): Uint8Arra if (options?.salt) options.salt = ensureBytes(options.salt); if (options?.personalization) options.personalization = ensureBytes(options.personalization); - return _blake2b(ensureBytes(message), options); + const opts: Blake2Opts = { + key: options?.key ? ensureBytes(options?.key) : undefined, + salt: options?.salt ? ensureBytes(options?.salt) : undefined, + personalization: options?.personalization ? ensureBytes(options?.personalization) : undefined, + dkLen: options?.dkLen + }; + return _blake2b(ensureBytes(message), opts); } export function blake2b256(message: ByteInput, options?: Blake2b256Options): Uint8Array { - return blake2b(ensureBytes(message), { dkLen: 32, ...options }); + return blake2b(message, { dkLen: 32, ...options }); } export function sha256(message: ByteInput): Uint8Array { diff --git a/packages/crypto/src/index.ts b/packages/crypto/src/index.ts index f87caac1..b0f8748d 100644 --- a/packages/crypto/src/index.ts +++ b/packages/crypto/src/index.ts @@ -1,4 +1,4 @@ -import { randomBytes as nobleRandomBytes } from "@noble/hashes/utils"; +import { randomBytes as nobleRandomBytes } from "@noble/hashes/utils.js"; /** * Secure PRNG from "@noble/hashes". Uses crypto.getRandomValues, which defers to OS. diff --git a/packages/wallet/package.json b/packages/wallet/package.json index 70f2dd2e..c3bb2a0f 100644 --- a/packages/wallet/package.json +++ b/packages/wallet/package.json @@ -43,9 +43,9 @@ "@fleet-sdk/core": "workspace:^", "@fleet-sdk/crypto": "workspace:^", "@fleet-sdk/serializer": "workspace:^", - "@noble/curves": "^1.9.2", - "@scure/bip32": "^1.7.0", - "@scure/bip39": "^1.6.0" + "@noble/curves": "^2.0.1", + "@scure/bip32": "^2.0.1", + "@scure/bip39": "^2.0.1" }, "engines": { "node": ">=18" diff --git a/packages/wallet/src/mnemonic.ts b/packages/wallet/src/mnemonic.ts index 63d6873c..e1f9bd1b 100644 --- a/packages/wallet/src/mnemonic.ts +++ b/packages/wallet/src/mnemonic.ts @@ -1,5 +1,5 @@ import { generateMnemonic as generate, validateMnemonic as validate } from "@scure/bip39"; -import { wordlist as english } from "@scure/bip39/wordlists/english"; +import { wordlist as english } from "@scure/bip39/wordlists/english.js"; export function generateMnemonic(strength = 160, wordlist = english): string { return generate(wordlist, strength); diff --git a/packages/wallet/src/prover/proveDLogProtocol.spec.ts b/packages/wallet/src/prover/proveDLogProtocol.spec.ts index 1729d1f9..3bb16887 100644 --- a/packages/wallet/src/prover/proveDLogProtocol.spec.ts +++ b/packages/wallet/src/prover/proveDLogProtocol.spec.ts @@ -1,5 +1,5 @@ import { hex } from "@fleet-sdk/crypto"; -import { secp256k1 } from "@noble/curves/secp256k1"; +import { secp256k1 } from "@noble/curves/secp256k1.js"; import { Address, verify_signature } from "ergo-lib-wasm-nodejs"; import fc from "fast-check"; import { describe, expect, it, test } from "vitest"; @@ -79,7 +79,7 @@ describe("ProveDLog protocol", () => { sk: fc.uint8Array({ minLength: 32, maxLength: 32 }) }), ({ msg, sk }) => { - const pk = getPublicKey(hex.encode(sk)); + const pk = getPublicKey(sk); const signature = sign(msg, sk); expect(verify(msg, signature, pk)).to.be.true; diff --git a/packages/wallet/src/prover/proveDLogProtocol.ts b/packages/wallet/src/prover/proveDLogProtocol.ts index 087f461c..dd040a56 100644 --- a/packages/wallet/src/prover/proveDLogProtocol.ts +++ b/packages/wallet/src/prover/proveDLogProtocol.ts @@ -1,9 +1,10 @@ import { FleetError, _0n, concatBytes } from "@fleet-sdk/common"; import { bigintBE, blake2b256, hex, randomBytes, validateEcPoint } from "@fleet-sdk/crypto"; -import { secp256k1 } from "@noble/curves/secp256k1"; +import { secp256k1 } from "@noble/curves/secp256k1.js"; -const { ProjectivePoint: ECPoint, CURVE } = secp256k1; -const G = ECPoint.BASE; +const { Point } = secp256k1; +const G = Point.BASE; +const N = Point.CURVE().n; const BLAKE2B_256_DIGEST_LEN = 32; const ERGO_SOUNDNESS_BYTES = 24; @@ -39,16 +40,16 @@ export function sign(message: Uint8Array, secretKey: Uint8Array) { */ export function genSignature(message: Uint8Array, secretKey: Uint8Array): undefined | Uint8Array { const sk = bigintBE.encode(secretKey); - const pk = G.multiply(sk).toRawBytes(); + const pk = G.multiply(sk).toBytes(); const k = genRandomSecret(); - const w = G.multiply(k).toRawBytes(); + const w = G.multiply(k).toBytes(); const c = fiatShamirHash(genCommitment(pk, w, message)); // The next line is ignored in the coverage report because it depends on randomness. /* v8 ignore next -- @preserve */ if (c === 0n) throw new FleetError("Failed to generate challenge"); - const z = umod(sk * c + k, CURVE.n); + const z = umod(sk * c + k, N); const signature = concatBytes(bigintBE.decode(c), bigintBE.decode(z)); // The next line is ignored in the coverage report because it depends on randomness. @@ -69,7 +70,7 @@ function genRandomSecret() { let c = 0; while (r === 0n && c < MAX_ITERATIONS) { - r = umod(bigintBE.encode(randomBytes(32)), CURVE.n); + r = umod(bigintBE.encode(randomBytes(32)), N); c++; } @@ -105,8 +106,8 @@ export function verify(message: Uint8Array, proof: Uint8Array, publicKey: Uint8A const c = bigintBE.encode(proof.slice(0, ERGO_SOUNDNESS_BYTES)); const z = bigintBE.encode(proof.slice(ERGO_SOUNDNESS_BYTES, ERGO_SCHNORR_SIG_LEN)); - const t = ECPoint.fromHex(publicKey).multiply(CURVE.n - c); - const w = G.multiply(z).add(t).toRawBytes(); + const t = Point.fromBytes(publicKey).multiply(N - c); + const w = G.multiply(z).add(t).toBytes(); const c2 = fiatShamirHash(genCommitment(publicKey, w, message)); return c2 === c; diff --git a/packages/wallet/src/wordlists.spec.ts b/packages/wallet/src/wordlists.spec.ts index 072f9b39..5e3413a6 100644 --- a/packages/wallet/src/wordlists.spec.ts +++ b/packages/wallet/src/wordlists.spec.ts @@ -8,8 +8,7 @@ import { korean, portuguese, simplifiedChinese, - spanish, - traditionalChinese + spanish } from "./wordlists"; describe("wordlists", () => { @@ -18,7 +17,6 @@ describe("wordlists", () => { expect(english).to.have.length(wordlistLength); expect(portuguese).to.have.length(wordlistLength); expect(simplifiedChinese).to.have.length(wordlistLength); - expect(traditionalChinese).to.have.length(wordlistLength); expect(czech).to.have.length(wordlistLength); expect(french).to.have.length(wordlistLength); expect(italian).to.have.length(wordlistLength); diff --git a/packages/wallet/src/wordlists.ts b/packages/wallet/src/wordlists.ts index b8f66666..e2d05d49 100644 --- a/packages/wallet/src/wordlists.ts +++ b/packages/wallet/src/wordlists.ts @@ -1,10 +1,9 @@ -export { wordlist as english } from "@scure/bip39/wordlists/english"; -export { wordlist as japanese } from "@scure/bip39/wordlists/japanese"; -export { wordlist as korean } from "@scure/bip39/wordlists/korean"; -export { wordlist as spanish } from "@scure/bip39/wordlists/spanish"; -export { wordlist as simplifiedChinese } from "@scure/bip39/wordlists/simplified-chinese"; -export { wordlist as traditionalChinese } from "@scure/bip39/wordlists/traditional-chinese"; -export { wordlist as french } from "@scure/bip39/wordlists/french"; -export { wordlist as italian } from "@scure/bip39/wordlists/italian"; -export { wordlist as portuguese } from "@scure/bip39/wordlists/portuguese"; -export { wordlist as czech } from "@scure/bip39/wordlists/czech"; +export { wordlist as english } from "@scure/bip39/wordlists/english.js"; +export { wordlist as japanese } from "@scure/bip39/wordlists/japanese.js"; +export { wordlist as korean } from "@scure/bip39/wordlists/korean.js"; +export { wordlist as spanish } from "@scure/bip39/wordlists/spanish.js"; +export { wordlist as simplifiedChinese } from "@scure/bip39/wordlists/simplified-chinese.js"; +export { wordlist as french } from "@scure/bip39/wordlists/french.js"; +export { wordlist as italian } from "@scure/bip39/wordlists/italian.js"; +export { wordlist as portuguese } from "@scure/bip39/wordlists/portuguese.js"; +export { wordlist as czech } from "@scure/bip39/wordlists/czech.js"; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b7334315..2542b749 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -117,11 +117,11 @@ importers: specifier: workspace:^ version: link:../common '@noble/hashes': - specifier: ^1.8.0 - version: 1.8.0 + specifier: ^2.0.1 + version: 2.0.1 '@scure/base': - specifier: ^1.2.6 - version: 1.2.6 + specifier: ^2.0.0 + version: 2.0.0 packages/mock-chain: dependencies: @@ -174,14 +174,14 @@ importers: specifier: workspace:^ version: link:../serializer '@noble/curves': - specifier: ^1.9.2 - version: 1.9.2 + specifier: ^2.0.1 + version: 2.0.1 '@scure/bip32': - specifier: ^1.7.0 - version: 1.7.0 + specifier: ^2.0.1 + version: 2.0.1 '@scure/bip39': - specifier: ^1.6.0 - version: 1.6.0 + specifier: ^2.0.1 + version: 2.0.1 plugins/ageusd: dependencies: @@ -561,9 +561,9 @@ packages: '@napi-rs/wasm-runtime@1.0.7': resolution: {integrity: sha512-SeDnOO0Tk7Okiq6DbXmmBODgOAb9dp9gjlphokTUxmt8U3liIP1ZsozBahH69j/RJv+Rfs6IwUKHTgQYJ/HBAw==} - '@noble/curves@1.9.2': - resolution: {integrity: sha512-HxngEd2XUcg9xi20JkwlLCtYwfoFw4JGkuZpT+WlsPD4gB/cxkvTD8fSsoAnphGZhFdZYKeQIPCuFlWPm1uE0g==} - engines: {node: ^14.21.3 || >=16} + '@noble/curves@2.0.1': + resolution: {integrity: sha512-vs1Az2OOTBiP4q0pwjW5aF0xp9n4MxVrmkFBxc6EKZc6ddYx5gaZiAsZoq0uRRXWbi3AT/sBqn05eRPtn1JCPw==} + engines: {node: '>= 20.19.0'} '@noble/hashes@1.1.4': resolution: {integrity: sha512-+PYsVPrTSqtVjatKt2A/Proukn2Yrz61OBThOCKErc5w2/r1Fh37vbDv0Eah7pyNltrmacjwTvdw3JoR+WE4TA==} @@ -572,6 +572,10 @@ packages: resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} engines: {node: ^14.21.3 || >=16} + '@noble/hashes@2.0.1': + resolution: {integrity: sha512-XlOlEbQcE9fmuXxrVTXCTlG2nlRXa9Rj3rr5Ue/+tX+nmkgbX720YHh0VR3hBF9xDvwnb8D2shVGOwNx+ulArw==} + engines: {node: '>= 20.19.0'} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -790,14 +794,14 @@ packages: cpu: [x64] os: [win32] - '@scure/base@1.2.6': - resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + '@scure/base@2.0.0': + resolution: {integrity: sha512-3E1kpuZginKkek01ovG8krQ0Z44E3DHPjc5S2rjJw9lZn3KSQOs8S7wqikF/AH7iRanHypj85uGyxk0XAyC37w==} - '@scure/bip32@1.7.0': - resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + '@scure/bip32@2.0.1': + resolution: {integrity: sha512-4Md1NI5BzoVP+bhyJaY3K6yMesEFzNS1sE/cP+9nuvE7p/b0kx9XbpDHHFl8dHtufcbdHRUUQdRqLIPHN/s7yA==} - '@scure/bip39@1.6.0': - resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + '@scure/bip39@2.0.1': + resolution: {integrity: sha512-PsxdFj/d2AcJcZDX1FXN3dDgitDDTmwf78rKZq1a6c1P1Nan1X/Sxc7667zU3U+AN60g7SxxP0YCVw2H/hBycg==} '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} @@ -2563,14 +2567,16 @@ snapshots: '@tybys/wasm-util': 0.10.1 optional: true - '@noble/curves@1.9.2': + '@noble/curves@2.0.1': dependencies: - '@noble/hashes': 1.8.0 + '@noble/hashes': 2.0.1 '@noble/hashes@1.1.4': {} '@noble/hashes@1.8.0': {} + '@noble/hashes@2.0.1': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -2703,18 +2709,18 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.53.2': optional: true - '@scure/base@1.2.6': {} + '@scure/base@2.0.0': {} - '@scure/bip32@1.7.0': + '@scure/bip32@2.0.1': dependencies: - '@noble/curves': 1.9.2 - '@noble/hashes': 1.8.0 - '@scure/base': 1.2.6 + '@noble/curves': 2.0.1 + '@noble/hashes': 2.0.1 + '@scure/base': 2.0.0 - '@scure/bip39@1.6.0': + '@scure/bip39@2.0.1': dependencies: - '@noble/hashes': 1.8.0 - '@scure/base': 1.2.6 + '@noble/hashes': 2.0.1 + '@scure/base': 2.0.0 '@standard-schema/spec@1.0.0': {} @@ -3898,7 +3904,7 @@ snapshots: sigmajs-crypto-facade@0.0.7: dependencies: - '@noble/hashes': 1.1.4 + '@noble/hashes': 1.8.0 sigmastate-js@0.4.6: dependencies: