{"record":{"id":"38ccb6dc190a26e6","repo":"gchq/CyberChef","slug":"invalid-nonce-length-nonce-length-bytes-xsal","errorCode":null,"errorMessage":"Invalid nonce length: ${nonce.length} bytes.\n\nXSalsa20 uses a nonce of 24 bytes (192 bits).","messagePattern":"Invalid nonce length: (.+?) bytes\\.\n\nXSalsa20 uses a nonce of 24 bytes \\(192 bits\\)\\.","errorType":"validation","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/XSalsa20.mjs","lineNumber":91,"sourceCode":"        const key = Utils.convertToByteArray(args[0].string, args[0].option),\n            nonceType = args[1].option,\n            rounds = parseInt(args[3], 10),\n            inputType = args[4],\n            outputType = args[5];\n\n        if (key.length !== 16 && key.length !== 32) {\n            throw new OperationError(`Invalid key length: ${key.length} bytes.\n\nXSalsa20 uses a key of 16 or 32 bytes (128 or 256 bits).`);\n        }\n\n        let counter, nonce;\n        if (nonceType === \"Integer\") {\n            nonce = Utils.intToByteArray(parseInt(args[1].string, 10), 8, \"little\");\n        } else {\n            nonce = Utils.convertToByteArray(args[1].string, args[1].option);\n            if (!(nonce.length === 24)) {\n                throw new OperationError(`Invalid nonce length: ${nonce.length} bytes.\n\nXSalsa20 uses a nonce of 24 bytes (192 bits).`);\n            }\n        }\n        counter = Utils.intToByteArray(args[2], 8, \"little\");\n\n        const xsalsaKey = hsalsa20(key, nonce.slice(0, 16), rounds);\n\n        const output = [];\n        input = Utils.convertToByteArray(input, inputType);\n\n        let counterAsInt = Utils.byteArrayToInt(counter, \"little\");\n        for (let i = 0; i < input.length; i += 64) {\n            counter = Utils.intToByteArray(counterAsInt, 8, \"little\");\n            const stream = salsa20Block(xsalsaKey, nonce.slice(16, 24), counter, rounds);\n            for (let j = 0; j < 64 && i + j < input.length; j++) {\n                output.push(input[i + j] ^ stream[j]);\n            }","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/XSalsa20.mjs#L73-L109","documentation":"Thrown by XSalsa20.run in the non-Integer nonce branch when the decoded nonce byte array is not exactly 24 bytes. XSalsa20 requires a 192-bit (24-byte) nonce; the 'Integer' option derives an 8-byte nonce from args[1].string and is handled separately, so this check only applies to user-supplied nonce formats (Hex/UTF8/Base64...).","triggerScenarios":"nonceType (args[1].option) is not 'Integer', so Utils.convertToByteArray is used; the resulting nonce is not 24 bytes. Example: a 24-character hex nonce is only 12 bytes (invalid); 48 hex chars = 24 bytes (valid).","commonSituations":"Selecting Hex for the nonce but supplying a UTF8-length nonce (or vice versa); reusing a 12-byte Salsa20 nonce with XSalsa20; truncating the nonce during copy-paste.","solutions":["Provide exactly 24 bytes of nonce (48 hex characters, 24 UTF8 bytes, or 32 Base64 chars).","Confirm args[1].option matches the nonce encoding.","Use the 'Integer' nonce option if you want to specify a small counter as a number instead of raw bytes."],"exampleFix":"// before: 24 hex chars -> 12-byte nonce\nargs:[{string:\"<key>\",option:\"Hex\"},{string:\"aabb...24hex\",option:\"Hex\"}, ...]\n// after: 48 hex chars -> 24-byte nonce\nargs:[{string:\"<key>\",option:\"Hex\"},{string:\"<48 hex chars>\",option:\"Hex\"}, ...]","handlingStrategy":"validation","validationCode":"function xsalsa20NonceRecipe(nonceStr, nonceOption) {\n  if (nonceOption === \"Integer\") return {string:nonceStr, option:nonceOption};\n  const n = Utils.convertToByteArray(nonceStr, nonceOption);\n  if (n.length !== 24) throw new Error(`XSalsa20 nonce must be 24 bytes, got ${n.length}`);\n  return {string:nonceStr, option:nonceOption};\n}","typeGuard":"const isXsalsa20NonceLen = (bytes) => bytes.length === 24;","tryCatchPattern":"try { chef.bake(data, recipe); } catch (e) { if (/Invalid nonce length/.test(e.message) && /XSalsa20/.test(e.message)) { /* fix nonce */ } else throw e; }","preventionTips":["Use 24-byte (192-bit) nonces; do not reuse Salsa20's 12-byte nonce.","Match the nonce format option to the encoding.","Prefer the Integer nonce option only for counter-style nonces."],"tags":["xsalsa20","crypto","nonce-length","operation-args"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}