Two-Way Cipher

September 20, 2016

This sounds hard but is actually easy to arrange. We use a one-time pad (that is, a key that is as long as the ciphertext) and an encryption operation that adds and subtracts letters, wrapping around the end of the alphabet.

Consider encryption and decryption as mathematical operations. With P as the plaintext, K as the key, and C as the ciphertext, encryption is P + K = C, where the plus sign performs the encryption operation, and decryption is C – K = P, where the minus sign performs the decryption operation. By rearranging terms, we can easily find the key that corresponds to a given ciphertext and plaintext: C – P = K. And we can find the two different keys that correspond to two different plaintexts as C – P1 = K1 and C – P2 = K2. We begin with the plus and minus operations, which assume that the strings contain only upper-case letters:

(define (plus str1 str2)
    (map (lambda (x y)
             (+ (modulo
                  (+ (- (char->integer x) 65)
                     (- (char->integer y) 65))
         (string->list str1) (string->list str2))))
(define (minus str1 str2)
    (map (lambda (x y)
             (+ (modulo
                  (- (- (char->integer x) 65)
                     (- (char->integer y) 65))
         (string->list str1) (string->list str2))))

The two plaintext strings are PROGRAMMING and PRAXIS. We have to pad the shorter of the two so both are the same length:

(define plaintext1 "PROGRAMMING")
(define plaintext2 "PRAXISXXXXX")

Then we choose a random ciphertext (well, not too random) as long as the longer of the two plaintexts:

(define ciphertext "ABCDEFGHIJK")

Finally, we compute the two keys:

(define key1 (minus ciphertext plaintext1))
(define key2 (minus ciphertext plaintext2))
> key1
> key2

The decryption works in the normal way:

> (minus ciphertext key1)
> (minus ciphertext key2)

You can run the program at

Pages: 1 2

2 Responses to “Two-Way Cipher”

  1. Graham said

    Just leaving a comment would be poor form; here’s my Haskell solution.

    module Main where
    import Data.Char (chr, ord)
    sub x y = chr $ 65 + (x' - y') `mod` 26
        x' = ord x - 65
        y' = ord y - 65
    crypt = zipWith sub
    cipher = "ABCDEFGHIJK"
    key1 = crypt cipher "PROGRAMMING"
    key2 = crypt cipher "PRAXISXXXXX"
    main = do
      print cipher
      mapM_ (print . crypt cipher) [key1, key2]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: