Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members

# tea.cpp

    00001 // tea.cpp - modified by Wei Dai from code in the original paper
    00002
    00003 #include "pch.h"
    00004 #include "tea.h"
    00005 #include "misc.h"
    00006
    00007 NAMESPACE_BEGIN(CryptoPP)
    00008
    00009 static const word32 DELTA = 0x9e3779b9;
    00010 typedef BlockGetAndPut<word32, BigEndian> Block;
    00011
    00012 void TEA::Base::UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length, unsigned int rounds)
    00013 {
    00014         AssertValidKeyLength(length);
    00015
    00016         GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH);
    00017         m_limit = rounds * DELTA;
    00018 }
    00019
    00020 void TEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
    00021 {
    00022         word32 y, z;
    00023         Block::Get(inBlock)(y)(z);
    00024
    00025         word32 sum = 0;
    00026         while (sum != m_limit)
    00027         {
    00028                 sum += DELTA;
    00029                 y += (z << 4) + m_k[0] ^ z + sum ^ (z >> 5) + m_k[1];
    00030                 z += (y << 4) + m_k[2] ^ y + sum ^ (y >> 5) + m_k[3];
    00031         }
    00032
    00033         Block::Put(xorBlock, outBlock)(y)(z);
    00034 }
    00035
    00036 void TEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
    00037 {
    00038         word32 y, z;
    00039         Block::Get(inBlock)(y)(z);
    00040
    00041         word32 sum = m_limit;
    00042         while (sum != 0)
    00043         {
    00044                 z -= (y << 4) + m_k[2] ^ y + sum ^ (y >> 5) + m_k[3];
    00045                 y -= (z << 4) + m_k[0] ^ z + sum ^ (z >> 5) + m_k[1];
    00046                 sum -= DELTA;
    00047         }
    00048
    00049         Block::Put(xorBlock, outBlock)(y)(z);
    00050 }
    00051
    00052 void XTEA::Base::UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length, unsigned int rounds)
    00053 {
    00054         AssertValidKeyLength(length);
    00055
    00056         GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH);
    00057         m_limit = rounds * DELTA;
    00058 }
    00059
    00060 void XTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
    00061 {
    00062         word32 y, z;
    00063         Block::Get(inBlock)(y)(z);
    00064
    00065         word32 sum = 0;
    00066         while (sum != m_limit)
    00067         {
    00068                 y += (z<<4 ^ z>>5) + z ^ sum + m_k[sum&3];
    00069                 sum += DELTA;
    00070                 z += (y<<4 ^ y>>5) + y ^ sum + m_k[sum>>11 & 3];
    00071         }
    00072
    00073         Block::Put(xorBlock, outBlock)(y)(z);
    00074 }
    00075
    00076 void XTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
    00077 {
    00078         word32 y, z;
    00079         Block::Get(inBlock)(y)(z);
    00080
    00081         word32 sum = m_limit;
    00082         while (sum != 0)
    00083         {
    00084                 z -= (y<<4 ^ y>>5) + y ^ sum + m_k[sum>>11 & 3];
    00085                 sum -= DELTA;
    00086                 y -= (z<<4 ^ z>>5) + z ^ sum + m_k[sum&3];
    00087         }
    00088
    00089         Block::Put(xorBlock, outBlock)(y)(z);
    00090 }
    00091
    00092 #define MX (z>>5^y<<2)+(y>>3^z<<4)^(sum^y)+(m_k[p&3^e]^z)
    00093
    00094 void BTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
    00095 {
    00096         unsigned int n = m_blockSize / 4;
    00097         word32 *v = (word32*)outBlock;
    00098         ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize);
    00099
    00100         word32 y = v[0], z = v[n-1], e;
    00101         word32 p, q = 6+52/n;
    00102         word32 sum = 0;
    00103
    00104         while (q-- > 0)
    00105         {
    00106                 sum += DELTA;
    00107                 e = sum>>2 & 3;
    00108                 for (p = 0; p < n-1; p++)
    00109                 {
    00110                         y = v[p+1];
    00111                         z = v[p] += MX;
    00112                 }
    00113                 y = v[0];
    00114                 z = v[n-1] += MX;
    00115         }
    00116
    00117         ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
    00118 }
    00119
    00120 void BTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
    00121 {
    00122         unsigned int n = m_blockSize / 4;
    00123         word32 *v = (word32*)outBlock;
    00124         ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize);
    00125
    00126         word32 y = v[0], z = v[n-1], e;
    00127         word32 p, q = 6+52/n;
    00128         word32 sum = q * DELTA;
    00129
    00130         while (sum != 0)
    00131         {
    00132                 e = sum>>2 & 3;
    00133                 for (p = n-1; p > 0; p--)
    00134                 {
    00135                         z = v[p-1];
    00136                         y = v[p] -= MX;
    00137                 }
    00138
    00139                 z = v[n-1];
    00140                 y = v[0] -= MX;
    00141                 sum -= DELTA;
    00142         }
    00143
    00144         ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
    00145 }
    00146
    00147 NAMESPACE_END