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
78using CryptoPP::word32;
79using CryptoPP::rotrConstant;
83 return rotrConstant<7>(x) ^ rotrConstant<18>(x) ^ ((x) >> 3);
88 return rotrConstant<17>(x) ^ rotrConstant<19>(x) ^ ((x) >> 10);
91ANONYMOUS_NAMESPACE_END
93NAMESPACE_BEGIN(CryptoPP)
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);
194 CRYPTOPP_UNUSED(params);
197 for (
unsigned int i = 4; i < 8; i++)
198 m_key[i] = m_key[i - 4];
203 while (iterationCount--)
206 GenerateKeystream(keystream);
234 xorbuf(output, input, BYTES_PER_ITERATION);
235 input += BYTES_PER_ITERATION;
238 output += BYTES_PER_ITERATION;
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++)
void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
Operates the keystream.
void CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length)
Key the cipher.
void CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
Resynchronize the cipher.
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 PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock=NULLPTR)
Access a block of memory.
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.
Classes and functions for secure memory allocations.
KeystreamOperation
Keystream operation flags.
@ INPUT_NULL
Input buffer is NULL.