From 2c2358c534f67a20904f457d49ddfd5f9463cdb5 Mon Sep 17 00:00:00 2001 From: dynst <148708712+dynst@users.noreply.github.com> Date: Sun, 20 Jul 2025 00:00:00 +0000 Subject: [PATCH 1/9] use lightweight tweetnacl --- .pnp.cjs | 14 ++++++++++++++ .../tweetnacl-npm-1.0.3-b7eef04660-069d9df51e.zip | 3 +++ packages/crypto/package.json | 3 ++- packages/crypto/src/libsodium.spec.ts | 4 ++-- packages/crypto/src/libsodium.ts | 12 +++++------- yarn.lock | 8 ++++++++ 6 files changed, 34 insertions(+), 10 deletions(-) create mode 100644 .yarn/cache/tweetnacl-npm-1.0.3-b7eef04660-069d9df51e.zip diff --git a/.pnp.cjs b/.pnp.cjs index cc55526c84..75a44f08c8 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -2891,6 +2891,10 @@ const RAW_RUNTIME_STATE = "tunnel-agent",\ "npm:0.6.0"\ ],\ + [\ + "tweetnacl",\ + "npm:1.0.3"\ + ],\ [\ "type-check",\ "npm:0.4.0"\ @@ -3526,6 +3530,7 @@ const RAW_RUNTIME_STATE = ["prettier", "npm:3.5.3"],\ ["ses", "npm:1.13.1"],\ ["source-map-support", "npm:0.5.21"],\ + ["tweetnacl", "npm:1.0.3"],\ ["typedoc", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:0.28.5"],\ ["typescript", "patch:typescript@npm%3A5.9.2#optional!builtin::version=5.9.2&hash=5786d5"],\ ["webpack", "virtual:1a72a83ae6f92c6f3e756c713a9a31ccfa711e7e2f1243788a7cf7ade4d78c0c1ff62213d9b07eaa19d318c078695418641698a55516ba18eae8be3fd315083a#npm:5.76.1"],\ @@ -13315,6 +13320,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["tweetnacl", [\ + ["npm:1.0.3", {\ + "packageLocation": "./.yarn/cache/tweetnacl-npm-1.0.3-b7eef04660-069d9df51e.zip/node_modules/tweetnacl/",\ + "packageDependencies": [\ + ["tweetnacl", "npm:1.0.3"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["type-check", [\ ["npm:0.4.0", {\ "packageLocation": "./.yarn/cache/type-check-npm-0.4.0-60565800ce-7b3fd0ed43.zip/node_modules/type-check/",\ diff --git a/.yarn/cache/tweetnacl-npm-1.0.3-b7eef04660-069d9df51e.zip b/.yarn/cache/tweetnacl-npm-1.0.3-b7eef04660-069d9df51e.zip new file mode 100644 index 0000000000..64cb359927 --- /dev/null +++ b/.yarn/cache/tweetnacl-npm-1.0.3-b7eef04660-069d9df51e.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ff2b5ec746b6c3d057fea7ec5b12c14dcb3bbca7e99a5ae007dffee789dc1036 +size 176758 diff --git a/packages/crypto/package.json b/packages/crypto/package.json index cd70985294..84a6f55948 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -42,7 +42,8 @@ "@cosmjs/utils": "workspace:^", "@noble/curves": "^1.9.2", "@noble/hashes": "^1", - "libsodium-wrappers-sumo": "^0.7.11" + "libsodium-wrappers-sumo": "^0.7.11", + "tweetnacl": "^1.0.3" }, "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", diff --git a/packages/crypto/src/libsodium.spec.ts b/packages/crypto/src/libsodium.spec.ts index d812d4f505..57139054f1 100644 --- a/packages/crypto/src/libsodium.spec.ts +++ b/packages/crypto/src/libsodium.spec.ts @@ -238,7 +238,7 @@ describe("Libsodium", () => { fail("promise must not resolve"); }) .catch((error) => { - expect(error.message).toContain("invalid seed length"); + expect(error.message).toContain("bad seed size"); }); } @@ -250,7 +250,7 @@ describe("Libsodium", () => { fail("promise must not resolve"); }) .catch((error) => { - expect(error.message).toContain("invalid seed length"); + expect(error.message).toContain("bad seed size"); }); } }); diff --git a/packages/crypto/src/libsodium.ts b/packages/crypto/src/libsodium.ts index 27d41d98c3..e898f41ee6 100644 --- a/packages/crypto/src/libsodium.ts +++ b/packages/crypto/src/libsodium.ts @@ -8,6 +8,7 @@ import { isNonNullObject } from "@cosmjs/utils"; // Argon2 implementation, we can use the normal libsodium-wrappers // again: https://github.com/cosmos/cosmjs/issues/1031 import sodium from "libsodium-wrappers-sumo"; +import nacl from "tweetnacl"; export interface Argon2idOptions { /** Output length in bytes */ @@ -86,14 +87,12 @@ export class Ed25519 { * and diagram on https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/ */ public static async makeKeypair(seed: Uint8Array): Promise { - await sodium.ready; - const keypair = sodium.crypto_sign_seed_keypair(seed); - return Ed25519Keypair.fromLibsodiumPrivkey(keypair.privateKey); + const keypair = nacl.sign.keyPair.fromSeed(seed); + return Ed25519Keypair.fromLibsodiumPrivkey(keypair.secretKey); } public static async createSignature(message: Uint8Array, keyPair: Ed25519Keypair): Promise { - await sodium.ready; - return sodium.crypto_sign_detached(message, keyPair.toLibsodiumPrivkey()); + return nacl.sign.detached(message, keyPair.toLibsodiumPrivkey()); } public static async verifySignature( @@ -101,8 +100,7 @@ export class Ed25519 { message: Uint8Array, pubkey: Uint8Array, ): Promise { - await sodium.ready; - return sodium.crypto_sign_verify_detached(signature, message, pubkey); + return nacl.sign.detached.verify(message, signature, pubkey); } } diff --git a/yarn.lock b/yarn.lock index 4db3b6b546..dfd9d7d56b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -344,6 +344,7 @@ __metadata: prettier: "npm:^3.5.3" ses: "npm:^1.13.0" source-map-support: "npm:^0.5.19" + tweetnacl: "npm:^1.0.3" typedoc: "npm:^0.28" typescript: "npm:~5.9" webpack: "npm:^5.76.0" @@ -7758,6 +7759,13 @@ __metadata: languageName: node linkType: hard +"tweetnacl@npm:^1.0.3": + version: 1.0.3 + resolution: "tweetnacl@npm:1.0.3" + checksum: 10c0/069d9df51e8ad4a89fbe6f9806c68e06c65be3c7d42f0701cc43dba5f0d6064686b238bbff206c5addef8854e3ce00c643bff59432ea2f2c639feab0ee1a93f9 + languageName: node + linkType: hard + "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" From 21b1d547ae1fe4a7bcf1840def7a586a0cd2f68e Mon Sep 17 00:00:00 2001 From: dynst <148708712+dynst@users.noreply.github.com> Date: Sun, 20 Jul 2025 00:00:00 +0000 Subject: [PATCH 2/9] migrate encryption to @stablelib/ --- .pnp.cjs | 150 ++++++++++++++++++ ...b-aead-npm-2.0.0-08c9763f2c-fa80f5499b.zip | 3 + ...binary-npm-2.0.1-eeaf1c2cc4-6c6a5c84e5.zip | 3 + ...chacha-npm-2.0.1-a6576d4026-f6a4416bdb.zip | 3 + ...ly1305-npm-2.0.1-05089d8d27-75a5ef9016.zip | 3 + ...t-time-npm-2.0.1-51f3947aeb-d81e360245.zip | 3 + ...ib-int-npm-2.0.1-4b54f9cbc4-bf70d40b91.zip | 3 + ...ly1305-npm-2.0.1-0f4dbbf406-87b4adfb50.zip | 3 + ...b-wipe-npm-2.0.1-3323c03e2a-f0b76e98f7.zip | 3 + ...acha20-npm-2.0.1-579641491a-4fb631e027.zip | 3 + ...ly1305-npm-2.0.1-34d0e44487-15655e0824.zip | 3 + packages/crypto/package.json | 1 + packages/crypto/src/libsodium.spec.ts | 8 +- packages/crypto/src/libsodium.ts | 35 ++-- yarn.lock | 96 +++++++++++ 15 files changed, 298 insertions(+), 22 deletions(-) create mode 100644 .yarn/cache/@stablelib-aead-npm-2.0.0-08c9763f2c-fa80f5499b.zip create mode 100644 .yarn/cache/@stablelib-binary-npm-2.0.1-eeaf1c2cc4-6c6a5c84e5.zip create mode 100644 .yarn/cache/@stablelib-chacha-npm-2.0.1-a6576d4026-f6a4416bdb.zip create mode 100644 .yarn/cache/@stablelib-chacha20poly1305-npm-2.0.1-05089d8d27-75a5ef9016.zip create mode 100644 .yarn/cache/@stablelib-constant-time-npm-2.0.1-51f3947aeb-d81e360245.zip create mode 100644 .yarn/cache/@stablelib-int-npm-2.0.1-4b54f9cbc4-bf70d40b91.zip create mode 100644 .yarn/cache/@stablelib-poly1305-npm-2.0.1-0f4dbbf406-87b4adfb50.zip create mode 100644 .yarn/cache/@stablelib-wipe-npm-2.0.1-3323c03e2a-f0b76e98f7.zip create mode 100644 .yarn/cache/@stablelib-xchacha20-npm-2.0.1-579641491a-4fb631e027.zip create mode 100644 .yarn/cache/@stablelib-xchacha20poly1305-npm-2.0.1-34d0e44487-15655e0824.zip diff --git a/.pnp.cjs b/.pnp.cjs index 75a44f08c8..4b98bc0364 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -517,6 +517,46 @@ const RAW_RUNTIME_STATE = "@socket.io/component-emitter",\ "npm:3.1.0"\ ],\ + [\ + "@stablelib/aead",\ + "npm:2.0.0"\ + ],\ + [\ + "@stablelib/binary",\ + "npm:2.0.1"\ + ],\ + [\ + "@stablelib/chacha",\ + "npm:2.0.1"\ + ],\ + [\ + "@stablelib/chacha20poly1305",\ + "npm:2.0.1"\ + ],\ + [\ + "@stablelib/constant-time",\ + "npm:2.0.1"\ + ],\ + [\ + "@stablelib/int",\ + "npm:2.0.1"\ + ],\ + [\ + "@stablelib/poly1305",\ + "npm:2.0.1"\ + ],\ + [\ + "@stablelib/wipe",\ + "npm:2.0.1"\ + ],\ + [\ + "@stablelib/xchacha20",\ + "npm:2.0.1"\ + ],\ + [\ + "@stablelib/xchacha20poly1305",\ + "npm:2.0.1"\ + ],\ [\ "@tootallnate/once",\ "npm:2.0.0"\ @@ -3510,6 +3550,7 @@ const RAW_RUNTIME_STATE = ["@istanbuljs/nyc-config-typescript", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:1.0.1"],\ ["@noble/curves", "npm:1.9.2"],\ ["@noble/hashes", "npm:1.8.0"],\ + ["@stablelib/xchacha20poly1305", "npm:2.0.1"],\ ["@types/jasmine", "npm:4.6.1"],\ ["@types/karma-firefox-launcher", "npm:2.1.0"],\ ["@types/karma-jasmine", "npm:4.0.2"],\ @@ -4730,6 +4771,115 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["@stablelib/aead", [\ + ["npm:2.0.0", {\ + "packageLocation": "./.yarn/cache/@stablelib-aead-npm-2.0.0-08c9763f2c-fa80f5499b.zip/node_modules/@stablelib/aead/",\ + "packageDependencies": [\ + ["@stablelib/aead", "npm:2.0.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@stablelib/binary", [\ + ["npm:2.0.1", {\ + "packageLocation": "./.yarn/cache/@stablelib-binary-npm-2.0.1-eeaf1c2cc4-6c6a5c84e5.zip/node_modules/@stablelib/binary/",\ + "packageDependencies": [\ + ["@stablelib/binary", "npm:2.0.1"],\ + ["@stablelib/int", "npm:2.0.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@stablelib/chacha", [\ + ["npm:2.0.1", {\ + "packageLocation": "./.yarn/cache/@stablelib-chacha-npm-2.0.1-a6576d4026-f6a4416bdb.zip/node_modules/@stablelib/chacha/",\ + "packageDependencies": [\ + ["@stablelib/binary", "npm:2.0.1"],\ + ["@stablelib/chacha", "npm:2.0.1"],\ + ["@stablelib/wipe", "npm:2.0.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@stablelib/chacha20poly1305", [\ + ["npm:2.0.1", {\ + "packageLocation": "./.yarn/cache/@stablelib-chacha20poly1305-npm-2.0.1-05089d8d27-75a5ef9016.zip/node_modules/@stablelib/chacha20poly1305/",\ + "packageDependencies": [\ + ["@stablelib/aead", "npm:2.0.0"],\ + ["@stablelib/binary", "npm:2.0.1"],\ + ["@stablelib/chacha", "npm:2.0.1"],\ + ["@stablelib/chacha20poly1305", "npm:2.0.1"],\ + ["@stablelib/constant-time", "npm:2.0.1"],\ + ["@stablelib/poly1305", "npm:2.0.1"],\ + ["@stablelib/wipe", "npm:2.0.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@stablelib/constant-time", [\ + ["npm:2.0.1", {\ + "packageLocation": "./.yarn/cache/@stablelib-constant-time-npm-2.0.1-51f3947aeb-d81e360245.zip/node_modules/@stablelib/constant-time/",\ + "packageDependencies": [\ + ["@stablelib/constant-time", "npm:2.0.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@stablelib/int", [\ + ["npm:2.0.1", {\ + "packageLocation": "./.yarn/cache/@stablelib-int-npm-2.0.1-4b54f9cbc4-bf70d40b91.zip/node_modules/@stablelib/int/",\ + "packageDependencies": [\ + ["@stablelib/int", "npm:2.0.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@stablelib/poly1305", [\ + ["npm:2.0.1", {\ + "packageLocation": "./.yarn/cache/@stablelib-poly1305-npm-2.0.1-0f4dbbf406-87b4adfb50.zip/node_modules/@stablelib/poly1305/",\ + "packageDependencies": [\ + ["@stablelib/constant-time", "npm:2.0.1"],\ + ["@stablelib/poly1305", "npm:2.0.1"],\ + ["@stablelib/wipe", "npm:2.0.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@stablelib/wipe", [\ + ["npm:2.0.1", {\ + "packageLocation": "./.yarn/cache/@stablelib-wipe-npm-2.0.1-3323c03e2a-f0b76e98f7.zip/node_modules/@stablelib/wipe/",\ + "packageDependencies": [\ + ["@stablelib/wipe", "npm:2.0.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@stablelib/xchacha20", [\ + ["npm:2.0.1", {\ + "packageLocation": "./.yarn/cache/@stablelib-xchacha20-npm-2.0.1-579641491a-4fb631e027.zip/node_modules/@stablelib/xchacha20/",\ + "packageDependencies": [\ + ["@stablelib/binary", "npm:2.0.1"],\ + ["@stablelib/chacha", "npm:2.0.1"],\ + ["@stablelib/wipe", "npm:2.0.1"],\ + ["@stablelib/xchacha20", "npm:2.0.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ + ["@stablelib/xchacha20poly1305", [\ + ["npm:2.0.1", {\ + "packageLocation": "./.yarn/cache/@stablelib-xchacha20poly1305-npm-2.0.1-34d0e44487-15655e0824.zip/node_modules/@stablelib/xchacha20poly1305/",\ + "packageDependencies": [\ + ["@stablelib/aead", "npm:2.0.0"],\ + ["@stablelib/chacha20poly1305", "npm:2.0.1"],\ + ["@stablelib/constant-time", "npm:2.0.1"],\ + ["@stablelib/wipe", "npm:2.0.1"],\ + ["@stablelib/xchacha20", "npm:2.0.1"],\ + ["@stablelib/xchacha20poly1305", "npm:2.0.1"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@tootallnate/once", [\ ["npm:2.0.0", {\ "packageLocation": "./.yarn/cache/@tootallnate-once-npm-2.0.0-e36cf4f140-073bfa5480.zip/node_modules/@tootallnate/once/",\ diff --git a/.yarn/cache/@stablelib-aead-npm-2.0.0-08c9763f2c-fa80f5499b.zip b/.yarn/cache/@stablelib-aead-npm-2.0.0-08c9763f2c-fa80f5499b.zip new file mode 100644 index 0000000000..4b34fe0df5 --- /dev/null +++ b/.yarn/cache/@stablelib-aead-npm-2.0.0-08c9763f2c-fa80f5499b.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d04998ceb8a4e8e61715a41b9f1f6121754c54cb985fbeca69a5ee1508666892 +size 7192 diff --git a/.yarn/cache/@stablelib-binary-npm-2.0.1-eeaf1c2cc4-6c6a5c84e5.zip b/.yarn/cache/@stablelib-binary-npm-2.0.1-eeaf1c2cc4-6c6a5c84e5.zip new file mode 100644 index 0000000000..30bd384e45 --- /dev/null +++ b/.yarn/cache/@stablelib-binary-npm-2.0.1-eeaf1c2cc4-6c6a5c84e5.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d7d2dace6c37445fa819ea1f283f6e4a964a996f693695ce85de2dbcc0d9aa3 +size 103054 diff --git a/.yarn/cache/@stablelib-chacha-npm-2.0.1-a6576d4026-f6a4416bdb.zip b/.yarn/cache/@stablelib-chacha-npm-2.0.1-a6576d4026-f6a4416bdb.zip new file mode 100644 index 0000000000..77bff7821f --- /dev/null +++ b/.yarn/cache/@stablelib-chacha-npm-2.0.1-a6576d4026-f6a4416bdb.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:336f57a3f48a670bbc31c153f9bf49f8d3ed1ee5c30b064007acc527415c6cf5 +size 50157 diff --git a/.yarn/cache/@stablelib-chacha20poly1305-npm-2.0.1-05089d8d27-75a5ef9016.zip b/.yarn/cache/@stablelib-chacha20poly1305-npm-2.0.1-05089d8d27-75a5ef9016.zip new file mode 100644 index 0000000000..a5f8139fa2 --- /dev/null +++ b/.yarn/cache/@stablelib-chacha20poly1305-npm-2.0.1-05089d8d27-75a5ef9016.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c0f95f117241cd07d65992d6cf388cd0d7e6ae94f1c75510a33e38e1b0082663 +size 106493 diff --git a/.yarn/cache/@stablelib-constant-time-npm-2.0.1-51f3947aeb-d81e360245.zip b/.yarn/cache/@stablelib-constant-time-npm-2.0.1-51f3947aeb-d81e360245.zip new file mode 100644 index 0000000000..0b6cae3a97 --- /dev/null +++ b/.yarn/cache/@stablelib-constant-time-npm-2.0.1-51f3947aeb-d81e360245.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:42aaf6e15559d192647b1be83f6d91b1d6ecdb3305c144e9f6d1c933eba067f5 +size 20561 diff --git a/.yarn/cache/@stablelib-int-npm-2.0.1-4b54f9cbc4-bf70d40b91.zip b/.yarn/cache/@stablelib-int-npm-2.0.1-4b54f9cbc4-bf70d40b91.zip new file mode 100644 index 0000000000..2d524a9cf5 --- /dev/null +++ b/.yarn/cache/@stablelib-int-npm-2.0.1-4b54f9cbc4-bf70d40b91.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:38b445dc8b993217f659083845881fa7921273517274fdb25b3862d6619a7991 +size 13187 diff --git a/.yarn/cache/@stablelib-poly1305-npm-2.0.1-0f4dbbf406-87b4adfb50.zip b/.yarn/cache/@stablelib-poly1305-npm-2.0.1-0f4dbbf406-87b4adfb50.zip new file mode 100644 index 0000000000..5311bbff0b --- /dev/null +++ b/.yarn/cache/@stablelib-poly1305-npm-2.0.1-0f4dbbf406-87b4adfb50.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:26561f2881f4d82eb0541dbca1b2cf7311626704163b8aab72fb20a7e45cbd16 +size 90839 diff --git a/.yarn/cache/@stablelib-wipe-npm-2.0.1-3323c03e2a-f0b76e98f7.zip b/.yarn/cache/@stablelib-wipe-npm-2.0.1-3323c03e2a-f0b76e98f7.zip new file mode 100644 index 0000000000..8d7f4fd0c1 --- /dev/null +++ b/.yarn/cache/@stablelib-wipe-npm-2.0.1-3323c03e2a-f0b76e98f7.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a443924723b47f4605fa349b621cd5859a2073841cbcb778b4ceabe442df6988 +size 9319 diff --git a/.yarn/cache/@stablelib-xchacha20-npm-2.0.1-579641491a-4fb631e027.zip b/.yarn/cache/@stablelib-xchacha20-npm-2.0.1-579641491a-4fb631e027.zip new file mode 100644 index 0000000000..a0488ab7df --- /dev/null +++ b/.yarn/cache/@stablelib-xchacha20-npm-2.0.1-579641491a-4fb631e027.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1768feb6dcd134cb255debf24fa1aea7c343160b07ba14d6fdb95a5783b41771 +size 43986 diff --git a/.yarn/cache/@stablelib-xchacha20poly1305-npm-2.0.1-34d0e44487-15655e0824.zip b/.yarn/cache/@stablelib-xchacha20poly1305-npm-2.0.1-34d0e44487-15655e0824.zip new file mode 100644 index 0000000000..12ce033c92 --- /dev/null +++ b/.yarn/cache/@stablelib-xchacha20poly1305-npm-2.0.1-34d0e44487-15655e0824.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:219ab3e6e07ed4f7e113ccdda0fabc7d616acda1a4bc71584a2f848226f9215b +size 41847 diff --git a/packages/crypto/package.json b/packages/crypto/package.json index 84a6f55948..4503e565cf 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -42,6 +42,7 @@ "@cosmjs/utils": "workspace:^", "@noble/curves": "^1.9.2", "@noble/hashes": "^1", + "@stablelib/xchacha20poly1305": "^2.0.1", "libsodium-wrappers-sumo": "^0.7.11", "tweetnacl": "^1.0.3" }, diff --git a/packages/crypto/src/libsodium.spec.ts b/packages/crypto/src/libsodium.spec.ts index 57139054f1..1547823cd8 100644 --- a/packages/crypto/src/libsodium.spec.ts +++ b/packages/crypto/src/libsodium.spec.ts @@ -426,7 +426,7 @@ describe("Libsodium", () => { fail("encryption must not succeed"); }) .catch((error) => { - expect(error).toMatch(/invalid key length/); + expect(error).toMatch(/needs 32-byte key/); }); } { @@ -437,7 +437,7 @@ describe("Libsodium", () => { fail("encryption must not succeed"); }) .catch((error) => { - expect(error).toMatch(/invalid key length/); + expect(error).toMatch(/needs 32-byte key/); }); } { @@ -448,7 +448,7 @@ describe("Libsodium", () => { fail("encryption must not succeed"); }) .catch((error) => { - expect(error).toMatch(/invalid key length/); + expect(error).toMatch(/needs 32-byte key/); }); } { @@ -461,7 +461,7 @@ describe("Libsodium", () => { fail("encryption must not succeed"); }) .catch((error) => { - expect(error).toMatch(/invalid key length/); + expect(error).toMatch(/needs 32-byte key/); }); } }); diff --git a/packages/crypto/src/libsodium.ts b/packages/crypto/src/libsodium.ts index e898f41ee6..65615742f3 100644 --- a/packages/crypto/src/libsodium.ts +++ b/packages/crypto/src/libsodium.ts @@ -4,6 +4,7 @@ // libsodium.js API: https://gist.github.com/webmaster128/b2dbe6d54d36dd168c9fabf441b9b09c import { isNonNullObject } from "@cosmjs/utils"; +import { XChaCha20Poly1305 } from "@stablelib/xchacha20poly1305"; // Using crypto_pwhash requires sumo. Once we migrate to a standalone // Argon2 implementation, we can use the normal libsodium-wrappers // again: https://github.com/cosmos/cosmjs/issues/1031 @@ -113,17 +114,14 @@ export const xchacha20NonceLength = 24; export class Xchacha20poly1305Ietf { public static async encrypt(message: Uint8Array, key: Uint8Array, nonce: Uint8Array): Promise { - await sodium.ready; + const associatedData = undefined; - const additionalData = null; + const k = new XChaCha20Poly1305(key); - return sodium.crypto_aead_xchacha20poly1305_ietf_encrypt( - message, - additionalData, - null, // secret nonce: unused and should be null (https://download.libsodium.org/doc/secret-key_cryptography/aead/chacha20-poly1305/xchacha20-poly1305_construction) - nonce, - key, - ); + let ciphertext: Uint8Array = new Uint8Array(message.length + k.tagLength); + ciphertext = k.seal(nonce, message, associatedData, ciphertext); + + return ciphertext; } public static async decrypt( @@ -131,16 +129,17 @@ export class Xchacha20poly1305Ietf { key: Uint8Array, nonce: Uint8Array, ): Promise { - await sodium.ready; + const associatedData = undefined; - const additionalData = null; + const k = new XChaCha20Poly1305(key); - return sodium.crypto_aead_xchacha20poly1305_ietf_decrypt( - null, // secret nonce: unused and should be null (https://download.libsodium.org/doc/secret-key_cryptography/aead/chacha20-poly1305/xchacha20-poly1305_construction) - ciphertext, - additionalData, - nonce, - key, - ); + const plaintextBuffer = new Uint8Array(ciphertext.length - k.tagLength); + const plaintext = k.open(nonce, ciphertext, associatedData, plaintextBuffer); + + if (plaintext == null) { + throw new Error("ciphertext cannot be decrypted using that key"); + } + + return plaintext; } } diff --git a/yarn.lock b/yarn.lock index dfd9d7d56b..7751b6977b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -324,6 +324,7 @@ __metadata: "@istanbuljs/nyc-config-typescript": "npm:^1.0.1" "@noble/curves": "npm:^1.9.2" "@noble/hashes": "npm:^1" + "@stablelib/xchacha20poly1305": "npm:^2.0.1" "@types/jasmine": "npm:^4" "@types/karma-firefox-launcher": "npm:^2" "@types/karma-jasmine": "npm:^4" @@ -1374,6 +1375,101 @@ __metadata: languageName: node linkType: hard +"@stablelib/aead@npm:^2.0.0": + version: 2.0.0 + resolution: "@stablelib/aead@npm:2.0.0" + checksum: 10c0/fa80f5499bf746394409b99e09cd86953f40c10b5be17511aaf5f685f5185e726745ac51f31784fcb6e0b1b61db7517a750f6ec2fc1aac29610eb21a07e14d3d + languageName: node + linkType: hard + +"@stablelib/binary@npm:^2.0.1": + version: 2.0.1 + resolution: "@stablelib/binary@npm:2.0.1" + dependencies: + "@stablelib/int": "npm:^2.0.1" + checksum: 10c0/6c6a5c84e523fefa98ae50bb1dfe03d03df5d346a9f65da07d784901eb1f3df0d4f9382429ec56df2833c133a77be106e04c72254c9b9471c4f15da993cde24e + languageName: node + linkType: hard + +"@stablelib/chacha20poly1305@npm:^2.0.1": + version: 2.0.1 + resolution: "@stablelib/chacha20poly1305@npm:2.0.1" + dependencies: + "@stablelib/aead": "npm:^2.0.0" + "@stablelib/binary": "npm:^2.0.1" + "@stablelib/chacha": "npm:^2.0.1" + "@stablelib/constant-time": "npm:^2.0.1" + "@stablelib/poly1305": "npm:^2.0.1" + "@stablelib/wipe": "npm:^2.0.1" + checksum: 10c0/75a5ef9016653daf3d9b4065a021241c1bd9b3be46246938aa0b8410ec2319e2f8982fe8b20b4981d98a5c88f2a2d0a50a4da803db3b746710b0d0d300016b8e + languageName: node + linkType: hard + +"@stablelib/chacha@npm:^2.0.1": + version: 2.0.1 + resolution: "@stablelib/chacha@npm:2.0.1" + dependencies: + "@stablelib/binary": "npm:^2.0.1" + "@stablelib/wipe": "npm:^2.0.1" + checksum: 10c0/f6a4416bdb9b89e587da7490c4bccc2d41165328a29120af82fd1dca9c838aecf601b2552f1e1684022316c9909d997b45c4f206574549c5debce89f6e0a4971 + languageName: node + linkType: hard + +"@stablelib/constant-time@npm:^2.0.1": + version: 2.0.1 + resolution: "@stablelib/constant-time@npm:2.0.1" + checksum: 10c0/d81e3602450380f0991414d393cf5147c50eb7f2cbc306ac7f93d9131a6d4845ed4a04c5eb04438cf9b2cf8788da9e15f3045a270852d82d3d0e6fff075ffde6 + languageName: node + linkType: hard + +"@stablelib/int@npm:^2.0.1": + version: 2.0.1 + resolution: "@stablelib/int@npm:2.0.1" + checksum: 10c0/bf70d40b910dcc19e15e23eb6ce0beddb9bcc8bda958184490753b5e757c8028f5f1d7ccc056766129e02c416665ce474b95031c84f285105a8d7e1da781059a + languageName: node + linkType: hard + +"@stablelib/poly1305@npm:^2.0.1": + version: 2.0.1 + resolution: "@stablelib/poly1305@npm:2.0.1" + dependencies: + "@stablelib/constant-time": "npm:^2.0.1" + "@stablelib/wipe": "npm:^2.0.1" + checksum: 10c0/87b4adfb50456e32b35f021d955c2abfaf7030d01155a1b5436283500f2877edcd0ce7a76a100b1c382b36e53e25081ef0cb4bd97870ee407dea9db65ec40e1d + languageName: node + linkType: hard + +"@stablelib/wipe@npm:^2.0.1": + version: 2.0.1 + resolution: "@stablelib/wipe@npm:2.0.1" + checksum: 10c0/f0b76e98f773e5a9875a53fd5d3f311f2585aead8578c4cbd82719154ecf7ec98c9575e6c4068339b7bf445341180312f3a73b5c80b92eb24810c3511b5a4927 + languageName: node + linkType: hard + +"@stablelib/xchacha20@npm:^2.0.1": + version: 2.0.1 + resolution: "@stablelib/xchacha20@npm:2.0.1" + dependencies: + "@stablelib/binary": "npm:^2.0.1" + "@stablelib/chacha": "npm:^2.0.1" + "@stablelib/wipe": "npm:^2.0.1" + checksum: 10c0/4fb631e027da79e2f5d3067f181cecec927c6c3994697a21ff186abb952f6cf6c5ba3c43822dd520ff604bd4b242b5b4ca983664a74e126892e872c3535aa6f9 + languageName: node + linkType: hard + +"@stablelib/xchacha20poly1305@npm:^2.0.1": + version: 2.0.1 + resolution: "@stablelib/xchacha20poly1305@npm:2.0.1" + dependencies: + "@stablelib/aead": "npm:^2.0.0" + "@stablelib/chacha20poly1305": "npm:^2.0.1" + "@stablelib/constant-time": "npm:^2.0.1" + "@stablelib/wipe": "npm:^2.0.1" + "@stablelib/xchacha20": "npm:^2.0.1" + checksum: 10c0/15655e0824815dbe606e9f25a79273c42472c843e0046a5fc7508f554c149aa5e1e8bdf01bf9945488f0debf13ea869a855e0739bb12e17efeef0939cbb83ad1 + languageName: node + linkType: hard + "@tootallnate/once@npm:2": version: 2.0.0 resolution: "@tootallnate/once@npm:2.0.0" From dbcf6709abe7655897a2f382bd9a5e3b18739c9d Mon Sep 17 00:00:00 2001 From: dynst <148708712+dynst@users.noreply.github.com> Date: Mon, 21 Jul 2025 00:00:00 +0000 Subject: [PATCH 3/9] migrate encryption to @noble/ciphers --- .pnp.cjs | 164 ++---------------- ...iphers-npm-1.3.0-73a7db337f-3ba6da645c.zip | 3 + ...b-aead-npm-2.0.0-08c9763f2c-fa80f5499b.zip | 3 - ...binary-npm-2.0.1-eeaf1c2cc4-6c6a5c84e5.zip | 3 - ...chacha-npm-2.0.1-a6576d4026-f6a4416bdb.zip | 3 - ...ly1305-npm-2.0.1-05089d8d27-75a5ef9016.zip | 3 - ...t-time-npm-2.0.1-51f3947aeb-d81e360245.zip | 3 - ...ib-int-npm-2.0.1-4b54f9cbc4-bf70d40b91.zip | 3 - ...ly1305-npm-2.0.1-0f4dbbf406-87b4adfb50.zip | 3 - ...b-wipe-npm-2.0.1-3323c03e2a-f0b76e98f7.zip | 3 - ...acha20-npm-2.0.1-579641491a-4fb631e027.zip | 3 - ...ly1305-npm-2.0.1-34d0e44487-15655e0824.zip | 3 - packages/crypto/package.json | 2 +- packages/crypto/src/libsodium.spec.ts | 14 +- packages/crypto/src/libsodium.ts | 22 +-- yarn.lock | 104 +---------- 16 files changed, 42 insertions(+), 297 deletions(-) create mode 100644 .yarn/cache/@noble-ciphers-npm-1.3.0-73a7db337f-3ba6da645c.zip delete mode 100644 .yarn/cache/@stablelib-aead-npm-2.0.0-08c9763f2c-fa80f5499b.zip delete mode 100644 .yarn/cache/@stablelib-binary-npm-2.0.1-eeaf1c2cc4-6c6a5c84e5.zip delete mode 100644 .yarn/cache/@stablelib-chacha-npm-2.0.1-a6576d4026-f6a4416bdb.zip delete mode 100644 .yarn/cache/@stablelib-chacha20poly1305-npm-2.0.1-05089d8d27-75a5ef9016.zip delete mode 100644 .yarn/cache/@stablelib-constant-time-npm-2.0.1-51f3947aeb-d81e360245.zip delete mode 100644 .yarn/cache/@stablelib-int-npm-2.0.1-4b54f9cbc4-bf70d40b91.zip delete mode 100644 .yarn/cache/@stablelib-poly1305-npm-2.0.1-0f4dbbf406-87b4adfb50.zip delete mode 100644 .yarn/cache/@stablelib-wipe-npm-2.0.1-3323c03e2a-f0b76e98f7.zip delete mode 100644 .yarn/cache/@stablelib-xchacha20-npm-2.0.1-579641491a-4fb631e027.zip delete mode 100644 .yarn/cache/@stablelib-xchacha20poly1305-npm-2.0.1-34d0e44487-15655e0824.zip diff --git a/.pnp.cjs b/.pnp.cjs index 4b98bc0364..c0e7e0e905 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -413,6 +413,10 @@ const RAW_RUNTIME_STATE = "@napi-rs/wasm-runtime",\ "npm:0.2.12"\ ],\ + [\ + "@noble/ciphers",\ + "npm:1.3.0"\ + ],\ [\ "@noble/curves",\ "npm:1.9.2"\ @@ -517,46 +521,6 @@ const RAW_RUNTIME_STATE = "@socket.io/component-emitter",\ "npm:3.1.0"\ ],\ - [\ - "@stablelib/aead",\ - "npm:2.0.0"\ - ],\ - [\ - "@stablelib/binary",\ - "npm:2.0.1"\ - ],\ - [\ - "@stablelib/chacha",\ - "npm:2.0.1"\ - ],\ - [\ - "@stablelib/chacha20poly1305",\ - "npm:2.0.1"\ - ],\ - [\ - "@stablelib/constant-time",\ - "npm:2.0.1"\ - ],\ - [\ - "@stablelib/int",\ - "npm:2.0.1"\ - ],\ - [\ - "@stablelib/poly1305",\ - "npm:2.0.1"\ - ],\ - [\ - "@stablelib/wipe",\ - "npm:2.0.1"\ - ],\ - [\ - "@stablelib/xchacha20",\ - "npm:2.0.1"\ - ],\ - [\ - "@stablelib/xchacha20poly1305",\ - "npm:2.0.1"\ - ],\ [\ "@tootallnate/once",\ "npm:2.0.0"\ @@ -3548,9 +3512,9 @@ const RAW_RUNTIME_STATE = ["@cosmjs/math", "workspace:packages/math"],\ ["@cosmjs/utils", "workspace:packages/utils"],\ ["@istanbuljs/nyc-config-typescript", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:1.0.1"],\ + ["@noble/ciphers", "npm:1.3.0"],\ ["@noble/curves", "npm:1.9.2"],\ ["@noble/hashes", "npm:1.8.0"],\ - ["@stablelib/xchacha20poly1305", "npm:2.0.1"],\ ["@types/jasmine", "npm:4.6.1"],\ ["@types/karma-firefox-launcher", "npm:2.1.0"],\ ["@types/karma-jasmine", "npm:4.0.2"],\ @@ -4523,6 +4487,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["@noble/ciphers", [\ + ["npm:1.3.0", {\ + "packageLocation": "./.yarn/cache/@noble-ciphers-npm-1.3.0-73a7db337f-3ba6da645c.zip/node_modules/@noble/ciphers/",\ + "packageDependencies": [\ + ["@noble/ciphers", "npm:1.3.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@noble/curves", [\ ["npm:1.9.2", {\ "packageLocation": "./.yarn/cache/@noble-curves-npm-1.9.2-2584df26a7-21d049ae45.zip/node_modules/@noble/curves/",\ @@ -4771,115 +4744,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["@stablelib/aead", [\ - ["npm:2.0.0", {\ - "packageLocation": "./.yarn/cache/@stablelib-aead-npm-2.0.0-08c9763f2c-fa80f5499b.zip/node_modules/@stablelib/aead/",\ - "packageDependencies": [\ - ["@stablelib/aead", "npm:2.0.0"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@stablelib/binary", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/@stablelib-binary-npm-2.0.1-eeaf1c2cc4-6c6a5c84e5.zip/node_modules/@stablelib/binary/",\ - "packageDependencies": [\ - ["@stablelib/binary", "npm:2.0.1"],\ - ["@stablelib/int", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@stablelib/chacha", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/@stablelib-chacha-npm-2.0.1-a6576d4026-f6a4416bdb.zip/node_modules/@stablelib/chacha/",\ - "packageDependencies": [\ - ["@stablelib/binary", "npm:2.0.1"],\ - ["@stablelib/chacha", "npm:2.0.1"],\ - ["@stablelib/wipe", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@stablelib/chacha20poly1305", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/@stablelib-chacha20poly1305-npm-2.0.1-05089d8d27-75a5ef9016.zip/node_modules/@stablelib/chacha20poly1305/",\ - "packageDependencies": [\ - ["@stablelib/aead", "npm:2.0.0"],\ - ["@stablelib/binary", "npm:2.0.1"],\ - ["@stablelib/chacha", "npm:2.0.1"],\ - ["@stablelib/chacha20poly1305", "npm:2.0.1"],\ - ["@stablelib/constant-time", "npm:2.0.1"],\ - ["@stablelib/poly1305", "npm:2.0.1"],\ - ["@stablelib/wipe", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@stablelib/constant-time", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/@stablelib-constant-time-npm-2.0.1-51f3947aeb-d81e360245.zip/node_modules/@stablelib/constant-time/",\ - "packageDependencies": [\ - ["@stablelib/constant-time", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@stablelib/int", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/@stablelib-int-npm-2.0.1-4b54f9cbc4-bf70d40b91.zip/node_modules/@stablelib/int/",\ - "packageDependencies": [\ - ["@stablelib/int", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@stablelib/poly1305", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/@stablelib-poly1305-npm-2.0.1-0f4dbbf406-87b4adfb50.zip/node_modules/@stablelib/poly1305/",\ - "packageDependencies": [\ - ["@stablelib/constant-time", "npm:2.0.1"],\ - ["@stablelib/poly1305", "npm:2.0.1"],\ - ["@stablelib/wipe", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@stablelib/wipe", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/@stablelib-wipe-npm-2.0.1-3323c03e2a-f0b76e98f7.zip/node_modules/@stablelib/wipe/",\ - "packageDependencies": [\ - ["@stablelib/wipe", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@stablelib/xchacha20", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/@stablelib-xchacha20-npm-2.0.1-579641491a-4fb631e027.zip/node_modules/@stablelib/xchacha20/",\ - "packageDependencies": [\ - ["@stablelib/binary", "npm:2.0.1"],\ - ["@stablelib/chacha", "npm:2.0.1"],\ - ["@stablelib/wipe", "npm:2.0.1"],\ - ["@stablelib/xchacha20", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["@stablelib/xchacha20poly1305", [\ - ["npm:2.0.1", {\ - "packageLocation": "./.yarn/cache/@stablelib-xchacha20poly1305-npm-2.0.1-34d0e44487-15655e0824.zip/node_modules/@stablelib/xchacha20poly1305/",\ - "packageDependencies": [\ - ["@stablelib/aead", "npm:2.0.0"],\ - ["@stablelib/chacha20poly1305", "npm:2.0.1"],\ - ["@stablelib/constant-time", "npm:2.0.1"],\ - ["@stablelib/wipe", "npm:2.0.1"],\ - ["@stablelib/xchacha20", "npm:2.0.1"],\ - ["@stablelib/xchacha20poly1305", "npm:2.0.1"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["@tootallnate/once", [\ ["npm:2.0.0", {\ "packageLocation": "./.yarn/cache/@tootallnate-once-npm-2.0.0-e36cf4f140-073bfa5480.zip/node_modules/@tootallnate/once/",\ diff --git a/.yarn/cache/@noble-ciphers-npm-1.3.0-73a7db337f-3ba6da645c.zip b/.yarn/cache/@noble-ciphers-npm-1.3.0-73a7db337f-3ba6da645c.zip new file mode 100644 index 0000000000..723075d54b --- /dev/null +++ b/.yarn/cache/@noble-ciphers-npm-1.3.0-73a7db337f-3ba6da645c.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9ba9e326e29f1111f24f0d91cc6663dca45faf2a8e98a7e631db1a8fa62f11e7 +size 774440 diff --git a/.yarn/cache/@stablelib-aead-npm-2.0.0-08c9763f2c-fa80f5499b.zip b/.yarn/cache/@stablelib-aead-npm-2.0.0-08c9763f2c-fa80f5499b.zip deleted file mode 100644 index 4b34fe0df5..0000000000 --- a/.yarn/cache/@stablelib-aead-npm-2.0.0-08c9763f2c-fa80f5499b.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d04998ceb8a4e8e61715a41b9f1f6121754c54cb985fbeca69a5ee1508666892 -size 7192 diff --git a/.yarn/cache/@stablelib-binary-npm-2.0.1-eeaf1c2cc4-6c6a5c84e5.zip b/.yarn/cache/@stablelib-binary-npm-2.0.1-eeaf1c2cc4-6c6a5c84e5.zip deleted file mode 100644 index 30bd384e45..0000000000 --- a/.yarn/cache/@stablelib-binary-npm-2.0.1-eeaf1c2cc4-6c6a5c84e5.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2d7d2dace6c37445fa819ea1f283f6e4a964a996f693695ce85de2dbcc0d9aa3 -size 103054 diff --git a/.yarn/cache/@stablelib-chacha-npm-2.0.1-a6576d4026-f6a4416bdb.zip b/.yarn/cache/@stablelib-chacha-npm-2.0.1-a6576d4026-f6a4416bdb.zip deleted file mode 100644 index 77bff7821f..0000000000 --- a/.yarn/cache/@stablelib-chacha-npm-2.0.1-a6576d4026-f6a4416bdb.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:336f57a3f48a670bbc31c153f9bf49f8d3ed1ee5c30b064007acc527415c6cf5 -size 50157 diff --git a/.yarn/cache/@stablelib-chacha20poly1305-npm-2.0.1-05089d8d27-75a5ef9016.zip b/.yarn/cache/@stablelib-chacha20poly1305-npm-2.0.1-05089d8d27-75a5ef9016.zip deleted file mode 100644 index a5f8139fa2..0000000000 --- a/.yarn/cache/@stablelib-chacha20poly1305-npm-2.0.1-05089d8d27-75a5ef9016.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c0f95f117241cd07d65992d6cf388cd0d7e6ae94f1c75510a33e38e1b0082663 -size 106493 diff --git a/.yarn/cache/@stablelib-constant-time-npm-2.0.1-51f3947aeb-d81e360245.zip b/.yarn/cache/@stablelib-constant-time-npm-2.0.1-51f3947aeb-d81e360245.zip deleted file mode 100644 index 0b6cae3a97..0000000000 --- a/.yarn/cache/@stablelib-constant-time-npm-2.0.1-51f3947aeb-d81e360245.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:42aaf6e15559d192647b1be83f6d91b1d6ecdb3305c144e9f6d1c933eba067f5 -size 20561 diff --git a/.yarn/cache/@stablelib-int-npm-2.0.1-4b54f9cbc4-bf70d40b91.zip b/.yarn/cache/@stablelib-int-npm-2.0.1-4b54f9cbc4-bf70d40b91.zip deleted file mode 100644 index 2d524a9cf5..0000000000 --- a/.yarn/cache/@stablelib-int-npm-2.0.1-4b54f9cbc4-bf70d40b91.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:38b445dc8b993217f659083845881fa7921273517274fdb25b3862d6619a7991 -size 13187 diff --git a/.yarn/cache/@stablelib-poly1305-npm-2.0.1-0f4dbbf406-87b4adfb50.zip b/.yarn/cache/@stablelib-poly1305-npm-2.0.1-0f4dbbf406-87b4adfb50.zip deleted file mode 100644 index 5311bbff0b..0000000000 --- a/.yarn/cache/@stablelib-poly1305-npm-2.0.1-0f4dbbf406-87b4adfb50.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:26561f2881f4d82eb0541dbca1b2cf7311626704163b8aab72fb20a7e45cbd16 -size 90839 diff --git a/.yarn/cache/@stablelib-wipe-npm-2.0.1-3323c03e2a-f0b76e98f7.zip b/.yarn/cache/@stablelib-wipe-npm-2.0.1-3323c03e2a-f0b76e98f7.zip deleted file mode 100644 index 8d7f4fd0c1..0000000000 --- a/.yarn/cache/@stablelib-wipe-npm-2.0.1-3323c03e2a-f0b76e98f7.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a443924723b47f4605fa349b621cd5859a2073841cbcb778b4ceabe442df6988 -size 9319 diff --git a/.yarn/cache/@stablelib-xchacha20-npm-2.0.1-579641491a-4fb631e027.zip b/.yarn/cache/@stablelib-xchacha20-npm-2.0.1-579641491a-4fb631e027.zip deleted file mode 100644 index a0488ab7df..0000000000 --- a/.yarn/cache/@stablelib-xchacha20-npm-2.0.1-579641491a-4fb631e027.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1768feb6dcd134cb255debf24fa1aea7c343160b07ba14d6fdb95a5783b41771 -size 43986 diff --git a/.yarn/cache/@stablelib-xchacha20poly1305-npm-2.0.1-34d0e44487-15655e0824.zip b/.yarn/cache/@stablelib-xchacha20poly1305-npm-2.0.1-34d0e44487-15655e0824.zip deleted file mode 100644 index 12ce033c92..0000000000 --- a/.yarn/cache/@stablelib-xchacha20poly1305-npm-2.0.1-34d0e44487-15655e0824.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:219ab3e6e07ed4f7e113ccdda0fabc7d616acda1a4bc71584a2f848226f9215b -size 41847 diff --git a/packages/crypto/package.json b/packages/crypto/package.json index 4503e565cf..17c84c259b 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -40,9 +40,9 @@ "@cosmjs/encoding": "workspace:^", "@cosmjs/math": "workspace:^", "@cosmjs/utils": "workspace:^", + "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1", - "@stablelib/xchacha20poly1305": "^2.0.1", "libsodium-wrappers-sumo": "^0.7.11", "tweetnacl": "^1.0.3" }, diff --git a/packages/crypto/src/libsodium.spec.ts b/packages/crypto/src/libsodium.spec.ts index 1547823cd8..0bf5392bce 100644 --- a/packages/crypto/src/libsodium.spec.ts +++ b/packages/crypto/src/libsodium.spec.ts @@ -426,7 +426,7 @@ describe("Libsodium", () => { fail("encryption must not succeed"); }) .catch((error) => { - expect(error).toMatch(/needs 32-byte key/); + expect(error).toMatch(/key, got length=0/); }); } { @@ -437,7 +437,7 @@ describe("Libsodium", () => { fail("encryption must not succeed"); }) .catch((error) => { - expect(error).toMatch(/needs 32-byte key/); + expect(error).toMatch(/key, got length=31/); }); } { @@ -448,7 +448,7 @@ describe("Libsodium", () => { fail("encryption must not succeed"); }) .catch((error) => { - expect(error).toMatch(/needs 32-byte key/); + expect(error).toMatch(/key, got length=33/); }); } { @@ -461,7 +461,7 @@ describe("Libsodium", () => { fail("encryption must not succeed"); }) .catch((error) => { - expect(error).toMatch(/needs 32-byte key/); + expect(error).toMatch(/key, got length=64/); }); } }); @@ -487,7 +487,7 @@ describe("Libsodium", () => { fail("promise must not resolve"); }, (error) => { - expect(error.message).toMatch(/ciphertext cannot be decrypted using that key/i); + expect(error.message).toMatch(/invalid tag/i); }, ); } @@ -499,7 +499,7 @@ describe("Libsodium", () => { fail("promise must not resolve"); }, (error) => { - expect(error.message).toMatch(/ciphertext cannot be decrypted using that key/i); + expect(error.message).toMatch(/invalid tag/i); }, ); } @@ -511,7 +511,7 @@ describe("Libsodium", () => { fail("promise must not resolve"); }, (error) => { - expect(error.message).toMatch(/ciphertext cannot be decrypted using that key/i); + expect(error.message).toMatch(/invalid tag/i); }, ); } diff --git a/packages/crypto/src/libsodium.ts b/packages/crypto/src/libsodium.ts index 65615742f3..0edec9fdae 100644 --- a/packages/crypto/src/libsodium.ts +++ b/packages/crypto/src/libsodium.ts @@ -4,7 +4,7 @@ // libsodium.js API: https://gist.github.com/webmaster128/b2dbe6d54d36dd168c9fabf441b9b09c import { isNonNullObject } from "@cosmjs/utils"; -import { XChaCha20Poly1305 } from "@stablelib/xchacha20poly1305"; +import { xchacha20poly1305 } from "@noble/ciphers/chacha.js"; // Using crypto_pwhash requires sumo. Once we migrate to a standalone // Argon2 implementation, we can use the normal libsodium-wrappers // again: https://github.com/cosmos/cosmjs/issues/1031 @@ -114,12 +114,12 @@ export const xchacha20NonceLength = 24; export class Xchacha20poly1305Ietf { public static async encrypt(message: Uint8Array, key: Uint8Array, nonce: Uint8Array): Promise { - const associatedData = undefined; + const additionalAuthenticatedData = undefined; - const k = new XChaCha20Poly1305(key); + const cipher = xchacha20poly1305(key, nonce, additionalAuthenticatedData); - let ciphertext: Uint8Array = new Uint8Array(message.length + k.tagLength); - ciphertext = k.seal(nonce, message, associatedData, ciphertext); + let ciphertext: Uint8Array = new Uint8Array(message.length + 16); + ciphertext = cipher.encrypt(message, ciphertext); return ciphertext; } @@ -129,16 +129,12 @@ export class Xchacha20poly1305Ietf { key: Uint8Array, nonce: Uint8Array, ): Promise { - const associatedData = undefined; + const additionalAuthenticatedData = undefined; - const k = new XChaCha20Poly1305(key); + const cipher = xchacha20poly1305(key, nonce, additionalAuthenticatedData); - const plaintextBuffer = new Uint8Array(ciphertext.length - k.tagLength); - const plaintext = k.open(nonce, ciphertext, associatedData, plaintextBuffer); - - if (plaintext == null) { - throw new Error("ciphertext cannot be decrypted using that key"); - } + let plaintext: Uint8Array = new Uint8Array(ciphertext.length - 16); + plaintext = cipher.decrypt(ciphertext, plaintext); return plaintext; } diff --git a/yarn.lock b/yarn.lock index 7751b6977b..30f5d9ed64 100644 --- a/yarn.lock +++ b/yarn.lock @@ -322,9 +322,9 @@ __metadata: "@cosmjs/math": "workspace:^" "@cosmjs/utils": "workspace:^" "@istanbuljs/nyc-config-typescript": "npm:^1.0.1" + "@noble/ciphers": "npm:^1.3.0" "@noble/curves": "npm:^1.9.2" "@noble/hashes": "npm:^1" - "@stablelib/xchacha20poly1305": "npm:^2.0.1" "@types/jasmine": "npm:^4" "@types/karma-firefox-launcher": "npm:^2" "@types/karma-jasmine": "npm:^4" @@ -1170,6 +1170,13 @@ __metadata: languageName: node linkType: hard +"@noble/ciphers@npm:^1.3.0": + version: 1.3.0 + resolution: "@noble/ciphers@npm:1.3.0" + checksum: 10c0/3ba6da645ce45e2f35e3b2e5c87ceba86b21dfa62b9466ede9edfb397f8116dae284f06652c0cd81d99445a2262b606632e868103d54ecc99fd946ae1af8cd37 + languageName: node + linkType: hard + "@noble/curves@npm:^1.9.2": version: 1.9.2 resolution: "@noble/curves@npm:1.9.2" @@ -1375,101 +1382,6 @@ __metadata: languageName: node linkType: hard -"@stablelib/aead@npm:^2.0.0": - version: 2.0.0 - resolution: "@stablelib/aead@npm:2.0.0" - checksum: 10c0/fa80f5499bf746394409b99e09cd86953f40c10b5be17511aaf5f685f5185e726745ac51f31784fcb6e0b1b61db7517a750f6ec2fc1aac29610eb21a07e14d3d - languageName: node - linkType: hard - -"@stablelib/binary@npm:^2.0.1": - version: 2.0.1 - resolution: "@stablelib/binary@npm:2.0.1" - dependencies: - "@stablelib/int": "npm:^2.0.1" - checksum: 10c0/6c6a5c84e523fefa98ae50bb1dfe03d03df5d346a9f65da07d784901eb1f3df0d4f9382429ec56df2833c133a77be106e04c72254c9b9471c4f15da993cde24e - languageName: node - linkType: hard - -"@stablelib/chacha20poly1305@npm:^2.0.1": - version: 2.0.1 - resolution: "@stablelib/chacha20poly1305@npm:2.0.1" - dependencies: - "@stablelib/aead": "npm:^2.0.0" - "@stablelib/binary": "npm:^2.0.1" - "@stablelib/chacha": "npm:^2.0.1" - "@stablelib/constant-time": "npm:^2.0.1" - "@stablelib/poly1305": "npm:^2.0.1" - "@stablelib/wipe": "npm:^2.0.1" - checksum: 10c0/75a5ef9016653daf3d9b4065a021241c1bd9b3be46246938aa0b8410ec2319e2f8982fe8b20b4981d98a5c88f2a2d0a50a4da803db3b746710b0d0d300016b8e - languageName: node - linkType: hard - -"@stablelib/chacha@npm:^2.0.1": - version: 2.0.1 - resolution: "@stablelib/chacha@npm:2.0.1" - dependencies: - "@stablelib/binary": "npm:^2.0.1" - "@stablelib/wipe": "npm:^2.0.1" - checksum: 10c0/f6a4416bdb9b89e587da7490c4bccc2d41165328a29120af82fd1dca9c838aecf601b2552f1e1684022316c9909d997b45c4f206574549c5debce89f6e0a4971 - languageName: node - linkType: hard - -"@stablelib/constant-time@npm:^2.0.1": - version: 2.0.1 - resolution: "@stablelib/constant-time@npm:2.0.1" - checksum: 10c0/d81e3602450380f0991414d393cf5147c50eb7f2cbc306ac7f93d9131a6d4845ed4a04c5eb04438cf9b2cf8788da9e15f3045a270852d82d3d0e6fff075ffde6 - languageName: node - linkType: hard - -"@stablelib/int@npm:^2.0.1": - version: 2.0.1 - resolution: "@stablelib/int@npm:2.0.1" - checksum: 10c0/bf70d40b910dcc19e15e23eb6ce0beddb9bcc8bda958184490753b5e757c8028f5f1d7ccc056766129e02c416665ce474b95031c84f285105a8d7e1da781059a - languageName: node - linkType: hard - -"@stablelib/poly1305@npm:^2.0.1": - version: 2.0.1 - resolution: "@stablelib/poly1305@npm:2.0.1" - dependencies: - "@stablelib/constant-time": "npm:^2.0.1" - "@stablelib/wipe": "npm:^2.0.1" - checksum: 10c0/87b4adfb50456e32b35f021d955c2abfaf7030d01155a1b5436283500f2877edcd0ce7a76a100b1c382b36e53e25081ef0cb4bd97870ee407dea9db65ec40e1d - languageName: node - linkType: hard - -"@stablelib/wipe@npm:^2.0.1": - version: 2.0.1 - resolution: "@stablelib/wipe@npm:2.0.1" - checksum: 10c0/f0b76e98f773e5a9875a53fd5d3f311f2585aead8578c4cbd82719154ecf7ec98c9575e6c4068339b7bf445341180312f3a73b5c80b92eb24810c3511b5a4927 - languageName: node - linkType: hard - -"@stablelib/xchacha20@npm:^2.0.1": - version: 2.0.1 - resolution: "@stablelib/xchacha20@npm:2.0.1" - dependencies: - "@stablelib/binary": "npm:^2.0.1" - "@stablelib/chacha": "npm:^2.0.1" - "@stablelib/wipe": "npm:^2.0.1" - checksum: 10c0/4fb631e027da79e2f5d3067f181cecec927c6c3994697a21ff186abb952f6cf6c5ba3c43822dd520ff604bd4b242b5b4ca983664a74e126892e872c3535aa6f9 - languageName: node - linkType: hard - -"@stablelib/xchacha20poly1305@npm:^2.0.1": - version: 2.0.1 - resolution: "@stablelib/xchacha20poly1305@npm:2.0.1" - dependencies: - "@stablelib/aead": "npm:^2.0.0" - "@stablelib/chacha20poly1305": "npm:^2.0.1" - "@stablelib/constant-time": "npm:^2.0.1" - "@stablelib/wipe": "npm:^2.0.1" - "@stablelib/xchacha20": "npm:^2.0.1" - checksum: 10c0/15655e0824815dbe606e9f25a79273c42472c843e0046a5fc7508f554c149aa5e1e8bdf01bf9945488f0debf13ea869a855e0739bb12e17efeef0939cbb83ad1 - languageName: node - linkType: hard - "@tootallnate/once@npm:2": version: 2.0.0 resolution: "@tootallnate/once@npm:2.0.0" From b49271665ec9bcd9fc3d4a78b6ef93731c706ffe Mon Sep 17 00:00:00 2001 From: dynst <148708712+dynst@users.noreply.github.com> Date: Sun, 20 Jul 2025 22:37:41 +0000 Subject: [PATCH 4/9] migrate ed25519 to @noble/curves --- .pnp.cjs | 14 -------------- .../tweetnacl-npm-1.0.3-b7eef04660-069d9df51e.zip | 3 --- packages/crypto/package.json | 3 +-- packages/crypto/src/libsodium.spec.ts | 4 ++-- packages/crypto/src/libsodium.ts | 12 ++++++------ yarn.lock | 8 -------- 6 files changed, 9 insertions(+), 35 deletions(-) delete mode 100644 .yarn/cache/tweetnacl-npm-1.0.3-b7eef04660-069d9df51e.zip diff --git a/.pnp.cjs b/.pnp.cjs index c0e7e0e905..aff098d36b 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -2895,10 +2895,6 @@ const RAW_RUNTIME_STATE = "tunnel-agent",\ "npm:0.6.0"\ ],\ - [\ - "tweetnacl",\ - "npm:1.0.3"\ - ],\ [\ "type-check",\ "npm:0.4.0"\ @@ -3535,7 +3531,6 @@ const RAW_RUNTIME_STATE = ["prettier", "npm:3.5.3"],\ ["ses", "npm:1.13.1"],\ ["source-map-support", "npm:0.5.21"],\ - ["tweetnacl", "npm:1.0.3"],\ ["typedoc", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:0.28.5"],\ ["typescript", "patch:typescript@npm%3A5.9.2#optional!builtin::version=5.9.2&hash=5786d5"],\ ["webpack", "virtual:1a72a83ae6f92c6f3e756c713a9a31ccfa711e7e2f1243788a7cf7ade4d78c0c1ff62213d9b07eaa19d318c078695418641698a55516ba18eae8be3fd315083a#npm:5.76.1"],\ @@ -13334,15 +13329,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["tweetnacl", [\ - ["npm:1.0.3", {\ - "packageLocation": "./.yarn/cache/tweetnacl-npm-1.0.3-b7eef04660-069d9df51e.zip/node_modules/tweetnacl/",\ - "packageDependencies": [\ - ["tweetnacl", "npm:1.0.3"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["type-check", [\ ["npm:0.4.0", {\ "packageLocation": "./.yarn/cache/type-check-npm-0.4.0-60565800ce-7b3fd0ed43.zip/node_modules/type-check/",\ diff --git a/.yarn/cache/tweetnacl-npm-1.0.3-b7eef04660-069d9df51e.zip b/.yarn/cache/tweetnacl-npm-1.0.3-b7eef04660-069d9df51e.zip deleted file mode 100644 index 64cb359927..0000000000 --- a/.yarn/cache/tweetnacl-npm-1.0.3-b7eef04660-069d9df51e.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ff2b5ec746b6c3d057fea7ec5b12c14dcb3bbca7e99a5ae007dffee789dc1036 -size 176758 diff --git a/packages/crypto/package.json b/packages/crypto/package.json index 17c84c259b..83010892c1 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -43,8 +43,7 @@ "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", "@noble/hashes": "^1", - "libsodium-wrappers-sumo": "^0.7.11", - "tweetnacl": "^1.0.3" + "libsodium-wrappers-sumo": "^0.7.11" }, "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", diff --git a/packages/crypto/src/libsodium.spec.ts b/packages/crypto/src/libsodium.spec.ts index 0bf5392bce..6a39039036 100644 --- a/packages/crypto/src/libsodium.spec.ts +++ b/packages/crypto/src/libsodium.spec.ts @@ -238,7 +238,7 @@ describe("Libsodium", () => { fail("promise must not resolve"); }) .catch((error) => { - expect(error.message).toContain("bad seed size"); + expect(error.message).toContain("key of length 32 expected"); }); } @@ -250,7 +250,7 @@ describe("Libsodium", () => { fail("promise must not resolve"); }) .catch((error) => { - expect(error.message).toContain("bad seed size"); + expect(error.message).toContain("key of length 32 expected"); }); } }); diff --git a/packages/crypto/src/libsodium.ts b/packages/crypto/src/libsodium.ts index 0edec9fdae..4d507e7407 100644 --- a/packages/crypto/src/libsodium.ts +++ b/packages/crypto/src/libsodium.ts @@ -5,11 +5,11 @@ import { isNonNullObject } from "@cosmjs/utils"; import { xchacha20poly1305 } from "@noble/ciphers/chacha.js"; +import { ed25519 } from "@noble/curves/ed25519.js"; // Using crypto_pwhash requires sumo. Once we migrate to a standalone // Argon2 implementation, we can use the normal libsodium-wrappers // again: https://github.com/cosmos/cosmjs/issues/1031 import sodium from "libsodium-wrappers-sumo"; -import nacl from "tweetnacl"; export interface Argon2idOptions { /** Output length in bytes */ @@ -87,13 +87,13 @@ export class Ed25519 { * https://download.libsodium.org/doc/public-key_cryptography/public-key_signatures.html * and diagram on https://blog.mozilla.org/warner/2011/11/29/ed25519-keys/ */ - public static async makeKeypair(seed: Uint8Array): Promise { - const keypair = nacl.sign.keyPair.fromSeed(seed); - return Ed25519Keypair.fromLibsodiumPrivkey(keypair.secretKey); + public static async makeKeypair(privKey: Uint8Array): Promise { + const pubKey = ed25519.getPublicKey(privKey); + return new Ed25519Keypair(privKey, pubKey); } public static async createSignature(message: Uint8Array, keyPair: Ed25519Keypair): Promise { - return nacl.sign.detached(message, keyPair.toLibsodiumPrivkey()); + return ed25519.sign(message, keyPair.privkey); } public static async verifySignature( @@ -101,7 +101,7 @@ export class Ed25519 { message: Uint8Array, pubkey: Uint8Array, ): Promise { - return nacl.sign.detached.verify(message, signature, pubkey); + return ed25519.verify(signature, message, pubkey); } } diff --git a/yarn.lock b/yarn.lock index 30f5d9ed64..4b90ce29b4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -345,7 +345,6 @@ __metadata: prettier: "npm:^3.5.3" ses: "npm:^1.13.0" source-map-support: "npm:^0.5.19" - tweetnacl: "npm:^1.0.3" typedoc: "npm:^0.28" typescript: "npm:~5.9" webpack: "npm:^5.76.0" @@ -7767,13 +7766,6 @@ __metadata: languageName: node linkType: hard -"tweetnacl@npm:^1.0.3": - version: 1.0.3 - resolution: "tweetnacl@npm:1.0.3" - checksum: 10c0/069d9df51e8ad4a89fbe6f9806c68e06c65be3c7d42f0701cc43dba5f0d6064686b238bbff206c5addef8854e3ce00c643bff59432ea2f2c639feab0ee1a93f9 - languageName: node - linkType: hard - "type-check@npm:^0.4.0, type-check@npm:~0.4.0": version: 0.4.0 resolution: "type-check@npm:0.4.0" From 81a7b5d5a4b6542a443c54f15d382dae4841fc38 Mon Sep 17 00:00:00 2001 From: dynst <148708712+dynst@users.noreply.github.com> Date: Wed, 13 Aug 2025 00:00:00 +0000 Subject: [PATCH 5/9] drop explicit buffer allocation code --- packages/crypto/src/libsodium.ts | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/packages/crypto/src/libsodium.ts b/packages/crypto/src/libsodium.ts index 4d507e7407..a4a162b17f 100644 --- a/packages/crypto/src/libsodium.ts +++ b/packages/crypto/src/libsodium.ts @@ -118,10 +118,7 @@ export class Xchacha20poly1305Ietf { const cipher = xchacha20poly1305(key, nonce, additionalAuthenticatedData); - let ciphertext: Uint8Array = new Uint8Array(message.length + 16); - ciphertext = cipher.encrypt(message, ciphertext); - - return ciphertext; + return cipher.encrypt(message); } public static async decrypt( @@ -133,9 +130,6 @@ export class Xchacha20poly1305Ietf { const cipher = xchacha20poly1305(key, nonce, additionalAuthenticatedData); - let plaintext: Uint8Array = new Uint8Array(ciphertext.length - 16); - plaintext = cipher.decrypt(ciphertext, plaintext); - - return plaintext; + return cipher.decrypt(ciphertext); } } From 9169c091636c914d9b75adc60e761c41e8b74580 Mon Sep 17 00:00:00 2001 From: dynst <148708712+dynst@users.noreply.github.com> Date: Sun, 20 Jul 2025 00:00:00 +0000 Subject: [PATCH 6/9] migrate to argon2id from @noble/hashes --- .pnp.cjs | 28 ----------------- ...-sumo-npm-0.7.11-aaac6bcc6c-f7518d1781.zip | 3 -- ...-sumo-npm-0.7.11-08fe1b2cf4-81270738b3.zip | 3 -- packages/crypto/package.json | 3 +- packages/crypto/src/libsodium.ts | 31 ++++++++----------- yarn.lock | 17 ---------- 6 files changed, 14 insertions(+), 71 deletions(-) delete mode 100644 .yarn/cache/libsodium-sumo-npm-0.7.11-aaac6bcc6c-f7518d1781.zip delete mode 100644 .yarn/cache/libsodium-wrappers-sumo-npm-0.7.11-08fe1b2cf4-81270738b3.zip diff --git a/.pnp.cjs b/.pnp.cjs index aff098d36b..8226d7d04f 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -2109,14 +2109,6 @@ const RAW_RUNTIME_STATE = "levn",\ "npm:0.4.1"\ ],\ - [\ - "libsodium-sumo",\ - "npm:0.7.11"\ - ],\ - [\ - "libsodium-wrappers-sumo",\ - "npm:0.7.11"\ - ],\ [\ "linkify-it",\ "npm:5.0.0"\ @@ -3526,7 +3518,6 @@ const RAW_RUNTIME_STATE = ["karma-firefox-launcher", "npm:2.1.0"],\ ["karma-jasmine", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:5.1.0"],\ ["karma-jasmine-html-reporter", "virtual:4f1584ad4aba8733a24be7c8aebbffafef25607f2d00f4b314cf96717145c692763628a31c2b85d4686fbb091ff21ebffa3cc337399c042c19a32b9bdb786464#npm:1.6.0"],\ - ["libsodium-wrappers-sumo", "npm:0.7.11"],\ ["nyc", "npm:15.1.0"],\ ["prettier", "npm:3.5.3"],\ ["ses", "npm:1.13.1"],\ @@ -10526,25 +10517,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["libsodium-sumo", [\ - ["npm:0.7.11", {\ - "packageLocation": "./.yarn/cache/libsodium-sumo-npm-0.7.11-aaac6bcc6c-f7518d1781.zip/node_modules/libsodium-sumo/",\ - "packageDependencies": [\ - ["libsodium-sumo", "npm:0.7.11"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ - ["libsodium-wrappers-sumo", [\ - ["npm:0.7.11", {\ - "packageLocation": "./.yarn/cache/libsodium-wrappers-sumo-npm-0.7.11-08fe1b2cf4-81270738b3.zip/node_modules/libsodium-wrappers-sumo/",\ - "packageDependencies": [\ - ["libsodium-sumo", "npm:0.7.11"],\ - ["libsodium-wrappers-sumo", "npm:0.7.11"]\ - ],\ - "linkType": "HARD"\ - }]\ - ]],\ ["linkify-it", [\ ["npm:5.0.0", {\ "packageLocation": "./.yarn/cache/linkify-it-npm-5.0.0-adb5f9c96f-ff4abbcdfa.zip/node_modules/linkify-it/",\ diff --git a/.yarn/cache/libsodium-sumo-npm-0.7.11-aaac6bcc6c-f7518d1781.zip b/.yarn/cache/libsodium-sumo-npm-0.7.11-aaac6bcc6c-f7518d1781.zip deleted file mode 100644 index 30d2862d8a..0000000000 --- a/.yarn/cache/libsodium-sumo-npm-0.7.11-aaac6bcc6c-f7518d1781.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:10c50f9693feddb0b63486873d99544a7746fa15beafc4277c1f9c3462f0be50 -size 890614 diff --git a/.yarn/cache/libsodium-wrappers-sumo-npm-0.7.11-08fe1b2cf4-81270738b3.zip b/.yarn/cache/libsodium-wrappers-sumo-npm-0.7.11-08fe1b2cf4-81270738b3.zip deleted file mode 100644 index 7126be82e3..0000000000 --- a/.yarn/cache/libsodium-wrappers-sumo-npm-0.7.11-08fe1b2cf4-81270738b3.zip +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3bd785a7ff63201875fea98602b5c994dee8e79c6e09fbb773111b1f1dc140e3 -size 95203 diff --git a/packages/crypto/package.json b/packages/crypto/package.json index 83010892c1..a96290b6e1 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -42,8 +42,7 @@ "@cosmjs/utils": "workspace:^", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", - "@noble/hashes": "^1", - "libsodium-wrappers-sumo": "^0.7.11" + "@noble/hashes": "^1" }, "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", diff --git a/packages/crypto/src/libsodium.ts b/packages/crypto/src/libsodium.ts index a4a162b17f..f0c62dd0f9 100644 --- a/packages/crypto/src/libsodium.ts +++ b/packages/crypto/src/libsodium.ts @@ -1,15 +1,7 @@ -// Keep all classes requiring libsodium-js in one file as having multiple -// requiring of the libsodium-wrappers module currently crashes browsers -// -// libsodium.js API: https://gist.github.com/webmaster128/b2dbe6d54d36dd168c9fabf441b9b09c - import { isNonNullObject } from "@cosmjs/utils"; import { xchacha20poly1305 } from "@noble/ciphers/chacha.js"; import { ed25519 } from "@noble/curves/ed25519.js"; -// Using crypto_pwhash requires sumo. Once we migrate to a standalone -// Argon2 implementation, we can use the normal libsodium-wrappers -// again: https://github.com/cosmos/cosmjs/issues/1031 -import sodium from "libsodium-wrappers-sumo"; +import { type ArgonOpts, argon2id } from "@noble/hashes/argon2.js"; export interface Argon2idOptions { /** Output length in bytes */ @@ -44,15 +36,18 @@ export class Argon2id { salt: Uint8Array, options: Argon2idOptions, ): Promise { - await sodium.ready; - return sodium.crypto_pwhash( - options.outputLength, - password, - salt, // libsodium only supports 16 byte salts and will throw when you don't respect that - options.opsLimit, - options.memLimitKib * 1024, - sodium.crypto_pwhash_ALG_ARGON2ID13, - ); + const opts: ArgonOpts = { + t: options.opsLimit, + m: options.memLimitKib, + p: 1, // no parallelism allowed, just like libsodium + dkLen: options.outputLength, + }; + + if (salt.length !== 16) { + throw new Error(`Got invalid salt length ${salt.length}. Must be 16.`); + } + + return argon2id(password, salt, opts); } } diff --git a/yarn.lock b/yarn.lock index 4b90ce29b4..8c3eb7610f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -340,7 +340,6 @@ __metadata: karma-firefox-launcher: "npm:^2.1.0" karma-jasmine: "npm:^5" karma-jasmine-html-reporter: "npm:^1.5.4" - libsodium-wrappers-sumo: "npm:^0.7.11" nyc: "npm:^15.1.0" prettier: "npm:^3.5.3" ses: "npm:^1.13.0" @@ -5616,22 +5615,6 @@ __metadata: languageName: node linkType: hard -"libsodium-sumo@npm:^0.7.11": - version: 0.7.11 - resolution: "libsodium-sumo@npm:0.7.11" - checksum: 10c0/f7518d178148d17c04d716898ea8aa5c5ebc302920ff67258a1fbe52e9d4605bb4a9912541db06bce7c16bde9a3af86110b749c869846d087a1b64a921007db8 - languageName: node - linkType: hard - -"libsodium-wrappers-sumo@npm:^0.7.11": - version: 0.7.11 - resolution: "libsodium-wrappers-sumo@npm:0.7.11" - dependencies: - libsodium-sumo: "npm:^0.7.11" - checksum: 10c0/81270738b3e7c50910c34e161aa34d84ab6fbfe9e5256561fc279498b594cb3b090c58ec19d40ada67dc24e7f1f7e018d9fd68d2ae367196116164795b6d2896 - languageName: node - linkType: hard - "linkify-it@npm:^5.0.0": version: 5.0.0 resolution: "linkify-it@npm:5.0.0" From 072243dccb7d9f4fa7fae354377d6790bb807e33 Mon Sep 17 00:00:00 2001 From: dynst <148708712+dynst@users.noreply.github.com> Date: Wed, 13 Aug 2025 00:00:00 +0000 Subject: [PATCH 7/9] increase timeout in jasmine unit test for wallet deserialize/decryption --- packages/amino/src/secp256k1hdwallet.spec.ts | 4 ++-- packages/proto-signing/src/directsecp256k1hdwallet.spec.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/amino/src/secp256k1hdwallet.spec.ts b/packages/amino/src/secp256k1hdwallet.spec.ts index c0b54fb881..9440a7ed4f 100644 --- a/packages/amino/src/secp256k1hdwallet.spec.ts +++ b/packages/amino/src/secp256k1hdwallet.spec.ts @@ -77,7 +77,7 @@ describe("Secp256k1HdWallet", () => { pubkey: defaultPubkey, }, ]); - }); + }, 90000); it("can restore multiple accounts", async () => { const mnemonic = @@ -123,7 +123,7 @@ describe("Secp256k1HdWallet", () => { address: "wasm1hsm76p4ahyhl5yh3ve9ur49r5kemhp2r93f89d", }, ]); - }); + }, 90000); }); describe("deserializeWithEncryptionKey", () => { diff --git a/packages/proto-signing/src/directsecp256k1hdwallet.spec.ts b/packages/proto-signing/src/directsecp256k1hdwallet.spec.ts index 24757783c2..ca9b2b0d2d 100644 --- a/packages/proto-signing/src/directsecp256k1hdwallet.spec.ts +++ b/packages/proto-signing/src/directsecp256k1hdwallet.spec.ts @@ -77,7 +77,7 @@ describe("DirectSecp256k1HdWallet", () => { pubkey: defaultPubkey, }, ]); - }); + }, 90000); it("can restore multiple accounts", async () => { const mnemonic = @@ -123,7 +123,7 @@ describe("DirectSecp256k1HdWallet", () => { address: "wasm1hsm76p4ahyhl5yh3ve9ur49r5kemhp2r93f89d", }, ]); - }); + }, 90000); }); describe("deserializeWithEncryptionKey", () => { From 7b65103a2daea840e0173086a054cd545a3fdd5d Mon Sep 17 00:00:00 2001 From: dynst <148708712+dynst@users.noreply.github.com> Date: Wed, 13 Aug 2025 00:00:00 +0000 Subject: [PATCH 8/9] migrate to argon2id from hash-wasm --- .pnp.cjs | 14 ++++++++++++ ...-wasm-npm-4.12.0-d6bb202626-6cb9505531.zip | 3 +++ packages/crypto/package.json | 3 ++- packages/crypto/src/libsodium.ts | 22 ++++++++++++------- yarn.lock | 8 +++++++ 5 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 .yarn/cache/hash-wasm-npm-4.12.0-d6bb202626-6cb9505531.zip diff --git a/.pnp.cjs b/.pnp.cjs index 8226d7d04f..57288f5008 100644 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -1713,6 +1713,10 @@ const RAW_RUNTIME_STATE = "hash-base",\ "npm:3.1.0"\ ],\ + [\ + "hash-wasm",\ + "npm:4.12.0"\ + ],\ [\ "hasha",\ "npm:5.2.2"\ @@ -3511,6 +3515,7 @@ const RAW_RUNTIME_STATE = ["@types/node", "npm:22.10.6"],\ ["buffer", "npm:6.0.3"],\ ["glob", "npm:11.0.3"],\ + ["hash-wasm", "npm:4.12.0"],\ ["jasmine", "npm:4.6.0"],\ ["jasmine-spec-reporter", "npm:6.0.0"],\ ["karma", "npm:6.3.16"],\ @@ -9353,6 +9358,15 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ + ["hash-wasm", [\ + ["npm:4.12.0", {\ + "packageLocation": "./.yarn/unplugged/hash-wasm-npm-4.12.0-d6bb202626/node_modules/hash-wasm/",\ + "packageDependencies": [\ + ["hash-wasm", "npm:4.12.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["hasha", [\ ["npm:5.2.2", {\ "packageLocation": "./.yarn/cache/hasha-npm-5.2.2-d171116d12-9d10d4e665.zip/node_modules/hasha/",\ diff --git a/.yarn/cache/hash-wasm-npm-4.12.0-d6bb202626-6cb9505531.zip b/.yarn/cache/hash-wasm-npm-4.12.0-d6bb202626-6cb9505531.zip new file mode 100644 index 0000000000..77c02b309f --- /dev/null +++ b/.yarn/cache/hash-wasm-npm-4.12.0-d6bb202626-6cb9505531.zip @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:505d7271f3fa67b1baedc9c0259b5c37dcfdbd8a3334f962266468c4945b9de0 +size 1820660 diff --git a/packages/crypto/package.json b/packages/crypto/package.json index a96290b6e1..bdce04c10e 100644 --- a/packages/crypto/package.json +++ b/packages/crypto/package.json @@ -42,7 +42,8 @@ "@cosmjs/utils": "workspace:^", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.2", - "@noble/hashes": "^1" + "@noble/hashes": "^1", + "hash-wasm": "^4.12.0" }, "devDependencies": { "@istanbuljs/nyc-config-typescript": "^1.0.1", diff --git a/packages/crypto/src/libsodium.ts b/packages/crypto/src/libsodium.ts index f0c62dd0f9..9b8fd70348 100644 --- a/packages/crypto/src/libsodium.ts +++ b/packages/crypto/src/libsodium.ts @@ -1,7 +1,7 @@ -import { isNonNullObject } from "@cosmjs/utils"; +import { assert, isNonNullObject } from "@cosmjs/utils"; import { xchacha20poly1305 } from "@noble/ciphers/chacha.js"; import { ed25519 } from "@noble/curves/ed25519.js"; -import { type ArgonOpts, argon2id } from "@noble/hashes/argon2.js"; +import { type IArgon2Options, argon2id } from "hash-wasm"; export interface Argon2idOptions { /** Output length in bytes */ @@ -36,18 +36,24 @@ export class Argon2id { salt: Uint8Array, options: Argon2idOptions, ): Promise { - const opts: ArgonOpts = { - t: options.opsLimit, - m: options.memLimitKib, - p: 1, // no parallelism allowed, just like libsodium - dkLen: options.outputLength, + const opts: IArgon2Options = { + password, + salt, + outputType: "binary", + iterations: options.opsLimit, + memorySize: options.memLimitKib, + parallelism: 1, // no parallelism allowed, just like libsodium + hashLength: options.outputLength, }; if (salt.length !== 16) { throw new Error(`Got invalid salt length ${salt.length}. Must be 16.`); } - return argon2id(password, salt, opts); + const hash = await argon2id(opts); + // guaranteed by outputType: 'binary' + assert(typeof hash !== "string"); + return hash; } } diff --git a/yarn.lock b/yarn.lock index 8c3eb7610f..98d6935cd1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -333,6 +333,7 @@ __metadata: "@types/node": "npm:*" buffer: "npm:^6.0.3" glob: "npm:^11" + hash-wasm: "npm:^4.12.0" jasmine: "npm:^4" jasmine-spec-reporter: "npm:^6" karma: "npm:^6.3.14" @@ -4601,6 +4602,13 @@ __metadata: languageName: node linkType: hard +"hash-wasm@npm:^4.12.0": + version: 4.12.0 + resolution: "hash-wasm@npm:4.12.0" + checksum: 10c0/6cb95055319810b6f673de755289960683a9831807690795f0e8918b2fd7e6ae5b82a9dc47cbace171cf2814b412ef68c315a0ead0b4d96bd3e56a05e4bde136 + languageName: node + linkType: hard + "hasha@npm:^5.0.0": version: 5.2.2 resolution: "hasha@npm:5.2.2" From a0e779dffaa787fdbb4d3b50137ddb4760d7cac2 Mon Sep 17 00:00:00 2001 From: dynst <148708712+dynst@users.noreply.github.com> Date: Wed, 13 Aug 2025 00:00:00 +0000 Subject: [PATCH 9/9] amino, proto-signing: add explicit scream test to KDF code This should make the deserialize 'can restore multiple accounts' unit test take about 12s, approximating pure JS performance on node 22. --- packages/amino/src/wallet.ts | 8 +++++++- packages/proto-signing/src/wallet.ts | 8 +++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/amino/src/wallet.ts b/packages/amino/src/wallet.ts index dc85068a1d..ece40bc67d 100644 --- a/packages/amino/src/wallet.ts +++ b/packages/amino/src/wallet.ts @@ -28,7 +28,13 @@ export async function executeKdf(password: string, configuration: KdfConfigurati case "argon2id": { const options = configuration.params; if (!isArgon2idOptions(options)) throw new Error("Invalid format of argon2id params"); - return Argon2id.execute(password, cosmjsSalt, options); + + // Emulate a slower implementation. The fast WASM code may get removed. + // This approximates the speed of using a pure JS implementation (@noble/hashes) in Node 22. + const screamTest = new Promise((resolve) => setTimeout(resolve, options.opsLimit * 250)); + const result = await Argon2id.execute(password, cosmjsSalt, options); + await screamTest; + return result; } default: throw new Error("Unsupported KDF algorithm"); diff --git a/packages/proto-signing/src/wallet.ts b/packages/proto-signing/src/wallet.ts index dc85068a1d..ece40bc67d 100644 --- a/packages/proto-signing/src/wallet.ts +++ b/packages/proto-signing/src/wallet.ts @@ -28,7 +28,13 @@ export async function executeKdf(password: string, configuration: KdfConfigurati case "argon2id": { const options = configuration.params; if (!isArgon2idOptions(options)) throw new Error("Invalid format of argon2id params"); - return Argon2id.execute(password, cosmjsSalt, options); + + // Emulate a slower implementation. The fast WASM code may get removed. + // This approximates the speed of using a pure JS implementation (@noble/hashes) in Node 22. + const screamTest = new Promise((resolve) => setTimeout(resolve, options.opsLimit * 250)); + const result = await Argon2id.execute(password, cosmjsSalt, options); + await screamTest; + return result; } default: throw new Error("Unsupported KDF algorithm");