gchq/CyberChef · error · OperationError

Invalid nonce length: ${nonce.length} bytes. Ascon-AEAD128

Error message

Invalid nonce length: ${nonce.length} bytes.

Ascon-AEAD128 requires a nonce of exactly 16 bytes (128 bits).

What it means

Thrown by AsconDecrypt.run when the supplied nonce is not exactly 16 bytes (128 bits). Ascon-AEAD128 uses a 128-bit nonce, so the operation hard-validates nonce.length === 16 before decryption. The nonce is converted via Utils.convertToByteArray honoring the input option, so the measured length is decoded bytes; a hex string must be 32 characters and a base64 value must decode to exactly 16 bytes.

Source

Thrown at src/core/operations/AsconDecrypt.mjs:82

     * @param {Object[]} args
     * @returns {string}
     * @throws {OperationError} if invalid key or nonce length, or authentication fails
     */
    run(input, args) {
        const key = Utils.convertToByteArray(args[0].string, args[0].option),
            nonce = Utils.convertToByteArray(args[1].string, args[1].option),
            ad = Utils.convertToByteArray(args[2].string, args[2].option),
            inputType = args[3],
            outputType = args[4];

        if (key.length !== 16) {
            throw new OperationError(`Invalid key length: ${key.length} bytes.

Ascon-AEAD128 requires a key of exactly 16 bytes (128 bits).`);
        }

        if (nonce.length !== 16) {
            throw new OperationError(`Invalid nonce length: ${nonce.length} bytes.

Ascon-AEAD128 requires a nonce of exactly 16 bytes (128 bits).`);
        }

        // Convert input to byte array
        const inputData = Utils.convertToByteArray(input, inputType);

        const keyUint8 = new Uint8Array(key);
        const nonceUint8 = new Uint8Array(nonce);
        const adUint8 = new Uint8Array(ad);
        const ciphertextUint8 = new Uint8Array(inputData);

        try {
            // Decrypt (returns Uint8Array containing plaintext)
            const plaintext = JsAscon.decrypt(keyUint8, nonceUint8, adUint8, ciphertextUint8);

            // Return in requested format
            if (outputType === "Hex") {

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Provide exactly 16 bytes of nonce (32 hex chars).
  2. Generate a fresh random 16-byte nonce per encryption; never reuse a nonce with the same key.
  3. Double-check the argument order: key is arg[0], nonce is arg[1] in AsconDecrypt.

Example fix

// before - 12-byte AES-GCM style nonce
chef.asconDecrypt(ct, { nonce: "00112233445566778899aabb", nonceOption: "Hex" });

// after - 16-byte (32 hex char) nonce
chef.asconDecrypt(ct, { nonce: "00112233445566778899aabbccddeeff", nonceOption: "Hex" });
Defensive patterns

Strategy: validation

Validate before calling

import Utils from "src/core/Utils.mjs";
function assertAsconNonce(nonceStr, nonceOption) {
  const bytes = Utils.convertToByteArray(nonceStr, nonceOption);
  if (bytes.length !== 16) {
    throw new Error(`Ascon nonce must be 16 bytes, got ${bytes.length}`);
  }
  return bytes;
}
assertAsconNonce(nonce, nonceOption);

Type guard

function is16ByteHex(s) { return /^[0-9a-f]{32}$/i.test(s); }

Prevention

When it happens

Trigger: Supplying a 12-byte nonce (the more common AES-GCM nonce size), a reused/empty nonce, a hex string of odd or wrong length, or a base64 value decoding to != 16 bytes.

Common situations: Copying an AES-GCM 96-bit nonce by habit; using a counter nonce shorter than 16 bytes; nonce and key arguments swapped in the recipe.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/ad68382de0c870c9. Report an issue: GitHub.