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 affineEncode when the multiplier `a` is not coprime to 26 (the alphabet length). The affine cipher maps each letter x to (a*x + b) mod 26, and this map is only a bijection (hence invertible for decoding) when a and 26 share no common factor. Coprime-to-26 values of a are exactly {1,3,5,7,9,11,15,17,19,21,23,25}; every even number and every multiple of 13 fails.

Source

Thrown at src/core/lib/Ciphers.mjs:36

 * Affine Cipher Encode operation.
 *
 * @author Matt C [matt@artemisbot.uk]
 * @param {string} input
 * @param {Object[]} args
 * @returns {string}
 */
export function affineEncode(input, args) {
    const alphabet = "abcdefghijklmnopqrstuvwxyz",
        a = args[0],
        b = args[1];
    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 function ax+b % m = y (where m is length of the alphabet)
            output += alphabet[((a * alphabet.indexOf(input[i])) + b) % 26];
        } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {
            // Same as above, accounting for uppercase
            output += alphabet[((a * alphabet.indexOf(input[i].toLowerCase())) + b) % 26].toUpperCase();
        } else {
            // Non-alphabetic characters
            output += input[i];
        }
    }
    return output;
}

/**

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Choose a from the set coprime to 26: 1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25.
  2. When generating keys randomly, loop until Utils.gcd(candidate, 26) === 1.
  3. Verify the key pair before invoking affineEncode (see validationCode).

Example fix

// before
affineEncode(text, [2, 3]); // gcd(2,26)=2 -> throws

// after
affineEncode(text, [5, 8]); // gcd(5,26)=1 -> ok
Defensive patterns

Strategy: validation

Validate before calling

import Utils from ".../Utils.mjs";
function isValidAffineA(a) {
  return Number.isInteger(a) && Utils.gcd(a, 26) === 1;
}
// call site:
if (!isValidAffineA(a)) {
  throw new Error(`a=${a} is not coprime to 26; use one of 1,3,5,7,9,11,15,17,19,21,23,25`);
}
affineEncode(input, [a, b]);

Type guard

function isCoprimeTo26(a) {
  return Number.isInteger(a) && a > 0 && Utils.gcd(a, 26) === 1;
}

Prevention

When it happens

Trigger: affineEncode(input, [a, b]) is called with a being even (e.g. 2, 4, 26) or a multiple of 13 (13, 39). The check Utils.gcd(a, 26) !== 1 fires before any character is processed, so even valid-looking text throws on the first call.

Common situations: Developer copies an example key pair where a=2 or a=10; auto-generating random affine keys without filtering for coprimality; treating a as any integer rather than a unit mod 26; passing a=0 (also rejected because gcd(0,26)=26).

Related errors


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