Crypto++  8.9
Free C++ class library of cryptographic schemes
rabbit.cpp
1 // rabbit.cpp - written and placed in the public domain by Jeffrey Walton
2 // based on public domain code by Martin Boesgaard, Mette Vesterager,
3 // Thomas Pedersen, Jesper Christiansen and Ove Scavenius.
4 //
5 // The reference materials and source files are available at
6 // The eSTREAM Project, http://www.ecrypt.eu.org/stream/e2-rabbit.html.
7 
8 #include "pch.h"
9 #include "config.h"
10 
11 #include "rabbit.h"
12 #include "secblock.h"
13 #include "strciphr.h"
14 #include "misc.h"
15 
16 #define WordType word32
17 
18 #define BYTES_PER_ITERATION 16
19 
20 #define RABBIT_OUTPUT(x){\
21  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 0, (m_wx[0] ^ (m_wx[5] >> 16) ^ (m_wx[3] << 16)));\
22  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 1, (m_wx[2] ^ (m_wx[7] >> 16) ^ (m_wx[5] << 16)));\
23  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 2, (m_wx[4] ^ (m_wx[1] >> 16) ^ (m_wx[7] << 16)));\
24  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, LITTLE_ENDIAN_ORDER, 3, (m_wx[6] ^ (m_wx[3] >> 16) ^ (m_wx[1] << 16)));}
25 
26 ANONYMOUS_NAMESPACE_BEGIN
27 
28 using CryptoPP::word32;
29 using CryptoPP::word64;
31 
32 word32 G_func(word32 x)
33 {
34 #if 0
35  /* Temporary variables */
36  word32 a, b, h, l;
37 
38  /* Construct high and low argument for squaring */
39  a = x & 0xFFFF;
40  b = x >> 16;
41 
42  /* Calculate high and low result of squaring */
43  h = (((static_cast<word32>(a*a) >> 17U) + static_cast<word32>(a*b)) >> 15U) + b*b;
44  l = x*x;
45 
46  /* Return high XOR low */
47  return static_cast<word32>(h^l);
48 #endif
49 
50  // Thanks to Jack Lloyd for suggesting the 64-bit multiply.
51  word64 z = x;
52  z *= x;
53  return static_cast<word32>((z >> 32) ^ z);
54 }
55 
56 word32 NextState(word32 c[8], word32 x[8], word32 carry)
57 {
58  /* Temporary variables */
59  word32 g[8], c_old[8], i;
60 
61  /* Save old counter values */
62  for (i = 0; i<8; i++)
63  c_old[i] = c[i];
64 
65  /* Calculate new counter values */
66  c[0] = static_cast<word32>(c[0] + 0x4D34D34D + carry);
67  c[1] = static_cast<word32>(c[1] + 0xD34D34D3 + (c[0] < c_old[0]));
68  c[2] = static_cast<word32>(c[2] + 0x34D34D34 + (c[1] < c_old[1]));
69  c[3] = static_cast<word32>(c[3] + 0x4D34D34D + (c[2] < c_old[2]));
70  c[4] = static_cast<word32>(c[4] + 0xD34D34D3 + (c[3] < c_old[3]));
71  c[5] = static_cast<word32>(c[5] + 0x34D34D34 + (c[4] < c_old[4]));
72  c[6] = static_cast<word32>(c[6] + 0x4D34D34D + (c[5] < c_old[5]));
73  c[7] = static_cast<word32>(c[7] + 0xD34D34D3 + (c[6] < c_old[6]));
74  carry = (c[7] < c_old[7]);
75 
76  /* Calculate the g-values */
77  for (i = 0; i<8; i++)
78  g[i] = G_func(static_cast<word32>(x[i] + c[i]));
79 
80  /* Calculate new state values */
81  x[0] = static_cast<word32>(g[0] + rotlConstant<16>(g[7]) + rotlConstant<16>(g[6]));
82  x[1] = static_cast<word32>(g[1] + rotlConstant<8>(g[0]) + g[7]);
83  x[2] = static_cast<word32>(g[2] + rotlConstant<16>(g[1]) + rotlConstant<16>(g[0]));
84  x[3] = static_cast<word32>(g[3] + rotlConstant<8>(g[2]) + g[1]);
85  x[4] = static_cast<word32>(g[4] + rotlConstant<16>(g[3]) + rotlConstant<16>(g[2]));
86  x[5] = static_cast<word32>(g[5] + rotlConstant<8>(g[4]) + g[3]);
87  x[6] = static_cast<word32>(g[6] + rotlConstant<16>(g[5]) + rotlConstant<16>(g[4]));
88  x[7] = static_cast<word32>(g[7] + rotlConstant<8>(g[6]) + g[5]);
89 
90  return carry;
91 }
92 
93 ANONYMOUS_NAMESPACE_END
94 
95 NAMESPACE_BEGIN(CryptoPP)
96 
97 void RabbitPolicy::CipherSetKey(const NameValuePairs &params, const byte *userKey, size_t keylen)
98 {
99  /* Generate four subkeys */
100  CRYPTOPP_UNUSED(params);
101  GetUserKey(LITTLE_ENDIAN_ORDER, m_t.begin(), 4, userKey, keylen);
102 
103  /* Generate initial state variables */
104  m_mx[0] = m_t[0];
105  m_mx[2] = m_t[1];
106  m_mx[4] = m_t[2];
107  m_mx[6] = m_t[3];
108  m_mx[1] = static_cast<word32>(m_t[3] << 16) | (m_t[2] >> 16);
109  m_mx[3] = static_cast<word32>(m_t[0] << 16) | (m_t[3] >> 16);
110  m_mx[5] = static_cast<word32>(m_t[1] << 16) | (m_t[0] >> 16);
111  m_mx[7] = static_cast<word32>(m_t[2] << 16) | (m_t[1] >> 16);
112 
113  /* Generate initial counter values */
114  m_mc[0] = rotlConstant<16>(m_t[2]);
115  m_mc[2] = rotlConstant<16>(m_t[3]);
116  m_mc[4] = rotlConstant<16>(m_t[0]);
117  m_mc[6] = rotlConstant<16>(m_t[1]);
118  m_mc[1] = (m_t[0] & 0xFFFF0000) | (m_t[1] & 0xFFFF);
119  m_mc[3] = (m_t[1] & 0xFFFF0000) | (m_t[2] & 0xFFFF);
120  m_mc[5] = (m_t[2] & 0xFFFF0000) | (m_t[3] & 0xFFFF);
121  m_mc[7] = (m_t[3] & 0xFFFF0000) | (m_t[0] & 0xFFFF);
122 
123  /* Clear carry bit */
124  m_mcy = 0;
125 
126  /* Iterate the system four times */
127  for (size_t i = 0; i<4; i++)
128  m_mcy = NextState(m_mc, m_mx, m_mcy);
129 
130  /* Modify the counters */
131  for (size_t i = 0; i<8; i++)
132  m_mc[i] ^= m_mx[(i + 4) & 0x7];
133 
134  /* Copy master instance to work instance */
135  for (size_t i = 0; i<8; i++)
136  {
137  m_wx[i] = m_mx[i];
138  m_wc[i] = m_mc[i];
139  }
140  m_wcy = m_mcy;
141 }
142 
143 void RabbitPolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
144 {
145  do
146  {
147  /* Iterate the system */
148  m_wcy = NextState(m_wc, m_wx, m_wcy);
149 
151 
152  } while (--iterationCount);
153 }
154 
155 void RabbitWithIVPolicy::CipherSetKey(const NameValuePairs &params, const byte *userKey, size_t keylen)
156 {
157  /* Generate four subkeys */
158  CRYPTOPP_UNUSED(params);
159  GetUserKey(LITTLE_ENDIAN_ORDER, m_t.begin(), 4, userKey, keylen);
160 
161  /* Generate initial state variables */
162  m_mx[0] = m_t[0];
163  m_mx[2] = m_t[1];
164  m_mx[4] = m_t[2];
165  m_mx[6] = m_t[3];
166  m_mx[1] = static_cast<word32>(m_t[3] << 16) | (m_t[2] >> 16);
167  m_mx[3] = static_cast<word32>(m_t[0] << 16) | (m_t[3] >> 16);
168  m_mx[5] = static_cast<word32>(m_t[1] << 16) | (m_t[0] >> 16);
169  m_mx[7] = static_cast<word32>(m_t[2] << 16) | (m_t[1] >> 16);
170 
171  /* Generate initial counter values */
172  m_mc[0] = rotlConstant<16>(m_t[2]);
173  m_mc[2] = rotlConstant<16>(m_t[3]);
174  m_mc[4] = rotlConstant<16>(m_t[0]);
175  m_mc[6] = rotlConstant<16>(m_t[1]);
176  m_mc[1] = (m_t[0] & 0xFFFF0000) | (m_t[1] & 0xFFFF);
177  m_mc[3] = (m_t[1] & 0xFFFF0000) | (m_t[2] & 0xFFFF);
178  m_mc[5] = (m_t[2] & 0xFFFF0000) | (m_t[3] & 0xFFFF);
179  m_mc[7] = (m_t[3] & 0xFFFF0000) | (m_t[0] & 0xFFFF);
180 
181  /* Clear carry bit */
182  m_mcy = 0;
183 
184  /* Iterate the system four times */
185  for (size_t i = 0; i<4; i++)
186  m_mcy = NextState(m_mc, m_mx, m_mcy);
187 
188  /* Modify the counters */
189  for (size_t i = 0; i<8; i++)
190  m_mc[i] ^= m_mx[(i + 4) & 0x7];
191 
192  /* Copy master instance to work instance */
193  for (size_t i = 0; i<8; i++)
194  {
195  m_wx[i] = m_mx[i];
196  m_wc[i] = m_mc[i];
197  }
198  m_wcy = m_mcy;
199 }
200 
201 void RabbitWithIVPolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
202 {
203  CRYPTOPP_UNUSED(keystreamBuffer);
204  CRYPTOPP_UNUSED(length);
205  CRYPTOPP_ASSERT(length == 8);
206 
207  /* Generate four subvectors */
208  GetBlock<word32, LittleEndian> v(iv); v(m_t[0])(m_t[2]);
209  m_t[1] = (m_t[0] >> 16) | (m_t[2] & 0xFFFF0000);
210  m_t[3] = (m_t[2] << 16) | (m_t[0] & 0x0000FFFF);
211 
212  /* Modify counter values */
213  m_wc[0] = m_mc[0] ^ m_t[0];
214  m_wc[1] = m_mc[1] ^ m_t[1];
215  m_wc[2] = m_mc[2] ^ m_t[2];
216  m_wc[3] = m_mc[3] ^ m_t[3];
217  m_wc[4] = m_mc[4] ^ m_t[0];
218  m_wc[5] = m_mc[5] ^ m_t[1];
219  m_wc[6] = m_mc[6] ^ m_t[2];
220  m_wc[7] = m_mc[7] ^ m_t[3];
221 
222  /* Copy state variables */
223  for (size_t i = 0; i<8; i++)
224  m_wx[i] = m_mx[i];
225  m_wcy = m_mcy;
226 
227  /* Iterate the system four times */
228  for (size_t i = 0; i<4; i++)
229  m_wcy = NextState(m_wc, m_wx, m_wcy);
230 }
231 
232 void RabbitWithIVPolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
233 {
234  do
235  {
236  /* Iterate the system */
237  m_wcy = NextState(m_wc, m_wx, m_wcy);
238 
240 
241  } while (--iterationCount);
242 }
243 
244 NAMESPACE_END
Access a block of memory.
Definition: misc.h:2975
Interface for retrieving values given their names.
Definition: cryptlib.h:327
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:836
Library configuration file.
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:72
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:101
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Definition: cryptlib.h:150
Utility functions for the Crypto++ library.
T rotlConstant(T x)
Performs a left rotate.
Definition: misc.h:1757
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.
Definition: misc.h:2500
Crypto++ library namespace.
Precompiled header file.
Classes for Rabbit stream cipher.
Classes and functions for secure memory allocations.
Classes for implementing stream ciphers.
#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y)
Helper macro to implement OperateKeystream.
Definition: strciphr.h:266
KeystreamOperation
Keystream operation flags.
Definition: strciphr.h:88
static const int BYTES_PER_ITERATION
Number of bytes for an iteration.
Definition: strciphr.h:211
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68