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
- Choose a from the valid set coprime to 26: 1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25.
- Cross-check the value against the key used to encode the text (Affine Cipher Encode).
- 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
- Pick a from {1,3,5,7,9,11,15,17,19,21,23,25}.
- Keep the same a used at encode time when decoding.
- Pre-check gcd(a,26)===1 before building the recipe.
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
- The values of a and b can only be integers.
- The value of `a` must be coprime to 26.
- Rotor ${i} must be provided.
- Invalid block cipher mode: ${mode}
- Invalid ciphertext length: ${originalLength} bytes. Must be
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/6e282ff64b9639b1.
Report an issue: GitHub.