ComfyUI Node

Affine Cipher

A Little Math Goes a Long Way (If the Key Cooperates)

By AzelusLightvale·Created 12 months ago·Updated about 10 hours ago· 1
Affine Cipher
    • encrypted_txt
    textHello World!
    alphabetENGLISH
    modetrue
    keep_formattingtrue
    key_17
    key_28

    The Affine cipher is what happens when someone looks at a Caesar shift and thinks "we can do better with a line equation." Instead of shifting every letter by a fixed amount, it maps each letter to (a × position + b) mod alphabet_size - one multiplicative step, one additive step. Two knobs, marginally more security, and a far more interesting puzzle. In the ARG Toolkit it's the classical cipher that feels like it was designed by someone who actually thought about the math, because the two keys have very different personalities.

    The personality difference matters: key_1 is the multiplicative part, and it must be relatively prime to the alphabet length (no common factors). With a 26-letter alphabet, that means key_1 has to be one of 1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, or 25. Pick something like 4, which shares a factor of 2 with 26, and letters start mapping to the same outputs - the cipher stops being reversible and your decrypt turns to mush. key_2 is the additive part and is far more forgiving: any integer from 0 to alphabet length minus 1 works, think of it as a starting index. Defaults are key_1 = 7 and key_2 = 8, which are valid for English.

    The inputs that matter

    • key_1 (INT) - the multiplicative key. The node's tooltip calls out the relatively-prime requirement. This is the one that'll reject you.
    • key_2 (INT) - the additive key. Forgiving by design.
    • mode - encrypt/decrypt toggle (on = encrypt).
    • text, alphabet, keep_formatting - the standard classical-cipher kit, with alphabet defaulting to ENGLISH.

    Output is the usual single encrypted_txt STRING.

    A word on the validation

    The source's key validation is... enthusiastic. It tries to verify your key_1 against the alphabet size, and the check as shipped has quirks - it can throw an error for values that are actually fine, and its internal gcd math isn't quite the textbook version. What this means in practice: don't fight the node. If it rejects a key_1, pick one of the coprime values listed above (7, 11, 17, 23 are all safe bets) and move on. The node's math on the actual encryption side is correct; it's the guard at the door that's a little overzealous.

    Where people get burned

    Beyond the coprime rule, the classic failure is cross-validating with an online tool and getting a different result. Affine implementations disagree on whether a=1, b=0 is "identity" or whether the alphabet starts at 0 or 1 - the pack lowercases and strips your input in shared preprocessing, which changes what you're comparing. If your output doesn't match dCode, check keep_formatting and the case of your input before suspecting the node. And remember decrypt needs the same two keys as encrypt; one digit off in key_1 and the whole round-trip is garbage, no error, no mercy.

    Installing it

    Like every node in this pack, it comes with the ARG Toolkit:

    cd ComfyUI/custom_nodes
    git clone https://github.com/AzelusLightvale/ComfyUI-ARG-Toolkit
    

    Restart ComfyUI and find it under ARG Toolkit → Cryptography → Classical. Or ComfyUI Manager → search "ComfyUI ARG Toolkit" → Install. The classical ciphers depend on secretpy, handled by Manager (or pip install -r requirements.txt for manual clones). Pure Python, no models.

    Troubleshooting

    • Node refuses key_1 → it's not coprime with 26. Use 7, 11, 17, or 23.
    • Decrypt is garbage → key mismatch, or you changed a key between encrypt and decrypt.
    • Result differs from a website → flip keep_formatting and match the case conventions; implementations differ there, not in the core math.

    Affine is a lovely intro cipher and a staple of puzzle ciphers because the "crack" involves a tiny bit of modular arithmetic - perfect difficulty for an ARG step that should reward a solver who paid attention in math class.

    CategoryARG Toolkit/Cryptography/Classical

    Inputs (6)

    NameTypeDefaultDescription
    textSTRINGHello World!
    alphabetSTRINGENGLISHInput your alphabet here. If left blank, uses the alphabet default to the cipher. Uses standard connected format ('abcdef'), but can also accept the alphabets defined in secretpy in alphabets.py.
    modeBOOLEANtrueToggle between encrypting or decrypting a message.
    keep_formattingBOOLEANtrueToggle between preserving the format of the message or remove all spaces, punctuations, and convert to lowercase.
    key_1INT7The multiplicative part of the Affine key. Allows only numbers with no common factors to the alphabet length (relatively prime).
    key_2INT8The additive part of the Affine key. Allows every integer from 0 up to the length of the alphabet minus 1 (imagine an index starting from 0).

    Outputs (1)

    NameTypeDescription
    encrypted_txtSTRING