1
3-Way Cipher Attack
Team Cipher Crushers Stephen Hammack, Amruta Andurkar, and Himanshu Kale Graduate Cryptography – RIT – 2122
Table of Contents
Cipher Description ...................................................................................................................................... 2
Mu .......................................................................................................................................................... 2
Description .......................................................................................................................................... 2
Cryptanalysis ....................................................................................................................................... 2
Gamma ................................................................................................................................................... 2
Description .......................................................................................................................................... 2
Cryptanalysis ....................................................................................................................................... 4
Theta ....................................................................................................................................................... 4
Description .......................................................................................................................................... 4
Cryptanalysis ....................................................................................................................................... 5
Pi1 and Pi2 .............................................................................................................................................. 5
Description .......................................................................................................................................... 5
Cryptanalysis ....................................................................................................................................... 5
Rho .......................................................................................................................................................... 6
Key Schedule ........................................................................................................................................... 6
Description .......................................................................................................................................... 6
Cryptanalysis ....................................................................................................................................... 7
Encryption ............................................................................................................................................... 8
Decryption .............................................................................................................................................. 8
Source Code .............................................................................................................................................. 10
Attacks ...................................................................................................................................................... 16
Meet-in-the-Middle .............................................................................................................................. 16
Single Round Meet-in-the-Middle ........................................................................................................ 17
Literature Search ...................................................................................................................................... 18
Developer’s Manual .................................................................................................................................. 18
2
User’s Manual ........................................................................................................................................... 19
Lessons Learned ........................................................................................................................................ 19
Future Work .............................................................................................................................................. 19
Team Member Contributions ................................................................................................................... 19
References ................................................................................................................................................ 20
Cipher Description
3-Way is a 96-bit key, 96-bit block size, 11 round block cipher, specifically designed with 32-bit
computation in mind. Technically it can work on any key and block size that is a multiple of 12, as long
as both sizes are equal, but the suggested implementation is 96-bit.
There are several functions used in this cipher. All of them are described in detail below.
Mu
Description
Mu (μ) reverses the order of the input bits. Therefore,
Cryptanalysis
Mu is needed to invert the gamma and theta functions when decrypting. and
. It is also needed to get the inverted key for decryption.
Gamma
Description
Gamma (γ) is a non-linear, 3-bit S-box function. The function used for the S-box is:
3
Where is the input vector, is the output vector, is a position in the vector, is the length of
, and . All vector positions are modulo .
The 96-bit block is processed to produce 32 bits of output in parallel at one time. Therefore,
only three high level computations are necessary.
96-bit
32-bit 32-bit 32-bit
S-Box
a b c
S-Box
a b c
S-Box
a b c
96-bit
32-bit 32-bit 32-bit
a
b
32-bit 32-bit 32-bit
Figure 1 - Overview of the Gamma function
a b c
32-bit 32-bit 32-bit
32-bit Output
Figure 2 - Internals of the Gamma S-box
4
Cryptanalysis
Here is the table of Gamma’s S-box:
Input Bits Output Bit
000 1
001 0
010 1
011 1
100 0
101 1
110 0
111 0 Table 1 - Gamma's S-box Output
This S-box is designed to run very efficiently on a 32-bit machine, since only three sets of high
level computations are necessary to run the 96-bit input through the S-boxes. Because it is a simple
design, it is a potential weak point for attack. However, the other functions in the algorithm make
attacks more difficult.
Theta
Description
Theta (θ) is a linear substitution operation that operates on inputs that have a multiple of 12 bits.
There are two ways to describe it: either a finite field polynomial multiplication problem or an XOR
matrix multiplication. For simplicity, the matrix multiplication will be used to describe Theta.
The rows of the matrix represent 12 inputs and the columns of the matrix represent 12 outputs.
In this implementation, each of the inputs and outputs are 8 bits, since the block size is 96-bit. To
produce the outputs, XOR the inputs with a 1 within each output column.
5
Cryptanalysis
This function causes the most problems in the attacks we attempt on 3-Way. A lot of inputs are
required to produce each output (7 inputs per output) and the pattern is irregular. Trying to determine
a particular output involves a lot more input information than Gamma. This function caused the most
troubles with attacks against 3-Way.
Pi1 and Pi2
Description
These two functions diffuse the bits between certain functions. Pi1 performs a right rotation of
10 bits on the most significant 32-bit block and a left rotation of 1 bit on the least significant 32-bit block
(no operation on the middle 32-bit block). Pi2 performs a left rotation of 1 bit on the most significant
32-bit block and a right rotation of 10 bits on the least significant 32-bit block (no operation on the
middle 32-bit block). These are designed such that π1 ○ μ ○ π2 = μ
Cryptanalysis
These functions make it more difficult to trace an output bit up through the encryption function,
as the positions of most of the bits end up shifting around.
1 1 1 1 0 0 1 0 0 1 1 0
0 1 1 1 0 0 0 1 1 0 1 1
1 0 1 1 1 0 0 0 1 1 0 1
0 1 0 1 1 1 0 0 1 1 1 0
0 1 1 0 1 1 1 1 0 0 1 0
1 0 1 1 0 1 1 1 0 0 0 1
1 1 0 1 1 0 1 1 1 0 0 0
1 1 1 0 0 1 0 1 1 1 0 0
0 0 1 0 0 1 1 0 1 1 1 1
0 0 0 1 1 0 1 1 0 1 1 1
1 0 0 0 1 1 0 1 1 0 1 1
1 1 0 0 1 1 1 0 0 1 0 1
Figure 3 – Multiplication matrix used for Theta (note: image is supposed to look transposed)
6
Rho
Rho (ρ) is the round function for 3-Way. It executes the following functions in order on the
input data bits: Theta, Pi1, Gamma, Pi2. This function is called once per round.
Figure 4 - Visual representation of Rho
Key Schedule
Description
3-Way’s key schedule is very simple. Every round’s subkey is the global key XORed with a round
constant with a small hamming weight. The round constant is only 16 bits and is only XORed with the
7
first and last 16 bits of the global key. With 11 round 3-Way, the encryption round constants are the
following, with one extra round constant for the subkey used after the last round:
0B0B
1616
2C2C
5858
B0B0
7171
E2E2
D5D5
BBBB
6767
CECE
8D8D
If more than 11 rounds are used, the round constants loop back to the top. If less than 11
rounds are used, the remaining round constants are ignored.
The decryption round constants are as follows:
B1B1
7373
E6E6
DDDD
ABAB
4747
8E8E
0D0D
1A1A
3434
6868
D0D0
Note: if anything other than 11 rounds is used, the starting point for the decryption round
constants is different. The last decryption round constant must always be the 12th one.
Cryptanalysis
Due to the extremely simple nature of the key schedule, the global key can be trivially
determined from any subkey. Therefore, if any subkey is found, the cipher is broken. This can also
simplify attacks, as guesses on one subkey directly apply to another subkey, when keeping the round
constants in mind.
8
Encryption
Encryption works by XORing the data block with the current round’s subkey and running the
data block through Rho. This process is repeated for the number of rounds desired. After all of the
rounds, one final subkey is XORed with the data block and the data is passed through Theta again.
Figure 5 - Visual representation of one round encryption
Decryption
Decryption is similar to encryption, but there are several differences. The global key is passed
through Theta, then Mu to get the decryption key. This decryption key is XORed with the decryption
round constants to get the subkeys. Before starting any rounds, the data is passed through Mu. The
rounds operate the same way as encryption: XOR data with the subkey and pass through Rho. After all
the rounds, one more subkey is XORed with the data block and the data passes through Theta again,
then Mu.
9
Figure 6 - Visual representation of one round decryption
10
Source Code
#include <iostream>
#include <sstream>
#include "ThreeWay.h"
using namespace std;
/**
* Reverse the order of the bits of the dataBlock
*
* @param dataBlock The 96-bit data block to reverse
*/
void ThreeWay::muFunction(word32 *dataBlock) {
// Temporary block that will store reversed bits of dataBlock
word32 tempWord[3];
tempWord[0] = tempWord[1] = tempWord[2] = 0;
for(int i = 0; i < 32; i++) {
tempWord[0] <<= 1;
tempWord[1] <<= 1;
tempWord[2] <<= 1;
tempWord[0] |= dataBlock[2] & 1;
tempWord[1] |= dataBlock[1] & 1;
tempWord[2] |= dataBlock[0] & 1;
dataBlock[0] >>= 1;
dataBlock[1] >>= 1;
dataBlock[2] >>= 1;
}
dataBlock[0] = tempWord[0];
dataBlock[1] = tempWord[1];
dataBlock[2] = tempWord[2];
}
/**
* The Nonlinear substitution function gamma
*
* @param dataBlock Data block after performing the pi_1 operation
*/
void ThreeWay::gammaFunction(word32 *dataBlock) {
word32 tempWord[3] ;
// S-box[i] = ~input[i] xor (~input[i + k] and input[i + 2k])
// Where k = Size Of DataBlock / 3
tempWord[0] = (~dataBlock[0]) ^ (~dataBlock[1]) & dataBlock[2];
tempWord[1] = (~dataBlock[1]) ^ (~dataBlock[2]) & dataBlock[0];
tempWord[2] = (~dataBlock[2]) ^ (~dataBlock[0]) & dataBlock[1];
dataBlock[0] = tempWord[0];
dataBlock[1] = tempWord[1];
11
dataBlock[2] = tempWord[2];
}
/**
* The linear substitution function theta
*
* @param dataBlock Data block after XORing with the round subkey
*/
void ThreeWay::thetaFunction(word32 *dataBlock) {
word32 tempWord[3];
tempWord[0] = dataBlock[0] ^ (dataBlock[0] >> 16) ^ (dataBlock[1]
<< 16) ^ (dataBlock[1] >> 16)
^ (dataBlock[2] << 16) ^
(dataBlock[1] >> 24) ^ (dataBlock[2] << 8)
^ (dataBlock[2] >> 8) ^
(dataBlock[0] << 24) ^ (dataBlock[2] >> 16)
^ (dataBlock[0] << 16) ^
(dataBlock[2] >> 24) ^ (dataBlock[0] << 8);
tempWord[1] = dataBlock[1] ^ (dataBlock[1] >> 16) ^ (dataBlock[2]
<< 16) ^ (dataBlock[2] >> 16)
^ (dataBlock[0] << 16) ^
(dataBlock[2] >> 24) ^ (dataBlock[0] << 8)
^ (dataBlock[0] >> 8) ^
(dataBlock[1] << 24) ^ (dataBlock[0] >> 16)
^ (dataBlock[1] << 16) ^
(dataBlock[0] >> 24) ^ (dataBlock[1] << 8);
tempWord[2] = dataBlock[2] ^ (dataBlock[2] >> 16) ^ (dataBlock[0]
<< 16) ^ (dataBlock[0] >> 16)
^ (dataBlock[1] << 16) ^
(dataBlock[0] >> 24) ^ (dataBlock[1] << 8)
^ (dataBlock[1] >> 8) ^
(dataBlock[2] << 24) ^ (dataBlock[1] >> 16)
^ (dataBlock[2] << 16) ^
(dataBlock[1] >> 24) ^ (dataBlock[2] << 8);
dataBlock[0] = tempWord[0];
dataBlock[1] = tempWord[1];
dataBlock[2] = tempWord[2];
}
/**
* The pi_1 bit permutation function which rotates 10 bits to the
* right for the first 32-bit block and 1 bit to the left for the
* the third 32-bit block
*
* @param dataBlock Data block after performing the theta operation
*/
void ThreeWay::pi_1Function(word32 *dataBlock) {
dataBlock[0] = (dataBlock[0] >> 10) ^ (dataBlock[0] << 22);
dataBlock[2] = (dataBlock[2] << 1) ^ (dataBlock[2] >> 31);
}
/**
* The pi_2 bit permutation function which rotates 1 bit to the left
12
* for the first 32-bit block and 10 bits to the right for the third
* 32-bit block
*
* @param dataBlock Data Block after performing the gamma operation
*/
void ThreeWay::pi_2Function(word32 *dataBlock) {
dataBlock[0] = (dataBlock[0] << 1) ^ (dataBlock[0] >> 31);
dataBlock[2] = (dataBlock[2] >> 10) ^ (dataBlock[2] << 22);
}
/**
* The round function rho
*
* @param dataBlock Data block for the current round
*/
void ThreeWay::rhoFunction(word32 *dataBlock) {
thetaFunction(dataBlock);
pi_1Function(dataBlock);
gammaFunction(dataBlock);
pi_2Function(dataBlock);
}
/**
* Default constructor for class ThreeWay
*/
ThreeWay::ThreeWay() {
this->BlockSize = 12;
this->KeySize = 12;
this->numberOfRounds = 11;
}
/**
* Returns this block cipher's block size in bytes.
*
* @return Block size.
*/
int ThreeWay::blockSize() {
return this->BlockSize;
}
/**
* Returns this block cipher's key size in bytes.
*
* @return Key size.
*/
int ThreeWay::keySize() {
return this->KeySize;
}
/**
* Set the number of rounds to use in this block cipher's algorithm. If
* <TT>setRounds()</TT> is not called, the official number of rounds
stated
* in the algorithm specification is used.
*
* @param R Number of rounds.
*/
13
void ThreeWay::setRounds(int R) {
this->numberOfRounds = R;
}
/**
* Set the key for this block cipher. <TT>key</TT> must be an array of
bytes
* whose length is equal to <TT>keySize()</TT>.
*
* @param key Key.
*/
void ThreeWay::setKey(byte key[]) {
this->key[0] = ((word32) key[3]) << 24;
this->key[0] |= ((word32) key[2]) << 16;
this->key[0] |= ((word32) key[1]) << 8;
this->key[0] |= ((word32) key[0]);
this->key[1] = ((word32) key[7]) << 24;
this->key[1] |= ((word32) key[6]) << 16;
this->key[1] |= ((word32) key[5]) << 8;
this->key[1] |= ((word32) key[4]);
this->key[2] = ((word32) key[11]) << 24;
this->key[2] |= ((word32) key[10]) << 16;
this->key[2] |= ((word32) key[9]) << 8;
this->key[2] |= ((word32) key[8]);
}
/**
* The encryption function
*
* @param text The plaintext to encrypt
*/
void ThreeWay::encrypt(byte text[]) {
// Convert byte array into word32 array
word32 plainText[3];
plainText[0] = ((word32) text[3]) << 24;
plainText[0] |= ((word32) text[2]) << 16;
plainText[0] |= ((word32) text[1]) << 8;
plainText[0] |= ((word32) text[0]);
plainText[1] = ((word32) text[7]) << 24;
plainText[1] |= ((word32) text[6]) << 16;
plainText[1] |= ((word32) text[5]) << 8;
plainText[1] |= ((word32) text[4]);
plainText[2] = ((word32) text[11]) << 24;
plainText[2] |= ((word32) text[10]) << 16;
plainText[2] |= ((word32) text[9]) << 8;
plainText[2] |= ((word32) text[8]);
for(int i = 0; i < this->numberOfRounds; i++) {
// Delta operation which XORs the data block with the round
key
14
plainText[0] ^= key[0] ^ (ENCRYPTION_ROUND_CONSTANTS[i %
12] << 16);
plainText[1] ^= key[1] ;
plainText[2] ^= key[2] ^ ENCRYPTION_ROUND_CONSTANTS[i %
12];
// Round function
rhoFunction(plainText);
}
// Final delta and theta operations after the last round
plainText[0] ^= key[0] ^ (ENCRYPTION_ROUND_CONSTANTS[this-
>numberOfRounds % 12] << 16);
plainText[1] ^= key[1];
plainText[2] ^= key[2] ^ ENCRYPTION_ROUND_CONSTANTS[this-
>numberOfRounds % 12];
thetaFunction(plainText);
// Convert the word32 array back into the byte array
text[3] = (plainText[0] >> 24) & 0xFF;
text[2] = (plainText[0] >> 16) & 0xFF;
text[1] = (plainText[0] >> 8) & 0XFF;
text[0] = (plainText[0] & 0XFF);
text[7] = (plainText[1] >> 24) & 0xFF;
text[6] = (plainText[1] >> 16) & 0xFF;
text[5] = (plainText[1] >> 8) & 0XFF;
text[4] = (plainText[1] & 0XFF);
text[11] = (plainText[2] >> 24) & 0xFF;
text[10] = (plainText[2] >> 16) & 0xFF;
text[9] = (plainText[2] >> 8) & 0XFF;
text[8] = (plainText[2] & 0XFF);
}
/**
* The decryption function
*
* @param dataBlock The ciphertext to decrypt
*/
void ThreeWay::decrypt(byte text[]) {
// Convert byte array into word32 array
word32 cipherText[3];
cipherText[0] = ((word32) text[3]) << 24;
cipherText[0] |= ((word32) text[2]) << 16;
cipherText[0] |= ((word32) text[1]) << 8;
cipherText[0] |= ((word32) text[0]);
cipherText[1] = ((word32) text[7]) << 24;
cipherText[1] |= ((word32) text[6]) << 16;
cipherText[1] |= ((word32) text[5]) << 8;
cipherText[1] |= ((word32) text[4]);
cipherText[2] = ((word32) text[11]) << 24;
cipherText[2] |= ((word32) text[10]) << 16;
cipherText[2] |= ((word32) text[9]) << 8;
15
cipherText[2] |= ((word32) text[8]);
word32 inverseKey[3]; // Inverse key used for decryption
inverseKey[0] = this->key[0];
inverseKey[1] = this->key[1];
inverseKey[2] = this->key[2];
// Inverse key for decryption is obtained by performing theta and
mu operations
// on the original key
thetaFunction(inverseKey);
muFunction(inverseKey);
// Invert the order of bits in the data block before passing it
to the round functions
muFunction(cipherText);
int j;
for(int i = 0; i < this->numberOfRounds; i++) {
// Calculate which decryption round constant to use from
the decryption round
// constant array
j = (11 - (numberOfRounds % 12) + i) % 12;
// Delta operation which XORs the round subkey with the
data block
cipherText[0] ^= inverseKey[0] ^
(DECRYPTION_ROUND_CONSTANTS[j] << 16);
cipherText[1] ^= inverseKey[1];
cipherText[2] ^= inverseKey[2] ^
DECRYPTION_ROUND_CONSTANTS[j];
rhoFunction(cipherText);
}
// Final delta and theta operations after the last round
cipherText[0] ^= inverseKey[0] ^ (DECRYPTION_ROUND_CONSTANTS[11]
<< 16);
cipherText[1] ^= inverseKey[1];
cipherText[2] ^= inverseKey[2] ^ DECRYPTION_ROUND_CONSTANTS[11];
thetaFunction(cipherText);
// Reverse the data block to get the original plaintext
muFunction(cipherText);
// Convert the word32 array back into the byte array
text[3] = (cipherText[0] >> 24) & 0xFF;
text[2] = (cipherText[0] >> 16) & 0xFF;
text[1] = (cipherText[0] >> 8) & 0XFF;
text[0] = (cipherText[0] & 0XFF);
text[7] = (cipherText[1] >> 24) & 0xFF;
text[6] = (cipherText[1] >> 16) & 0xFF;
text[5] = (cipherText[1] >> 8) & 0XFF;
text[4] = (cipherText[1] & 0XFF);
16
text[11] = (cipherText[2] >> 24) & 0xFF;
text[10] = (cipherText[2] >> 16) & 0xFF;
text[9] = (cipherText[2] >> 8) & 0XFF;
text[8] = (cipherText[2] & 0XFF);
}
// Static array which contains the round constants for the encryption rounds
const word32 ThreeWay::ENCRYPTION_ROUND_CONSTANTS[12] =
{0x0b0b, 0x1616, 0x2c2c, 0x5858, 0xb0b0, 0x7171, 0xe2e2, 0xd5d5, 0xbbbb,
0x6767, 0xcece, 0x8d8d};
// Static array which contains the round constants for the decryption rounds
const word32 ThreeWay::DECRYPTION_ROUND_CONSTANTS[12] =
{0xb1b1, 0x7373, 0xe6e6, 0xdddd, 0xabab, 0x4747, 0x8e8e, 0x0d0d, 0x1a1a,
0x3434, 0x6868, 0xd0d0};
Attacks
Two different attacks were attempted on 3-Way, but both failed to be effective.
Meet-in-the-Middle
This attack involves guessing parts of the subkeys of the first and second round. Known
plaintexts and ciphertexts are used to carry out the attack. A plaintext is encrypted through the first
round and a ciphertext is decrypted through the second round. Subkeys that produce matching results
in the middle, or between the first and second rounds, give the guess on the subkey a probability of
working. More plaintext and ciphertext pairs are attempted on remaining possible subkeys until only
one possibility remains. Then the attack continues on to a different section of the subkeys.
The primary reason that this fails to work on 3-Way is because encryption and decryption work
very differently. The subkeys generated for both processes are different. Also, there is a Mu step at the
end of decryption that doesn’t exist in encryption. The ultimate result is that meeting in the middle on
valid subkeys will fail because the output values of the encryption and decryption rounds do not match.
Even if the outputs of the encryption and decryption rounds matched, there is no way to break
up the subkeys for guessing. The combination of Gamma, Pi, and Theta make it impossible for a portion
of one subkey to match up to a portion of the other subkey. More details are in the next attack.
17
Single Round Meet-in-the-Middle
This attack is similar to Meet-in-the-Middle, but instead the meet up point is in the middle of
one round of a single round 3-Way cipher.
Figure 7 - Visual representation of a single round cipher
The idea is to guess a portion of the key (which produces the two subkeys above) that is
required to produce twelve bits (each separated by eight bits) of the ciphertext. Twelve bits are
necessary here because it lines up well with how Theta is structured. Each bit position mod 8 needs to
be equal to the same thing so the inputs line up with the outputs. Otherwise, more input bits are
necessary to produce the output of Theta.
The key addition is a trival XOR, since XOR by itself is reversible.
The bits trace upwards to Pi2, which changes the positions of some of the bits being looked at.
The bits are now traced up to the outputs of Gamma. This is the meeting point of the attack,
since Gamma cannot be inverted. Unfortunately, since the bits being looked at were shuffled through
18
Pi2, none of the S-boxes that are being looked at have identical inputs (in different positions). So the
number of bits being looked at from the top becomes 36.
The bits trace upwards to Pi1, which changes the positions of some of the bits being looked at.
The bits are now traced up to the outputs of another Theta. Unfortunately, due to the shuffling
of bits, there is no group of all eight bits in the 36 bits being examined. Fortunately, all of them only
belong to six of the eight bit groups, so 72 inputs to Theta are necessary.
This makes the time complexity of this attack at least 272 + 224 (to guess the remaining key bits),
which is infeasible for this project.
Literature Search
There was very little literature available for 3-Way. The primary resources we used were [1] and
[2] for the implementation. The first resource was the original paper for 3-Way and described how it
works, but some implementation details were vague. The second resource was very useful for
implementation details.
There was no literature available for meet-in-the-middle attacks on 3-Way, which further
suggests that is likely an infeasible attack on this cipher. Resource [2] suggested that 3-Way was
vulnerable to an XSL attack, but there were no details on how it would work specifically on 3-Way. XSL
requires finding a quadratic representation of the cipher, which would take a long time to figure out.
Resource [3] also suggested that 3-Way was vulnerable to a related key attack, but no details were given
so, once again, it would take a long time to figure out.
Developer’s Manual
Compile and link ThreeWay.cpp and ThreeWayMain.cpp using any version of gcc. There are no
required libraries. Use ThreeWay.h to use ThreeWay.cpp as a library.
19
User’s Manual
ThreeWayMain.exe
Usage: <Key3> <Key2> <Key1> <PlainText3> <PlainText2> <PlainText1> <NumberOfRounds>
<Key3> <Key2> <Key1> = Three 32-bit blocks of the key
<PlainText3> <PlainText2> <PlainText1> = Three 32-bit blocks of the plain text
<NumberOfRounds> = Number of rounds of the 3-way cipher to execute
Lessons Learned
Generic attacks are not effective against every cipher. Even through 3-Way is not considered
secure, it is still not vulnerable to the meet-in-the-middle attack. The second attack was able to reduce
the time complexity from brute force, but that particular attack was in an unrealistic situation of having
only one round. In the end, ciphers that appear to be simple like 3-Way can actually be very complex.
Future Work
Literature suggests that 3-Way is vulnerable to related key attacks and XSL attacks. We could try
to implement one of those attacks, given enough time.
3-Way does not have much literary work, so we could do a deep analysis of the cipher and write
a paper with far more detail than what exists for it.
Team Member Contributions
Stephen Hammack – Attack analysis, presentations, final paper
Amruta Andurkar – Attack analysis, presentations, programming
Himanshu Kale – Programming, presentations, attack analysis
20
References
[1] J. Daemen, R. Govaerts and J. Vandewalle, "A New Approach Towards Block Cipher Design," in Fast Software Encryption, 1993.
[2] J. Savard, "Quadibloc - 3-Way," 1998. [Online]. Available: http://quadibloc.com/crypto/co040307.htm. [Accessed February 2013].
[3] J. Kelsey, B. Schneier and D. Wagner, "Related-Key Cryptanalysis of 3-WAY, Biham-DES, CAST, DES-X, NewDES, RC2, and TEA," in ICICS '97 Proceedings, 1997.