Nodes/ComfyUI ARG Toolkit/Foursquare Cipher
ComfyUI Node

Foursquare Cipher

The digraph cipher that's genuinely fun to bury clues in

By AzelusLightvale·Created 12 months ago·Updated 5 days ago· 1
Foursquare Cipher
    • encrypted_txt
    textHello World!
    alphabetENGLISH
    modetrue
    keep_formattingtrue
    key_1
    key_2

    Foursquare is a classical cipher with a genuinely good payoff for ARGs: it encrypts two letters at a time (digraphs), which smears out the single-letter frequency patterns that make simple substitution ciphers trivially crackable. If you've ever hidden a message with a Caesar shift and watched a solver crack it in thirty seconds, this is the step up that still feels like a puzzle rather than homework. It's powered by the secretpy library, the same engine behind most of the pack's classical ciphers.

    How it works

    The cipher uses four 5×5 grids of letters - a 2×2 arrangement of Polybius squares. Two of the squares (top-left and bottom-right) hold the plain alphabet; the other two hold alphabets scrambled by two keywords, key_1 and key_2. To encrypt a pair like "hi," you find the H in the plain square and the I in the plain square, then read the letters at the opposite corners of the rectangle they form - one from the key_1-mixed square, one from the key_2-mixed square. Two keywords means two independent scrambling alphabets, which is what makes it stronger than Playfair against frequency analysis.

    The inputs that matter

    • text - the message, defaults to "Hello World!".
    • key_1 and key_2 - the two keywords, each in the alphabet's language. These are the actual secrets. In the classic Foursquare setup, the solver needs both keywords to decrypt, and having two lets you hand out one key to some people and the other to others for partial messages. Keyword letters just get used to build the mixed alphabets, so spaces and punctuation are ignored.
    • alphabet - defaults to ENGLISH; you can supply a custom alphabet string, or the name of a predefined one from secretpy's alphabets.py. The tooltip spells out the accepted format (abcdef connected). This matters more than it looks: classical ciphers are language-specific, so your text has to be in the alphabet's language or you'll encrypt nonsense.
    • mode - on is encrypt, off is decrypt.
    • keep_formatting - on preserves the message's spaces/punctuation/case in the output; off strips everything and lowercases. For hiding clues, keep_formatting on makes the output look like real text; off gives you the classic solid-ciphertext block.

    The output

    • encrypted_txt (STRING) - the ciphertext (or plaintext, in decrypt mode). Wire it anywhere a string flows, or save it out. Since the underlying alphabet is 25 letters (I/J combined, per the standard 5×5 square), the output is clean uppercase letters.

    Installing it

    Part of the ComfyUI ARG Toolkit:

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

    Restart ComfyUI, or grab it via ComfyUI Manager ("ComfyUI ARG Toolkit"), which installs secretpy along with the pack's other dependencies.

    Where people get burned

    • Empty keywords. Both key_1 and key_2 default to empty strings. With no keywords the mixed squares come out... standard, which technically encrypts nothing. Fill both keys in or the "cipher" is about as secure as a screen door.
    • Wrong language. Feed Cyrillic text with the English alphabet and you'll get errors or garbage. Match the alphabet to the message.
    • Odd-length messages. Digraph ciphers want even-length input; a dangling single letter usually gets dropped or padded depending on the library. If your decrypted message looks short by a character, that's the classic culprit.

    The Foursquare node is where the pack's "poor-man's cryptanalysis lab" framing starts to make sense - encrypt a clue with two keywords, hide the keywords in different parts of the trail, and let the solver do the rectangle work.

    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_1STRINGAccepts any text (or alphabet) in the alphabet's language as the first key to decrypt/encrypt.
    key_2STRINGAccepts any text (or alphabet) in the alphabet's language as the first key to decrypt/encrypt.

    Outputs (1)

    NameTypeDescription
    encrypted_txtSTRING