Crypto++ 8.1 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 "misc.h"
13
14 ANONYMOUS_NAMESPACE_BEGIN
15
16 using CryptoPP::word32;
17 using CryptoPP::rotrConstant;
18
19 inline word32 f1(word32 x)
20 {
21 return rotrConstant<7>(x) ^ rotrConstant<18>(x) ^ (x >> 3);
22 }
23
24 inline word32 f2(word32 x)
25 {
26 return rotrConstant<17>(x) ^ rotrConstant<19>(x) ^ (x >> 10);
27 }
28
29 ANONYMOUS_NAMESPACE_END
30
31 NAMESPACE_BEGIN(CryptoPP)
32
33 inline word32 HC256Policy::H1(word32 u)
34 {
35 word32 tem;
36 byte a, b, c, d;
37 a = (byte)(u);
38 b = (byte)(u >> 8);
39 c = (byte)(u >> 16);
40 d = (byte)(u >> 24);
41 tem = m_Q[a] + m_Q[256 + b] + m_Q[512 + c] + m_Q[768 + d];
42 return (tem);
43 }
44
45 inline word32 HC256Policy::H2(word32 u)
46 {
47 word32 tem;
48 byte a, b, c, d;
49 a = (byte)(u);
50 b = (byte)(u >> 8);
51 c = (byte)(u >> 16);
52 d = (byte)(u >> 24);
53 tem = m_P[a] + m_P[256 + b] + m_P[512 + c] + m_P[768 + d];
54 return (tem);
55 }
56
57 inline word32 HC256Policy::Generate() /*one step of the cipher*/
58 {
59 word32 i, i3, i10, i12, i1023;
60 word32 output;
61
62 i = m_ctr & 0x3ff;
63 i3 = (i - 3) & 0x3ff;
64 i10 = (i - 10) & 0x3ff;
65 i12 = (i - 12) & 0x3ff;
66 i1023 = (i - 1023) & 0x3ff;
67
68 if (m_ctr < 1024) {
69 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];
70 output = H1(m_P[i12]) ^ m_P[i];
71 }
72 else {
73 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];
74 output = H2(m_Q[i12]) ^ m_Q[i];
75 }
76 m_ctr = (m_ctr + 1) & 0x7ff;
77 return (output);
78 }
79
80 void HC256Policy::CipherSetKey(const NameValuePairs &params, const byte *userKey, size_t keylen)
81 {
82 CRYPTOPP_UNUSED(params); CRYPTOPP_UNUSED(keylen);
83 CRYPTOPP_ASSERT(keylen == 32);
84
85 for (unsigned int i = 0; i < 8; i++)
86 m_key[i] = 0;
87
88 for (unsigned int i = 0; i < 32; i++)
89 {
90 m_key[i >> 2] = m_key[i >> 2] | userKey[i];
91 m_key[i >> 2] = rotlConstant<8>(m_key[i >> 2]);
92 }
93 }
94
95 void HC256Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
96 {
97 while (iterationCount--)
98 {
99 PutWord(false, LITTLE_ENDIAN_ORDER, output + 0, Generate());
100 PutWord(false, LITTLE_ENDIAN_ORDER, output + 4, Generate());
101 PutWord(false, LITTLE_ENDIAN_ORDER, output + 8, Generate());
102 PutWord(false, LITTLE_ENDIAN_ORDER, output + 12, Generate());
103
104 // If AdditiveCipherTemplate does not have an accumulated keystream
105 // then it will ask OperateKeystream to generate one. Optionally it
106 // will ask for an XOR of the input with the keystream while
107 // writing the result to the output buffer. In all cases the
108 // keystream is written to the output buffer. The optional part is
109 // adding the input buffer and keystream.
110 if ((operation & INPUT_NULL) != INPUT_NULL)
111 {
112 xorbuf(output, input, BYTES_PER_ITERATION);
113 input += BYTES_PER_ITERATION;
114 }
115
116 output += BYTES_PER_ITERATION;
117 }
118 }
119
120 void HC256Policy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
121 {
122 CRYPTOPP_UNUSED(keystreamBuffer); CRYPTOPP_UNUSED(length);
123 CRYPTOPP_ASSERT(length == 32);
124
125 /* initialize the iv */
126 word32 W[2560];
127 for (unsigned int i = 0; i < 8; i++)
128 m_iv[i] = 0;
129
130 for (unsigned int i = 0; i < 32; i++)
131 {
132 m_iv[i >> 2] = m_iv[i >> 2] | iv[i];
133 m_iv[i >> 2] = rotlConstant<8>(m_iv[i >> 2]);
134 }
135
136 /* setup the table P and Q */
137
138 for (unsigned int i = 0; i < 8; i++)
139 W[i] = m_key[i];
140 for (unsigned int i = 8; i < 16; i++)
141 W[i] = m_iv[i - 8];
142
143 for (unsigned int i = 16; i < 2560; i++)
144 W[i] = f2(W[i - 2]) + W[i - 7] + f1(W[i - 15]) + W[i - 16] + i;
145
146 for (unsigned int i = 0; i < 1024; i++)
147 m_P[i] = W[i + 512];
148 for (unsigned int i = 0; i < 1024; i++)
149 m_Q[i] = W[i + 1536];
150
151 m_ctr = 0;
152
153 /* run the cipher 4096 steps before generating the output */
154 for (unsigned int i = 0; i < 4096; i++)
155 Generate();
156 }
157
158 NAMESPACE_END
misc.h
Utility functions for the Crypto++ library.
PutWord
void PutWord(bool assumeAligned, ByteOrder order, byte *block, T value, const byte *xorBlock=NULL)
Access a block of memory.
Definition: misc.h:2396
config.h
Library configuration file.
LITTLE_ENDIAN_ORDER
byte order is little-endian
Definition: cryptlib.h:145
secblock.h
Classes and functions for secure memory allocations.
INPUT_NULL
Input buffer is NULL.
Definition: strciphr.h:82
AdditiveCipherConcretePolicy< word32, 4 >::BYTES_PER_ITERATION
static const int BYTES_PER_ITERATION
Number of bytes for an iteration.
Definition: strciphr.h:211
hc256.h
Classes for HC-256 stream cipher.
pch.h
Precompiled header file.
CRYPTOPP_ASSERT
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:69
xorbuf
void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Definition: misc.cpp:32
rotrConstant
T rotrConstant(T x)
Performs a right rotate.
Definition: misc.h:1493
KeystreamOperation
KeystreamOperation
Keystream operation flags.
Definition: strciphr.h:88
CryptoPP
Crypto++ library namespace.
NameValuePairs
Interface for retrieving values given their names.
Definition: cryptlib.h:293