Crypto++  5.6.5
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;
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, sum = 0;
23  Block::Get(inBlock)(y)(z);
24 
25  // http://github.com/weidai11/cryptopp/issues/503
26  while (*const_cast<volatile word32*>(&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, sum = m_limit;
39  Block::Get(inBlock)(y)(z);
40 
41  // http://github.com/weidai11/cryptopp/issues/503
42  while (*const_cast<volatile word32*>(&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, sum = 0;
63  Block::Get(inBlock)(y)(z);
64 
65  // http://github.com/weidai11/cryptopp/issues/503
66  while (*const_cast<volatile word32*>(&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 
76 void XTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
77 {
78  word32 y, z, sum = m_limit;
79  Block::Get(inBlock)(y)(z);
80 
81  // http://github.com/weidai11/cryptopp/issues/503
82  while (*const_cast<volatile word32*>(&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 
94 void BTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
95 {
96  CRYPTOPP_UNUSED(xorBlock);
97  CRYPTOPP_ASSERT(IsAlignedOn(inBlock,GetAlignmentOf<word32>()));
98  CRYPTOPP_ASSERT(IsAlignedOn(outBlock,GetAlignmentOf<word32>()));
99 
100  unsigned int n = m_blockSize / 4;
101  word32 *v = (word32*)(void *)outBlock;
102  ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)(void *)inBlock, m_blockSize);
103 
104  word32 y = v[0], z = v[n-1], e;
105  word32 p, q = 6+52/n;
106  word32 sum = 0;
107 
108  while (q-- > 0)
109  {
110  sum += DELTA;
111  e = sum>>2 & 3;
112  for (p = 0; p < n-1; p++)
113  {
114  y = v[p+1];
115  z = v[p] += MX;
116  }
117  y = v[0];
118  z = v[n-1] += MX;
119  }
120 
121  ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
122 }
123 
124 void BTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
125 {
126  CRYPTOPP_UNUSED(xorBlock);
127  CRYPTOPP_ASSERT(IsAlignedOn(inBlock,GetAlignmentOf<word32>()));
128  CRYPTOPP_ASSERT(IsAlignedOn(outBlock,GetAlignmentOf<word32>()));
129 
130  unsigned int n = m_blockSize / 4;
131  word32 *v = (word32*)(void *)outBlock;
132  ConditionalByteReverse(BIG_ENDIAN_ORDER, v, (const word32*)(void *)inBlock, m_blockSize);
133 
134  word32 y = v[0], z = v[n-1], e;
135  word32 p, q = 6+52/n;
136  word32 sum = q * DELTA;
137 
138  while (sum != 0)
139  {
140  e = sum>>2 & 3;
141  for (p = n-1; p > 0; p--)
142  {
143  z = v[p-1];
144  y = v[p] -= MX;
145  }
146 
147  z = v[n-1];
148  y = v[0] -= MX;
149  sum -= DELTA;
150  }
151 
152  ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
153 }
154 
155 NAMESPACE_END
Utility functions for the Crypto++ library.
Access a block of memory.
Definition: misc.h:2403
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
Definition: misc.h:1028
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
Definition: misc.h:1977
Classes for the TEA, BTEA and XTEA block ciphers.
byte order is big-endian
Definition: cryptlib.h:145
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:60
Access a block of memory.
Definition: misc.h:2365
Crypto++ library namespace.
Interface for retrieving values given their names.
Definition: cryptlib.h:294