Crypto++  8.8
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  std::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  std::memcpy(Z, H, 20);
42  D[0] = shaIndex;
43  SHA1::Transform(Z, D);
44  lastIndex = shaIndex;
45  }
46 
47  return Z[i%5];
48 }
49 
50 template <class B>
51 void SEAL_Policy<B>::CipherSetKey(const NameValuePairs &params, const byte *key, size_t length)
52 {
53  CRYPTOPP_UNUSED(length);
54  m_insideCounter = m_outsideCounter = m_startCount = 0;
55 
56  unsigned int L = params.GetIntValueWithDefault("NumberOfOutputBitsPerPositionIndex", 32*1024);
57  m_iterationsPerCount = L / 8192;
58 
59  SEAL_Gamma gamma(key);
60  unsigned int i;
61 
62  for (i=0; i<512; i++)
63  m_T[i] = gamma.Apply(i);
64 
65  for (i=0; i<256; i++)
66  m_S[i] = gamma.Apply(0x1000+i);
67 
68  m_R.New(4*(L/8192));
69 
70  for (i=0; i<m_R.size(); i++)
71  m_R[i] = gamma.Apply(0x2000+i);
72 }
73 
74 template <class B>
75 void SEAL_Policy<B>::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length)
76 {
77  CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(IV), CRYPTOPP_UNUSED(length);
78  CRYPTOPP_ASSERT(length==4);
79 
80  m_outsideCounter = IV ? GetWord<word32>(false, BIG_ENDIAN_ORDER, IV) : 0;
81  m_startCount = m_outsideCounter;
82  m_insideCounter = 0;
83 }
84 
85 template <class B>
86 void SEAL_Policy<B>::SeekToIteration(lword iterationCount)
87 {
88  m_outsideCounter = m_startCount + (unsigned int)(iterationCount / m_iterationsPerCount);
89  m_insideCounter = (unsigned int)(iterationCount % m_iterationsPerCount);
90 }
91 
92 template <class B>
93 void SEAL_Policy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
94 {
95  word32 a, b, c, d, n1, n2, n3, n4;
96  unsigned int p, q;
97 
98  CRYPTOPP_ASSERT(IsAlignedOn(m_T.begin(),GetAlignmentOf<word32>()));
99  for (size_t iteration = 0; iteration < iterationCount; ++iteration)
100  {
101  #define Ttab(x) *(word32 *)(void*)((byte *)m_T.begin()+x)
102 
103  a = m_outsideCounter ^ m_R[4*m_insideCounter];
104  b = rotrConstant<8>(m_outsideCounter) ^ m_R[4*m_insideCounter+1];
105  c = rotrConstant<16>(m_outsideCounter) ^ m_R[4 * m_insideCounter + 2];
106  d = rotrConstant<24>(m_outsideCounter) ^ m_R[4 * m_insideCounter + 3];
107 
108  for (unsigned int j=0; j<2; j++)
109  {
110  p = a & 0x7fc;
111  b += Ttab(p);
112  a = rotrConstant<9>(a);
113 
114  p = b & 0x7fc;
115  c += Ttab(p);
116  b = rotrConstant<9>(b);
117 
118  p = c & 0x7fc;
119  d += Ttab(p);
120  c = rotrConstant<9>(c);
121 
122  p = d & 0x7fc;
123  a += Ttab(p);
124  d = rotrConstant<9>(d);
125  }
126 
127  n1 = d, n2 = b, n3 = a, n4 = c;
128 
129  p = a & 0x7fc;
130  b += Ttab(p);
131  a = rotrConstant<9>(a);
132 
133  p = b & 0x7fc;
134  c += Ttab(p);
135  b = rotrConstant<9>(b);
136 
137  p = c & 0x7fc;
138  d += Ttab(p);
139  c = rotrConstant<9>(c);
140 
141  p = d & 0x7fc;
142  a += Ttab(p);
143  d = rotrConstant<9>(d);
144 
145  // generate 8192 bits
146  for (unsigned int i=0; i<64; i++)
147  {
148  p = a & 0x7fc;
149  a = rotrConstant<9>(a);
150  b += Ttab(p);
151  b ^= a;
152 
153  q = b & 0x7fc;
154  b = rotrConstant<9>(b);
155  c ^= Ttab(q);
156  c += b;
157 
158  p = (p+c) & 0x7fc;
159  c = rotrConstant<9>(c);
160  d += Ttab(p);
161  d ^= c;
162 
163  q = (q+d) & 0x7fc;
164  d = rotrConstant<9>(d);
165  a ^= Ttab(q);
166  a += d;
167 
168  p = (p+a) & 0x7fc;
169  b ^= Ttab(p);
170  a = rotrConstant<9>(a);
171 
172  q = (q+b) & 0x7fc;
173  c += Ttab(q);
174  b = rotrConstant<9>(b);
175 
176  p = (p+c) & 0x7fc;
177  d ^= Ttab(p);
178  c = rotrConstant<9>(c);
179 
180  q = (q+d) & 0x7fc;
181  d = rotrConstant<9>(d);
182  a += Ttab(q);
183 
184 #define SEAL_OUTPUT(x) \
185  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, b + m_S[4*i+0]);\
186  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 1, c ^ m_S[4*i+1]);\
187  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 2, d + m_S[4*i+2]);\
188  CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 3, a ^ m_S[4*i+3]);
189 
190  CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SEAL_OUTPUT, 4*4);
191 
192  if (i & 1)
193  {
194  a += n3;
195  b += n4;
196  c ^= n3;
197  d ^= n4;
198  }
199  else
200  {
201  a += n1;
202  b += n2;
203  c ^= n1;
204  d ^= n2;
205  }
206  }
207 
208  if (++m_insideCounter == m_iterationsPerCount)
209  {
210  ++m_outsideCounter;
211  m_insideCounter = 0;
212  }
213  }
214 
215  a = b = c = d = n1 = n2 = n3 = n4 = 0;
216  p = q = 0;
217 }
218 
219 template class SEAL_Policy<BigEndian>;
220 template class SEAL_Policy<LittleEndian>;
221 
222 NAMESPACE_END
Interface for retrieving values given their names.
Definition: cryptlib.h:327
CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
Definition: cryptlib.h:429
SEAL stream cipher operation.
Definition: seal.h:29
static void Transform(HashWordType *digest, const HashWordType *data)
Operate the hash.
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:836
SymmetricCipher implementation.
Definition: strciphr.h:684
unsigned int word32
32-bit unsigned datatype
Definition: config_int.h:72
word64 lword
Large word type.
Definition: config_int.h:168
Functions for CPU features and intrinsics.
@ BIG_ENDIAN_ORDER
byte order is big-endian
Definition: cryptlib.h:152
Utility functions for the Crypto++ library.
bool IsAlignedOn(const void *ptr, unsigned int alignment)
Determines whether ptr is aligned to a minimum value.
Definition: misc.h:1436
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.
const char * IV()
ConstByteArrayParameter, also accepts const byte * for backwards compatibility.
Definition: argnames.h:21
Precompiled header file.
Classes for SEAL stream cipher.
Classes and functions for secure memory allocations.
Classes for SHA-1 and SHA-2 family of message digests.
#define CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(x, y)
Helper macro to implement OperateKeystream.
Definition: strciphr.h:266
KeystreamOperation
Keystream operation flags.
Definition: strciphr.h:88
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:68