19 c = (byte) ((x) >> 16); \
20 y = (m_T[512+a])+(m_T[512+256+c]); \
27 c = (byte) ((x) >> 16); \
28 y = (m_T[a])+(m_T[256+c]); \
32#define step_P(u,v,a,b,c,d,n){ \
33 word32 tem0,tem1,tem2,tem3; \
35 tem0 = rotrConstant<23>(m_T[(v)]); \
36 tem1 = rotrConstant<10>(m_X[(c)]); \
37 tem2 = rotrConstant<8>(m_X[(b)]); \
38 (m_T[(u)]) += tem2+(tem0 ^ tem1); \
39 (m_X[(a)]) = (m_T[(u)]); \
40 (n) = tem3 ^ (m_T[(u)]); \
44#define step_Q(u,v,a,b,c,d,n){ \
45 word32 tem0,tem1,tem2,tem3; \
47 tem0 = rotrConstant<(32-23)>(m_T[(v)]); \
48 tem1 = rotrConstant<(32-10)>(m_Y[(c)]); \
49 tem2 = rotrConstant<(32-8)>(m_Y[(b)]); \
50 (m_T[(u)]) += tem2 + (tem0 ^ tem1); \
51 (m_Y[(a)]) = (m_T[(u)]); \
52 (n) = tem3 ^ (m_T[(u)]) ; \
56#define update_P(u,v,a,b,c,d){ \
57 word32 tem0,tem1,tem2,tem3; \
58 tem0 = rotrConstant<23>(m_T[(v)]); \
59 tem1 = rotrConstant<10>(m_X[(c)]); \
60 tem2 = rotrConstant<8>(m_X[(b)]); \
62 (m_T[(u)]) = ((m_T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \
63 (m_X[(a)]) = (m_T[(u)]); \
67#define update_Q(u,v,a,b,c,d){ \
68 word32 tem0,tem1,tem2,tem3; \
69 tem0 = rotrConstant<(32-23)>(m_T[(v)]); \
70 tem1 = rotrConstant<(32-10)>(m_Y[(c)]); \
71 tem2 = rotrConstant<(32-8)>(m_Y[(b)]); \
73 (m_T[(u)]) = ((m_T[(u)]) + tem2+(tem0^tem1)) ^ tem3; \
74 (m_Y[(a)]) = (m_T[(u)]); \
77#define BYTES_PER_ITERATION 64
79#define WordType word32
81#define HC128_OUTPUT(x){\
82 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, keystream[ 0]);\
83 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, keystream[ 1]);\
84 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, keystream[ 2]);\
85 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, keystream[ 3]);\
86 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 4, keystream[ 4]);\
87 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 5, keystream[ 5]);\
88 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 6, keystream[ 6]);\
89 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 7, keystream[ 7]);\
90 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 8, keystream[ 8]);\
91 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 9, keystream[ 9]);\
92 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 10, keystream[10]);\
93 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 11, keystream[11]);\
94 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 12, keystream[12]);\
95 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 13, keystream[13]);\
96 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 14, keystream[14]);\
97 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 15, keystream[15]);}
99ANONYMOUS_NAMESPACE_BEGIN
101using CryptoPP::word32;
102using CryptoPP::rotrConstant;
106 return rotrConstant<7>(x) ^ rotrConstant<18>(x) ^ ((x) >> 3);
111 return rotrConstant<17>(x) ^ rotrConstant<19>(x) ^ ((x) >> 10);
114ANONYMOUS_NAMESPACE_END
119void HC128Policy::GenerateKeystream(
word32 keystream[16])
121 unsigned int cc = m_ctr & 0x1ff;
122 unsigned int dd = (cc + 16) & 0x1ff;
126 m_ctr = (m_ctr + 16) & 0x3ff;
127 step_P(cc + 0, cc + 1, 0, 6, 13, 4, keystream[0]);
128 step_P(cc + 1, cc + 2, 1, 7, 14, 5, keystream[1]);
129 step_P(cc + 2, cc + 3, 2, 8, 15, 6, keystream[2]);
130 step_P(cc + 3, cc + 4, 3, 9, 0, 7, keystream[3]);
131 step_P(cc + 4, cc + 5, 4, 10, 1, 8, keystream[4]);
132 step_P(cc + 5, cc + 6, 5, 11, 2, 9, keystream[5]);
133 step_P(cc + 6, cc + 7, 6, 12, 3, 10, keystream[6]);
134 step_P(cc + 7, cc + 8, 7, 13, 4, 11, keystream[7]);
135 step_P(cc + 8, cc + 9, 8, 14, 5, 12, keystream[8]);
136 step_P(cc + 9, cc + 10, 9, 15, 6, 13, keystream[9]);
137 step_P(cc + 10, cc + 11, 10, 0, 7, 14, keystream[10]);
138 step_P(cc + 11, cc + 12, 11, 1, 8, 15, keystream[11]);
139 step_P(cc + 12, cc + 13, 12, 2, 9, 0, keystream[12]);
140 step_P(cc + 13, cc + 14, 13, 3, 10, 1, keystream[13]);
141 step_P(cc + 14, cc + 15, 14, 4, 11, 2, keystream[14]);
142 step_P(cc + 15, dd + 0, 15, 5, 12, 3, keystream[15]);
146 m_ctr = (m_ctr + 16) & 0x3ff;
147 step_Q(512 + cc + 0, 512 + cc + 1, 0, 6, 13, 4, keystream[0]);
148 step_Q(512 + cc + 1, 512 + cc + 2, 1, 7, 14, 5, keystream[1]);
149 step_Q(512 + cc + 2, 512 + cc + 3, 2, 8, 15, 6, keystream[2]);
150 step_Q(512 + cc + 3, 512 + cc + 4, 3, 9, 0, 7, keystream[3]);
151 step_Q(512 + cc + 4, 512 + cc + 5, 4, 10, 1, 8, keystream[4]);
152 step_Q(512 + cc + 5, 512 + cc + 6, 5, 11, 2, 9, keystream[5]);
153 step_Q(512 + cc + 6, 512 + cc + 7, 6, 12, 3, 10, keystream[6]);
154 step_Q(512 + cc + 7, 512 + cc + 8, 7, 13, 4, 11, keystream[7]);
155 step_Q(512 + cc + 8, 512 + cc + 9, 8, 14, 5, 12, keystream[8]);
156 step_Q(512 + cc + 9, 512 + cc + 10, 9, 15, 6, 13, keystream[9]);
157 step_Q(512 + cc + 10, 512 + cc + 11, 10, 0, 7, 14, keystream[10]);
158 step_Q(512 + cc + 11, 512 + cc + 12, 11, 1, 8, 15, keystream[11]);
159 step_Q(512 + cc + 12, 512 + cc + 13, 12, 2, 9, 0, keystream[12]);
160 step_Q(512 + cc + 13, 512 + cc + 14, 13, 3, 10, 1, keystream[13]);
161 step_Q(512 + cc + 14, 512 + cc + 15, 14, 4, 11, 2, keystream[14]);
162 step_Q(512 + cc + 15, 512 + dd + 0, 15, 5, 12, 3, keystream[15]);
168void HC128Policy::SetupUpdate()
170 unsigned int cc = m_ctr & 0x1ff;
171 unsigned int dd = (cc + 16) & 0x1ff;
175 m_ctr = (m_ctr + 16) & 0x3ff;
176 update_P(cc + 0, cc + 1, 0, 6, 13, 4);
177 update_P(cc + 1, cc + 2, 1, 7, 14, 5);
178 update_P(cc + 2, cc + 3, 2, 8, 15, 6);
179 update_P(cc + 3, cc + 4, 3, 9, 0, 7);
180 update_P(cc + 4, cc + 5, 4, 10, 1, 8);
181 update_P(cc + 5, cc + 6, 5, 11, 2, 9);
182 update_P(cc + 6, cc + 7, 6, 12, 3, 10);
183 update_P(cc + 7, cc + 8, 7, 13, 4, 11);
184 update_P(cc + 8, cc + 9, 8, 14, 5, 12);
185 update_P(cc + 9, cc + 10, 9, 15, 6, 13);
186 update_P(cc + 10, cc + 11, 10, 0, 7, 14);
187 update_P(cc + 11, cc + 12, 11, 1, 8, 15);
188 update_P(cc + 12, cc + 13, 12, 2, 9, 0);
189 update_P(cc + 13, cc + 14, 13, 3, 10, 1);
190 update_P(cc + 14, cc + 15, 14, 4, 11, 2);
191 update_P(cc + 15, dd + 0, 15, 5, 12, 3);
195 m_ctr = (m_ctr + 16) & 0x3ff;
196 update_Q(512 + cc + 0, 512 + cc + 1, 0, 6, 13, 4);
197 update_Q(512 + cc + 1, 512 + cc + 2, 1, 7, 14, 5);
198 update_Q(512 + cc + 2, 512 + cc + 3, 2, 8, 15, 6);
199 update_Q(512 + cc + 3, 512 + cc + 4, 3, 9, 0, 7);
200 update_Q(512 + cc + 4, 512 + cc + 5, 4, 10, 1, 8);
201 update_Q(512 + cc + 5, 512 + cc + 6, 5, 11, 2, 9);
202 update_Q(512 + cc + 6, 512 + cc + 7, 6, 12, 3, 10);
203 update_Q(512 + cc + 7, 512 + cc + 8, 7, 13, 4, 11);
204 update_Q(512 + cc + 8, 512 + cc + 9, 8, 14, 5, 12);
205 update_Q(512 + cc + 9, 512 + cc + 10, 9, 15, 6, 13);
206 update_Q(512 + cc + 10, 512 + cc + 11, 10, 0, 7, 14);
207 update_Q(512 + cc + 11, 512 + cc + 12, 11, 1, 8, 15);
208 update_Q(512 + cc + 12, 512 + cc + 13, 12, 2, 9, 0);
209 update_Q(512 + cc + 13, 512 + cc + 14, 13, 3, 10, 1);
210 update_Q(512 + cc + 14, 512 + cc + 15, 14, 4, 11, 2);
211 update_Q(512 + cc + 15, 512 + dd + 0, 15, 5, 12, 3);
215void HC128Policy::CipherSetKey(
const NameValuePairs ¶ms,
const byte *userKey,
size_t keylen)
217 CRYPTOPP_UNUSED(params);
220 for (
unsigned int i = 4; i < 8; i++)
221 m_key[i] = m_key[i - 4];
224void HC128Policy::OperateKeystream(
KeystreamOperation operation,
byte *output,
const byte *input,
size_t iterationCount)
226 while (iterationCount--)
229 GenerateKeystream(keystream);
235void HC128Policy::CipherResynchronize(
byte *keystreamBuffer,
const byte *iv,
size_t length)
237 CRYPTOPP_UNUSED(keystreamBuffer);
240 for (
unsigned int i = 4; i < 8; i++)
241 m_iv[i] = m_iv[i - 4];
246 for (
unsigned int i = 0; i < 8; i++)
248 for (
unsigned int i = 8; i < 16; i++)
249 m_T[i] = m_iv[i - 8];
251 for (
unsigned int i = 16; i < (256 + 16); i++)
252 m_T[i] = f2(m_T[i - 2]) + m_T[i - 7] + f1(m_T[i - 15]) + m_T[i - 16] + i;
254 for (
unsigned int i = 0; i < 16; i++)
255 m_T[i] = m_T[256 + i];
257 for (
unsigned int i = 16; i < 1024; i++)
258 m_T[i] = f2(m_T[i - 2]) + m_T[i - 7] + f1(m_T[i - 15]) + m_T[i - 16] + 256 + i;
262 for (
unsigned int i = 0; i < 16; i++)
263 m_X[i] = m_T[512 - 16 + i];
264 for (
unsigned int i = 0; i < 16; i++)
265 m_Y[i] = m_T[512 + 512 - 16 + i];
268 for (
unsigned int i = 0; i < 64; i++)
Fixed size stack-based SecBlock.
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.
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.
Crypto++ library namespace.
Classes and functions for secure memory allocations.
Classes for implementing stream ciphers.
#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y)
Helper macro to implement OperateKeystream.
KeystreamOperation
Keystream operation flags.
static const int BYTES_PER_ITERATION
Number of bytes for an iteration.