18 c = (byte) ((x) >> 16); \
19 y = (m_T[512+a])+(m_T[512+256+c]); \
26 c = (byte) ((x) >> 16); \
27 y = (m_T[a])+(m_T[256+c]); \
31#define step_P(u,v,a,b,c,d,n){ \
32 word32 tem0,tem1,tem2,tem3; \
34 tem0 = rotrConstant<23>(m_T[(v)]); \
35 tem1 = rotrConstant<10>(m_X[(c)]); \
36 tem2 = rotrConstant<8>(m_X[(b)]); \
37 (m_T[(u)]) += tem2+(tem0 ^ tem1); \
38 (m_X[(a)]) = (m_T[(u)]); \
39 (n) = tem3 ^ (m_T[(u)]); \
43#define step_Q(u,v,a,b,c,d,n){ \
44 word32 tem0,tem1,tem2,tem3; \
46 tem0 = rotrConstant<(32-23)>(m_T[(v)]); \
47 tem1 = rotrConstant<(32-10)>(m_Y[(c)]); \
48 tem2 = rotrConstant<(32-8)>(m_Y[(b)]); \
49 (m_T[(u)]) += tem2 + (tem0 ^ tem1); \
50 (m_Y[(a)]) = (m_T[(u)]); \
51 (n) = tem3 ^ (m_T[(u)]) ; \
55#define update_P(u,v,a,b,c,d){ \
56 word32 tem0,tem1,tem2,tem3; \
57 tem0 = rotrConstant<23>(m_T[(v)]); \
58 tem1 = rotrConstant<10>(m_X[(c)]); \
59 tem2 = rotrConstant<8>(m_X[(b)]); \
61 (m_T[(u)]) = ((m_T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \
62 (m_X[(a)]) = (m_T[(u)]); \
66#define update_Q(u,v,a,b,c,d){ \
67 word32 tem0,tem1,tem2,tem3; \
68 tem0 = rotrConstant<(32-23)>(m_T[(v)]); \
69 tem1 = rotrConstant<(32-10)>(m_Y[(c)]); \
70 tem2 = rotrConstant<(32-8)>(m_Y[(b)]); \
72 (m_T[(u)]) = ((m_T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \
73 (m_Y[(a)]) = (m_T[(u)]); \
76ANONYMOUS_NAMESPACE_BEGIN
83 return rotrConstant<7>(x) ^ rotrConstant<18>(x) ^ ((x) >> 3);
88 return rotrConstant<17>(x) ^ rotrConstant<19>(x) ^ ((x) >> 10);
91ANONYMOUS_NAMESPACE_END
96void HC128Policy::GenerateKeystream(
word32 keystream[16])
98 unsigned int cc = m_ctr & 0x1ff;
99 unsigned int dd = (cc + 16) & 0x1ff;
103 m_ctr = (m_ctr + 16) & 0x3ff;
104 step_P(cc + 0, cc + 1, 0, 6, 13, 4, keystream[0]);
105 step_P(cc + 1, cc + 2, 1, 7, 14, 5, keystream[1]);
106 step_P(cc + 2, cc + 3, 2, 8, 15, 6, keystream[2]);
107 step_P(cc + 3, cc + 4, 3, 9, 0, 7, keystream[3]);
108 step_P(cc + 4, cc + 5, 4, 10, 1, 8, keystream[4]);
109 step_P(cc + 5, cc + 6, 5, 11, 2, 9, keystream[5]);
110 step_P(cc + 6, cc + 7, 6, 12, 3, 10, keystream[6]);
111 step_P(cc + 7, cc + 8, 7, 13, 4, 11, keystream[7]);
112 step_P(cc + 8, cc + 9, 8, 14, 5, 12, keystream[8]);
113 step_P(cc + 9, cc + 10, 9, 15, 6, 13, keystream[9]);
114 step_P(cc + 10, cc + 11, 10, 0, 7, 14, keystream[10]);
115 step_P(cc + 11, cc + 12, 11, 1, 8, 15, keystream[11]);
116 step_P(cc + 12, cc + 13, 12, 2, 9, 0, keystream[12]);
117 step_P(cc + 13, cc + 14, 13, 3, 10, 1, keystream[13]);
118 step_P(cc + 14, cc + 15, 14, 4, 11, 2, keystream[14]);
119 step_P(cc + 15, dd + 0, 15, 5, 12, 3, keystream[15]);
123 m_ctr = (m_ctr + 16) & 0x3ff;
124 step_Q(512 + cc + 0, 512 + cc + 1, 0, 6, 13, 4, keystream[0]);
125 step_Q(512 + cc + 1, 512 + cc + 2, 1, 7, 14, 5, keystream[1]);
126 step_Q(512 + cc + 2, 512 + cc + 3, 2, 8, 15, 6, keystream[2]);
127 step_Q(512 + cc + 3, 512 + cc + 4, 3, 9, 0, 7, keystream[3]);
128 step_Q(512 + cc + 4, 512 + cc + 5, 4, 10, 1, 8, keystream[4]);
129 step_Q(512 + cc + 5, 512 + cc + 6, 5, 11, 2, 9, keystream[5]);
130 step_Q(512 + cc + 6, 512 + cc + 7, 6, 12, 3, 10, keystream[6]);
131 step_Q(512 + cc + 7, 512 + cc + 8, 7, 13, 4, 11, keystream[7]);
132 step_Q(512 + cc + 8, 512 + cc + 9, 8, 14, 5, 12, keystream[8]);
133 step_Q(512 + cc + 9, 512 + cc + 10, 9, 15, 6, 13, keystream[9]);
134 step_Q(512 + cc + 10, 512 + cc + 11, 10, 0, 7, 14, keystream[10]);
135 step_Q(512 + cc + 11, 512 + cc + 12, 11, 1, 8, 15, keystream[11]);
136 step_Q(512 + cc + 12, 512 + cc + 13, 12, 2, 9, 0, keystream[12]);
137 step_Q(512 + cc + 13, 512 + cc + 14, 13, 3, 10, 1, keystream[13]);
138 step_Q(512 + cc + 14, 512 + cc + 15, 14, 4, 11, 2, keystream[14]);
139 step_Q(512 + cc + 15, 512 + dd + 0, 15, 5, 12, 3, keystream[15]);
145void HC128Policy::SetupUpdate()
147 unsigned int cc = m_ctr & 0x1ff;
148 unsigned int dd = (cc + 16) & 0x1ff;
152 m_ctr = (m_ctr + 16) & 0x3ff;
153 update_P(cc + 0, cc + 1, 0, 6, 13, 4);
154 update_P(cc + 1, cc + 2, 1, 7, 14, 5);
155 update_P(cc + 2, cc + 3, 2, 8, 15, 6);
156 update_P(cc + 3, cc + 4, 3, 9, 0, 7);
157 update_P(cc + 4, cc + 5, 4, 10, 1, 8);
158 update_P(cc + 5, cc + 6, 5, 11, 2, 9);
159 update_P(cc + 6, cc + 7, 6, 12, 3, 10);
160 update_P(cc + 7, cc + 8, 7, 13, 4, 11);
161 update_P(cc + 8, cc + 9, 8, 14, 5, 12);
162 update_P(cc + 9, cc + 10, 9, 15, 6, 13);
163 update_P(cc + 10, cc + 11, 10, 0, 7, 14);
164 update_P(cc + 11, cc + 12, 11, 1, 8, 15);
165 update_P(cc + 12, cc + 13, 12, 2, 9, 0);
166 update_P(cc + 13, cc + 14, 13, 3, 10, 1);
167 update_P(cc + 14, cc + 15, 14, 4, 11, 2);
168 update_P(cc + 15, dd + 0, 15, 5, 12, 3);
172 m_ctr = (m_ctr + 16) & 0x3ff;
173 update_Q(512 + cc + 0, 512 + cc + 1, 0, 6, 13, 4);
174 update_Q(512 + cc + 1, 512 + cc + 2, 1, 7, 14, 5);
175 update_Q(512 + cc + 2, 512 + cc + 3, 2, 8, 15, 6);
176 update_Q(512 + cc + 3, 512 + cc + 4, 3, 9, 0, 7);
177 update_Q(512 + cc + 4, 512 + cc + 5, 4, 10, 1, 8);
178 update_Q(512 + cc + 5, 512 + cc + 6, 5, 11, 2, 9);
179 update_Q(512 + cc + 6, 512 + cc + 7, 6, 12, 3, 10);
180 update_Q(512 + cc + 7, 512 + cc + 8, 7, 13, 4, 11);
181 update_Q(512 + cc + 8, 512 + cc + 9, 8, 14, 5, 12);
182 update_Q(512 + cc + 9, 512 + cc + 10, 9, 15, 6, 13);
183 update_Q(512 + cc + 10, 512 + cc + 11, 10, 0, 7, 14);
184 update_Q(512 + cc + 11, 512 + cc + 12, 11, 1, 8, 15);
185 update_Q(512 + cc + 12, 512 + cc + 13, 12, 2, 9, 0);
186 update_Q(512 + cc + 13, 512 + cc + 14, 13, 3, 10, 1);
187 update_Q(512 + cc + 14, 512 + cc + 15, 14, 4, 11, 2);
188 update_Q(512 + cc + 15, 512 + dd + 0, 15, 5, 12, 3);
192void HC128Policy::CipherSetKey(
const NameValuePairs ¶ms,
const byte *userKey,
size_t keylen)
194 CRYPTOPP_UNUSED(params);
197 for (
unsigned int i = 4; i < 8; i++)
198 m_key[i] = m_key[i - 4];
201void HC128Policy::OperateKeystream(
KeystreamOperation operation,
byte *output,
const byte *input,
size_t iterationCount)
203 while (iterationCount--)
206 GenerateKeystream(keystream);
242void HC128Policy::CipherResynchronize(
byte *keystreamBuffer,
const byte *iv,
size_t length)
244 CRYPTOPP_UNUSED(keystreamBuffer);
247 for (
unsigned int i = 4; i < 8; i++)
248 m_iv[i] = m_iv[i - 4];
253 for (
unsigned int i = 0; i < 8; i++)
255 for (
unsigned int i = 8; i < 16; i++)
256 m_T[i] = m_iv[i - 8];
258 for (
unsigned int i = 16; i < (256 + 16); i++)
259 m_T[i] = f2(m_T[i - 2]) + m_T[i - 7] + f1(m_T[i - 15]) + m_T[i - 16] + i;
261 for (
unsigned int i = 0; i < 16; i++)
262 m_T[i] = m_T[256 + i];
264 for (
unsigned int i = 16; i < 1024; i++)
265 m_T[i] = f2(m_T[i - 2]) + m_T[i - 7] + f1(m_T[i - 15]) + m_T[i - 16] + 256 + i;
269 for (
unsigned int i = 0; i < 16; i++)
270 m_X[i] = m_T[512 - 16 + i];
271 for (
unsigned int i = 0; i < 16; i++)
272 m_Y[i] = m_T[512 + 512 - 16 + i];
275 for (
unsigned int i = 0; i < 64; i++)
Interface for retrieving values given their names.
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Library configuration file.
unsigned int word32
32-bit unsigned datatype
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Classes for HC-128 stream cipher.
Utility functions for the Crypto++ library.
T rotrConstant(T x)
Performs a right rotate.
void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
Copy bytes in a buffer to an array of elements in big-endian order.
#define EnumToInt(v)
Integer value.
void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock=NULL)
Access a block of memory.
CRYPTOPP_DLL void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Crypto++ library namespace.
Classes and functions for secure memory allocations.
KeystreamOperation
Keystream operation flags.
@ INPUT_NULL
Input buffer is NULL.
static const int BYTES_PER_ITERATION
Number of bytes for an iteration.