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  assert(IsAlignedOn(inBlock,GetAlignmentOf<word32>()));
110  assert(IsAlignedOn(outBlock,GetAlignmentOf<word32>()));
111 
112  unsigned int n = m_blockSize / 4;
113  word32 *v = (word32*)(void *)outBlock;
114  ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)(void *)inBlock, m_blockSize);
115 
116  word32 y = v[0], z = v[n-1], e;
117  word32 p, q = 6+52/n;
118  word32 sum = 0;
119 
120  while (q-- > 0)
121  {
122  sum += DELTA;
123  e = sum>>2 & 3;
124  for (p = 0; p < n-1; p++)
125  {
126  y = v[p+1];
127  z = v[p] += MX;
128  }
129  y = v[0];
130  z = v[n-1] += MX;
131  }
132 
133  ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
134 }
135 
136 void BTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
137 {
138  CRYPTOPP_UNUSED(xorBlock);
139  assert(IsAlignedOn(inBlock,GetAlignmentOf<word32>()));
140  assert(IsAlignedOn(outBlock,GetAlignmentOf<word32>()));
141 
142  unsigned int n = m_blockSize / 4;
143  word32 *v = (word32*)(void *)outBlock;
144  ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)(void *)inBlock, m_blockSize);
145 
146  word32 y = v[0], z = v[n-1], e;
147  word32 p, q = 6+52/n;
148  word32 sum = q * DELTA;
149 
150  while (sum != 0)
151  {
152  e = sum>>2 & 3;
153  for (p = n-1; p > 0; p--)
154  {
155  z = v[p-1];
156  y = v[p] -= MX;
157  }
158 
159  z = v[n-1];
160  y = v[0] -= MX;
161  sum -= DELTA;
162  }
163 
164  ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
165 }
166 
167 NAMESPACE_END
Utility functions for the Crypto++ library.
Converts a typename to an enumerated value.
Definition: cryptlib.h:115
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
Definition: misc.h:811
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianess.
Definition: misc.h:1705
Classes for the TEA, BTEA and XTEA block ciphers.
TEA block cipher.
Definition: tea.h:25
byte order is big-endian
Definition: cryptlib.h:127
Crypto++ library namespace.
Interface for retrieving values given their names.
Definition: cryptlib.h:277