gchq/CyberChef · error · OperationError
Invalid nonce length: ${nonce.length} bytes. Salsa20 uses a
Error message
Invalid nonce length: ${nonce.length} bytes.
Salsa20 uses a nonce of 8 bytes (64 bits). What it means
Thrown by Salsa20 when the nonce (decoded from its toggle) is not exactly 8 bytes, but only when the nonce type is not 'Integer' (the Integer branch builds an 8-byte little-endian nonce from the parsed number). Salsa20 uses a 64-bit nonce.
Source
Thrown at src/core/operations/Salsa20.mjs:91
const key = Utils.convertToByteArray(args[0].string, args[0].option),
nonceType = args[1].option,
rounds = parseInt(args[3], 10),
inputType = args[4],
outputType = args[5];
if (key.length !== 16 && key.length !== 32) {
throw new OperationError(`Invalid key length: ${key.length} bytes.
Salsa20 uses a key of 16 or 32 bytes (128 or 256 bits).`);
}
let counter, nonce;
if (nonceType === "Integer") {
nonce = Utils.intToByteArray(parseInt(args[1].string, 10), 8, "little");
} else {
nonce = Utils.convertToByteArray(args[1].string, args[1].option);
if (!(nonce.length === 8)) {
throw new OperationError(`Invalid nonce length: ${nonce.length} bytes.
Salsa20 uses a nonce of 8 bytes (64 bits).`);
}
}
counter = Utils.intToByteArray(args[2], 8, "little");
const output = [];
input = Utils.convertToByteArray(input, inputType);
let counterAsInt = Utils.byteArrayToInt(counter, "little");
for (let i = 0; i < input.length; i += 64) {
counter = Utils.intToByteArray(counterAsInt, 8, "little");
const stream = salsa20Block(key, nonce, counter, rounds);
for (let j = 0; j < 64 && i + j < input.length; j++) {
output.push(input[i + j] ^ stream[j]);
}
counterAsInt++;
}View on GitHub (pinned to 4290ea7539)
Solutions
- Provide an 8-byte nonce, or switch the nonce toggle to 'Integer' and supply a numeric value (auto-converted to 8 bytes little-endian).
- For hex nonces use the 'Hex' toggle so 16 chars decode to 8 bytes.
- Do not reuse ChaCha20 nonces; Salsa20 requires exactly 64 bits.
Example fix
// before: 16 hex chars as UTF8 -> 16 bytes
salsa20.run(pt, [keyArg, {string:"0011223344556677", option:"UTF8"}, ...])
// after
salsa20.run(pt, [keyArg, {string:"0011223344556677", option:"Hex"}, ...]) Defensive patterns
Strategy: validation
Validate before calling
let nonce;
if (nonceType === "Integer") {
nonce = Utils.intToByteArray(parseInt(nonceArg.string, 10), 8, "little");
} else {
nonce = Utils.convertToByteArray(nonceArg.string, nonceArg.option);
if (nonce.length !== 8) {
throw new Error(`Salsa20 nonce must be 8 bytes, got ${nonce.length}`);
}
} Type guard
function isSalsa20NonceValid(nonceArg) {
if (nonceArg.option === "Integer") return true;
return Utils.convertToByteArray(nonceArg.string, nonceArg.option).length === 8;
} Prevention
- Use the 'Integer' nonce type for numeric nonces (auto-sized to 8 bytes).
- For byte nonces, decode to exactly 8 bytes; do not reuse ChaCha20's 12-byte nonce.
When it happens
Trigger: Nonce toggle set to Hex/UTF8/Latin1/Base64 with a decoded length other than 8 bytes. E.g. a 16-char hex nonce with 'Hex' toggle = 8 bytes (valid), but the same with UTF8 = 16 bytes (fails); a 12-byte nonce (ChaCha-style) always fails.
Common situations: Using a ChaCha20 12-byte/24-byte nonce by mistake; toggle mismatch; blank nonce (0 bytes) with a non-Integer toggle; hex nonce with UTF8 toggle.
Related errors
- Invalid key length: ${key.length} bytes. Salsa20 uses a key
- Invalid key length: ${key.length} bytes SM4 uses a key leng
- Invalid IV length: ${iv.length} bytes SM4 uses an IV length
- Invalid key length: ${key.length} bytes SM4 uses a key leng
- Invalid IV length: ${iv.length} bytes SM4 uses an IV length
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/c218d2e1fe5d5e9e.
Report an issue: GitHub.