Crypto++ 8.2
Free C&
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
7NAMESPACE_BEGIN(CryptoPP)
8
9static const word32 DELTA = 0x9e3779b9;
11
12#define UINT32_CAST(x) ((word32*)(void*)(x))
13#define CONST_UINT32_CAST(x) ((const word32*)(const void*)(x))
14
15void TEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &params)
16{
17 AssertValidKeyLength(length);
18
19 GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH);
20 m_limit = GetRoundsAndThrowIfInvalid(params, this) * DELTA;
21}
22
23void TEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
24{
25 word32 y, z, sum = 0;
26 Block::Get(inBlock)(y)(z);
27
28 // http://github.com/weidai11/cryptopp/issues/503
29 while (*const_cast<volatile word32*>(&sum) != m_limit)
30 {
31 sum += DELTA;
32 y += ((z << 4) + m_k[0]) ^ (z + sum) ^ ((z >> 5) + m_k[1]);
33 z += ((y << 4) + m_k[2]) ^ (y + sum) ^ ((y >> 5) + m_k[3]);
34 }
35
36 Block::Put(xorBlock, outBlock)(y)(z);
37}
38
39void TEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
40{
41 word32 y, z, sum = m_limit;
42 Block::Get(inBlock)(y)(z);
43
44 // http://github.com/weidai11/cryptopp/issues/503
45 while (*const_cast<volatile word32*>(&sum) != 0)
46 {
47 z -= ((y << 4) + m_k[2]) ^ (y + sum) ^ ((y >> 5) + m_k[3]);
48 y -= ((z << 4) + m_k[0]) ^ (z + sum) ^ ((z >> 5) + m_k[1]);
49 sum -= DELTA;
50 }
51
52 Block::Put(xorBlock, outBlock)(y)(z);
53}
54
55void XTEA::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &params)
56{
57 AssertValidKeyLength(length);
58
59 GetUserKey(BIG_ENDIAN_ORDER, m_k.begin(), 4, userKey, KEYLENGTH);
60 m_limit = GetRoundsAndThrowIfInvalid(params, this) * DELTA;
61}
62
63void XTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
64{
65 word32 y, z, sum = 0;
66 Block::Get(inBlock)(y)(z);
67
68 // http://github.com/weidai11/cryptopp/issues/503
69 while (*const_cast<volatile word32*>(&sum) != m_limit)
70 {
71 y += ((z<<4 ^ z>>5) + z) ^ (sum + m_k[sum&3]);
72 sum += DELTA;
73 z += ((y<<4 ^ y>>5) + y) ^ (sum + m_k[sum>>11 & 3]);
74 }
75
76 Block::Put(xorBlock, outBlock)(y)(z);
77}
78
79void XTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
80{
81 word32 y, z, sum = m_limit;
82 Block::Get(inBlock)(y)(z);
83
84 // http://github.com/weidai11/cryptopp/issues/503
85 while (*const_cast<volatile word32*>(&sum) != 0)
86 {
87 z -= ((y<<4 ^ y>>5) + y) ^ (sum + m_k[sum>>11 & 3]);
88 sum -= DELTA;
89 y -= ((z<<4 ^ z>>5) + z) ^ (sum + m_k[sum&3]);
90 }
91
92 Block::Put(xorBlock, outBlock)(y)(z);
93}
94
95#define MX ((z>>5^y<<2)+(y>>3^z<<4))^((sum^y)+(m_k[(p&3)^e]^z))
96
97void BTEA::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
98{
99 CRYPTOPP_UNUSED(xorBlock);
100 CRYPTOPP_ASSERT(IsAlignedOn(inBlock,GetAlignmentOf<word32>()));
101 CRYPTOPP_ASSERT(IsAlignedOn(outBlock,GetAlignmentOf<word32>()));
102
103 unsigned int n = m_blockSize / 4;
104 word32 *v = UINT32_CAST(outBlock);
105 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, CONST_UINT32_CAST(inBlock), m_blockSize);
106
107 word32 y, z = v[n-1], e;
108 word32 p, q = 6+52/n;
109 word32 sum = 0;
110
111 while (q-- > 0)
112 {
113 sum += DELTA;
114 e = sum>>2 & 3;
115 for (p = 0; p < n-1; p++)
116 {
117 y = v[p+1];
118 z = v[p] += MX;
119 }
120 y = v[0];
121 z = v[n-1] += MX;
122 }
123
124 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
125}
126
127void BTEA::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
128{
129 CRYPTOPP_UNUSED(xorBlock);
130 CRYPTOPP_ASSERT(IsAlignedOn(inBlock,GetAlignmentOf<word32>()));
131 CRYPTOPP_ASSERT(IsAlignedOn(outBlock,GetAlignmentOf<word32>()));
132
133 unsigned int n = m_blockSize / 4;
134 word32 *v = UINT32_CAST(outBlock);
135 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, CONST_UINT32_CAST(inBlock), m_blockSize);
136
137 word32 y = v[0], z, e;
138 word32 p, q = 6+52/n;
139 word32 sum = q * DELTA;
140
141 while (sum != 0)
142 {
143 e = sum>>2 & 3;
144 for (p = n-1; p > 0; p--)
145 {
146 z = v[p-1];
147 y = v[p] -= MX;
148 }
149
150 z = v[n-1];
151 y = v[0] -= MX;
152 sum -= DELTA;
153 }
154
155 ConditionalByteReverse(BIG_ENDIAN_ORDER, v, v, m_blockSize);
156}
157
158NAMESPACE_END
Interface for retrieving values given their names.
Definition: cryptlib.h:294
Access a block of memory.
Definition: misc.h:2496
@ BIG_ENDIAN_ORDER
byte order is big-endian
Definition: cryptlib.h:147
Utility functions for the Crypto++ library.
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
Definition: misc.h:1143
T ConditionalByteReverse(ByteOrder order, T value)
Reverses bytes in a value depending upon endianness.
Definition: misc.h:2113
Crypto++ library namespace.
Precompiled header file.
Access a block of memory.
Definition: misc.h:2533
Classes for the TEA, BTEA and XTEA block ciphers.
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:69