A fiercer four-square cipher

17

Background

One-hundred and thirteen years ago, amateur cryptographer Félix Delastelle published his work on the four-square cipher, a digraphic substitution cipher that accepts two permutations of a 25-letter alphabet as keys and encodes messages consisting of those letters.

Like most pen-and-paper ciphers, the four-square cipher does not have any cryptographic value today, but at the time of its invention, it had a significant advantage over its monographic counterparts.

One-hundred and thirteen years later, Alice Delastelle decides to improve the four-square cipher by increasing the alphabet's size and the number of keys.[citation needed]

Key setup

The alphabet contains the following characters (starting with space):

 !"#$%&'()*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ

Given a pass phrase, we construct a permutation of this alphabet as follows:

  1. Keep only the first occurrence of each character.

  2. Append the unused characters from the alphabet, in their natural order.

After turning four pass phrases into four keys, we split each key into a square of side length 7 and arrange the four resulting squares so that they form one big square.

For example, if the pass phrases were

PROGRAMMING PUZZLES & CODE GOLF
POPULARITY CONTESTS & CODE BOWLING
CORRECT HORSE BATTERY STAPLE
DON'T TELL EVE!!!

the keys would be constructed and arranged like this:

PROGAMI  POULARI
N UZLES  TY CNES
&CDF!"#  &DBWG!"
$%'()*+  #$%'()*
,-./:;<  +,-./:;
=>?@BHJ  <=>?@FH
KQTVWXY  JKMQVXZ

CORET H  DON'T E
SBAYPL!  LV!"#$%
"#$%&'(  &()*+,-
)*+,-./  ./:;<=>
:;<=>?@  ?@ABCFG
DFGIJKM  HIJKMPQ
NQUVWXZ  RSUWXYZ

Encryption

Given a plaintext message such as

ALICE LOVES BOB.

we append 0 or 1 spaces to make its length even and split it into character pairs:

["AL" "IC" "E " "LO" "VE" "S " "BO" "B."]

For each character pair, we locate the the first character in the first square (reading order) and the second in the fourth.

Then, we choose the characters in the remaining squares such that the four selected characters form a rectangle whose sides are parallel to the sides of the squares.

Finally, we replace the character pair by the selected characters of the second and third square.

For our example string, this yields

["PP" "A@" "E " "YT" "ZE" "EH" "=T" "<-"]

resulting in the following ciphertext:

PPA@E YTZEEH=T<-

Task

Write a program or function that accepts four pass phrases and a plaintext, uses the above variant of the four-square cipher to encrypt it and returns the resulting ciphertext.

Details:

  • The five input strings will consist solely of characters of the mentioned alphabet.

  • The five input strings can be read in any order, as such, a single string delimited by newlines or as an array of five strings.

  • You may assume that none of the strings is empty.

  • The output must be a single string.

    If you choose to print the output to STDOUT, you may print only the characters of the ciphertext and (optionally) a trailing newline.

  • Standard rules apply.

Test cases

In all test cases, the first four strings correspond to the key squares in reading order and the last input string to the plaintext.

Input

PROGRAMMING PUZZLES & CODE GOLF
POPULARITY CONTESTS & CODE BOWLING
CORRECT HORSE BATTERY STAPLE
DON'T TELL EVE!!!
ALICE LOVES BOB.

Output

PPA@E YTZEEH=T<-

Input

 !"#$%&'()*+,-./:;<=>
 !"#$%&'()*+,-./:;<=>?@ABCDE
 !"#$%&'()*+,-./:;<=>?@ABCDEFGHIJKL
 !"#$%&'()*+,-./:;<=>?@ABCDEFGHIJKLMNOPQRS
HELLO, WORLD! 

Output

LALLR)#TROKE !

Input

,'K AB-Q=?@("W$>XM).C#<I:G!OLP*+;SZJTU%NED/&VFHRY
:,-D$C<SU=IYHFVA;! JG/M&L+WT%#.Q@(N*R")EZOBKX?'>P
L()JX,BND?Z<>P*FU%=O@&KIC+A!Y:;$SWHR.EMG'/T"QV #-
<->CI")AP Q:+U;O/F(KH&ER!MW?X'VJLZ#.$,BSGN@TD%*Y=
SPIN THE PPCG WHEEL OF BLAME!

Output

#>TE,VK+,ZQ(&<F@RA.NL@DM%NAC&>

Input

& %(,-#)$@?/=>'*"<:;!.+
=/$- ?;',@#!(&<")%.:>+*
&%-/<?.;$'#:=!( ,>"+*)@
=,<-*?#.'@/;>%!+:(& ")$
HNRA#JX$H %JAV+"GTS,

Output

GOOD LUCK, HAVE FUN.

Dennis

Posted 2015-07-31T20:05:07.990

Reputation: 196 637

Answers

4

CJam, 52 50 49 47 46 44 bytes

l2/qN/'[,32>A,s-f|2/f{~@S+2<.#_7f%_W%.m.m.=}

The input order is lines 5, 2, 3, 1, 4. Try it online.

(-1 byte thanks to @MartinBüttner, -2 bytes thanks to @Dennis)

Explanation

l2/           Read the message and split into chunks of 2
qN/           Read rest of input and split by newlines (pass phrases)
'[,32>        Generate " !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ"
A,s-          Remove digits 0123456789
f|            Setwise OR with each pass phrase to remove duplicates, giving keys
2/            Split keys into two pairs
f{ ... }      For each message chunk...
  ~             Unwrap key pairs
  @S+2<         Add a space to the message chunk then cap to length 2
  .#            Find the two chars in keys 1, 4
  _7f%          Copy indices and perform modulo 7 on both
  _W%           Copy and reverse
  .m.m          Vectorised subtraction twice
  .=            Apply both indices to keys 2, 3

For the indices, we want to swap the least significant digits, base 7. For instance, for the first example AL are indices 4 and 7 in keys 1 and 4 respectively. In base 7, this is [0 4] and [1 0]. Swapping the least significant digits gives [0 0] and [1 4], i.e. 0 and 11, and this corresponds to P and P in keys 2 and 3 respectively.

However, instead of base converting, the code does the following:

[4 7]     A: Initial indices
[4 0]     B: Indices mod 7
[0 4]     C: Reverse of B

[4 -4]    B-C
[0 11]    A-(B-C)

Sp3000

Posted 2015-07-31T20:05:07.990

Reputation: 58 729

6

Pyth, 74 71 bytes

L+%eb7*7/hb7Jcms+oxdN{d--CMr33 91`MTd.z2ssm@VeJ,ydy_dCmxLhdedC,hJ.tcz2d

Could probably be optimized a lot. I use a lot of zipping.

Takes input in the following order:

ALICE LOVES BOB.
PROGRAMMING PUZZLES & CODE GOLF
DON'T TELL EVE!!!
POPULARITY CONTESTS & CODE BOWLING
CORRECT HORSE BATTERY STAPLE

orlp

Posted 2015-07-31T20:05:07.990

Reputation: 37 067

Can I steal your input order idea? – Maltysen – 2015-08-01T04:15:52.827

@Maltysen Sure. – orlp – 2015-08-01T04:19:10.277

4

Pyth - 88 86 83 78 76 75 72 bytes

8 bytes saved thanks to @orlp.

Waaay too long, I'm pretty unhappy with this, but just posting it while I look for a better way to handle the squares.

Jm+oxdN{d-+d-CMr33 91`MTd.zsms@VtPJ,+*7hKs.DR7xV,hJeJdeK+*7@K2@K1C.tcz2d

Try it online here.

Maltysen

Posted 2015-07-31T20:05:07.990

Reputation: 25 023

You can replace c+e.z*%le.z2d2 with C.tce.z2d. Don't ask :) – orlp – 2015-08-01T00:00:18.213