Description

The Chaocipher was invented by J.F.Byrne in 1918 and, although simple by modern cryptographic standards, does not appear to have been broken until the algorithm was finally disclosed by his family in 2010.

The algorithm is described in this paper by M.Rubin in 2010 and there is a C# implementation here.



Task

Code the algorithm in your language and to test that it works with the plaintext 'WELLDONEISBETTERTHANWELLSAID' used in the paper itself.




-- demo\rosetta\Chao_cipher.exw
with javascript_semantics
constant l_alphabet = "HXUCZVAMDSLKPEFJRIGTWOBNYQ",
         r_alphabet = "PTLNBQDEOYSFAVZKGJRIHWXUMC"

enum ENCRYPT, DECRYPT
 
function chao_cipher(string s, integer mode, bool show_steps)
    integer len = length(s)
    string out = repeat(' ',len),
           left = l_alphabet,
           right = r_alphabet
    for i=1 to len do
        if show_steps then printf(1,"%s  %s\n", {left, right}) end if
        integer index = find(s[i],iff(mode==ENCRYPT?right:left))
        out[i] = iff(mode==ENCRYPT?left:right)[index]

        if i==len then exit end if
 
        /* permute left */
        left = left[index..26]&left[1..index-1]
        left[2..14] = left[3..14]&left[2]

        /* permute right */
        right = right[index+1..26]&right[1..index]
        right[3..14] = right[4..14]&right[3]
    end for
    return out
end function
 
string plain_text = "WELLDONEISBETTERTHANWELLSAID"
printf(1,"The original plaintext is : %s\n", {plain_text})

--printf(1,"\nThe left and right alphabets after each permutation"&
--       " during encryption are :\n\n")
--string cipher_text = chao_cipher(plain_text, ENCRYPT, true)
string cipher_text = chao_cipher(plain_text, ENCRYPT, false)
printf(1,"\nThe ciphertext is : %s\n", {cipher_text})

string plain_text2 = chao_cipher(cipher_text, DECRYPT, false)
printf(1,"\nThe recovered plaintext is : %s\n", {plain_text2})
