1// tea.cpp - modified by Wei Dai from code in the original paper 2 3#include "pch.h" 4#include "tea.h" 5#include "misc.h" 6 7NAMESPACE_BEGIN(CryptoPP) 8 9static const word32 DELTA = 0x9e3779b9; 10typedef BlockGetAndPut<word32, BigEndian> Block; 11 12void TEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) 13{ 14 AssertValidKeyLength(length); 15 16 GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH); 17 m_limit = GetRoundsAndThrowIfInvalid(params, this) * DELTA; 18} 19 20void TEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 21{ 22 word32 y, z; 23 Block::Get(inBlock)(y)(z); 24 25 word32 sum = 0; 26 while (sum != m_limit) 27 { 28 sum += DELTA; 29 y += (z << 4) + m_k[0] ^ z + sum ^ (z >> 5) + m_k[1]; 30 z += (y << 4) + m_k[2] ^ y + sum ^ (y >> 5) + m_k[3]; 31 } 32 33 Block::Put(xorBlock, outBlock)(y)(z); 34} 35 36void TEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 37{ 38 word32 y, z; 39 Block::Get(inBlock)(y)(z); 40 41 word32 sum = m_limit; 42 while (sum != 0) 43 { 44 z -= (y << 4) + m_k[2] ^ y + sum ^ (y >> 5) + m_k[3]; 45 y -= (z << 4) + m_k[0] ^ z + sum ^ (z >> 5) + m_k[1]; 46 sum -= DELTA; 47 } 48 49 Block::Put(xorBlock, outBlock)(y)(z); 50} 51 52void XTEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs ¶ms) 53{ 54 AssertValidKeyLength(length); 55 56 GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH); 57 m_limit = GetRoundsAndThrowIfInvalid(params, this) * DELTA; 58} 59 60void XTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 61{ 62 word32 y, z; 63 Block::Get(inBlock)(y)(z); 64 65 word32 sum = 0; 66 while (sum != m_limit) 67 { 68 y += (z<<4 ^ z>>5) + z ^ sum + m_k[sum&3]; 69 sum += DELTA; 70 z += (y<<4 ^ y>>5) + y ^ sum + m_k[sum>>11 & 3]; 71 } 72 73 Block::Put(xorBlock, outBlock)(y)(z); 74} 75 76void XTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 77{ 78 word32 y, z; 79 Block::Get(inBlock)(y)(z); 80 81 word32 sum = m_limit; 82 while (sum != 0) 83 { 84 z -= (y<<4 ^ y>>5) + y ^ sum + m_k[sum>>11 & 3]; 85 sum -= DELTA; 86 y -= (z<<4 ^ z>>5) + z ^ sum + m_k[sum&3]; 87 } 88 89 Block::Put(xorBlock, outBlock)(y)(z); 90} 91 92#define MX (z>>5^y<<2)+(y>>3^z<<4)^(sum^y)+(m_k[p&3^e]^z) 93 94void BTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 95{ 96 unsigned int n = m_blockSize / 4; 97 word32 *v = (word32*)outBlock; 98 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize); 99 100 word32 y = v[0], z = v[n-1], e; 101 word32 p, q = 6+52/n; 102 word32 sum = 0; 103 104 while (q-- > 0) 105 { 106 sum += DELTA; 107 e = sum>>2 & 3; 108 for (p = 0; p < n-1; p++) 109 { 110 y = v[p+1]; 111 z = v[p] += MX; 112 } 113 y = v[0]; 114 z = v[n-1] += MX; 115 } 116 117 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize); 118} 119 120void BTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 121{ 122 unsigned int n = m_blockSize / 4; 123 word32 *v = (word32*)outBlock; 124 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize); 125 126 word32 y = v[0], z = v[n-1], e; 127 word32 p, q = 6+52/n; 128 word32 sum = q * DELTA; 129 130 while (sum != 0) 131 { 132 e = sum>>2 & 3; 133 for (p = n-1; p > 0; p--) 134 { 135 z = v[p-1]; 136 y = v[p] -= MX; 137 } 138 139 z = v[n-1]; 140 y = v[0] -= MX; 141 sum -= DELTA; 142 } 143 144 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize); 145} 146 147NAMESPACE_END 148