summaryrefslogtreecommitdiff
path: root/tea.cpp
diff options
context:
space:
mode:
authorweidai <weidai11@users.noreply.github.com>2003-07-30 00:28:54 +0000
committerweidai <weidai11@users.noreply.github.com>2003-07-30 00:28:54 +0000
commit4bf1528bb04d54cb3008a8a6169a14de87f43bc8 (patch)
treec85dbf46190ebeec51e7406e9e06fa79ea7dbc00 /tea.cpp
parent9c5c4769a9c7a16aecc6cc7dd297bfe243dd022f (diff)
downloadcryptopp-git-4bf1528bb04d54cb3008a8a6169a14de87f43bc8.tar.gz
add XTEA and BTEA
Diffstat (limited to 'tea.cpp')
-rw-r--r--tea.cpp121
1 files changed, 107 insertions, 14 deletions
diff --git a/tea.cpp b/tea.cpp
index 3b5d181c..a9710535 100644
--- a/tea.cpp
+++ b/tea.cpp
@@ -6,49 +6,142 @@
NAMESPACE_BEGIN(CryptoPP)
-const word32 TEA::Base::DELTA = 0x9e3779b9;
+static const word32 DELTA = 0x9e3779b9;
+typedef BlockGetAndPut<word32, BigEndian> Block;
-void TEA::Base::UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length)
+void TEA::Base::UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length, unsigned int rounds)
{
AssertValidKeyLength(length);
- GetUserKey(BIG_ENDIAN_ORDER, k.begin(), 4, userKey, KEYLENGTH);
+ GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH);
+ m_limit = rounds * DELTA;
}
-typedef BlockGetAndPut<word32, BigEndian> Block;
-
void TEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
word32 y, z;
Block::Get(inBlock)(y)(z);
word32 sum = 0;
- for (int i=0; i<ROUNDS; i++)
+ while (sum != m_limit)
{
sum += DELTA;
- y += (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1];
- z += (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3];
+ y += (z << 4) + m_k[0] ^ z + sum ^ (z >> 5) + m_k[1];
+ z += (y << 4) + m_k[2] ^ y + sum ^ (y >> 5) + m_k[3];
}
Block::Put(xorBlock, outBlock)(y)(z);
}
-typedef BlockGetAndPut<word32, BigEndian> Block;
-
void TEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
word32 y, z;
Block::Get(inBlock)(y)(z);
- word32 sum = DELTA << LOG_ROUNDS;
- for (int i=0; i<ROUNDS; i++)
+ word32 sum = m_limit;
+ while (sum != 0)
{
- z -= (y << 4) + k[2] ^ y + sum ^ (y >> 5) + k[3];
- y -= (z << 4) + k[0] ^ z + sum ^ (z >> 5) + k[1];
+ z -= (y << 4) + m_k[2] ^ y + sum ^ (y >> 5) + m_k[3];
+ y -= (z << 4) + m_k[0] ^ z + sum ^ (z >> 5) + m_k[1];
sum -= DELTA;
}
Block::Put(xorBlock, outBlock)(y)(z);
}
+void XTEA::Base::UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length, unsigned int rounds)
+{
+ AssertValidKeyLength(length);
+
+ GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH);
+ m_limit = rounds * DELTA;
+}
+
+void XTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
+{
+ word32 y, z;
+ Block::Get(inBlock)(y)(z);
+
+ word32 sum = 0;
+ while (sum != m_limit)
+ {
+ y += (z<<4 ^ z>>5) + z ^ sum + m_k[sum&3];
+ sum += DELTA;
+ z += (y<<4 ^ y>>5) + y ^ sum + m_k[sum>>11 & 3];
+ }
+
+ Block::Put(xorBlock, outBlock)(y)(z);
+}
+
+void XTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
+{
+ word32 y, z;
+ Block::Get(inBlock)(y)(z);
+
+ word32 sum = m_limit;
+ while (sum != 0)
+ {
+ z -= (y<<4 ^ y>>5) + y ^ sum + m_k[sum>>11 & 3];
+ sum -= DELTA;
+ y -= (z<<4 ^ z>>5) + z ^ sum + m_k[sum&3];
+ }
+
+ Block::Put(xorBlock, outBlock)(y)(z);
+}
+
+#define MX (z>>5^y<<2)+(y>>3^z<<4)^(sum^y)+(m_k[p&3^e]^z)
+
+void BTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
+{
+ unsigned int n = m_blockSize / 4;
+ word32 *v = (word32*)outBlock;
+ ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize);
+
+ word32 y = v[0], z = v[n-1], e;
+ word32 p, q = 6+52/n;
+ word32 sum = 0;
+
+ while (q-- > 0)
+ {
+ sum += DELTA;
+ e = sum>>2 & 3;
+ for (p = 0; p < n-1; p++)
+ {
+ y = v[p+1];
+ z = v[p] += MX;
+ }
+ y = v[0];
+ z = v[n-1] += MX;
+ }
+
+ ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
+}
+
+void BTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
+{
+ unsigned int n = m_blockSize / 4;
+ word32 *v = (word32*)outBlock;
+ ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize);
+
+ word32 y = v[0], z = v[n-1], e;
+ word32 p, q = 6+52/n;
+ word32 sum = q * DELTA;
+
+ while (sum != 0)
+ {
+ e = sum>>2 & 3;
+ for (p = n-1; p > 0; p--)
+ {
+ z = v[p-1];
+ y = v[p] -= MX;
+ }
+
+ z = v[n-1];
+ y = v[0] -= MX;
+ sum -= DELTA;
+ }
+
+ ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
+}
+
NAMESPACE_END