Clutch cryptanalysis of Wring

Clutch cryptanalysis (named for the car part, not the bird litter) is applicable to ciphers with data-dependent rotations. It is a chosen-plaintext attack which tries to find pairs of plaintexts which are rotated by the same number of bits for some number of rounds. As applied to Wring, it consists of the following steps:

  1. Pick a plaintext and either one byte or three bytes affected by the mix3 operation.
  2. Change the selected byte(s) to all possible values.
  3. Encrypt all the plaintexts, using full or reduced rounds.
  4. Find pairs of ciphertexts that match more than chance; they were probably rotated together.
  5. From the bytes that changed, try to figure out which bytes in the S-boxes have the same number of bits, or even what the bytes in the S-boxes are.

Jiggle and decay graphs

These graphs are from running a version of clutch cryptanalysis in which the reduced-round encryption function returns the number of bits that the message was rotated by in each round as well as the ciphertext. This enables me to check what happens when the total number of bits two plaintexts were rotated is the same, but the number of bits they were rotated by in some round differs. I use four keys each of three different lengths, originally chosen for a related-key attack, a Wring with linear S-boxes, and two variants of a Wring like what a weak key would produce, and encrypt random-looking 10000-byte, 8192-byte, and 7776-byte messages. These message sizes take 15 rounds [4096,8192) or 16 rounds [8192,16384), but I do only 8 rounds, by which no messages are rotated together all the way through.

Graphs by key, 10000 byte messages:

key96_0 key96_1 key96_2 key96_3
key30_0 key30_1 key30_2 key30_3
key6_0 key6_1 key6_2 key6_3
Linear Weak Weak ⊻0x69

Graphs by key, 8192 byte messages:

key96_0 key96_1 key96_2 key96_3
key30_0 key30_1 key30_2 key30_3
key6_0 key6_1 key6_2 key6_3
Linear Weak Weak ⊻0x69

Graphs by key, 7776 byte messages:

key96_0 key96_1 key96_2 key96_3
key30_0 key30_1 key30_2 key30_3
key6_0 key6_1 key6_2 key6_3
Linear Weak Weak ⊻0x69

Growth of byte difference

This is the number of different bytes at the end of n rounds of encrypting 10000-byte messages that start out differing by one byte and continue rotating together for that many rounds, averaged over the eight keys that ran for the full 2049 iterations. Starting with one different byte, there were 2.543 different bytes partway through the round, 3.484 bytes different at the end of one round, and so on. One pair kept rotating together for six rounds; I ignored it.

RoundsNumber of different bytesRatioNumber of different bytes before rotBitcount
13.8483.852.543
213.4683.58.230
340.404323.949
4105.052.659.61
5220.62.1143.03

These are the data from running key96_3 for 8192 iterations, not computing jiggle statistics but counting how many bytes differ and how many pairs remain after each round. For speed, I did not count any pair that did not rotate together for two rounds, hence the asterisk at one round.

RoundsRemainingNumber of different bytesRatio
1*3.82386555237725873.8238655523772587
2229228313.4481545254229083.5169004613832002
39324840.051486358956762.9782143180495058
42395106.710229645093952.6643263295827775
545219.22.0541610746133165