gchq/CyberChef · error · OperationError

The value of `a` must be coprime to 26.

Error message

The value of `a` must be coprime to 26.

What it means

Thrown by AffineCipherDecode.run when Utils.gcd(a, 26) !== 1, i.e. the slope value a does not share coprimality with the alphabet length 26. Decoding the affine cipher requires multiplying by the modular inverse of a modulo 26, which exists only when a and 26 are coprime. Without coprimality the mapping is not bijective and decryption is impossible, so the operation aborts before running the decode loop.

Source

Thrown at src/core/operations/AffineCipherDecode.mjs:60

    /**
     * @param {string} input
     * @param {Object[]} args
     * @returns {string}
     *
     * @throws {OperationError} if a or b values are invalid
     */
    run(input, args) {
        const alphabet = "abcdefghijklmnopqrstuvwxyz",
            [a, b] = args,
            aModInv = Utils.modInv(a, 26); // Calculates modular inverse of a
        let output = "";

        if (!/^\+?(0|[1-9]\d*)$/.test(a) || !/^\+?(0|[1-9]\d*)$/.test(b)) {
            throw new OperationError("The values of a and b can only be integers.");
        }

        if (Utils.gcd(a, 26) !== 1) {
            throw new OperationError("The value of `a` must be coprime to 26.");
        }

        for (let i = 0; i < input.length; i++) {
            if (alphabet.indexOf(input[i]) >= 0) {
                // Uses the affine decode function (y-b * A') % m = x (where m is length of the alphabet and A' is modular inverse)
                output += alphabet[Utils.mod((alphabet.indexOf(input[i]) - b) * aModInv, 26)];
            } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
                // Same as above, accounting for uppercase
                output += alphabet[Utils.mod((alphabet.indexOf(input[i].toLowerCase()) - b) * aModInv, 26)].toUpperCase();
            } else {
                // Non-alphabetic characters
                output += input[i];
            }
        }
        return output;
    }

    /**

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Choose a from the valid set coprime to 26: 1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25.
  2. Cross-check the value against the key used to encode the text (Affine Cipher Encode).
  3. Pre-validate: Utils.gcd(a, 26) === 1 must hold before decoding.

Example fix

// before - a=2 shares factor 2 with 26
chef.affineCipherDecode(input, [2, 8]);

// after - a=5 is coprime to 26
chef.affineCipherDecode(input, [5, 8]);
Defensive patterns

Strategy: validation

Validate before calling

import Utils from "src/core/Utils.mjs";
const VALID_A = [1,3,5,7,9,11,15,17,19,21,23,25];
function assertAffineCoprime(a) {
  if (!VALID_A.includes(((a % 26) + 26) % 26)) {
    throw new Error(`a must be coprime to 26; valid: ${VALID_A.join(", ")}`);
  }
}
assertAffineCoprime(a);

Type guard

function isAffineCoprime(a) {
  function gcd(x, y) { while (y) { [x, y] = [y, x % y]; } return x; }
  return Number.isInteger(a) && gcd(((a % 26) + 26) % 26, 26) === 1;
}

Prevention

When it happens

Trigger: Passing any even value for a (2, 4, 6, ...), a multiple of 13 (13, 39, ...), 0, or any value sharing a factor with 26. Valid a values modulo 26 are exactly {1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25}.

Common situations: User guesses an arbitrary a like 2 or 10; a was encoded with a valid a but the decoder typed the wrong key; values imported from a tool that allowed non-coprime slopes; a=0 passed because the field defaulted incorrectly.

Related errors


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