2343fcaa7564

fix: noiseKKResponder rejects small-order X25519 initiator keys before the WASM core (audit PB-26-601, v5.1.10)

time
2026-09-06 14:44 UTC · 1 month ago
machine
koh2
agent
openrouter/tencent/hy4-preview
session
PB-26-601..611 audit closeout
parent
21d00cee79fd
5 files manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/shared/noise-js.ts+3 −0src/shared/noise-small-order-dh.test.ts+25 −0
manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach Password Manager",4-  "version": "5.1.9",4+  "version": "5.1.10",55   "description": "Zero-knowledge password manager",66   "browser_specific_settings": {77     "gecko": {

view file

manifest.json+1 −1
@@ -2,7 +2,7 @@22   "manifest_version": 3,33   "minimum_chrome_version": "116",44   "name": "Peach Password Manager",5-  "version": "5.1.9",5+  "version": "5.1.10",66   "description": "Zero-knowledge password manager",77   "action": {88     "default_popup": "src/popup/index.html",

view file

package.json+1 −1
@@ -1,6 +1,6 @@11 {22   "name": "peach",3-  "version": "5.1.9",3+  "version": "5.1.10",44   "description": "Zero-knowledge password manager",55   "license": "GPL-3.0-only",66   "type": "module",

view file

src/shared/noise-js.ts+3 −0
@@ -118,6 +118,9 @@118118   send: (msg: Uint8Array) => Promise<void>,119119   receive: () => Promise<Uint8Array>,120120 ): Promise<NoiseNKSession> {121+  if (isSmallOrderPubkey(expectedInitiatorStaticPublicKey)) {122+    throw new Error("noise: small-order X25519 initiator static key");123+  }121124   return rustNoiseKkResponder(122125     ourStaticPrivateKey,123126     ourStaticPublicKey,

view file

src/shared/noise-small-order-dh.test.ts+25 −0
@@ -10,6 +10,7 @@1010   hexToBytes,1111   isSmallOrderPubkey,1212   noiseKKInitiator,13+  noiseKKResponder,1314   performResponderAuth,1415 } from "./noise-js";1516 import type { NoiseNKSession } from "./noise-js";@@ -51,6 +52,30 @@5152           deadTransport.receive,5253         ),5354       ).rejects.toThrow(/small-order/i);55+    }56+  });57+58+  it("PB-26-601: KK responder aborts against a small-order initiator static", async () => {59+    const responder = generateKeyPair();60+    for (const hex of SMALL_ORDER_PUBKEY_HEX) {61+      // A transport that reports if the WASM core is reached: the guard must62+      // throw first, so neither callback may ever run.63+      const touched = { send: 0, receive: 0 };64+      await expect(65+        noiseKKResponder(66+          responder.secretKey,67+          responder.publicKey,68+          hexToBytes(hex),69+          async () => {70+            touched.send += 1;71+          },72+          () => {73+            touched.receive += 1;74+            return Promise.reject(new Error("reached the WASM core"));75+          },76+        ),77+      ).rejects.toThrow(/small-order/i);78+      expect(touched).toEqual({ send: 0, receive: 0 });5479     }5580   });5681 

view file