Crypto++ 8.7
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
12NAMESPACE_BEGIN(CryptoPP)
13
14#if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
15void SEAL_TestInstantiations()
16{
18}
19#endif
20
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
36word32 SEAL_Gamma::Apply(word32 i)
37{
38 word32 shaIndex = i/5;
39 if (shaIndex != lastIndex)
40 {
41 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
50template <class B>
51void 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
74template <class B>
75void 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
85template <class B>
86void 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
92template <class B>
93void 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
219template class SEAL_Policy<BigEndian>;
220template class SEAL_Policy<LittleEndian>;
221
222NAMESPACE_END
Interface for retrieving values given their names.
Definition: cryptlib.h:322
CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
Definition: cryptlib.h:424
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:62
word64 lword
Large word type.
Definition: config_int.h:158
Functions for CPU features and intrinsics.
@ BIG_ENDIAN_ORDER
byte order is big-endian
Definition: cryptlib.h:147
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:1227
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:2291
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