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 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