{"record":{"id":"6e282ff64b9639b1","repo":"gchq/CyberChef","slug":"the-value-of-a-must-be-coprime-to-26-6e282f","errorCode":null,"errorMessage":"The value of `a` must be coprime to 26.","messagePattern":"The value of `a` must be coprime to 26\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/AffineCipherDecode.mjs","lineNumber":60,"sourceCode":"    /**\n     * @param {string} input\n     * @param {Object[]} args\n     * @returns {string}\n     *\n     * @throws {OperationError} if a or b values are invalid\n     */\n    run(input, args) {\n        const alphabet = \"abcdefghijklmnopqrstuvwxyz\",\n            [a, b] = args,\n            aModInv = Utils.modInv(a, 26); // Calculates modular inverse of a\n        let output = \"\";\n\n        if (!/^\\+?(0|[1-9]\\d*)$/.test(a) || !/^\\+?(0|[1-9]\\d*)$/.test(b)) {\n            throw new OperationError(\"The values of a and b can only be integers.\");\n        }\n\n        if (Utils.gcd(a, 26) !== 1) {\n            throw new OperationError(\"The value of `a` must be coprime to 26.\");\n        }\n\n        for (let i = 0; i < input.length; i++) {\n            if (alphabet.indexOf(input[i]) >= 0) {\n                // Uses the affine decode function (y-b * A') % m = x (where m is length of the alphabet and A' is modular inverse)\n                output += alphabet[Utils.mod((alphabet.indexOf(input[i]) - b) * aModInv, 26)];\n            } else if (alphabet.indexOf(input[i].toLowerCase()) >= 0) {\n                // Same as above, accounting for uppercase\n                output += alphabet[Utils.mod((alphabet.indexOf(input[i].toLowerCase()) - b) * aModInv, 26)].toUpperCase();\n            } else {\n                // Non-alphabetic characters\n                output += input[i];\n            }\n        }\n        return output;\n    }\n\n    /**","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/AffineCipherDecode.mjs#L42-L78","documentation":"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.","triggerScenarios":"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}.","commonSituations":"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.","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."],"exampleFix":"// before - a=2 shares factor 2 with 26\nchef.affineCipherDecode(input, [2, 8]);\n\n// after - a=5 is coprime to 26\nchef.affineCipherDecode(input, [5, 8]);","handlingStrategy":"validation","validationCode":"import Utils from \"src/core/Utils.mjs\";\nconst VALID_A = [1,3,5,7,9,11,15,17,19,21,23,25];\nfunction assertAffineCoprime(a) {\n  if (!VALID_A.includes(((a % 26) + 26) % 26)) {\n    throw new Error(`a must be coprime to 26; valid: ${VALID_A.join(\", \")}`);\n  }\n}\nassertAffineCoprime(a);","typeGuard":"function isAffineCoprime(a) {\n  function gcd(x, y) { while (y) { [x, y] = [y, x % y]; } return x; }\n  return Number.isInteger(a) && gcd(((a % 26) + 26) % 26, 26) === 1;\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["cipher","affine-cipher","math","argument-validation"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}