Help design a cipher for my crypto wedding-rings!

When my wife and I started to plan our wedding, we inevitably turned to the question of rings, and it was only a matter of time before we came to the idea of rings with little wheels on them that could be used as crypto devices, in the manner of super-duper Captain Midnight Decoder Badges.

So we asked Bruce Schneier for some advice and he suggested that we make each ring with one static band and two rotating ones, each inscribed with the alphabet. The first wheel has dots on the letters, alternating above, none, below. The second wheel has the repeating sequence of above, above, none, none, below, below. The third wheel has the repeating sequence of above, above, above, none, none, none, below, below, below (it sounds confusing, but you can see a chart here).

The rings were made in white gold by Isabel Rucker (daughter of master cyberpunk author Rudy Rucker -- and a fantastic jeweler in her own right) and they turned out great.

Now it's time that we turn to the Internet with a challenge: given these two matching rings, what crypto applications can you come up with? Could you use them to scramble passwords (possibly hashed with a key)? How about encoding messages for secret transmission? What additional common apparatus (say, different-sized coins) could you use to generate initialization vectors and increase the system's security?

This is an open competition to be judged by Bruce "Applied Cryptography" Schneier and me -- the winner gets a copy of Little Brother signed by both of us. Post your submissions to the comments or send them to before Oct 1, 2008. Crytpo Wedding Ring



  1. I imagine spending 10 minutes feverishly decoding a request to take out the goddamn garbage like I asked you this morning. :D

  2. You said “Take out the garbage?”

    Funny, when I decoded the note it told me to lie on the couch and watch football all afternoon.

    Honest mistake, I suppose.

  3. Cory – can you clarify something, please?

    You said that two bands rotate and one is static. Is it the case that the middle band is static?

    If so, these are essentially a spinner or fidget ring, but with two spinners instead of one, right?

  4. So the easy points first, so that we can understand the upper bounds on the algorithm:
    -Your max key size is going to be 26*26
    -Something needs to change each step, so that you don’t encode consecutive same letters to the same thing.

    I also wonder if it would’ve been better with a 27th letter for “other” used whereever there was ambiguity, such as NOONE — is that “no-one” or “Noon e”, it could be vital for proper names.

  5. I’m just chalking it up to cruel fate that I’m probably going to spend time I don’t have fretting over this. Cripes it’s like the contest was specifically designed to suck me in.

    Robert Richardson

  6. What does it matter which ring doesn’t move? If the middle ring is fixed (relative to what? your finger?), then essentially all three rings can move relative to each other, allowing any initial setting you would like, right? (Or am I missing something?)

    BTW – I want to you to know I’m totally jealous of the ring. :-)

  7. That’s fantastic – and, suddenly, a little spring in the back of my skull went “ping!” with the thought of a story, akin to “The Man Who Never Was” where an encryption ring is found at the scene of a crime or on a corpse and ultimately holds the key to solving the mystery – whatever that is – I can’t write it now I’m going camping – and I will be forever jealous of your rings. I have a dual set of rings with inscriptions of them but it’s just gobbledy gook and almost worn off now but the romance is still there even if we can’t tell each to “Always Drink Your Ovaltine”.


  8. When you say matching, do you mean “look the same in proportion on the hand” (like most matched pairs of wedding rings) or “have the same external dimensions”? If the ring sizes differ significantly then using common objects as initialisation vectors may not be an option.

  9. Learn a second language. Don’t tell anyone you are learning that language. Use that language exclusively for the secret messages. Anyone trying to crack the code will assume the cleartext is english, and have a much harder time of it.

  10. @Daemon

    oh yeah, what a staggeringly easy cipher. If you’re going to do that why don’t you learn to very quickly multiply prime numbers together, forget about the rings, write your public key on your forehead and encipher all your messages in mental arithmetic RSA.

    I don’t think there’s going to be that much of a rush to decode these communications…so maybe ease of use slightly trumps learning a new language.

  11. Here’s a simple cipher you can use.
    To encrypt:
    1. choose a password or passphrase.
    2. eliminate any duplicate letters. What’s left is the key. If there are an even number of letters, add an extra letter.
    3. Align the letter ‘A’ on the inner wheel with the first letter in the key on the middle wheel.
    4. Align the letter ‘A’ on the middle wheel with the second letter in the key on the outer wheel
    5. Find the first letter of your cleartext on the inner wheel and read across to find the ciphertext letter on the outer wheel.
    6. Lather, rinse and repeat at step 3, starting back at the beginning of the key as needed.

    To decrypt, generate the key and rotate the wheels the same way, but find the ciphertext on the outer wheel then read across to find the cleartext on the inner wheel.

  12. No suggestions on ciphers here, just wanted to say how much I -adore- the idea and realization of these rings… great idea and beautifully done.

  13. Seems to me you have a basic enigma machine with the dots encoding when to spin adjacent rotors. But I’m way too lazy to think about it much further than that.

  14. In this day and age, it should not be possible to decrypt a message encrypted with the rings if someone else sees how the rings are constructed.

    That may sound impossible, but if we include the possibility of an online element then this should be possible.

    Perhaps the numbers can be input into an external website for Cory and his wife that allows them to generate a unique key pair.

  15. Assuming that
    a) you only encrypt reasonably sized messages (i.e. no megabytes of data)
    b) the procedure should be reasonably easy (i.e. only needs the ring and no fancy math or good memory)

    (I’ll name the spinning rings “ring1″ and “ring2″ and the static ring “ring0″)

    Here’s what you do:

    Password: minimum of two letters, and a step size (valid values: 1,3,5,7,9,11 in either direction [equals 12 variations])

    1) align the first letter of the password on ring1 with third letter of password on ring0 (variation: align with letter “A”)
    2) align the second letter of the password on ring2 with fourth letter of password on ring0 (variation: align with letter “A”)
    3) prepend unused letters from password and two random letters to your message (i.e. message = remaining_password + “XY” + message)

    4) get next letter from message
    5) find letter on ring1 that matches letter of step 4 on ring0
    6) find letter on ring2 that matches letter of step 5 on ring0
    7) write down letter from step 6 (=encrypted letter), only if it is not prepended password letter from the setup
    8) spin ring1 by XX steps as defined in password
    9) align the letter from step 6 on ring2 with the next letter from the password on ring0 (if all password letters are used up, then start over again)
    10) goto 4

    Decryption is the inverse operation.

    I think that this is a fairly secure encryption algorithm with some nice properties. OTOH I am a cryptonoob and presumably someone can crack this with pencil and paper.

    Password: “CORYD”, step: 3 forward

    1) align “C” on ring1 with “R” on ring0
    2) align “O” on ring2 with “Y” on ring0
    3) unused password letters “D” + random letters “QL” == “DQLWILLYOUMARRYME”

    4) “D”
    5) “D” on ring0 = “O” on ring1
    6) “O” on ring0 = “E” on ring2
    7) do not write down (password letter)
    8) spin ring1 (3 steps forward), now “A” on ring0 == “I” on ring1
    9) next letter of password == first letter == “C”, spin ring2 so that “E” on ring2 == “C” on ring0
    next round:
    4) letter “Q”
    5) “Q” on ring0 == “Y” on ring1
    6) “Y” on ring0 == “A” on ring2
    7) write down letter “A”
    8) spin ring1 (3 steps forward), now “A” on ring0 matches “F” on ring1
    9) next letter of password: “O”, spin ring2 so that “A” on ring2 == “O” on ring0
    next round …

    encrypted text: “ACJSWYYIOEGKIDEV”

    Implemented as Javascript functions:

    function encrypt(salt, password, step, text)
    var ring1 = (password.charCodeAt(0) – password.charCodeAt(2) + 26) % 26;
    var ring2 = (password.charCodeAt(1) – password.charCodeAt(3) + 26) % 26;
    var msg = password.substring(4) + salt + text;
    var pwdchar = -1;
    var encrypt = “”;

    for (i=0; i < msg.length; i++) { var c = msg.charCodeAt(i) - 65; var enc = (c + ring1 + ring2) % 26; pwdchar = (pwdchar+1) % password.length; ring1 = (ring1+step) % 26; ring2 = (enc - (password.charCodeAt(pwdchar)-65)+26) % 26; encrypt += String.fromCharCode(enc+65); } return encrypt; } function decrypt(password, step, text) { var rem = encrypt("", password, step, ""); var msg = rem + text; var ring1 = (password.charCodeAt(0) - password.charCodeAt(2) + 26) % 26; var ring2 = (password.charCodeAt(1) - password.charCodeAt(3) + 26) % 26; var pwdchar = -1; var decrypt = ""; for (i=0; i < msg.length; i++) { var enc = msg.charCodeAt(i) - 65; var c = (enc - ring1 - ring2 + 52) % 26; pwdchar = (pwdchar+1) % password.length; ring1 = (ring1+step) % 26; ring2 = (enc - (password.charCodeAt(pwdchar)-65)+26) % 26; if (i >= 2+rem.length)
    decrypt += String.fromCharCode(c+65));
    return decrypt;

  16. ps: the encrypt javascript function is missing an IF statement:

    if (i >= password.length-4)
    encrypt += String.fromCharCode(enc+65);

    otherwise the encoded password chars get ouput as well.

  17. I like the ring, I don’t understand the purpose of the dots. No one seems to have mentioned them, unless I missed it.

  18. Dmn Cry, y sr d psh yr bk hrd. Mny, mny f yr psts hv n sm wy dvrtsd t. gt t bt t jst sms wrd n blg tht’s nt yrs spcfclly, yh?

  19. Wow. Just wow. This is *so* cool.

    #11: Tak-kun, one of your best suggestions ever. Cory, you’re a wordsmith. Pleeease do this and publish the rhyme online.

    #26: Don’t CATFOTFIC. A copy of Big Brother, signed by both Cory and Bruce Schneier, is a unique and potentially valuable prize. I really, really don’t see this as advertising.

  20. h Gd, gss cn xpct t b dsmvwlld fr vcng my pnn f th lst pst whr CTFTFC ( hd t Ggl t) pprd s ny ndctn. Tht sms prtty fscst t m.

  21. #25 I thought the dots were places where you could use a pen to turn the ring sections?
    Cory, those are cool rings and congratulations on the marriage, whenever it took place.

  22. Well, it could be very usefull for another form of user verification.

    Like a challnge response kind of thing with the shared secret being your key.

    You have a predifined start key like Schneier’s AEB. On the first of the month, you send your username and encrypted password. Next day,t he second ,beign an even day, you rotate the second right clockwise if you want to log in. The next day, the third, you rotate the third ring clounter clockwise.

    It ends up being something simular to a DUKPT key changing scheme.

  23. Improvement on my proposed encryption algorithm in comment #23, after seeing that encrypting a text consisting of only of ‘A’ letters with a password of ‘AAAAAA’ exhibits bad characteristics.

    – minimum of two letters (preferably a password with an odd number of letters not divisible by three, e.g. 5,7 or 11 letters long)
    – a step size (hereafter called step1) (valid values: 1,3,5,7,9,11 in either direction [equals 12 variations])
    – a selected ring and another step size (hereafter called step2) (valid values same as step1)

    1) align the first letter of the password on ring1 with third letter of password on ring0
    2) align the second letter of the password on ring2 with fourth letter of password on ring0
    3) prepend unused letters from password and two random letters to your message

    4) get next letter from message
    5) find letter on ring1 that matches letter of step 4 on ring0
    6) find letter on ring2 that matches letter of step 5 on ring0
    7) write down letter from step 6 (=encrypted letter), only if it is not prepended password letter from the setup
    8) spin ring1 by step1 steps as defined in password
    9) align the letter from step 6 on ring2 with the next letter from the password on ring0 (if all password letters are used up, then start over again)
    10) at every third letter: look up the letter of step 5 on your selected ring (from password) and
    – if the letter has a dot above, spin ring2 by step2 steps
    – if the letter has a dot below, spin ring2 by step2 steps in the opposite direction
    – if no dot, then do nothing

    11) goto 4

    The result looks better, not sure whether it actually is more secure :-) It makes use of the dots and doing the additional lookup only on every third step isn’t too much hassle. I think it is secure enough for your twitter messages :-)

    Javascript code:

  24. Eh. Don’t love it Cryptonoob.

    As a one-time Cypherpunk I just don’t like the idea of a cipher that is trivial to break if someone happens to know how the rings work (and that will be easy if it’s not already obvious), particularly in this survelliance state we find ourselves in.

    Rather, the rings should select out some sort of public/private key pair that is available on line somewhere.

    Come to think of it, the key pair should be one-time use only, so that Cory and his wife can select a key pair to trade information/email online, but after that it should be discarded so that if anyone else tries to listen in by observing the rings’ settings, the key pair they will receive won’t be the same and hence useless.

    This won’t prevent man (or woman!) in the middle attacks, but a married couple should have no problem creating a protocol to deflect those!

  25. Keeper,

    my algorithm does not stand up to modern cryptoanalysis. I know that. I would not try to invent any serious encryption algorithm myself – far more capable people than me have failed in that field.

    I think of this as a fun challenge: come up with something that provides security better than rot13, uses the ring and can be done manually without too much hassle. I think my algorithm has these properties.

    Regarding a one-time pad “available online,” say a text from a book: a simple implementation (OTP xor message) of that is not secure either: given a large (>10kb) encrypted message I’m almost sure I can break it. Weak point is that a text from a book is not a good OTP, because it is not random and contains predictable sequences (e.g. the word “the”).

    That being said, if you use my algorithm with a password as long as the message (password = OTP) it would thwart the easy attack outlined above. At least it would take real cryptobuffs to break it, not cryptonoobs like me :-)

  26. My idea.

    1) When encrypting, a dot above means the top ring; no dot means the middle ring; a dot below means the bottom ring. When decrypting, reverse this.

    2) Find the first letter of the key on the middle ring; the initial “current ring” is indicated by the dots as in (1).

    3) Set the next two letters of the key on the middle and bottom rings against A on the top ring. If you’ve come to the end of the key, start again at the start of the key.

    4) Find the first (/next) letter of the plaintext on the “current ring”. Look at the dots, as in (1). Replace with the letter on the indicated ring (if the dots indicate the same ring as the current one, replace with the next letter on that ring). These same dots also indicate the new “current ring”.

    5) Repeat (3) and (4) until finished.

    Hope that makes sense. I’m no cryptographer, but at least this allows you to use a longer key than Bruce’s suggestion.

  27. A clarification on my previous post.

    Those are actually two different ideas with the same key rotation.

    1) used for challange response authentication. Where the website presents you with a captcha ( just to make it more expensive for any automated cracker). You then encrypt the Captcha word and send it back. Proving you are you. This has the nice feature that the password is different every time. No replay attacks and you are always encrypting different passwords, rather than the same one over and over.

    2) DUKPT functionality: You have one password.

    Say Day 1 your password is password, you encrypt it to get uejowuop. That is your password for that day. Next day you take uejowuop and encrypt that with the days new key to get poivmeqi. That is your password for that day. And on and on and on. Might not be the most user friendly for the casual users bank password. Or you could actually do the key rotation on each successful use of the password, if you can make sure that both the bank and you agree when you’ve been authenticated.

  28. Just wait few years. Then you will both be able to speak to each other in shortened sentences that nobody else understands, anyway.


  29. Here’s your cipher, and a stealthy way to use another object for added encryption strength. You encrypt/decrypt using paper, a pencil, and… the serial number on a dollar bill that you pull out of your wallet.

    The simplest form (=most likely to be remembered) is one where you initialize two wheels using the first number off the dollar (e.g. if it’s 7, A+7=H, so line up A with H), and then generate the first letter of the ciphertext from that alignment. Now spin the wheel (up, down, or rot13) based on (1) the next number on the dollar bill, and (2) the position of the dot above of below the plaintext letter (no dot = rot13).

    When you get to the end of the serial number, just loop around and start again. You’re essentially using the dollar as a miniature one-time-pad, although it’s got a little weakness since you’re using it over and over again, but the business with the dots helps out a bit.

    Oh, yes, how do you get two identical dollar bills? (1) In a pinch, rip one in half. You could even plant it secretly on you wife! When she gets the message, she has to go searching in her pockets! (2) I assume that uncut currency (available at has sequential serial numbers, and you could just ignore the last digit. Using this method involves cutting up uncut sheets of dollar bills, which adds to the fun. I might use $20s, so that the decryper bill would be that secret folded-up twenty that we all carry stuffed behind our library card in case, say, we need cab fare home, or we see a mint condition 1924 Martin 5K Ukulele for ten bucks.


  30. Make the code linked to something else that has meaning to the both of you. Like all the letters or numbers in the ring cypher correspond to words or pages numbers or letter numbers in a book or poem or story or run times in a movie that’s meaningful to the two of you.
    So even if someone figured out the cypher itself, it would be just a series of seemingly random numbers or letters if they didn’t know what book or movie served as the “Key”. And it would add that extra bit of special sentiment to it for the two of you to have it linked to something special,too.

  31. While these rings may represent only a nod in the direction of truly robust encryption, for the purposes of ROMANCE to be adequately served your spouse’s ring needs to be designed to securely store the encryption key of your ring.

    These rings demonstrate to the world that True Love is an Enigma.

    I get misty just thinking about it.

  32. You will have a one time pad-type code. Both of you will know the key, so the code you come up with can mean anything you need it too–your own special code for something important, like your first date, or anniversary. Maybe you could have the interiors inscribed with elfin script: Two rings to bind us both, remind us that we took an oath: Forever yours, Forever mine, until the very end of time.

  33. Congratulations! Here’s my suggested algorithm. (You can find it in Perl here. Sorry about the formatting–I’m having trouble getting ordered list HTML tags to work.)


    (Ring 1 is the innermost. Ring 3 is the outermost.)

    Initialization Sequence
    1. Align all the A’s.

    2. For each letter in the key:

    a. Rotate rings 2 and 3 together so the A on ring 1 aligns with the letter of the key on ring 3.

    b. Calculate an advancement amount.
    i. Start with 1.
    ii. Look at the letter on ring 2 next to the A on ring 1. If there’s a dot above, add 9. If there’s a dot below, add 3.
    iii. Look at the letter on ring 3 next to the A on ring 1. If there’s a dot above, add 2. If there’s a dot below, add 1.

    c. Advance ring 3 that many letters.

    Encryption / Decryption
    (Initialization vector omitted for clarity. Consider using the current time, spelled out. When encrypting, skip spaces and punctuation.)

    1. Look at the letter on ring 3 adjacent to the A on ring 1. Rotate rings 2 and 3 together so that same letter on ring 2 is adjacent to the A on ring 1 (and some different letter on ring 3 is now adjacent to the A on ring 1).

    2. Calculate an advancement amount:
    a. Start with 1.
    b. Look at the letter on ring 2 adjacent to the A on ring 1. If there’s a dot above, add 9. If there’s a dot below, add 3.
    c. Look at the letter on ring 3 adjacent to the A on ring 1. If there’s a dot above, add 2. If there’s a dot below, add 1.

    3. Advance ring 3 that many letters.

    4. To encrypt the next letter of plaintext, find the plaintext letter on ring 1 and write down the cyphertext on ring 3. To decrypt, find the cyphertext on ring 3 and write down the plaintext on ring 1.

    5. Go back to step 1.

  34. Now that I’ve had more time to play with Conjugal, it gives a more even distribution of ring positions if you calculate the advance a bit differently, both when initializing and when encrypting/decrypting.

    1. Start with 1.
    2. Look at the letter on ring 2 next to the A on ring 1. If there’s a dot above, add 2. If there’s a dot below, add 1.
    3. Look at the letter on ring 3 next to the A on ring 1. If there’s a dot above, add 6. If there’s a dot below, add 3.

  35. Good stuff so far.

    To enlarge cypher space I suggest the following processes be included in a final real world crypto application, a couple things I have yet to see in any suggestions:

    1 – masking letters
    * irregularly spaced letters are free from the cypering process and appear in the cyper text

    2 – noise in plaintext
    * fold in plain text and nonsense, a nod to Steganography

    I have a process that feels bloated, but I don’t have the maths chops to really test it. I want to kick its tires a bit before posting.

    For those that like the tactile please see my image for printing out alphabet rings:

  36. htom (forgot my registration, I’ll find or fix it, the message is as I said at Schneier’s blog)

    Perfect pangrams are the first thought of how to extend it. The question is whether to use them as an additional, invisible ring, or in some other fashion. Imperfect pangrams, with repletions ignored, might be useful, too.

    And I want to use the dots to key transpositions. After doing the letter substitution on four letters, the dots and non-dots above the current trio of “active” letters on the rings indicate swapping; dot on left, swap the first pair of letters currently being encrypted with each other, dot on right, swap the second pair letters, dot in middle, swap the first pair and second pair.

  37. 4. Base iterative keys on the produced cypher text.

    a small toolkit for creating a cypher for the rings above:

    AL: starting alignment. AAA to ZZZ (26^3)
    – copying from key. AAA = QQQ, HAL = IBM

    AS: plain/cypher/advance assignment.
    – order sort of three letter combination. (CAT = 213 & LR=cypher MR=plaintext RR=advance), BAA = 312 = 321, FOO = 123.which ring holds the plain text, the cypher text, and the advancement gear? (3^3)

    M: masking (2^n), per iteration. (x*2^n)
    – dots in binary, convert digits to their base two representation. 1 or 0, yes or no to cyphering that letter.

    I: iterations (X*n), X = 1 to 100?
    – machine counting letter values, A=0, Z=25, MAC=12+0+3=15 iterations

    Align, Assign, Mask, Advance, Iterate
    AL. AS. M.A.I. cypher (sorry, that’s a horrible acronym) as in “alas mai cypher is bloated”
    Key length = 15 letters max per iteration. xxx xxx xxx xxx xxx, from plain text, ambient text, random text…
    Each part of the modular process can be dropped from the back forward for cheaper crypto. With the weakest being a straight offset and the full deal for a more expensive crypto taking more time.

    Each of these processes seem like they can be done with little pencil/paper figuring per iteration.

    It seems like a cellular automa question, seeing all those letters and iterations play out through time.

    And of course, the longer you iterate it the more brute force it takes to guess the key

  38. 5: Coins? Take 3 (or six, two, or one) different coins and flip them all at once. They’re assigned 1st, 2nd, 3rd smallest to largest. Heads(1) and tails(0) arbitrarily and consistently from flip to flop.
    1) Flip those coins once, then twice
    2) Add digits, 110+010 = 210 = 16 = P
    3) Do this 15 bloody times.
    4) Key! Memorize it with some whimsical mnemonic.

    caveat: You’ll be missing the 6 tails in a row, but it’s a 90 bit key space. That’s ok, right? Well, if you really want a bigger key, then cyper up your last scrambled text with your second key, again… and again… and again…

    I just tested it with a 1p, 2grosz, and an american quarter. Did it once, took about 10 minutes just flipping them all 30 times. It will be like those camping trips where you sat around a fire and played the name game.
    The key I generated: LJW KNA YOU MDQ PQI, can map to:

    Larry loves Jam in Washington
    Kim eats Nutella in Alberta
    Yumi farms Oysters in Uganda
    Melissa jellies Dingos in Quantico
    Pierre slices Quinces in Iceland!

  39. Rather than adding the values, skip the arithmetic and use a matrix of letters and just look up the flipped or rolled values.

    x 123456
    1 abcdef
    2 ghijkl
    3 mnopqr
    4 stuvwx
    5 yz0123
    6 456789

    first flip , second , third , fourth , fifth :

    ab cd . ef gh – ij kl . mn op / qr st . uv wx – yz 01 . 23 45

    Obviously, if you flip or roll a value that goes out of the desired values you try again. Does anyone know of an extension of the von Neumann procedure for “fairing” a coin to a die?

  40. Hmmm HTOM, that looks interesting, but there’s no numbers on the rings.

    I did some counting with my flipping and adding and found a strangely pretty and lumpy fractal distribution that looks a little like one side of a Kock snowflake.
    M seems to be the favored letter. It’s not evenly spaced because 100+011 is the same as 010+101…


  41. The Three’s Company algorithm:

    First, the dot positions are interpreted as balanced ternary operations (down, stay, and up), so the three rings taken as trits provide 27 values. You will probably want to create a table to aid in mapping the alphabet to ternary and back. Pick some unique character for the 27th slot (I like ‘&’ and ‘#’). You will need an agreed upon passage from a book the couple has enjoyed together (e.g., l’Histoire de Juliette).

    For each plaintext character
    1. align the next 3 characters from the passage on the rings
    2. find the ternary value for the next plaintext character in the table
    3. perform a trit-by trit addition (no carry) of the dot value on the rings with the plaintext
    4. find the resulting ciphertext character in the table

    Adding trits is simple, and even though subtraction is required to decrypt, you only need to replace “downs” with “ups” and vice versa in the subtrahend, then add.

    Unless a different passage is used for each message, the algorithm should be augmented with something like cipher feedback and a nonce message prefix. This may also require keying the table (columnar transposition with the couple’s safeword, e.g.)

  42. There are some constraints on this problem that people suggesting ciphers should be aware of:

    1. All existing public-key ciphers require difficult, multi-digit calculations. Assuming that they don’t want to use an arbitrary precision calculator with their rings, this is out.
    2. Without the option of a public-key cipher, a shared-key cipher is the only choice.
    3. The cipher will be well-known (no security through obscurity). The construction of the rings is well-known and since only a handful of ciphers have been suggested, it’s expected that somebody will be able to try all of the suggestions to find out which one Cory and his wife are using (assuming he doesn’t tell us straight out).
    4. Therefore, the only secret is the shared key.
    5. Unless otherwise stated, we should assume only simple additional tools (coins, pen, paper, etc.). This will limit us to simple math. It may also limit the size of the shared secret to something they can remember (carrying a book around may not be feasible).
    6. The key will not change very often. This is arguable, but being that they are human, they will not want to memorize a large amount. Assuming that they don’t carry a large source of key material (such as a novel), they will be limited to memorizing, at most, a few, short keys.

    Any other constraints that anyone can see? It helps to have requirements before designing algorithms (how can you tell I’m an engineer?).

    We should probably list the scope limitations as well:

    1. The algorithm doesn’t have to be secure against computer analysis. Given the key space and the limited number of calculations we can make, this level of security is unreasonable.
    2. The messages will be short. One could argue that this isn’t a necessary requirement, but them both being human, they won’t want to spend four hours encoding/decoding a dissertation. Should they wish to have further secure communication, the rings could be used to establish a more secure channel elsewhere (such as meeting in a secluded place).
  43. One suggestion for ciphers: rather than using both rotating rings in the same cipher, use them for different purposes. For example, consider the common technique of having a real and a fake password. We do something similar, only we use one rotating ring as the “real” ring and the other ring as the “fake” ring. The couple chooses these ahead of time (it’s a simple secret, but it’s not meant to be secure against guessing). Normally they encrypt everything with the “real” ring, but if they are forced to divulge their secret, they tell the attacker to use the other ring. The recipient will immediately be able to tell that the message wasn’t encoded with the real ring, and can then verify that it was actually encoded with the fake ring. They then know that the message is a fake, and know what the (intentionally misleading) message is.

    One possible hole in the above is that one ring isn’t used at all, which seems suspicious. Instead, you could make a cipher which uses both rings, but switch the order that rings are used in.

  44. 5b: Coins? How about a regular 6 sided die? They’re pretty darn innocuous. Shoved in with a generic board game, cribbage set, etc… And, if you’re really hard up it’s pretty easy to make an origami cube. There’s lots of different styles.

    That gets you evenly distributed ternary-tastic digits, just do a simple mod 3:


  45. Ha ha, one of the first things that came to my mind was balanced ternary, too (@snakeon, #55). My method is slightly different; instead of tritwise addition, just add the number represented by the dots to the plaintext letter by counting forward through the alphabet (or backward, if the dots represent a negative number). This has the advantage of not requiring the lookup table of balanced ternary representations of each letter.

    Here is a detailed description of how to convert a triple of letters into a number, for those unfamiliar with balanced ternary. I will abbreviate a dot above the letter as “^”, a dot below the letter as “v”, and no dot as 0. These correspond to the balanced ternary digits +1 (up), -1 (down), and zero.

    1. Align the three letters on the rings.
    2. The first ring is the nines place. ^ = 9, v = -9, 0 = 0
    3. The second ring is the threes place. ^ = 3, v = -3, 0 = 0
    4. The third ring is the ones place. ^ = 1, v = -1, 0 = 0
    5. Sum up the values of the rings.

    For example, AAA has dots ^^^, which equals 13 (9 + 3 + 1). RRR has dots vvv, which equals -13 ((-9) + (-3) + (-1)). PPP has dots ^0v, which equals 8 (9 + 0 + (-1)).

    Thus the rings embody a kind of hash function from letter triples to numbers in the range -13 to 13.

    The cipher (when the key stream is generated by the random generator described below, I call it the Rusty cipher):

    1. For a key stream, you need a sequence of letters at least three times as long as the message.
    2. For each letter in the plaintext, take the next three letters from the key stream and line them up on the rings.
    3. Convert the dots on those three letters into a number.
    4. If the number is positive, count forward that many letters in the alphabet, starting from the plaintext letter. If the number is negative, count backward. If you reach one end of the alphabet, wrap around to the other end. If the number is zero, use the plaintext letter unchanged.

    To decipher, follow the same process, but flip the sign on the number in step 3.

    Example, using a pseudorandom key stream (generated below):

    key stream: HEN ULR HFC YMH …
    dots : 0v0 vvv 0v^ ^^v …
    numbers : -3 -13 -2 11 …
    plain text: h a n k …
    ciphertext: E N L V …

    Using the text of a book as the key stream is easy, but letter frequencies and (most applicable to this method) trigram frequencies are well known, and would bias the output of this cipher. A random key stream would be better. Of course, if you had a way to share a truly random key stream, you would do a OTP, but that is impractical, so…

    Here is a way to generate a pseudorandom key stream using only one operation that is easy to perform on the cipher rings. This kind of PRNG is called a Lagged Fibonacci Generator (LFG). LFGs are not cryptographically secure, but combined with the crypto-ring hash function, they would have rocked in the classical crypto era.

    The key can be a word or a phrase or random letters. You need at least two letters. For best results, at least one should be one of: BDFHJLPRTVXZ. This is because we are effectively adding mod 26, with A=0, B=1, etc., and those are the letters that are relatively prime to 26.

    The sequence of letters produced by the LFG is defined as S[n] = S[n-k] + S[n-k+1], where k is the key length and + is the operation of adding letters together using the crypto rings. To add X and Y, for example, line up A on ring 1 with X on ring 2, then find Y on ring 1, and see what it lines up with on ring 2 (V, so X + Y = V).

    For example, using the key DEAN:
    D+E = H
    E+A = E
    A+N = N
    N+H = U
    H+E = L
    E+N = R
    N+U = H
    U+L = F
    L+R = C
    R+H = Y
    H+F = M
    F+C = H

    Take the output starting at the first letter after the key.

    LFGs are sensitive to initial state (in this case, the key). But with a key length of just five, most periods seem to range from 30941 to 649761, which should be long enough for any message you are likely to work by hand. Here is a table showing the maximum period I found for small key lengths.

    2 | 84
    3 | 1281
    4 | 10980
    5 | 649761
    6 | 7797132

  46. RS-1 is an attempt to combine the ring with some features of Solitaire. You’ll need a deck of cards (without jokers). Ring 1 is the one that doesn’t move. Ring 2’s in the middle, and ring 3 is the far one. To turn cards into numbers, they have the order A, 2, 3, 4, 5, 6, 7, 8, 9, 10, J, Q, K. Red represents 1-13, black 14-26.

    1. Look at the letter on ring 3 across from the A on ring 1. Rotate rings 2 and 3 together so that same letter on ring 2 is across from the A on ring 1 (and some other letter on ring 3 is across from it).
    2. Convert the letter on ring 3 to a number, 1 to 26, and add 1. Deal that many cards into two piles, alternating left and right. Put the left pile on the bottom of the deck. Put the right pile below the left.
    3. Calculate a cut value. Start with 1. If the letter on ring 2 across from the A on ring 1 has a dot above, add 2; if it has a dot below, add 1. If the letter on ring 3 across from the A on ring 1 has a dot above, add 6; if it has a dot below, add 3.
    4. Perform a cut using the cut value. Count down that many cards into the deck, moving them from the top of the deck to the bottom, in order.
    5. Convert the top card of the deck to a number from 1 to 26. Advance ring 3 (but not ring 2) forward that many letters.
    6. To encrypt a character, find the plaintext on ring 1 and use the corresponding cyphertext on ring 2 (ignore spaces and punctuation). To decrypt, find the cyphertext on ring 2 and use the corresponding plaintext on ring 1.
    7. Go back to step 1.

    You can use a pre-ordered deck as discussed at

    You can also initialize using a key string. Start from an ordered deck and with all the “A”‘s aligned on the ring. Then follow these steps:

    1. Get the next character of the key. Ignore spaces and punctuation.
    2. Look at the letter on ring 3 across from the A on ring 1. Rotate rings 2 and 3 together so that same letter on ring 2 is across from the A on ring 1 (and some different letter on ring 3 is across from the A on ring 1).
    3. Convert the key character to a number, 1 to 26, and add 1. Deal that may cards into two piles, alternating left and right. Put the left pile on the bottom of the deck. Put the right pile below the left pile.
    4. Calculate a cut value. Start with 1. If the letter on ring 2 across from the A on ring 1 has a dot above, add 2; if it has a dot below, add 1. If the letter on ring 3 across from the A on ring 1 has a dot above, add 6; if it has a dot below, add 3.
    5. Perform a cut using the cut value. Count down that many cards into the deck, moving them from the top of the deck to the bottom, in order.
    6. Convert the top card of the deck to a number from 1 to 26. Advance ring 3 (but not ring 2) forward that many letters.
    7. Repeat from step 1 until you run out of characters in the key.

  47. Hi gtllama,

    I submit that the ^ov, three:two (like a smooth rumba) method is good for generating a balanced key IF the rings are spun around a lot between samples. At least 26 times while not looking.

    I just had a go with a set of 3 die and it took me 8 minutes to generate sufficiently satisfactory set of 15 digits. For me the physicality of the ring makes me want to use a mock up of the rings and real die. Yah know, to get feedback. And might I add, dumb paper is still more difficult to duplicate than digital.

    So, if you don’t have die or coins to flip… I think the ring its self can be used to generate a balanced and reasonable random key.

    I wonder how many spins the rings are rated for and if graphite or silicon based lube would be best.

  48. Cypher and Mask.

    Message can be of any length greater than zero characters. Key can be any multiple of three. Binary assignment is length of key divided by 3.
    The Plain text is split into sets of three. Remainder is fine.

    First the two perpendicular schemes of “mask and cypher”:

    1) The Cypher:
    Align rings to triplet reading left to right. First plain letter starts on left ring and cyphers to the middle ring. Second character goes middle-right, 3rd is left-right: 1st (p,c,-) 2nd (-,p,c) 3rd (p,-,c). RVI * TRS = T->X (LR to MR) , R->E (MR to RR), S->W (LR to RG).
    Once you have coded through your initial 3 characters then use the coded triplet backwards as a key for the next plain text triplet.
    BEL TBU CKL E = plaintext. XCF = key. GHT (THG is the next key for the next triplet) HAH (to HAH->) VRL (to LRV->) K

    2) The Mask:
    Align rings at triplet and begin tracing to the right and then down and back to the left, zig-zagging like reading English (or your language of choice). Use the dots to process the plain text.
    top dot = ascend plain text back through alphabet, subtract, A=Z, M=L, J=I, etc. no dot = plain letter is unchanged. bottom dot = drop plain letter down, add, A=B, M=N, J=K.
    EAT ATJ OES = plain text. PHY = mask. duu,-ud,-d-,-du = dot pattern on PHY OGX NFW makes

    And finally the binary assignment:
    When these two cyphers work in concert, layer and iterate, we get what seems to me to be an appreciable mess. CCM MMC CMM CMM, would code for a key that was 36 (3*12) characters long telling the 2nd party to use the key triples as cypher, cypher, mask, mask, mask, cypher, cypher, mask, mask, cypher, mask, mask…

    On the technical side the Mask space has only 3*6*9=162 unique starting places while Cypher triplets are a full 26^2 = 676 places large. With the addition of the binary assignment sequence a key of 9 characters + 3 binary can create a key space of (26^2)*(162)*(26^2)*(162)*(26^2)*(162) = 1.31 × 10^15

    Going from cypher text to plain text I shall leave as an remedial and academic exercise for the reader.

    I recommend full keys no less than 20 letters (15 cypher/mask and 5 binary). You could easily code the binary assignments into a base ten number. In this instance from 0 to 31. Binary assignments should be random, not based off a continuous sequence of dots like in the Mask cypher scheme.

    I designed this scheme to be easy to remember, physically execute and reverse, with a near limitless space for keys. Full strength can be accomplished with an long key. Think of 240 random letters. That’s 80 triplets. It would take you about a day to code a paragraph long letter and there would be ((26^2) * 162)^40 = 3.78 × 10^201 keys to help you hide. Unless of course there’s some subtle flaw in my design it should be pretty secure if the key is not found.

  49. Wow, what was I smoking?! Those numbers are way too big. Exciting though.
    It’s actually 3*(26^2) PLUS 3*(162) = 2514 places in a 9 character key.
    and an 80 triplet key with associated binary assignments would give you a 80*(26^2+162)= 67,040 key space. Much more reasonable sounding.

    I think it might be pretty strong against a fequency attack if the keys are picked randomly (which you can get pretty easily with a few 6 sided dice) AND if you mangle the plain text (disemvowel and misspell). Without a better maths background I’m not certain, but I think it would be difficult to pinpoint the keylength from the cypher text alone. Any mathHeads what can set me straight?

  50. Uh oh, I made another mistake. My mask cypher leaves a portion of the key in plain sight. If the offset for the second triplet is the cypher of the first triplet then it all unravels from there.
    What it should read is:

    1) The Cypher:
    Align rings to triplet reading left to right. First plain letter starts on left ring and cyphers to the middle ring. Second character goes left-right, 3rd is left-right…
    1st (p,c,-) 2nd (p,-,c) 3rd (c,p,-) 4th (-,p,c) 5th (c,-,p) 6th (-,c,p) 1->2 , 1->3 , 2->1 , 2->3 , 3->1 , 3->2. (See, it has a kind of rhythm.)
    Once you have coded through your initial 6 characters do the same to the next plain text pair of triplets. You can group the letters in three groups of two for easier error checking
    BE LT BU / CK LE = plaintext. XCF = key.
    GM GO TR / HS GZ

    And an additional bit of info on the #2 process, the Masking:
    If you’re not really into English as a basis of pattern gathering I suggest picking one of the many languages we have as a template.
    And to that end here’s some info on writing directionality:
    Like Tagalog, Aramic, Sogdian, Korean, Rongo Rongo, or a particular piece of ancient text that breaks any particular rule or tickles your fancy.
    Or you could make up something where the pattern has no basis in real language or document.

    What’s missing here is a scheme to shuffle the letters about like there is in strong computer assisted schemes. Simply leaving out the first letter would botch the whole thing, or an extra first letter. Hmmm.

    And since the time draws near, that is my submission.

  51. Can I get in under the wire? It’s still before Oct 1 in my timezone! Here’s a simple asynchronous stream cypher that I think makes good use of the design of the rings.

    At any time, think of the ring as being in some “state”, where states are indexed by three-letter strings — to put the ring in state ABC, just line up A-B-C on the three bands, and then look at the ABC line. Note that this is *different* from the state B-C-D — the difference between these states is not the relative position of the bands, but rather which row of the ring you are looking at. So there are 26^3 states the ring could be in, though by looking at the physical orientation of the bands you can only tell which class of 26 you’re in.

    First let’s define two operations that change the ring’s state:

    1) Shift. This is easy, just a simple cyclic shift: move the first letter of the state to the end.

    Example: A-B-C becomes state B-C-A.

    2) Twiddle. This is the trickier state change; it involves the dots on the various bands. Here is the basic version of twiddle:
    a. Look at band 3 (the outermost), and check whether the letter there in the current state has a dot above/below the letter. If so, change the state by looking at the row of the ring above/below the current one. (No bands have rotated, but the state changes anyway.)
    b. Look at band 2 (the middle), and check whether the letter there in the current state has a dot above/below the letter. If so, rotate band 3 by one step up/down.
    c. Look at band 1 (the innermost), and check whether the letter there in the current state has a dot above/below the letter. If so, rotate band 2 by one step up/down.

    Example: start in state A-B-C.
    a. Look at band 3, note the dot above the C, so move your eyes up one row. The state becomes Z-A-B.
    b. Look at band 2, note the dot above the A, so rotate band 3 up one step. The state becomes Z-A-C.
    c. Look at band 1, note the lack of dot around Z, so band 2 doesn’t rotate. The state stays Z-A-C.

    To make twiddle more complex, the number of rows by which you move the bands or your eyes doesn’t have to be 1 in each case — you could choose other easy-to-remember constants. The set of constants you use is part of the algorithm, to be chosen for cryptographic qualities, kind of like S-boxes (but only kind of). Let’s call them T( for Twiddle)-boxes; the version described above is for T-box (1,1,1).

    The TETS Cypher:

    Using these operations, the encryption scheme is easy to implement. You start with a shared secret 3-letter word of the day, let’s say CAT, which is the initial state of the ring. You probably don’t plan to send too many messages a day, so you can just reuse the start state.

    To encypher each letter in the message, you take the ring in whatever state it’s in, and do TETS:
    1) Twiddle! Now you have a new state.
    2) Encode! Find the plaintext letter on band 1, and write down the letter in that same row on band 3. That’s the cyphertext. You’ve also just changed your state: you’re now looking at the row with that plaintext/cyphertext pair written on it.
    3) Twiddle again!
    4) Shift!

    To decypher a message you receive, the steps are exactly the same, except that during “2) Encode!” you find the cyphertext letter on band 3 and read the corresponding plaintext off of band 1.

    The “T-boxes” for the two twiddle stages can be set (independently of each other), to something easy to remember and cryptographically more mixing than (1,1,1). If you like the method, it comes with an IOU redeemable for an analysis of T-box choice.

  52. Here is python sample code for the TETS Cypher I suggested yesterday

    from string import ascii_lowercase as alphabet
    L = len(alphabet)

    def to_alpha(num):
        return alphabet[num]

    def to_num(alpha):
        return alphabet.find(alpha)

    def Dot(char, band):
        “””Return +1/0/-1 for a dot above/no dot/dot below this char on this band.

        char is a number (not a character!) from 0 to L = len(alphabet).
        band is 0/1/2 for the left/middle/right bands on the ring.
        return 1 – ((char/(band+1)) % 3)

    def Shift(state):
        return [state[1], state[2], state[0]]

    def Twiddle(state, Tbox=(1,1,1)):
        def dot(i): return Tbox[i] * Dot(state[i],i)
        state = [(s – dot(2)) % L for s in state]
        state[2] = (state[2] + dot(1)) % L
        state[1] = (state[1] + dot(0)) % L
        return state

    def LookAt(state, band, char):
        “””State you get by looking at at the row of the ring with char on band.”””
        return [(i – state[band] + char) % L for i in state]

    def CypherChar(in_char, state, in_band, out_band):
        “””Encypher or decypher the given character.

        state is the ring state beforehand.
        char is a number (not a character!) from 0 to L = len(alphabet).
        (in_band, out_band) = (0,2) to encypher, (2,0) to decypher.

        Returns the pair (char, state) of char to emit and new state.
        state = Twiddle(state)
        state = LookAt(state, in_band, in_char)
        out_char = state[out_band]
        state = Twiddle(state)
        state = Shift(state)
        return (out_char, state)

    def EncypherChar(plainchar, state):
        return CypherChar(plainchar, state, 0, 2)

    def DecypherChar(cypherchar, state):
        return CypherChar(cypherchar, state, 2, 0)

    def Encypher(plaintext, key):
        “””Encypher the given plaintext string, using the 3-character string key.”””
        state = map(to_num, key)
        cyphertext = []
        for plain in plaintext.lower():
            if plain in alphabet:
                (cypher, state) = EncypherChar(to_num(plain), state)
        return ”.join(cyphertext)

    def Decypher(cyphertext, key):
        “””Decypher the cyphertext string, using the 3-character string key.”””
        state = map(to_num, key)
        plaintext = []
        for cypher in cyphertext.lower():
            (plain, state) = DecypherChar(to_num(cypher), state)
        return ”.join(plaintext)

    if __name__ == ‘__main__':
        key = ‘cat’
        message = ‘Hello, World!’
        print Decypher(Encypher(message, key), key)

  53. Yes, for the TETS scheme each message is encoded and decoded with a shared 3-letter key.

    There are all the usual choices for key management. They could agree on a 3-letter “word of the day” in the morning and use that for every message (or one word each, eg he sends to her with key ‘cat’ and she sends to him with key ‘dog’). They could pick a “phrase of the day” (each) and use 3-letter chunks from it for successive messages. They could preserve the ring state and decode the second-received message in a day from the state at which the first message ended.

    And so on; what’s best depends on use patterns…

  54. I’ve been fiddling with the number to letter transform, 1=A, 14=N, etc… and I think I’ve come up with a mnemonic. I’m afraid it may seem convoluted to the non visual thinkers, but I like it.

    “Each New Word”

    write out the alphabet in three groups of 3×3.



    You’ll notice that the inner most letters are “ENW”. Those corespond to the 5th ,14th , and 23rd letters. They’re 9 apart. Remember that 9 plus any number leaves you with one less that number in the ones place, or whatever arithmetic short cuts you learned as a kid.
    Use this short sequence to recall the shapes of the three squares like faces of a rubik’s cube side by side. What ever number you’re given is going to be close to one of those numbers.

    Say you roll a 22, that’s more than 14, but less than 23, that’s ONE less than 23, V is before W.
    Or a 9. That’s more than 5, less than 14. e-f-g-h-I. I’s you’re man.
    This may seem simplistic or mad, but in doing multiple random letter selections over and over and over again. I found myself inefficiently counting on my fingers. I didn’t have any pins on the map as it were.
    I tried every 6th letter. I tried the prime numbers. Each to no avail.
    I’m certain that with enough practice it will be rote and the mnemonic can be dropped.

  55. Quick question.
    Under what conditions would make a winning technique?

    And if you want to only use two die you address a bit more, 10 more.
    It’s “naught”, A, B, C… The number zero. It’ll make sense when you roll a double 6 and count “A” as 1. Regular human counting, natural not digital.

    I wonder, if you had a room full of people throwing dice, if that would work well as a random number generator. Sounds like the backdrop to a caper movie. A casino is being used to crack government codes. Someone on the inside wants out. Can they trust the black market net cafe owner?! Blockbusterlarity ensues.

    Or maybe a triple pendulum with atomic controlled actuators. Just a tiny bit from a smoke detector. How cheap could you make them?

  56. for the 36 letter alphaNumericabet you can address all the characters with two regulation 6 sided die.
    You’ll want two different colored die. One is the ones place, the other is the 6 place. Sixes are nill because we’re doing the modulus function (like I mentioned before).

    You could use this to fill a 6×6 grid too, placing the letters down one at a time where the die land.

    I’ve found it easiest to start the regular base 26 alphabet at 1=A. That leaves you with double sixes=nill, anything over 26 is just the number you rolled minus 26. You rolled a 32? That’s 32-26 = 6, “6” is your character.

    This could be taught to people using a variation of the good ol’ game Bingo. You get a 5×5 (or 3×3, I guess) card, freebie in the middle (or mark up your own and have it checked and laminated before the game starts). Every box has a A-Z,0-9 character and the dealer rolls. First person to get 5 accross wins. If it was a classroom activity you’d probably want to have the people in a circle and one by one everyone shouts out the character to be crossed off. Of course you’ll want someone to keep track as well.

  57. Construction of a regular 6×6 grid of 36 alpha numeric characters (A-Z & 0-9) from 2d6.

    Draw out your 6×6 grid.x & y axes corespond to 0-5 left-right and top to bottom.
    One die is always the 6’s place, the other is the 1’s place.
    Start with the character zero, roll. “0” goes in the square defined by that roll. Next character is “A”… and so on.

    Once your 6×6 grid is full that becomes your alphabet coordinates for generating cypher text. If your first plain letter is C, and C is at position 5,3 then your cypher letter is (5×6)+(3×1) = 31 = 26+5 = “5”

    There’s 36! grid keys. 3.719e41

    It seems to be vulnerable to something. I’m not sure what. It’s not iterative, nor is there feedback. You could solve it part way and get a partial plain text, I think.

  58. oh, and if you roll on a space you’ve already written in then, in a spiral outwards, write your new letter in the first open space.
    I think that’s okay. I think that keeps it random enough.

  59. Ok, 36 letter alphabet. In 45 minutes or so I:
    – folded a square piece of paper in half, half again, in thirds in one direction, unfold, in thirds the other way.
    – rolled 2d6 36 times for a monster key of 12 triplets
    – rolled 2d6 another bloody 36 times for the shuffled alphabet written on the other side of the sheet.
    – Rolled 2d6 6 times, (mod 2) for the binary triplet switches.
    – copied the key and alphabet to another sheet.

    Of course it could all be for naught if my scheme is worth bupkis, or the pad is compromised.

    36!*(26^2+(3*6*9))^12 (4.46e76) keys.

Comments are closed.