Crypto++  5.6.4
Free C++ class library of cryptographic schemes
seal.cpp
1 // seal.cpp - written and placed in the public domain by Wei Dai
2 // updated to SEAL 3.0 by Leonard Janke
3 
4 #include "pch.h"
5 
6 #include "seal.h"
7 #include "sha.h"
8 #include "misc.h"
9 #include "secblock.h"
10 
11 NAMESPACE_BEGIN(CryptoPP)
12 
13 #if CRYPTOPP_DEBUG && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
14 void SEAL_TestInstantiations()
15 {
17 }
18 #endif
19 
20 struct SEAL_Gamma
21 {
22  SEAL_Gamma(const byte *key)
23  : H(5), Z(5), D(16), lastIndex(0xffffffff)
24  {
25  GetUserKey(BIG_ENDIAN_ORDER, H.begin(), 5, key, 20);
26  memset(D, 0, 64);
27  }
28 
29  word32 Apply(word32 i);
30 
31  SecBlock<word32> H, Z, D;
32  word32 lastIndex;
33 };
34 
35 word32 SEAL_Gamma::Apply(word32 i)
36 {
37  word32 shaIndex = i/5;
38  if (shaIndex != lastIndex)
39  {
40  memcpy(Z, H, 20);
41  D[0] = shaIndex;
42  SHA::Transform(Z, D);
43  lastIndex = shaIndex;
44  }
45  return Z[i%5];
46 }
47 
48 template <class B>
49 void SEAL_Policy<B>::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
50 {
51  CRYPTOPP_UNUSED(length);
52  m_insideCounter = m_outsideCounter = m_startCount = 0;
53 
54  unsigned int L = params.GetIntValueWithDefault("NumberOfOutputBitsPerPositionIndex", 32*1024);
55  m_iterationsPerCount = L / 8192;
56 
57  SEAL_Gamma gamma(key);
58  unsigned int i;
59 
60  for (i=0; i<512; i++)
61  m_T[i] = gamma.Apply(i);
62 
63  for (i=0; i<256; i++)
64  m_S[i] = gamma.Apply(0x1000+i);
65 
66  m_R.New(4*(L/8192));
67 
68  for (i=0; i<m_R.size(); i++)
69  m_R[i] = gamma.Apply(0x2000+i);
70 }
71 
72 template <class B>
73 void SEAL_Policy<B>::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length)
74 {
75  CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(IV), CRYPTOPP_UNUSED(length);
76  CRYPTOPP_ASSERT(length==4);
77 
78  m_outsideCounter = IV ? GetWord<word32>(false, BIG_ENDIAN_ORDER, IV) : 0;
79  m_startCount = m_outsideCounter;
80  m_insideCounter = 0;
81 }
82 
83 template <class B>
84 void SEAL_Policy<B>::SeekToIteration(lword iterationCount)
85 {
86  m_outsideCounter = m_startCount + (unsigned int)(iterationCount / m_iterationsPerCount);
87  m_insideCounter = (unsigned int)(iterationCount % m_iterationsPerCount);
88 }
89 
90 template <class B>
91 void SEAL_Policy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
92 {
93  word32 a, b, c, d, n1, n2, n3, n4;
94  unsigned int p, q;
95 
96  CRYPTOPP_ASSERT(IsAlignedOn(m_T.begin(),GetAlignmentOf<word32>()));
97  for (size_t iteration = 0; iteration < iterationCount; ++iteration)
98  {
99  #define Ttab(x) *(word32 *)(void*)((byte *)m_T.begin()+x)
100 
101  a = m_outsideCounter ^ m_R[4*m_insideCounter];
102  b = rotrFixed(m_outsideCounter, 8U) ^ m_R[4*m_insideCounter+1];
103  c = rotrFixed(m_outsideCounter, 16U) ^ m_R[4*m_insideCounter+2];
104  d = rotrFixed(m_outsideCounter, 24U) ^ m_R[4*m_insideCounter+3];
105 
106  for (unsigned int j=0; j<2; j++)
107  {
108  p = a & 0x7fc;
109  b += Ttab(p);
110  a = rotrFixed(a, 9U);
111 
112  p = b & 0x7fc;
113  c += Ttab(p);
114  b = rotrFixed(b, 9U);
115 
116  p = c & 0x7fc;
117  d += Ttab(p);
118  c = rotrFixed(c, 9U);
119 
120  p = d & 0x7fc;
121  a += Ttab(p);
122  d = rotrFixed(d, 9U);
123  }
124 
125  n1 = d, n2 = b, n3 = a, n4 = c;
126 
127  p = a & 0x7fc;
128  b += Ttab(p);
129  a = rotrFixed(a, 9U);
130 
131  p = b & 0x7fc;
132  c += Ttab(p);
133  b = rotrFixed(b, 9U);
134 
135  p = c & 0x7fc;
136  d += Ttab(p);
137  c = rotrFixed(c, 9U);
138 
139  p = d & 0x7fc;
140  a += Ttab(p);
141  d = rotrFixed(d, 9U);
142 
143  // generate 8192 bits
144  for (unsigned int i=0; i<64; i++)
145  {
146  p = a & 0x7fc;
147  a = rotrFixed(a, 9U);
148  b += Ttab(p);
149  b ^= a;
150 
151  q = b & 0x7fc;
152  b = rotrFixed(b, 9U);
153  c ^= Ttab(q);
154  c += b;
155 
156  p = (p+c) & 0x7fc;
157  c = rotrFixed(c, 9U);
158  d += Ttab(p);
159  d ^= c;
160 
161  q = (q+d) & 0x7fc;
162  d = rotrFixed(d, 9U);
163  a ^= Ttab(q);
164  a += d;
165 
166  p = (p+a) & 0x7fc;
167  b ^= Ttab(p);
168  a = rotrFixed(a, 9U);
169 
170  q = (q+b) & 0x7fc;
171  c += Ttab(q);
172  b = rotrFixed(b, 9U);
173 
174  p = (p+c) & 0x7fc;
175  d ^= Ttab(p);
176  c = rotrFixed(c, 9U);
177 
178  q = (q+d) & 0x7fc;
179  d = rotrFixed(d, 9U);
180  a += Ttab(q);
181 
182 #define SEAL_OUTPUT(x) \
183  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, b + m_S[4*i+0]);\
184  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 1, c ^ m_S[4*i+1]);\
185  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 2, d + m_S[4*i+2]);\
186  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 3, a ^ m_S[4*i+3]);
187 
188  CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SEAL_OUTPUT, 4*4);
189 
190  if (i & 1)
191  {
192  a += n3;
193  b += n4;
194  c ^= n3;
195  d ^= n4;
196  }
197  else
198  {
199  a += n1;
200  b += n2;
201  c ^= n1;
202  d ^= n2;
203  }
204  }
205 
206  if (++m_insideCounter == m_iterationsPerCount)
207  {
208  ++m_outsideCounter;
209  m_insideCounter = 0;
210  }
211  }
212 
213  a = b = c = d = n1 = n2 = n3 = n4 = 0;
214  p = q = 0;
215 }
216 
217 template class SEAL_Policy<BigEndian>;
218 template class SEAL_Policy<LittleEndian>;
219 
220 NAMESPACE_END
SEAL stream cipher operation.
Definition: seal.h:27
Utility functions for the Crypto++ library.
#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y)
Helper macro to implement OperateKeystream.
Definition: strciphr.h:237
Classes and functions for secure memory allocations.
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
Definition: misc.h:916
int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
Definition: cryptlib.h:385
byte order is big-endian
Definition: cryptlib.h:132
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:62
Classes for SEAL stream cipher.
Classes for SHA-1 and SHA-2 family of message digests.
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:499
const char * IV()
ConstByteArrayParameter, also accepts const byte * for backwards compatibility.
Definition: argnames.h:21
KeystreamOperation
Keystream operation flags.
Definition: strciphr.h:92
Crypto++ library namespace.
SymmetricCipher implementation.
Definition: strciphr.h:584
T rotrFixed(T x, unsigned int y)
Performs a right rotate.
Definition: misc.h:1336
Interface for retrieving values given their names.
Definition: cryptlib.h:282