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
- Choose a from the set coprime to 26: 1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25.
- When generating keys randomly, loop until Utils.gcd(candidate, 26) === 1.
- 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
- Maintain a constant COPRIME_A = [1,3,5,7,9,11,15,17,19,21,23,25] and select from it.
- When generating random keys, retry until gcd(a,26)===1 rather than accepting the first draw.
- Never use even values or multiples of 13 for a.
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
- Rotor wiring must be 26 unique uppercase letters
- Rotor steps must be 0-26 unique uppercase letters
- Rotor ring setting must be exactly one uppercase letter
- Rotor initial position must be exactly one uppercase letter
- Rotor wiring must have each letter exactly once
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/8bb28b98c4272177.
Report an issue: GitHub.