1fc1bb91666b

test: fix flaky tampered-ciphertext crypto test (v4.8.1)

Root cause: tamper appended fixed 'ff', a no-op when random ciphertext already ended in ff (~1/256 flake) so decrypt correctly succeeded. Fix: flip first nibble to a guaranteed-different value. 40/40 clean. AES-256-GCM impl verified sound; no shipped code changed.

time
2026-08-01 21:56 UTC · 2 months ago
machine
koh2
parent
351f84bfff6e
4 files manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/crypto/crypto.test.ts+4 −1
manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach Password Manager",4-  "version": "4.8.0",4+  "version": "4.8.1",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": "4.8.0",5+  "version": "4.8.1",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": "4.8.0",3+  "version": "4.8.1",44   "description": "Zero-knowledge password manager",55   "license": "GPL-3.0-only",66   "type": "module",

view file

src/crypto/crypto.test.ts+4 −1
@@ -15,7 +15,10 @@1515     const salt = generateSalt();1616     const key = await deriveKey("correct-horse", salt);1717     const { nonce, ciphertext, tag } = await encrypt(key, "secret data");18-    const tampered = ciphertext.slice(0, -2) + "ff";18+    // Flip the first nibble to a guaranteed-different value. Appending a19+    // fixed "ff" was a ~1/256 flake: when the random ciphertext already20+    // ended in ff the "tamper" was a no-op and decrypt rightly succeeded.21+    const tampered = (ciphertext[0] === "f" ? "0" : "f") + ciphertext.slice(1);1922     await expect(decrypt(key, nonce, tampered, tag)).rejects.toThrow();2023   });2124 

view file