Nodes/ComfyUI ARG Toolkit/Gronsfeld Cipher
ComfyUI Node

Gronsfeld Cipher

A Vigenère variant that turns a phone number into a cipher key

By AzelusLightvale·Created 12 months ago·Updated 4 days ago· 1
Gronsfeld Cipher
    • encrypted_txt
    textHello World!
    alphabetENGLISH
    modetrue
    keep_formattingtrue
    key

    Gronsfeld is the cipher you get when someone looks at Vigenère and says "what if the key was just numbers?" It's a polyalphabetic substitution cipher - the same family as Vigenère - but instead of shifting each letter by a keyword letter, it shifts by a digit. That's a small change with a big consequence for ARG design: your key can be a date, a phone number, a sequence from a map, anything digits can encode. The Gronsfeld node wraps that in a single text box and a toggle.

    How it works

    Each digit of the key shifts the corresponding letter of the plaintext forward (encrypt) or backward (decrypt) through the alphabet. Key 42 means: shift the first letter by 4, the second by 2, then wrap around and repeat - 4, 2, 4, 2, forever. Because the key cycles and the shifts are small, Gronsfeld is harder to break than a monoalphabetic Caesar but far weaker than a full-keyword Vigenère: a solver only needs to figure out the number of digits and try the shifts. For a puzzle trail, that's the sweet spot - solvable with patience, not instantly crackable by a frequency table.

    The node builds the key by reading the key string and keeping only the digits (tuple(int(ch) for ch in key if ch.isdigit())), so you can type "04 22 21" or "042221" and get the same result. Anything that isn't a number is ignored - which is convenient, and also the source of a fun failure mode if your key has no digits at all.

    The inputs that matter

    • key - the digits that drive the shifts. It must contain at least one digit, or the node raises ValueError("Invalid Gronsfeld key: must contain at least one digit."). No default, so the first run is a guaranteed error if you don't type one - that's the "Hello World!"-adjacent surprise of this node.
    • text - the message, in the alphabet's language.
    • alphabet - defaults to ENGLISH; a custom alphabet string works too. The digits shift through whatever alphabet you set, so a custom alphabet changes the math completely - a feature if you want non-standard mappings, a trap if you forgot it's set.
    • mode - on is encrypt, off is decrypt.
    • keep_formatting - preserves spaces/punctuation/case, or strips to a solid lowercase block.

    The output

    • encrypted_txt (STRING) - the ciphertext or plaintext. Simple string out, wire it anywhere.

    Installing it

    Part of the ComfyUI ARG Toolkit:

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

    Restart ComfyUI, or install via ComfyUI Manager ("ComfyUI ARG Toolkit"), which handles the secretpy dependency.

    Where people get burned

    • A key with no digits. This is the #1 gotcha. Type "abc" as the key and the node errors out immediately. Any key, but it has to have at least one number in it.
    • Digits only, not numbers. "25" shifts by 2 then 5 - two digits, not twenty-five. The key is a sequence of single digits, so a year like 2026 becomes 2, 0, 2, 6.
    • Secret sharing. Gronsfeld's security is the key. Since the key is numeric and short, brute-forcing it by hand is entirely doable - which is fine for a puzzle and terrible for anything you actually want secret. Use it where the difficulty is part of the game.

    For "hide a message behind a number someone can find," Gronsfeld is the natural pick - and unlike Foursquare, there's no pair of keywords to juggle, just one string of digits that could be sitting in plain sight the whole time.

    CategoryARG Toolkit/Cryptography/Classical

    Inputs (5)

    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.
    keySTRINGAccepts a string of numbers (punctuation optional) as the first key to decrypt/encrypt. Note that anything not a number is ignored.

    Outputs (1)

    NameTypeDescription
    encrypted_txtSTRING