Chao Cipher
The 'unbreakable' WWII-era puzzle that's mostly a vibe now
- encrypted_txt
The Chao cipher is the one with a story. Invented by John F. Byrne - a friend of James Joyce, no less - in 1918, it was touted as unbreakable, famously survived an attack by the US Army's codebreakers in the 1950s, and stayed a family secret until his heirs published it in 2010. In modern terms it's a sophisticated polyalphabetic cipher that rotates two permuted alphabets as it goes, so each letter depends on all the state built up before it. In an ARG, that history is half the appeal: the ciphertext "looks like a proper puzzle" in a way a Caesar never will, and solving one is a flex.
The practical reality is more modest. Modern cryptanalysis has long since cracked it, so nobody in their right mind uses Chao for actual secrecy - it's a solving toy and a historical curiosity. But that's exactly the audience this node serves: it puts a genuinely obscure classical cipher inside ComfyUI with the same input layout as every other cipher in the pack, so an ARG creator can embed a Chao-encrypted clue and solvers can decrypt it in-graph instead of bouncing to dCode.
How it works
Like all the classical ciphers here, it's a wrapper around secretpy - specifically secretpy.Chao, registered in the pack under the display name "Chao Cipher". The mechanism is the interesting part: Chao needs two alphabets that start as permutations of your alphabet and both get permuted after each letter is enciphered. That dynamic re-arrangement is why it defeated 1950s codebreaking - there's no fixed substitution table to recover.
The practical consequence is the key field. For most of the pack's ciphers, the key is a number or a word; for Chao, the tooltip tells you plainly: the key must be an alphabet of equivalent length to your chosen alphabet - i.e., a permutation of the 26 letters (if you're using ENGLISH). Leave key blank and the cipher will do whatever secretpy does with a blank key, which is not what you want. This is the input that separates "this works" from "garbled output."
The inputs that matter
text- the message to encrypt/decrypt, matching the alphabet's language.key- a permutation alphabet, same length as your chosenalphabet. The one non-obvious input.alphabet-ENGLISHby default; custom connected alphabets allowed.mode- encrypt/decrypt toggle.keep_formatting- preserve spaces/case or strip to lowercase.
Output: a single encrypted_txt string.
Installing it
Ships in the ComfyUI ARG Toolkit pack. Install via ComfyUI Manager (search "ComfyUI ARG Toolkit") or:
cd ComfyUI/custom_nodes
git clone https://github.com/AzelusLightvale/ComfyUI-ARG-Toolkit
Restart ComfyUI. Pack-wide install brings secretpy, cryptography, stegano, invisible-watermark, reedsolo, and heavy transitive deps (torch, opencv-python). No models, no API keys.
Gotchas
The key-format trap is the whole game: give Chao a normal word as the key and you'll get nonsense, because it wants a full permuted alphabet, not a keyword. Also bear in mind this is an amateur-implemented wrapper over a library - the author's own README says tests cover common cases only - so if your custom alphabet produces odd output, double-check it against a reference implementation before assuming you broke something. And set your expectations: as a cipher it's historically fascinating and worth having, but "unbreakable" applied to a 2010-published algorithm means "fun puzzle," not "secure."
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| text | STRING | Hello World! | — |
| alphabet | STRING | ENGLISH | Input 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. |
| mode | BOOLEAN | true | Toggle between encrypting or decrypting a message. |
| keep_formatting | BOOLEAN | true | Toggle between preserving the format of the message or remove all spaces, punctuations, and convert to lowercase. |
| key | STRING | Accepts an alphabet of equivalent length to the chosen alphabet as the key to decrypt/encrypt. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| encrypted_txt | STRING | — |