Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

3way.cpp

00001 // 3way.cpp - modifed by Wei Dai from Joan Daemen's 3way.c
00002 // The original code and all modifications are in the public domain.
00003 
00004 #include "pch.h"
00005 #include "3way.h"
00006 
00007 NAMESPACE_BEGIN(CryptoPP)
00008 
00009 static const word32 START_E = 0x0b0b; // round constant of first encryption round
00010 static const word32 START_D = 0xb1b1; // round constant of first decryption round
00011 
00012 static inline word32 reverseBits(word32 a)
00013 {
00014         a = ((a & 0xAAAAAAAA) >> 1) | ((a & 0x55555555) << 1);
00015         a = ((a & 0xCCCCCCCC) >> 2) | ((a & 0x33333333) << 2);
00016         return ((a & 0xF0F0F0F0) >> 4) | ((a & 0x0F0F0F0F) << 4);
00017 }
00018 
00019 #define mu(a0, a1, a2)                          \
00020 {                                                                       \
00021         a1 = reverseBits(a1);                   \
00022         word32 t = reverseBits(a0);             \
00023         a0 = reverseBits(a2);                   \
00024         a2 = t;                                                 \
00025 }
00026 
00027 #define pi_gamma_pi(a0, a1, a2)         \
00028 {                                                                       \
00029         word32 b0, b2;                                  \
00030         b2 = rotlFixed(a2, 1U);                         \
00031         b0 = rotlFixed(a0, 22U);                                \
00032         a0 = rotlFixed(b0 ^ (a1|(~b2)), 1U);    \
00033         a2 = rotlFixed(b2 ^ (b0|(~a1)), 22U);\
00034         a1 ^= (b2|(~b0));                               \
00035 }
00036 
00037 // thanks to Paulo Barreto for this optimized theta()
00038 #define theta(a0, a1, a2)                                                                       \
00039 {                                                                                                                       \
00040         word32 b0, b1, c;                                                                               \
00041         c = a0 ^ a1 ^ a2;                                                                               \
00042         c = rotlFixed(c, 16U) ^ rotlFixed(c, 8U);                               \
00043         b0 = (a0 << 24) ^ (a2 >> 8) ^ (a1 << 8) ^ (a0 >> 24);   \
00044         b1 = (a1 << 24) ^ (a0 >> 8) ^ (a2 << 8) ^ (a1 >> 24);   \
00045         a0 ^= c ^ b0;                                                                                   \
00046         a1 ^= c ^ b1;                                                                                   \
00047         a2 ^= c ^ (b0 >> 16) ^ (b1 << 16);                                              \
00048 }                                                                                                                       
00049 
00050 #define rho(a0, a1, a2)                 \
00051 {                                                               \
00052         theta(a0, a1, a2);                      \
00053         pi_gamma_pi(a0, a1, a2);        \
00054 }                                                                                       
00055 
00056 static void GenerateRoundConstants(word32 strt, word32 *rtab, unsigned int rounds)
00057 {
00058         for(unsigned i=0; i<=rounds; i++)
00059         {
00060                 rtab[i] = strt;
00061                 strt <<= 1;
00062                 if (strt&0x10000) strt ^= 0x11011;
00063         }
00064 }
00065 
00066 ThreeWayEncryption::ThreeWayEncryption(const byte *uk, unsigned int keylength, unsigned int rounds)
00067         : rounds(rounds), rc(rounds+1)
00068 {
00069         assert(keylength == 0 || keylength == KEYLENGTH);
00070         GenerateRoundConstants(START_E, rc, rounds);
00071         for (int i=0; i<3; i++)
00072                 k[i] = (word32)uk[4*i+3] | ((word32)uk[4*i+2]<<8) | ((word32)uk[4*i+1]<<16) | ((word32)uk[4*i]<<24);
00073 }
00074 
00075 ThreeWayEncryption::~ThreeWayEncryption()
00076 {
00077         k[0]=k[1]=k[2]=0;
00078 }
00079 
00080 void ThreeWayEncryption::ProcessBlock(const byte *in, byte * out) const
00081 {
00082         word32 a0, a1, a2;
00083 
00084 #ifdef IS_LITTLE_ENDIAN
00085         a0 = byteReverse(*(word32 *)in);
00086         a1 = byteReverse(*(word32 *)(in+4));
00087         a2 = byteReverse(*(word32 *)(in+8));
00088 #else
00089         a0 = *(word32 *)in;
00090         a1 = *(word32 *)(in+4);
00091         a2 = *(word32 *)(in+8);
00092 #endif
00093 
00094         for(unsigned i=0; i<rounds; i++)
00095         {
00096                 a0 ^= k[0] ^ (rc[i]<<16);
00097                 a1 ^= k[1];
00098                 a2 ^= k[2] ^ rc[i];
00099                 rho(a0, a1, a2);
00100         }
00101         a0 ^= k[0] ^ (rc[rounds]<<16);
00102         a1 ^= k[1];
00103         a2 ^= k[2] ^ rc[rounds];
00104         theta(a0, a1, a2);
00105 
00106 #ifdef IS_LITTLE_ENDIAN
00107         *(word32 *)out = byteReverse(a0);
00108         *(word32 *)(out+4) = byteReverse(a1);
00109         *(word32 *)(out+8) = byteReverse(a2);
00110 #else
00111         *(word32 *)out = a0;
00112         *(word32 *)(out+4) = a1;
00113         *(word32 *)(out+8) = a2;
00114 #endif
00115 }
00116 
00117 ThreeWayDecryption::ThreeWayDecryption(const byte *uk, unsigned int keylength, unsigned int rounds)
00118         : rounds(rounds), rc(rounds+1)
00119 {
00120         assert(keylength == 0 || keylength == KEYLENGTH);
00121         GenerateRoundConstants(START_D, rc, rounds);
00122         for (int i=0; i<3; i++)
00123                 k[i] = (word32)uk[4*i+3] | ((word32)uk[4*i+2]<<8) | ((word32)uk[4*i+1]<<16) | ((word32)uk[4*i]<<24);
00124         theta(k[0], k[1], k[2]);
00125         mu(k[0], k[1], k[2]);
00126         k[0] = byteReverse(k[0]);
00127         k[1] = byteReverse(k[1]);
00128         k[2] = byteReverse(k[2]);
00129 }
00130 
00131 ThreeWayDecryption::~ThreeWayDecryption()
00132 {
00133         k[0]=k[1]=k[2]=0;
00134 }
00135 
00136 void ThreeWayDecryption::ProcessBlock(const byte *in, byte * out) const
00137 {
00138         word32 a0, a1, a2;
00139 
00140 #ifndef IS_LITTLE_ENDIAN
00141         a0 = byteReverse(*(word32 *)in);
00142         a1 = byteReverse(*(word32 *)(in+4));
00143         a2 = byteReverse(*(word32 *)(in+8));
00144 #else
00145         a0 = *(word32 *)in;
00146         a1 = *(word32 *)(in+4);
00147         a2 = *(word32 *)(in+8);
00148 #endif
00149 
00150         mu(a0, a1, a2);
00151         for(unsigned i=0; i<rounds; i++)
00152         {
00153                 a0 ^= k[0] ^ (rc[i]<<16);
00154                 a1 ^= k[1];
00155                 a2 ^= k[2] ^ rc[i];
00156                 rho(a0, a1, a2);
00157         }
00158         a0 ^= k[0] ^ (rc[rounds]<<16);
00159         a1 ^= k[1];
00160         a2 ^= k[2] ^ rc[rounds];
00161         theta(a0, a1, a2);
00162         mu(a0, a1, a2);
00163 
00164 #ifndef IS_LITTLE_ENDIAN
00165         *(word32 *)out = byteReverse(a0);
00166         *(word32 *)(out+4) = byteReverse(a1);
00167         *(word32 *)(out+8) = byteReverse(a2);
00168 #else
00169         *(word32 *)out = a0;
00170         *(word32 *)(out+4) = a1;
00171         *(word32 *)(out+8) = a2;
00172 #endif
00173 }
00174 
00175 NAMESPACE_END

Generated at Mon Jan 15 01:16:28 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000