00001
00002
00003
00004 #include "pch.h"
00005
00006 #include "seal.h"
00007 #include "sha.h"
00008 #include "misc.h"
00009 #include "secblock.h"
00010
00011 NAMESPACE_BEGIN(CryptoPP)
00012
00013 #if !defined(NDEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING)
00014 void SEAL_TestInstantiations()
00015 {
00016 SEAL<>::Encryption x;
00017 }
00018 #endif
00019
00020 struct SEAL_Gamma
00021 {
00022 SEAL_Gamma(const byte *key)
00023 : H(5), Z(5), D(16), lastIndex(0xffffffff)
00024 {
00025 GetUserKey(BIG_ENDIAN_ORDER, H.begin(), 5, key, 20);
00026 memset(D, 0, 64);
00027 }
00028
00029 word32 Apply(word32 i);
00030
00031 SecBlock<word32> H, Z, D;
00032 word32 lastIndex;
00033 };
00034
00035 word32 SEAL_Gamma::Apply(word32 i)
00036 {
00037 word32 shaIndex = i/5;
00038 if (shaIndex != lastIndex)
00039 {
00040 memcpy(Z, H, 20);
00041 D[0] = shaIndex;
00042 SHA::Transform(Z, D);
00043 lastIndex = shaIndex;
00044 }
00045 return Z[i%5];
00046 }
00047
00048 template <class B>
00049 void SEAL_Policy<B>::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length)
00050 {
00051 CRYPTOPP_UNUSED(length);
00052 m_insideCounter = m_outsideCounter = m_startCount = 0;
00053
00054 unsigned int L = params.GetIntValueWithDefault("NumberOfOutputBitsPerPositionIndex", 32*1024);
00055 m_iterationsPerCount = L / 8192;
00056
00057 SEAL_Gamma gamma(key);
00058 unsigned int i;
00059
00060 for (i=0; i<512; i++)
00061 m_T[i] = gamma.Apply(i);
00062
00063 for (i=0; i<256; i++)
00064 m_S[i] = gamma.Apply(0x1000+i);
00065
00066 m_R.New(4*(L/8192));
00067
00068 for (i=0; i<m_R.size(); i++)
00069 m_R[i] = gamma.Apply(0x2000+i);
00070 }
00071
00072 template <class B>
00073 void SEAL_Policy<B>::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length)
00074 {
00075 CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(IV), CRYPTOPP_UNUSED(length);
00076 assert(length==4);
00077
00078 m_outsideCounter = IV ? GetWord<word32>(false, BIG_ENDIAN_ORDER, IV) : 0;
00079 m_startCount = m_outsideCounter;
00080 m_insideCounter = 0;
00081 }
00082
00083 template <class B>
00084 void SEAL_Policy<B>::SeekToIteration(lword iterationCount)
00085 {
00086 m_outsideCounter = m_startCount + (unsigned int)(iterationCount / m_iterationsPerCount);
00087 m_insideCounter = (unsigned int)(iterationCount % m_iterationsPerCount);
00088 }
00089
00090 template <class B>
00091 void SEAL_Policy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
00092 {
00093 word32 a, b, c, d, n1, n2, n3, n4;
00094 unsigned int p, q;
00095
00096 for (size_t iteration = 0; iteration < iterationCount; ++iteration)
00097 {
00098 #define Ttab(x) *(word32 *)((byte *)m_T.begin()+x)
00099
00100 a = m_outsideCounter ^ m_R[4*m_insideCounter];
00101 b = rotrFixed(m_outsideCounter, 8U) ^ m_R[4*m_insideCounter+1];
00102 c = rotrFixed(m_outsideCounter, 16U) ^ m_R[4*m_insideCounter+2];
00103 d = rotrFixed(m_outsideCounter, 24U) ^ m_R[4*m_insideCounter+3];
00104
00105 for (unsigned int j=0; j<2; j++)
00106 {
00107 p = a & 0x7fc;
00108 b += Ttab(p);
00109 a = rotrFixed(a, 9U);
00110
00111 p = b & 0x7fc;
00112 c += Ttab(p);
00113 b = rotrFixed(b, 9U);
00114
00115 p = c & 0x7fc;
00116 d += Ttab(p);
00117 c = rotrFixed(c, 9U);
00118
00119 p = d & 0x7fc;
00120 a += Ttab(p);
00121 d = rotrFixed(d, 9U);
00122 }
00123
00124 n1 = d, n2 = b, n3 = a, n4 = c;
00125
00126 p = a & 0x7fc;
00127 b += Ttab(p);
00128 a = rotrFixed(a, 9U);
00129
00130 p = b & 0x7fc;
00131 c += Ttab(p);
00132 b = rotrFixed(b, 9U);
00133
00134 p = c & 0x7fc;
00135 d += Ttab(p);
00136 c = rotrFixed(c, 9U);
00137
00138 p = d & 0x7fc;
00139 a += Ttab(p);
00140 d = rotrFixed(d, 9U);
00141
00142
00143 for (unsigned int i=0; i<64; i++)
00144 {
00145 p = a & 0x7fc;
00146 a = rotrFixed(a, 9U);
00147 b += Ttab(p);
00148 b ^= a;
00149
00150 q = b & 0x7fc;
00151 b = rotrFixed(b, 9U);
00152 c ^= Ttab(q);
00153 c += b;
00154
00155 p = (p+c) & 0x7fc;
00156 c = rotrFixed(c, 9U);
00157 d += Ttab(p);
00158 d ^= c;
00159
00160 q = (q+d) & 0x7fc;
00161 d = rotrFixed(d, 9U);
00162 a ^= Ttab(q);
00163 a += d;
00164
00165 p = (p+a) & 0x7fc;
00166 b ^= Ttab(p);
00167 a = rotrFixed(a, 9U);
00168
00169 q = (q+b) & 0x7fc;
00170 c += Ttab(q);
00171 b = rotrFixed(b, 9U);
00172
00173 p = (p+c) & 0x7fc;
00174 d ^= Ttab(p);
00175 c = rotrFixed(c, 9U);
00176
00177 q = (q+d) & 0x7fc;
00178 d = rotrFixed(d, 9U);
00179 a += Ttab(q);
00180
00181 #define SEAL_OUTPUT(x) \
00182 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, b + m_S[4*i+0]);\
00183 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 1, c ^ m_S[4*i+1]);\
00184 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 2, d + m_S[4*i+2]);\
00185 CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 3, a ^ m_S[4*i+3]);
00186
00187 CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SEAL_OUTPUT, 4*4);
00188
00189 if (i & 1)
00190 {
00191 a += n3;
00192 b += n4;
00193 c ^= n3;
00194 d ^= n4;
00195 }
00196 else
00197 {
00198 a += n1;
00199 b += n2;
00200 c ^= n1;
00201 d ^= n2;
00202 }
00203 }
00204
00205 if (++m_insideCounter == m_iterationsPerCount)
00206 {
00207 ++m_outsideCounter;
00208 m_insideCounter = 0;
00209 }
00210 }
00211
00212 a = b = c = d = n1 = n2 = n3 = n4 = 0;
00213 p = q = 0;
00214 }
00215
00216 template class SEAL_Policy<BigEndian>;
00217 template class SEAL_Policy<LittleEndian>;
00218
00219 NAMESPACE_END