00001
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(const byte *userKey, unsigned int length, const NameValuePairs ¶ms)
00013 {
00014 AssertValidKeyLength(length);
00015
00016 GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH);
00017 m_limit = GetRoundsAndThrowIfInvalid(params, this) * 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(const byte *userKey, unsigned int length, const NameValuePairs ¶ms)
00053 {
00054 AssertValidKeyLength(length);
00055
00056 GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH);
00057 m_limit = GetRoundsAndThrowIfInvalid(params, this) * 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 #ifdef __SUNPRO_CC
00066
00067 size_t sum = 0;
00068 while ((sum&0xffffffff) != m_limit)
00069 #else
00070 word32 sum = 0;
00071 while (sum != m_limit)
00072 #endif
00073 {
00074 y += ((z<<4 ^ z>>5) + z) ^ (sum + m_k[sum&3]);
00075 sum += DELTA;
00076 z += ((y<<4 ^ y>>5) + y) ^ (sum + m_k[sum>>11 & 3]);
00077 }
00078
00079 Block::Put(xorBlock, outBlock)(y)(z);
00080 }
00081
00082 void XTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00083 {
00084 word32 y, z;
00085 Block::Get(inBlock)(y)(z);
00086
00087 #ifdef __SUNPRO_CC
00088
00089 size_t sum = m_limit;
00090 while ((sum&0xffffffff) != 0)
00091 #else
00092 word32 sum = m_limit;
00093 while (sum != 0)
00094 #endif
00095 {
00096 z -= ((y<<4 ^ y>>5) + y) ^ (sum + m_k[sum>>11 & 3]);
00097 sum -= DELTA;
00098 y -= ((z<<4 ^ z>>5) + z) ^ (sum + m_k[sum&3]);
00099 }
00100
00101 Block::Put(xorBlock, outBlock)(y)(z);
00102 }
00103
00104 #define MX ((z>>5^y<<2)+(y>>3^z<<4))^((sum^y)+(m_k[(p&3)^e]^z))
00105
00106 void BTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00107 {
00108 CRYPTOPP_UNUSED(xorBlock);
00109 unsigned int n = m_blockSize / 4;
00110 word32 *v = (word32*)outBlock;
00111 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize);
00112
00113 word32 y = v[0], z = v[n-1], e;
00114 word32 p, q = 6+52/n;
00115 word32 sum = 0;
00116
00117 while (q-- > 0)
00118 {
00119 sum += DELTA;
00120 e = sum>>2 & 3;
00121 for (p = 0; p < n-1; p++)
00122 {
00123 y = v[p+1];
00124 z = v[p] += MX;
00125 }
00126 y = v[0];
00127 z = v[n-1] += MX;
00128 }
00129
00130 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
00131 }
00132
00133 void BTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00134 {
00135 CRYPTOPP_UNUSED(xorBlock);
00136 unsigned int n = m_blockSize / 4;
00137 word32 *v = (word32*)outBlock;
00138 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize);
00139
00140 word32 y = v[0], z = v[n-1], e;
00141 word32 p, q = 6+52/n;
00142 word32 sum = q * DELTA;
00143
00144 while (sum != 0)
00145 {
00146 e = sum>>2 & 3;
00147 for (p = n-1; p > 0; p--)
00148 {
00149 z = v[p-1];
00150 y = v[p] -= MX;
00151 }
00152
00153 z = v[n-1];
00154 y = v[0] -= MX;
00155 sum -= DELTA;
00156 }
00157
00158 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
00159 }
00160
00161 NAMESPACE_END