Crypto++
|
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(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 // workaround needed on Sun Studio 12u1 Sun C++ 5.10 SunOS_i386 128229-02 2009/09/21 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 // workaround needed on Sun Studio 12u1 Sun C++ 5.10 SunOS_i386 128229-02 2009/09/21 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 unsigned int n = m_blockSize / 4; 00109 word32 *v = (word32*)outBlock; 00110 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize); 00111 00112 word32 y = v[0], z = v[n-1], e; 00113 word32 p, q = 6+52/n; 00114 word32 sum = 0; 00115 00116 while (q-- > 0) 00117 { 00118 sum += DELTA; 00119 e = sum>>2 & 3; 00120 for (p = 0; p < n-1; p++) 00121 { 00122 y = v[p+1]; 00123 z = v[p] += MX; 00124 } 00125 y = v[0]; 00126 z = v[n-1] += MX; 00127 } 00128 00129 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize); 00130 } 00131 00132 void BTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 00133 { 00134 unsigned int n = m_blockSize / 4; 00135 word32 *v = (word32*)outBlock; 00136 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize); 00137 00138 word32 y = v[0], z = v[n-1], e; 00139 word32 p, q = 6+52/n; 00140 word32 sum = q * DELTA; 00141 00142 while (sum != 0) 00143 { 00144 e = sum>>2 & 3; 00145 for (p = n-1; p > 0; p--) 00146 { 00147 z = v[p-1]; 00148 y = v[p] -= MX; 00149 } 00150 00151 z = v[n-1]; 00152 y = v[0] -= MX; 00153 sum -= DELTA; 00154 } 00155 00156 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize); 00157 } 00158 00159 NAMESPACE_END