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