//============================================================================== // ZoidfarbCipher.java //============================================================================== package tribble.crypto; // System imports import java.lang.CloneNotSupportedException; import java.lang.Exception; import java.lang.NullPointerException; import java.lang.String; import java.security.InvalidKeyException; /******************************************************************************* * Zoidfarb cryptographic symmetric block cipher. * Encrypts or decrypts a 160-bit (20-byte) data block using a 128-bit symmetric * encryption key. * *

* Note that none of these methods are synchronized. * * *

* Acknowledgments *

* This code is based on an original algorithm invented by David R. Tribble in * April 2003. * This is version "C" of the algorithm. * *

* License is granted to use this algorithm without fees or restrictions for all * private and commercial uses. * * * @version API 2, $Revision: 1.6 $ $Date: 2005/09/11 15:17:34 $ * @since 2003-04-07 * @author * David R Tribble * (david@tribble.com). * *

* Copyright ©2003-2005 by David R. Tribble, all rights reserved. *
* Permission is granted to freely use and distribute this source code * provided that the original copyright and authorship notices remain * intact. * * @see tribble.security.ZoidfarbHash */ public class ZoidfarbCipher extends tribble.crypto.SymmetricCipher { // Identification /** Revision information. */ static final String REV = "@(#)tribble/crypto/ZoidfarbCipher.java $Revision: 1.6 $ $Date: 2005/09/11 15:17:34 $\n"; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Constants /** Cipher algorithm name. */ private static final String ALGORITHM = "ZoidfarbCipher"; /** Cipher block size (20 bytes, 160 bits). */ private static final short BLOCK_SIZE = 160/8; /** Cipher key size (16 bytes, 128 bits). */ private static final short KEY_SIZE = 128/8; //---------------------------------- // Test vectors (see #main) private static final byte[] TEST_KEY1 = { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, }; private static final byte[] TEST_PLAINTEXT1 = { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, }; private static final byte[] TEST_KEY2 = { (byte) 0x44, (byte) 0x61, (byte) 0x76, (byte) 0x69, (byte) 0x64, (byte) 0x20, (byte) 0x52, (byte) 0x2E, (byte) 0x20, (byte) 0x54, (byte) 0x72, (byte) 0x69, (byte) 0x62, (byte) 0x62, (byte) 0x6C, (byte) 0x65, }; private static final byte[] TEST_PLAINTEXT2 = { (byte) 0x01, (byte) 0x23, (byte) 0x45, (byte) 0x67, (byte) 0x89, (byte) 0xAB, (byte) 0xCD, (byte) 0xEF, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0xFF, (byte) 0x01, (byte) 0x80, (byte) 0xFF, (byte) 0xA5, (byte) 0xC3, (byte) 0xB4, (byte) 0x81, }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Static methods /*************************************************************************** * Test driver. * * @param args * Command line arguments. * * @throws Exception * Thrown if an error occurs in the encryption engine. * * @since 1.1, 2003-04-06 */ public static final void main(String[] args) throws Exception { // Check args if (args.length == 0) { // Test this cipher test(new ZoidfarbCipher(), TEST_KEY1, TEST_PLAINTEXT1); test(new ZoidfarbCipher(), TEST_KEY2, TEST_PLAINTEXT2); } else { /*+++NEW, INCOMPLETE boolean opt_encrypt; byte[] key; // Check args if (args.length < 2) usage(); // Get encrypt/decrypt option if (args[0].equals("-e")) opt_encrypt = true; else if (args[0].equals("-d")) opt_encrypt = false; else usage(); // Get the encryption key from the password arg key = KeyMaker.makeKey??(args[0], KEY_SIZE); if (args.length > 1) { // Encrypt/decrypt the command line arguments ...; } else { // Encrypt/decrypt data read from standard input ...; } +++*/ } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Variables //---------------------------------- // Subkey schedule (5x32=160 bits), derived from the encryption key private int m_k0; private int m_k1; private int m_k2; private int m_k3; private int m_k4; //---------------------------------- // Input block words (5x32=160 bits) private int m_in0; private int m_in1; private int m_in2; private int m_in3; private int m_in4; //---------------------------------- // Output block words (5x32=160 bits) private int m_out0; private int m_out1; private int m_out2; private int m_out3; private int m_out4; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Constructors /*************************************************************************** * Default constructor. * * @since 1.1, 2002-05-23 */ public ZoidfarbCipher() { // Initialize super(ALGORITHM, BLOCK_SIZE); m_keyLen = KEY_SIZE; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // Methods /*************************************************************************** * Initialize this cipher. * * @param key * The symmetric (secret) key for this cipher. * * @param decrypt * If true, this indicates that this cipher is to be initialized for * decrypting, otherwise it is to be initialized for encrypting. * * @see #clear clear() * * @since 1.1, 2002-04-26 */ protected void initialize(byte[] key, boolean decrypt) throws InvalidKeyException //overrides tribble.crypto.SymmetricCipher { // Check the key if (key == null) throw new InvalidKeyException("Key missing"); if (key.length != KEY_SIZE) throw new InvalidKeyException("Invalid key length"); // Generate the cipher subkey schedule makeKey(key); } /*************************************************************************** * Clear (wipe) this cipher. * Erases all sensitive information contained within this object. * *

* Note that this cipher object can no longer be used after this method has * been called. * * @since 1.5, 2004-12-20 */ protected void clear() //overrides tribble.crypto.SymmetricCipher { // Wipe the subkey schedule m_k0 = -1; m_k1 = -1; m_k2 = -1; m_k3 = -1; m_k4 = -1; // Wipe the input block words m_in0 = 0; m_in1 = 0; m_in2 = 0; m_in3 = 0; m_in4 = 0; // Wipe the output block words m_out0 = 0; m_out1 = 0; m_out2 = 0; m_out3 = 0; m_out4 = 0; } /*************************************************************************** * Encrypt a block of plaintext. * * @param in * Array containing a single block of plaintext bytes to encrypt. * The length of the block is exactly equal to the cipher block size * (160 bits, 20 bytes). * * @param inOff * Index of the first byte of the plaintext block within array in to * encrypt. * * @param out * Array that will be filled with the encrypted ciphertext block. * The length of the block is exactly equal to the cipher block size * (160 bits, 20 bytes). * * @param outOff * Index of the first byte of array out to fill with the encrypted * ciphertext block. * * @see #blockDecrypt blockDecrypt() * @see #initialize initialize() * * @since 1.1, 2002-04-26 */ protected void blockEncrypt(/*const*/ byte[] in, int inOff, byte[] out, int outOff) //overrides tribble.crypto.SymmetricCipher { // Encrypt the input block unpackInput(in, inOff); encrypt(); packOutput(out, outOff); } /*************************************************************************** * Decrypt a block of ciphertext. * * @param in * Array containing a single block of ciphertext bytes to decrypt. * The length of the block is exactly equal to the cipher block size * (160 bits, 20 bytes). * * @param inOff * Index of the first byte of the ciphertext block within array in * to decrypt. * * @param out * Array that will be filled with the decrypted plaintext block. * The length of the block is exactly equal to the cipher block size * (160 bits, 20 bytes). * * @param outOff * Index of the first byte of array out to fill with the decrypted * plaintext block. * * @see #blockEncrypt blockEncrypt() * @see #initialize initialize() * * @since 1.1, 2002-04-26 */ protected void blockDecrypt(/*const*/ byte[] in, int inOff, byte[] out, int outOff) //overrides tribble.crypto.SymmetricCipher { // Decrypt the input block unpackInput(in, inOff); decrypt(); packOutput(out, outOff); } /*************************************************************************** * Establish the encryption subkey schedule. * *

* The 128-bit encryption key is expanded into a 160-bit subkey schedule: *

    *   +-+-+-+-+    +-+-+-+-+    +-+-+-+-+    +-+-+-+-+
    *   |a b c d|    |e f g h|    |i j k l|    |m n o p|  Key (4x32=128 bits)
    *   +-+-+-+-+    +-+-+-+-+    +-+-+-+-+    +-+-+-+-+
    *       :            :            :            :
    *     :          :          :          :          :
    * +-+-+-+-+  +-+-+-+-+  +-+-+-+-+  +-+-+-+-+  +-+-+-+-+
    * |a b c d|  |d'e f g|  |g'h i j|  |j'k l m|  |m'n o p|  Subkeys (160 bits)
    * +-+-+-+-+  +-+-+-+-+  +-+-+-+-+  +-+-+-+-+  +-+-+-+-+
    *     :          :          :          :          :
    *  +-----+    +-----+    +-----+    +-----+    +-----+
    *  | k0  |    | k1  |    | k2  |    | k3  |    | k4  |  K (5x32=160 bits)
    *  +-----+    +-----+    +-----+    +-----+    +-----+
    * 
* *

* Individual octets marked with a prime (e.g., d') are * complemented, to insure that the resulting subkeys are not all zeros or * all ones. * * @param key * Encryption/decryption key, which must be exactly 128 bits (16 bytes) long. * * @since 1.1, 2002-05-23 */ private void makeKey(byte[] key) { int ka; int kb; // Compute the subkey schedule, spreading 128 bits across 160 bits kb = (key[0] & 0xFF); kb = (kb << 8) + (key[1] & 0xFF); kb = (kb << 8) + (key[2] & 0xFF); kb = (kb << 8) + (key[3] & 0xFF); m_k0 = kb; ka = kb; kb = (key[4] & 0xFF); kb = (kb << 8) + (key[5] & 0xFF); kb = (kb << 8) + (key[6] & 0xFF); kb = (kb << 8) + (key[7] & 0xFF); m_k1 = ((ka << 32-8*1) | (kb >>> 8*1)) ^ 0xFF000000; ka = kb; kb = (key[8] & 0xFF); kb = (kb << 8) + (key[9] & 0xFF); kb = (kb << 8) + (key[10] & 0xFF); kb = (kb << 8) + (key[11] & 0xFF); m_k2 = ((ka << 32-8*2) | (kb >>> 8*2)) ^ 0xFF000000; ka = kb; kb = (key[12] & 0xFF); kb = (kb << 8) + (key[13] & 0xFF); kb = (kb << 8) + (key[14] & 0xFF); kb = (kb << 8) + (key[15] & 0xFF); m_k3 = ((ka << 32-8*3) | (kb >>> 8*3)) ^ 0xFF000000; m_k4 = kb ^ 0xFF000000; } /*************************************************************************** * Extract 20 8-bit input bytes into 5 32-bit input words. * * @param in * Array containing a single block of bytes to encrypt/decrypt. * The length of the block is exactly equal to the cipher block size * (160 bits, 20 bytes). * * @param inOff * Index of the first byte of the block within array in to * encrypt/decrypt. * * @since 1.6, 2005-09-11 */ private void unpackInput(/*const*/ byte[] in, int inOff) { // Extract 20 8-bit input bytes into 5 32-bit input words m_in0 = ((((( (in[inOff+0] & 0xFF) << 8) + (in[inOff+1] & 0xFF)) << 8) + (in[inOff+2] & 0xFF)) << 8) + (in[inOff+3] & 0xFF); inOff += 4; m_in1 = ((((( (in[inOff+0] & 0xFF) << 8) + (in[inOff+1] & 0xFF)) << 8) + (in[inOff+2] & 0xFF)) << 8) + (in[inOff+3] & 0xFF); inOff += 4; m_in2 = ((((( (in[inOff+0] & 0xFF) << 8) + (in[inOff+1] & 0xFF)) << 8) + (in[inOff+2] & 0xFF)) << 8) + (in[inOff+3] & 0xFF); inOff += 4; m_in3 = ((((( (in[inOff+0] & 0xFF) << 8) + (in[inOff+1] & 0xFF)) << 8) + (in[inOff+2] & 0xFF)) << 8) + (in[inOff+3] & 0xFF); inOff += 4; m_in4 = ((((( (in[inOff+0] & 0xFF) << 8) + (in[inOff+1] & 0xFF)) << 8) + (in[inOff+2] & 0xFF)) << 8) + (in[inOff+3] & 0xFF); } /*************************************************************************** * Extract 5 32-bit output words into 20 8-bit output bytes. * * @param out * Array that will be filled with the encrypted/decrypted block. * The length of the block is exactly equal to the cipher block size * (160 bits, 20 bytes). * * @param outOff * Index of the first byte of array out to fill with the * encrypted/decrypted output block. * * @since 1.6, 2005-09-11 */ private void packOutput(byte[] out, int outOff) /*const*/ { int o; // Extract 5 32-bit output words into 20 8-bit output bytes o = m_out0; out[outOff++] = (byte) (o >>> 8*3); out[outOff++] = (byte) (o >>> 8*2); out[outOff++] = (byte) (o >>> 8*1); out[outOff++] = (byte) (o); o = m_out1; out[outOff++] = (byte) (o >>> 8*3); out[outOff++] = (byte) (o >>> 8*2); out[outOff++] = (byte) (o >>> 8*1); out[outOff++] = (byte) (o); o = m_out2; out[outOff++] = (byte) (o >>> 8*3); out[outOff++] = (byte) (o >>> 8*2); out[outOff++] = (byte) (o >>> 8*1); out[outOff++] = (byte) (o); o = m_out3; out[outOff++] = (byte) (o >>> 8*3); out[outOff++] = (byte) (o >>> 8*2); out[outOff++] = (byte) (o >>> 8*1); out[outOff++] = (byte) (o); o = m_out4; out[outOff++] = (byte) (o >>> 8*3); out[outOff++] = (byte) (o >>> 8*2); out[outOff++] = (byte) (o >>> 8*1); out[outOff] = (byte) (o); } /*************************************************************************** * Encrypt a single 160-bit (20-byte) input block of plaintext. * *

* Algorithm * *

* The encryption algorithm is a "braiding" of five 32-bit binary words, * which comprise a total of 160 bits of the cipher block. The "braiding" * refers to the way in which the words are permuted (rearranged). Between * each permuting operation (Pi-phase), the output of the permutation * is combined with the subkeys, using exclusive-or (X-phase) and * two's-complement addition (A-phase) operations. * *

* The 128-bit encryption key is expanded into a 160-bit subkey schedule: *

    *   +-+-+-+-+    +-+-+-+-+    +-+-+-+-+    +-+-+-+-+
    *   |a b c d|    |e f g h|    |i j k l|    |m n o p|  Key (4x32=128 bits)
    *   +-+-+-+-+    +-+-+-+-+    +-+-+-+-+    +-+-+-+-+
    *       :            :            :            :
    *     :          :          :          :          :
    * +-+-+-+-+  +-+-+-+-+  +-+-+-+-+  +-+-+-+-+  +-+-+-+-+
    * |a b c d|  |d'e f g|  |g'h i j|  |j'k l m|  |m'n o p|  Subkeys (160 bits)
    * +-+-+-+-+  +-+-+-+-+  +-+-+-+-+  +-+-+-+-+  +-+-+-+-+
    *     :          :          :          :          :
    *  +-----+    +-----+    +-----+    +-----+    +-----+
    *  | k0  |    | k1  |    | k2  |    | k3  |    | k4  |  K (5x32=160 bits)
    *  +-----+    +-----+    +-----+    +-----+    +-----+
    * 
* *

* Individual octets marked with a prime (e.g., d') are * complemented, to insure that the resulting subkeys are not all zeros or * all ones. * *

* KXi = KAi = Ki. *
* Each round uses key input vectors KXi and KAi, which are both identical to * the 160-bit key vector Ki. * After each iteration, the key vector is modified: *

    *    K0i = K0i + 0xA562F620;
    *    K1i = K1i + 0x5C8ACB59;
    *    K2i = K2i + 0x30330333;
    *    K3i = K3i + 0x70F9435E;
    *    K4i = K4i + 0x05550555;
    * 
* *

* The cipher uses 10 pairs of key vectors (KX1/KA1 through KX10/KA10), each * pair being derived from the pair used in the previous round. That is, * keys KX2 and KA2 are derived from KX1 and KA1, and so forth. This simple * scrambling of the initial key vector can be viewed as infusing a total of * 3,200 bits (10 x 2 x 160 bits) of key material into the rounds. * *

* The I vector is the input cipher data (160 bits) of each phase, which is * fed into the other phases of the algorithm. The R, P1, X, S, P2, and A * phases comprise a single round, which is repeated 10 times, intermixing * the contents of the input vector with the cipher vector. The final result * of the intermixing is the output cipher vector O. * * *

* Complete sequence: *

    *   +----+----+----+----+----+
    *   | i0 | i1 | i2 | i3 | i4 |  I, Input (5x32=160 bits)
    *   +----+----+----+----+----+
    *      :    :    :    :    :
    *   +------------------------+    +----+----+----+----+----+
    *   | Round 1                |<-- | k0 | k1 | k2 | k3 | k4 |  Key KX1
    *   |                        |    +----+----+----+----+----+
    *   |                        |<-- | k0 | k1 | k2 | k3 | k4 |  Key KA1
    *   +------------------------+    +----+----+----+----+----+  (160 bits)
    *      :    :    :    :    :
    *   +------------------------+    +----+----+----+----+----+
    *   | Round 2                |<-- | k0 | k1 | k2 | k3 | k4 |  Key KX2
    *   |                        |    +----+----+----+----+----+
    *   |                        |<-- | k0 | k1 | k2 | k3 | k4 |  Key KA2
    *   +------------------------+    +----+----+----+----+----+  (160 bits)
    *      :    :    :    :    :
    *               etc.           
    *      :    :    :    :    :
    *   +------------------------+    +----+----+----+----+----+
    *   | Round 10               |<-- | k0 | k1 | k2 | k3 | k4 |  Key KX10
    *   |                        |    +----+----+----+----+----+
    *   |                        |<-- | k0 | k1 | k2 | k3 | k4 |  Key KA10
    *   +------------------------+    +----+----+----+----+----+  (160 bits)
    *      :    :    :    :    :
    *   +----+----+----+----+----+
    *   | o0 | o1 | o2 | o3 | o4 |  O, Output (5x32=160 bits)
    *   +----+----+----+----+----+
    * 
* * *

* Each round is composed of a sequence of bit rotations, word-wise * permutation, bitwise exclusive-oring with the key, and bitwise addition * with the key. Each step (phase) in the round is illustrated here: * *

    * I-phase:
    * +-+-+-+-+ +-+-+-+-+ +-+-+-+-+ +-+-+-+-+ +-+-+-+-+
    * |a b c d| |e f g h| |i j k l| |m n o p| |q r s t|  Input bytes (20)
    * +-+-+-+-+ +-+-+-+-+ +-+-+-+-+ +-+-+-+-+ +-+-+-+-+
    *     :         :         :         :         :
    *  +-----+   +-----+   +-----+   +-----+   +-----+
    *  | i0  |   | i1  |   | i2  |   | i3  |   | i4  |  I (5x32=160 bits)
    *  +-----+   +-----+   +-----+   +-----+   +-----+
    *
    * R-phase:
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  | i0  | | i1  | | i2  | | i3  | | i4  |  Ii
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *     :       :       :       :       :
    *  ROR(17) ROR(5)  ROR(25) ROR(13) ROR(29)
    *     :       :       :       :       :
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  A  | |  B  | |  C  | |  D  | |  E  |  Ri
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *
    * P1-phase:
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  A  | |  B  | |  C  | |  D  | |  E  |  Ri
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *     :       :       :       :       :
    *         :  :       :       :       :
    *           : :     :       :       :
    *          :      ::       :       :
    *         :       :   :   :       :
    *        :       :       ::      :
    *       :       :       :     : :
    *      :       :       :       :  :
    *     :       :       :       :       :
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  B  | |  C  | |  D  | |  E  | |  A  |  P1i
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *
    * X-phase:
    *      +-----+    +-----+    +-----+    +-----+    +-----+
    *      |  A  |    |  B  |    |  C  |    |  D  |    |  E  |  P1i
    *      +-----+    +-----+    +-----+    +-----+    +-----+
    *          :          :          :          :          :
    *  +-----+ :  +-----+ :  +-----+ :  +-----+ :  +-----+ :
    *  | k0  | :  | k1  | :  | k2  | :  | k3  | :  | k4  | :  Key KXi
    *  +-----+ :  +-----+ :  +-----+ :  +-----+ :  +-----+ :
    *    :     :    :     :    :     :    :     :    :     :
    *    :    NEG   :     :    :     :    :     :    :     :
    *    :     :    :     :    :     :    :     :    :     :
    *     :   :      :   :      :   :      :   :      :   :
    *      XOR        XOR        XOR        XOR        XOR
    *       :          :          :          :          :
    *    +-----+    +-----+    +-----+    +-----+    +-----+
    *    |  A  |    |  B  |    |  C  |    |  D  |    |  E  |  Xi
    *    +-----+    +-----+    +-----+    +-----+    +-----+
    *
    * S-phase:
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  A  | |  B  | |  C  | |  D  | |  E  |  Xi
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *       :      :      :      :      :
    *     +-------------------------------+
    *     |            ROL(16)            |
    *     +-------------------------------+
    *       :      :      :      :      :
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  A  | |  B  | |  C  | |  D  | |  E  |  Si
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *
    * P2-phase:
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  A  | |  B  | |  C  | |  D  | |  E  |  Si
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *     :       :       :       :       :
    *       :    :          :   :        :
    *         : :             :         :
    *          ::           :   :      :
    *         :   :       :       :   :
    *        :      :   :           ::
    *       :         :             : :
    *      :        :   :          :    :
    *     :       :       :       :       :
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  B  | |  D  | |  A  | |  E  | |  C  |  P2i
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *
    * A-phase:
    *      +-----+    +-----+    +-----+    +-----+    +-----+
    *      |  A  |    |  B  |    |  C  |    |  D  |    |  E  |  P2i
    *      +-----+    +-----+    +-----+    +-----+    +-----+
    *          :          :          :          :          :
    *  +-----+ :  +-----+ :  +-----+ :  +-----+ :  +-----+ :
    *  | k0  | :  | k1  | :  | k2  | :  | k3  | :  | k4  | :  Key KAi
    *  +-----+ :  +-----+ :  +-----+ :  +-----+ :  +-----+ :
    *    :     :    :     :    :     :    :     :    :     :
    *     :   :      :   :      :   :      :   :      :   :
    *      ADD        ADD        ADD        ADD        ADD
    *       :          :          :          :          :
    *    +-----+    +-----+    +-----+    +-----+    +-----+
    *    |  A  |    |  B  |    |  C  |    |  D  |    |  E  |  Ai
    *    +-----+    +-----+    +-----+    +-----+    +-----+
    *
    * Ai becomes Ii for the next round.
    * 
* *

* The P1 and P2 phases permute the 5 words of the cipher vector in the * following braiding pattern (which repeats every 5 rounds): * *

*

    *     0.  A B C D E
    *     1.  B C D E A   P1   round 1
    *     2.  C E B A D   P2
    *     3.  E B A D C   P1   round 2
    *     4.  B D E C A   P2
    *     5.  D E C A B   P1   round 3
    *     6.  E A D B C   P2
    *     7.  A D B C E   P1   round 4
    *     8.  D C A E B   P2
    *     9.  C A E B D   P1   round 5
    *    10.  A B C D E   P2
    * 
* * *

* Test Vectors * *

* 1. * An input block of
* {00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00} *
* with a key of
* {00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00} *
* encrypts to an output block of
* {BE 82 D5 38 FB 49 22 FF E6 31 B4 F2 45 F2 9C 1E B6 EC 5B 7A}. * *

* 2. * An input block of
* {01 23 45 67 89 AB CD EF 00 00 00 00 FF 01 80 FF A5 C3 B4 81} *
* with a key of
* {44 61 76 69 64 20 52 2E 20 54 72 69 62 62 6C 65} *
* encrypts to an output block of
* {73 5C FE 1B 25 F4 8C BA BA 1E C5 E2 35 43 2F C1 2A 8F C3 1F}. * * @see #decrypt decrypt() * @see #makeKey makeKey() * * @since 1.1, 2003-04-06 */ private void encrypt() { int i0, i1, i2, i3, i4; int k0, k1, k2, k3, k4; // Get the words of the input block i0 = m_in0; i1 = m_in1; i2 = m_in2; i3 = m_in3; i4 = m_in4; // Get the words of the key k0 = m_k0; k1 = m_k1; k2 = m_k2; k3 = m_k3; k4 = m_k4; // Encipher, using multiple braiding rounds for (int i = 10; i > 0; i--) { int o0, o1, o2, o3, o4; int t; // R-phase: Rotate the I(i) cipher words by various amounts o0 = (i0 >>> 17) | (i0 << 32-17); o1 = (i1 >>> 5) | (i1 << 32- 5); o2 = (i2 >>> 25) | (i2 << 32-25); o3 = (i3 >>> 13) | (i3 << 32-13); o4 = (i4 >>> 29) | (i4 << 32-29); // P1-phase: Permute (braid) the R(i) cipher words t = o0; o0 = o1; o1 = o2; o2 = o3; o3 = o4; o4 = t; // X-phase: Exclusive-or the P1(i) cipher vector with Key KX(i) o0 = -o0 ^ k0; o1 ^= k1; o2 ^= k2; o3 ^= k3; o4 ^= k4; // Permute the key vector for the next round k0 += 0xA562F620; k1 += 0x5C8ACB59; k2 += 0x30330333; k3 += 0x70F9435E; k4 += 0x05550555; // S-phase: Rotate the entire vector by 16 bits t = o0; o0 = (o0 << 16) | (o1 >>> 32-16); o1 = (o1 << 16) | (o2 >>> 32-16); o2 = (o2 << 16) | (o3 >>> 32-16); o3 = (o3 << 16) | (o4 >>> 32-16); o4 = (o4 << 16) | (t >>> 32-16); // P2-phase: Permute (braid) the X(i) cipher words t = o0; o0 = o1; o1 = o3; o3 = o4; o4 = o2; o2 = t; // A-phase: Add the P2(i) cipher vector to Key KA(i) i0 = o0 + k0; i1 = o1 + k1; i2 = o2 + k2; i3 = o3 + k3; i4 = o4 + k4; // The input cipher vector I(i+1) for the next round is A(i) } // Update the output cipher vector with A(n) m_out0 = i0; m_out1 = i1; m_out2 = i2; m_out3 = i3; m_out4 = i4; } /*************************************************************************** * Decrypt a single 160-bit (20-byte) input block of ciphertext. * *

* Algorithm * *

* Decrypting a previously encrypted block is done by applying inverse * operations of each of the encryption phases in reverse order using * inverted subkeys. * *

* The 128-bit encryption key is expanded into a 160-bit subkey schedule: *

    *   +-+-+-+-+    +-+-+-+-+    +-+-+-+-+    +-+-+-+-+
    *   |a b c d|    |e f g h|    |i j k l|    |m n o p|  Key (4x32=128 bits)
    *   +-+-+-+-+    +-+-+-+-+    +-+-+-+-+    +-+-+-+-+
    *       :            :            :            :
    *     :          :          :          :          :
    * +-+-+-+-+  +-+-+-+-+  +-+-+-+-+  +-+-+-+-+  +-+-+-+-+
    * |a b c d|  |d'e f g|  |g'h i j|  |j'k l m|  |m'n o p|  Subkeys (160 bits)
    * +-+-+-+-+  +-+-+-+-+  +-+-+-+-+  +-+-+-+-+  +-+-+-+-+
    *     :          :          :          :          :
    *  +-----+    +-----+    +-----+    +-----+    +-----+
    *  | k0  |    | k1  |    | k2  |    | k3  |    | k4  |  K (5x32=160 bits)
    *  +-----+    +-----+    +-----+    +-----+    +-----+
    * 
* *

* Individual octets marked with a prime (e.g., d') are * complemented, to insure that the resulting subkeys are not all zeros or * all ones. * *

* For a given encryption subkey KXi for the X (exclusive-or) phase, the * inverse subkey KXi' is equal to KXi (since exclusive-or is its own inverse * operation). * *

* For a given encryption subkey KAi for the A (addition) phase, the inverse * subkey KAi' is the additive inverse (i.e., the two's-complement or * negation) of KAi. (Adding the additive inverse of a subkey is, of course, * equivalent to subtracting the subkey.) * *

* KXi' = KXi = Ki (exclusive-or inverse).
* KAi' = -KAi = -Ki (additive inverse). * *

* Note that the decryption process applies the algorithm rounds (i.e., the * round keys) in the reverse order as encryption. * * *

* Complete sequence: *

    *   +----+----+----+----+----+
    *   | i0 | i1 | i2 | i3 | i4 |  I, Input (5x32=160 bits)
    *   +----+----+----+----+----+
    *      :    :    :    :    :
    *   +------------------------+    +----+----+----+----+----+
    *   | Round 1                |<-- | k0 | k1 | k2 | k3 | k4 |  Key KX'10
    *   |                        |    +----+----+----+----+----+
    *   |                        |<-- | k0 | k1 | k2 | k3 | k4 |  Key KA'10
    *   +------------------------+    +----+----+----+----+----+  (160 bits)
    *      :    :    :    :    :
    *   +------------------------+    +----+----+----+----+----+
    *   | Round 2                |<-- | k0 | k1 | k2 | k3 | k4 |  Key KX'9
    *   |                        |    +----+----+----+----+----+
    *   |                        |<-- | k0 | k1 | k2 | k3 | k4 |  Key KA'9
    *   +------------------------+    +----+----+----+----+----+  (160 bits)
    *      :    :    :    :    :
    *               etc.           
    *      :    :    :    :    :
    *   +------------------------+    +----+----+----+----+----+
    *   | Round 10               |<-- | k0 | k1 | k2 | k3 | k4 |  Key KX'1
    *   |                        |    +----+----+----+----+----+
    *   |                        |<-- | k0 | k1 | k2 | k3 | k4 |  Key KA'1
    *   +------------------------+    +----+----+----+----+----+  (160 bits)
    *      :    :    :    :    :
    *   +----+----+----+----+----+
    *   | o0 | o1 | o2 | o3 | o4 |  O, Output (5x32=160 bits)
    *   +----+----+----+----+----+
    * 
* * *

* Each round: *

    * I-phase:
    * +-+-+-+-+ +-+-+-+-+ +-+-+-+-+ +-+-+-+-+ +-+-+-+-+
    * |a b c d| |e f g h| |i j k l| |m n o p| |q r s t|  Input bytes (20)
    * +-+-+-+-+ +-+-+-+-+ +-+-+-+-+ +-+-+-+-+ +-+-+-+-+
    *     :         :         :         :         :
    *  +-----+   +-----+   +-----+   +-----+   +-----+
    *  | i0  |   | i1  |   | i2  |   | i3  |   | i4  |  I (5x32=160 bits)
    *  +-----+   +-----+   +-----+   +-----+   +-----+
    *
    * A'-phase:
    *      +-----+    +-----+    +-----+    +-----+    +-----+
    *      | i0  |    | i1  |    | i2  |    | i3  |    | i4  |  Ii
    *      +-----+    +-----+    +-----+    +-----+    +-----+
    *          :          :          :          :          :
    *  +-----+ :  +-----+ :  +-----+ :  +-----+ :  +-----+ :
    *  | k0' | :  | k1' | :  | k2' | :  | k3' | :  | k4' | :  Key KAi'
    *  +-----+ :  +-----+ :  +-----+ :  +-----+ :  +-----+ :
    *    :     :    :     :    :     :    :     :    :     :
    *     :   :      :   :      :   :      :   :      :   :
    *      ADD        ADD        ADD        ADD        ADD
    *       :          :          :          :          :
    *    +-----+    +-----+    +-----+    +-----+    +-----+
    *    |  A  |    |  B  |    |  C  |    |  D  |    |  E  |  Ai
    *    +-----+    +-----+    +-----+    +-----+    +-----+
    *
    * P2'-phase:
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  A  | |  B  | |  C  | |  D  | |  E  |  Ai
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *     :       :       :       :       :
    *      :        :   :          :    :
    *       :         :             : :
    *        :      :   :           ::
    *         :   :       :       :   :
    *          ::           :   :      :
    *         : :             :         :
    *       :    :          :   :        :
    *     :       :       :       :       :
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  C  | |  A  | |  E  | |  B  | |  D  |  P2i
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *
    * S'-phase:
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  A  | |  B  | |  C  | |  D  | |  E  |  P2i
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *       :      :      :      :      :
    *     +-------------------------------+
    *     |            ROR(16)            |
    *     +-------------------------------+
    *       :      :      :      :      :
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  A  | |  B  | |  C  | |  D  | |  E  |  Si
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *
    * X'-phase:
    *      +-----+    +-----+    +-----+    +-----+    +-----+
    *      |  A  |    |  B  |    |  C  |    |  D  |    |  E  |  Si
    *      +-----+    +-----+    +-----+    +-----+    +-----+
    *          :          :          :          :          :
    *  +-----+ :  +-----+ :  +-----+ :  +-----+ :  +-----+ :
    *  | k'0 | :  | k'1 | :  | k'2 | :  | k'3 | :  | k'4 | :  Key KX'i
    *  +-----+ :  +-----+ :  +-----+ :  +-----+ :  +-----+ :
    *    :     :    :     :    :     :    :     :    :     :
    *     :   :      :   :      :   :      :   :      :   :
    *      XOR        XOR        XOR        XOR        XOR
    *       :          :          :          :          :
    *      NEG         :          :          :          :
    *       :          :          :          :          :
    *    +-----+    +-----+    +-----+    +-----+    +-----+
    *    |  A  |    |  B  |    |  C  |    |  D  |    |  E  |  Xi
    *    +-----+    +-----+    +-----+    +-----+    +-----+
    *
    * P1'-phase:
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  A  | |  B  | |  C  | |  D  | |  E  |  Xi
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *     :       :       :       :       :
    *      :       :       :       :  :
    *       :       :       :     : :
    *        :       :       ::      :
    *         :       :   :   :       :
    *          :      ::       :       :
    *           : :     :       :       :
    *         :  :       :       :       :
    *     :       :       :       :       :
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  E  | |  A  | |  B  | |  C  | |  D  |  P1i
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *
    * R'-phase:
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  A  | |  B  | |  C  | |  D  | |  E  |  P1i
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *     :       :       :       :       :
    *  ROL(17) ROL(5)  ROL(25) ROL(13) ROL(29)
    *     :       :       :       :       :
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *  |  A  | |  B  | |  C  | |  D  | |  E  |  Ri
    *  +-----+ +-----+ +-----+ +-----+ +-----+
    *
    * Ri becomes Ii for the next round.
    * 
* * @see #encrypt encrypt() * @see #makeKey makeKey() * * @since 1.1, 2003-04-06 */ private void decrypt() { int i0, i1, i2, i3, i4; int k0, k1, k2, k3, k4; // Get the words of the input block i0 = m_in0; i1 = m_in1; i2 = m_in2; i3 = m_in3; i4 = m_in4; // Initialize the words of the key k0 = m_k0 + 10*0xA562F620; // + 0x75DD9D40 k1 = m_k1 + 10*0x5C8ACB59; // + 0x9D6BF17A k2 = m_k2 + 10*0x30330333; // + 0xE1FE1FFE k3 = m_k3 + 10*0x70F9435E; // + 0x69BCA1AC k4 = m_k4 + 10*0x05550555; // + 0x35523552 // Encipher, using multiple braiding rounds for (int i = 10; i > 0; i--) { int o0, o1, o2, o3, o4; int t; // A-phase: Add (subtract) the P2(i) cipher vector to Key KA'(i) o0 = i0 - k0; o1 = i1 - k1; o2 = i2 - k2; o3 = i3 - k3; o4 = i4 - k4; // P2'-phase: Permute (braid) the X(i) cipher words t = o0; o0 = o2; o2 = o4; o4 = o3; o3 = o1; o1 = t; // S-phase: Rotate the entire vector by 16 bits t = o4; o4 = (o4 >>> 16) | (o3 << 32-16); o3 = (o3 >>> 16) | (o2 << 32-16); o2 = (o2 >>> 16) | (o1 << 32-16); o1 = (o1 >>> 16) | (o0 << 32-16); o0 = (o0 >>> 16) | (t << 32-16); // Permute the key vector for the next round k0 -= 0xA562F620; k1 -= 0x5C8ACB59; k2 -= 0x30330333; k3 -= 0x70F9435E; k4 -= 0x05550555; // X-phase: Exclusive-or the P1(i) cipher vector with Key KX'(i) o0 = -(o0 ^ k0); o1 ^= k1; o2 ^= k2; o3 ^= k3; o4 ^= k4; // P1'-phase: Permute (braid) the R(i) cipher words t = o0; o0 = o4; o4 = o3; o3 = o2; o2 = o1; o1 = t; // R'-phase: Rotate the I(i) cipher words by various amounts i0 = (o0 >>> 32-17) | (o0 << 17); i1 = (o1 >>> 32- 5) | (o1 << 5); i2 = (o2 >>> 32-25) | (o2 << 25); i3 = (o3 >>> 32-13) | (o3 << 13); i4 = (o4 >>> 32-29) | (o4 << 29); // The input cipher vector I(i+1) for the next round is A(i) } // Update the output cipher vector with A(n) m_out0 = i0; m_out1 = i1; m_out2 = i2; m_out3 = i3; m_out4 = i4; } } // End ZoidfarbCipher.java