Crypto++ 8.9 Free C++ class library of cryptographic schemes

hc256.cpp
1 // hc256.cpp - written and placed in the public domain by Jeffrey Walton
2 // based on public domain code by Hongjun Wu.
3 //
4 // The reference materials and source files are available at
5 // The eSTREAM Project, http://www.ecrypt.eu.org/stream/hc256.html.
6
7 #include "pch.h"
8 #include "config.h"
9
10 #include "hc256.h"
11 #include "secblock.h"
12 #include "strciphr.h"
13 #include "misc.h"
14
15 #define BYTES_PER_ITERATION 16
16
17 #define WordType word32
18
19 #define HC256_OUTPUT(x){\
20 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, keystream[0]);\
21 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, keystream[1]);\
22 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, keystream[2]);\
23 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, keystream[3]);}
24
25 ANONYMOUS_NAMESPACE_BEGIN
26
27 using CryptoPP::word32;
28 using CryptoPP::rotrConstant;
29
30 inline word32 f1(word32 x)
31 {
32 return rotrConstant<7>(x) ^ rotrConstant<18>(x) ^ (x >> 3);
33 }
34
35 inline word32 f2(word32 x)
36 {
37 return rotrConstant<17>(x) ^ rotrConstant<19>(x) ^ (x >> 10);
38 }
39
40 ANONYMOUS_NAMESPACE_END
41
42 NAMESPACE_BEGIN(CryptoPP)
43
44 inline word32 HC256Policy::H1(word32 u)
45 {
46 word32 tem;
47 byte a, b, c, d;
48 a = (byte)(u);
49 b = (byte)(u >> 8);
50 c = (byte)(u >> 16);
51 d = (byte)(u >> 24);
52 tem = m_Q[a] + m_Q[256 + b] + m_Q[512 + c] + m_Q[768 + d];
53 return (tem);
54 }
55
56 inline word32 HC256Policy::H2(word32 u)
57 {
58 word32 tem;
59 byte a, b, c, d;
60 a = (byte)(u);
61 b = (byte)(u >> 8);
62 c = (byte)(u >> 16);
63 d = (byte)(u >> 24);
64 tem = m_P[a] + m_P[256 + b] + m_P[512 + c] + m_P[768 + d];
65 return (tem);
66 }
67
68 inline word32 HC256Policy::Generate() /*one step of the cipher*/
69 {
70 word32 i, i3, i10, i12, i1023;
71 word32 output;
72
73 i = m_ctr & 0x3ff;
74 i3 = (i - 3) & 0x3ff;
75 i10 = (i - 10) & 0x3ff;
76 i12 = (i - 12) & 0x3ff;
77 i1023 = (i - 1023) & 0x3ff;
78
79 if (m_ctr < 1024) {
80 m_P[i] = m_P[i] + m_P[i10] + (rotrConstant<10>(m_P[i3]) ^ rotrConstant<23>(m_P[i1023])) + m_Q[(m_P[i3] ^ m_P[i1023]) & 0x3ff];
81 output = H1(m_P[i12]) ^ m_P[i];
82 }
83 else {
84 m_Q[i] = m_Q[i] + m_Q[i10] + (rotrConstant<10>(m_Q[i3]) ^ rotrConstant<23>(m_Q[i1023])) + m_P[(m_Q[i3] ^ m_Q[i1023]) & 0x3ff];
85 output = H2(m_Q[i12]) ^ m_Q[i];
86 }
87 m_ctr = (m_ctr + 1) & 0x7ff;
88 return (output);
89 }
90
91 void HC256Policy::GenerateKeystream(word32 keystream[4])
92 {
93 keystream[0] = Generate();
94 keystream[1] = Generate();
95 keystream[2] = Generate();
96 keystream[3] = Generate();
97 }
98
99 void HC256Policy::CipherSetKey(const NameValuePairs &params, const byte *userKey, size_t keylen)
100 {
101 CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(keylen);
102 CRYPTOPP_ASSERT(keylen == 32);
103
104 for (unsigned int i = 0; i < 8; i++)
105 m_key[i] = 0;
106
107 for (unsigned int i = 0; i < 32; i++)
108 {
109 m_key[i >> 2] = m_key[i >> 2] | userKey[i];
110 m_key[i >> 2] = rotlConstant<8>(m_key[i >> 2]);
111 }
112 }
113
114 void HC256Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
115 {
116 while (iterationCount--)
117 {
118 FixedSizeSecBlock<word32, 4> keystream;
119 GenerateKeystream(keystream);
120
121 CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(HC256_OUTPUT, BYTES_PER_ITERATION);
122 }
123 }
124
125 void HC256Policy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
126 {
127 CRYPTOPP_UNUSED(keystreamBuffer); CRYPTOPP_UNUSED(length);
128 CRYPTOPP_ASSERT(length == 32);
129
130 /* initialize the iv */
131 word32 W[2560];
132 for (unsigned int i = 0; i < 8; i++)
133 m_iv[i] = 0;
134
135 for (unsigned int i = 0; i < 32; i++)
136 {
137 m_iv[i >> 2] = m_iv[i >> 2] | iv[i];
138 m_iv[i >> 2] = rotlConstant<8>(m_iv[i >> 2]);
139 }
140
141 /* setup the table P and Q */
142
143 for (unsigned int i = 0; i < 8; i++)
144 W[i] = m_key[i];
145 for (unsigned int i = 8; i < 16; i++)
146 W[i] = m_iv[i - 8];
147
148 for (unsigned int i = 16; i < 2560; i++)
149 W[i] = f2(W[i - 2]) + W[i - 7] + f1(W[i - 15]) + W[i - 16] + i;
150
151 for (unsigned int i = 0; i < 1024; i++)
152 m_P[i] = W[i + 512];
153 for (unsigned int i = 0; i < 1024; i++)
154 m_Q[i] = W[i + 1536];
155
156 m_ctr = 0;
157
158 /* run the cipher 4096 steps before generating the output */
159 for (unsigned int i = 0; i < 4096; i++)
160 Generate();
161 }
162
163 NAMESPACE_END
FixedSizeSecBlock< word32, 4 >
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:327
config.h
Library configuration file.
byte
unsigned char byte
8-bit unsigned datatype
Definition: config_int.h:66
word32
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:72
hc256.h
Classes for HC-256 stream cipher.
misc.h
Utility functions for the Crypto++ library.
rotrConstant
T rotrConstant(T x)
Performs a right rotate.
Definition: misc.h:1783
CryptoPP
Crypto++ library namespace.
pch.h
Precompiled header file.
secblock.h
Classes and functions for secure memory allocations.
strciphr.h
Classes for implementing stream ciphers.
CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH
#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y)
Helper macro to implement OperateKeystream.
Definition: strciphr.h:266
KeystreamOperation
KeystreamOperation
Keystream operation flags.
Definition: strciphr.h:88
AdditiveCipherConcretePolicy< word32, 4 >::BYTES_PER_ITERATION
static const int BYTES_PER_ITERATION
Number of bytes for an iteration.
Definition: strciphr.h:211
CRYPTOPP_ASSERT
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68