Crypto++  5.6.3
Free C++ class library of cryptographic schemes
tea.cpp
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 
7 NAMESPACE_BEGIN(CryptoPP)
8 
9 static const word32 DELTA = 0x9e3779b9;
10 typedef BlockGetAndPut<word32, BigEndian> Block;
11 
12 void TEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &params)
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 
20 void 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 
36 void 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 
52 void XTEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &params)
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 
60 void 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 #ifdef __SUNPRO_CC
66  // workaround needed on Sun Studio 12u1 Sun C++ 5.10 SunOS_i386 128229-02 2009/09/21
67  size_t sum = 0;
68  while ((sum&0xffffffff) != m_limit)
69 #else
70  word32 sum = 0;
71  while (sum != m_limit)
72 #endif
73  {
74  y += ((z<<4 ^ z>>5) + z) ^ (sum + m_k[sum&3]);
75  sum += DELTA;
76  z += ((y<<4 ^ y>>5) + y) ^ (sum + m_k[sum>>11 & 3]);
77  }
78 
79  Block::Put(xorBlock, outBlock)(y)(z);
80 }
81 
82 void XTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
83 {
84  word32 y, z;
85  Block::Get(inBlock)(y)(z);
86 
87 #ifdef __SUNPRO_CC
88  // workaround needed on Sun Studio 12u1 Sun C++ 5.10 SunOS_i386 128229-02 2009/09/21
89  size_t sum = m_limit;
90  while ((sum&0xffffffff) != 0)
91 #else
92  word32 sum = m_limit;
93  while (sum != 0)
94 #endif
95  {
96  z -= ((y<<4 ^ y>>5) + y) ^ (sum + m_k[sum>>11 & 3]);
97  sum -= DELTA;
98  y -= ((z<<4 ^ z>>5) + z) ^ (sum + m_k[sum&3]);
99  }
100 
101  Block::Put(xorBlock, outBlock)(y)(z);
102 }
103 
104 #define MX ((z>>5^y<<2)+(y>>3^z<<4))^((sum^y)+(m_k[(p&3)^e]^z))
105 
106 void BTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
107 {
108  CRYPTOPP_UNUSED(xorBlock);
109  unsigned int n = m_blockSize / 4;
110  word32 *v = (word32*)outBlock;
111  ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize);
112 
113  word32 y = v[0], z = v[n-1], e;
114  word32 p, q = 6+52/n;
115  word32 sum = 0;
116 
117  while (q-- > 0)
118  {
119  sum += DELTA;
120  e = sum>>2 & 3;
121  for (p = 0; p < n-1; p++)
122  {
123  y = v[p+1];
124  z = v[p] += MX;
125  }
126  y = v[0];
127  z = v[n-1] += MX;
128  }
129 
130  ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
131 }
132 
133 void BTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
134 {
135  CRYPTOPP_UNUSED(xorBlock);
136  unsigned int n = m_blockSize / 4;
137  word32 *v = (word32*)outBlock;
138  ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)inBlock, m_blockSize);
139 
140  word32 y = v[0], z = v[n-1], e;
141  word32 p, q = 6+52/n;
142  word32 sum = q * DELTA;
143 
144  while (sum != 0)
145  {
146  e = sum>>2 & 3;
147  for (p = n-1; p > 0; p--)
148  {
149  z = v[p-1];
150  y = v[p] -= MX;
151  }
152 
153  z = v[n-1];
154  y = v[0] -= MX;
155  sum -= DELTA;
156  }
157 
158  ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
159 }
160 
161 NAMESPACE_END
Utility functions for the Crypto++ library.
Converts a typename to an enumerated value.
Definition: cryptlib.h:110
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianess.
Definition: misc.h:1695
Classes for the TEA, BTEA and XTEA block ciphers.
TEA
Definition: tea.h:22
Crypto++ library namespace.
Interface for retrieving values given their names.
Definition: cryptlib.h:261