Fix: Ensure unsigned 32-bit XOR in CTR mode

This commit is contained in:
2026-03-10 20:38:27 -07:00
parent f9b8e2a63c
commit 849a20f3a5

19
dash.js
View File

@@ -23,21 +23,24 @@ function deriveNonce(key64arr) {
return speck32_64.encrypt(0, key64arr) & 0xFFFF; return speck32_64.encrypt(0, key64arr) & 0xFFFF;
} }
function ctrEncrypt(ptStr, key64arr) { function ctrKeystream(key64arr, index) {
const nonce = deriveNonce(key64arr); const nonce = deriveNonce(key64arr);
const ctrBlock = ((nonce << 16) | (index & 0xFFFF)) >>> 0;
return speck32_64.encrypt(ctrBlock, key64arr) >>> 0;
}
function ctrEncrypt(ptStr, key64arr) {
return Array.from(ptStr, (c, i) => { return Array.from(ptStr, (c, i) => {
const ctrBlock = (nonce << 16) | (i & 0xFFFF); const ks = ctrKeystream(key64arr, i);
const keystream = speck32_64.encrypt(ctrBlock, key64arr); return (c.codePointAt(0) ^ ks) >>> 0;
return c.codePointAt(0) ^ keystream;
}); });
} }
function ctrDecrypt(numArr, key64arr) { function ctrDecrypt(numArr, key64arr) {
const nonce = deriveNonce(key64arr);
return numArr.map((ct, i) => { return numArr.map((ct, i) => {
const ctrBlock = (nonce << 16) | (i & 0xFFFF); const ks = ctrKeystream(key64arr, i);
const keystream = speck32_64.encrypt(ctrBlock, key64arr); const cp = (ct ^ ks) >>> 0;
try { return String.fromCodePoint(ct ^ keystream); } try { return String.fromCodePoint(cp); }
catch { return ''; } catch { return ''; }
}).join(''); }).join('');
} }