From 12e718c1d1797029f6294b3fb72bf7a9674940db Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 4 Nov 2025 16:14:02 +0100 Subject: [PATCH] Bump @noble/hashes from 1.8.0 to 2.0.1 (#246) * Bump @noble/hashes from 1.8.0 to 2.0.1 Bumps [@noble/hashes](https://github.com/paulmillr/noble-hashes) from 1.8.0 to 2.0.1. - [Release notes](https://github.com/paulmillr/noble-hashes/releases) - [Commits](https://github.com/paulmillr/noble-hashes/compare/1.8.0...2.0.1) --- updated-dependencies: - dependency-name: "@noble/hashes" dependency-version: 2.0.1 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Update noble-hashes usages --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: larabr <7375870+larabr@users.noreply.github.com> --- lib/crypto/_md5.ts | 86 ---------------------------------------------- lib/crypto/hash.ts | 4 +-- package.json | 2 +- yarn.lock | 10 +++--- 4 files changed, 8 insertions(+), 94 deletions(-) delete mode 100644 lib/crypto/_md5.ts diff --git a/lib/crypto/_md5.ts b/lib/crypto/_md5.ts deleted file mode 100644 index a868cfd..0000000 --- a/lib/crypto/_md5.ts +++ /dev/null @@ -1,86 +0,0 @@ -// Copied from https://github.com/paulmillr/noble-hashes/blob/main/test/misc/md5.ts - -import { HashMD } from '@noble/hashes/_md'; -import { rotl, wrapConstructor } from '@noble/hashes/utils'; - -// Per-round constants -const K = Array.from({ length: 64 }, (_, i) => Math.floor(2 ** 32 * Math.abs(Math.sin(i + 1)))); -// Choice: a ? b : c -const Chi = (a: number, b: number, c: number) => (a & b) ^ (~a & c); -// Initial state (same as sha1, but 4 u32 instead of 5) -const IV = /* @__PURE__ */ new Uint32Array([0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476]); -// Temporary buffer, not used to store anything between runs -// Named this way for SHA1 compat -const MD5_W = /* @__PURE__ */ new Uint32Array(16); -class MD5 extends HashMD { - private A = IV[0] | 0; - private B = IV[1] | 0; - private C = IV[2] | 0; - private D = IV[3] | 0; - - constructor() { - super(64, 16, 8, true); - } - - protected get(): [number, number, number, number] { - const { A, B, C, D } = this; - return [A, B, C, D]; - } - - protected set(A: number, B: number, C: number, D: number) { - this.A = A | 0; - this.B = B | 0; - this.C = C | 0; - this.D = D | 0; - } - - protected process(view: DataView, offset: number): void { - // eslint-disable-next-line no-param-reassign - for (let i = 0; i < 16; i++, offset += 4) MD5_W[i] = view.getUint32(offset, true); - // Compression function main loop, 64 rounds - let { A, B, C, D } = this; - for (let i = 0; i < 64; i++) { - let F, g, s; - if (i < 16) { - F = Chi(B, C, D); - g = i; - s = [7, 12, 17, 22]; - } else if (i < 32) { - F = Chi(D, B, C); - g = (5 * i + 1) % 16; - s = [5, 9, 14, 20]; - } else if (i < 48) { - F = B ^ C ^ D; - g = (3 * i + 5) % 16; - s = [4, 11, 16, 23]; - } else { - F = C ^ (B | ~D); - g = (7 * i) % 16; - s = [6, 10, 15, 21]; - } - F = F + A + K[i] + MD5_W[g]; - A = D; - D = C; - C = B; - B += rotl(F, s[i % 4]); - } - - // Add the compressed chunk to the current hash value - A = (A + this.A) | 0; - B = (B + this.B) | 0; - C = (C + this.C) | 0; - D = (D + this.D) | 0; - this.set(A, B, C, D); - } - - // eslint-disable-next-line class-methods-use-this - protected roundClean() { - MD5_W.fill(0); - } - - destroy() { - this.set(0, 0, 0, 0); - this.buffer.fill(0); - } -} -export const md5 = /* @__PURE__ */ wrapConstructor(() => new MD5()); diff --git a/lib/crypto/hash.ts b/lib/crypto/hash.ts index f4a7c69..5caddb6 100644 --- a/lib/crypto/hash.ts +++ b/lib/crypto/hash.ts @@ -14,7 +14,7 @@ export const SHA512 = async (data: Uint8Array) => { * MD5 is an unsafe hash function. It should normally not be used. * It's exposed because it's required for old auth versions. */ -export const unsafeMD5 = async (data: Uint8Array) => import('./_md5').then(({ md5 }) => md5(data) as Uint8Array); +export const unsafeMD5 = async (data: Uint8Array) => import('@noble/hashes/legacy.js').then(({ md5 }) => md5(data) as Uint8Array); /** * SHA1 is an unsafe hash function. It should not be used for cryptographic purposes. @@ -27,7 +27,7 @@ export async function unsafeSHA1(data: MaybeWebStream>) return new Uint8Array(digest); } - const { sha1 } = await import('@noble/hashes/legacy'); + const { sha1 } = await import('@noble/hashes/legacy.js'); const hashInstance = sha1.create(); const inputReader = data.getReader(); // AsyncInterator is still not widely supported while (true) { diff --git a/package.json b/package.json index cb18cc9..f488ad0 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ }, "homepage": "https://github.com/ProtonMail/pmcrypto#readme", "dependencies": { - "@noble/hashes": "^1.8.0", + "@noble/hashes": "^2.0.1", "@openpgp/web-stream-tools": "~0.1.3", "jsmimeparser": "npm:@protontech/jsmimeparser@^3.0.2", "openpgp": "npm:@protontech/openpgp@~6.2.2" diff --git a/yarn.lock b/yarn.lock index dfb4b25..ef27be2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -242,10 +242,10 @@ __metadata: languageName: node linkType: hard -"@noble/hashes@npm:^1.8.0": - version: 1.8.0 - resolution: "@noble/hashes@npm:1.8.0" - checksum: 10c0/06a0b52c81a6fa7f04d67762e08b2c476a00285858150caeaaff4037356dd5e119f45b2a530f638b77a5eeca013168ec1b655db41bae3236cb2e9d511484fc77 +"@noble/hashes@npm:^2.0.1": + version: 2.0.1 + resolution: "@noble/hashes@npm:2.0.1" + checksum: 10c0/e81769ce21c3b1c80141a3b99bd001f17edea09879aa936692ae39525477386d696101cd573928a304806efb2b9fa751e1dd83241c67d0c84d30091e85c79bdb languageName: node linkType: hard @@ -334,7 +334,7 @@ __metadata: resolution: "@protontech/pmcrypto@workspace:." dependencies: "@eslint/js": "npm:^9.35.0" - "@noble/hashes": "npm:^1.8.0" + "@noble/hashes": "npm:^2.0.1" "@openpgp/web-stream-tools": "npm:~0.1.3" "@protontech/eslint-plugin-enforce-uint8array-arraybuffer": "npm:^2.0.0" "@stylistic/eslint-plugin": "npm:^5.3.1"