00001
00002
00003
00004 #include "pch.h"
00005
00006
00007 #if !(defined(__SUNPRO_CC) && defined(CRYPTOPP_ITERHASH_H))
00008
00009 #include "seal.h"
00010 #include "sha.h"
00011 #include "misc.h"
00012
00013 NAMESPACE_BEGIN(CryptoPP)
00014
00015 void SEAL_TestInstantiations()
00016 {
00017 SEAL<>::Encryption x;
00018 }
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 m_insideCounter = m_outsideCounter = m_startCount = 0;
00052
00053 unsigned int L = params.GetIntValueWithDefault("NumberOfOutputBitsPerPositionIndex", 32*1024);
00054 m_iterationsPerCount = L / 8192;
00055
00056 SEAL_Gamma gamma(key);
00057 unsigned int i;
00058
00059 for (i=0; i<512; i++)
00060 m_T[i] = gamma.Apply(i);
00061
00062 for (i=0; i<256; i++)
00063 m_S[i] = gamma.Apply(0x1000+i);
00064
00065 m_R.New(4*(L/8192));
00066
00067 for (i=0; i<m_R.size(); i++)
00068 m_R[i] = gamma.Apply(0x2000+i);
00069 }
00070
00071 template <class B>
00072 void SEAL_Policy<B>::CipherResynchronize(byte *keystreamBuffer, const byte *IV)
00073 {
00074 m_outsideCounter = IV ? UnalignedGetWord<word32>(BIG_ENDIAN_ORDER, IV) : 0;
00075 m_startCount = m_outsideCounter;
00076 m_insideCounter = 0;
00077 }
00078
00079 template <class B>
00080 void SEAL_Policy<B>::SeekToIteration(lword iterationCount)
00081 {
00082 m_outsideCounter = m_startCount + (unsigned int)(iterationCount / m_iterationsPerCount);
00083 m_insideCounter = (unsigned int)(iterationCount % m_iterationsPerCount);
00084 }
00085
00086 template <class B>
00087 void SEAL_Policy<B>::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
00088 {
00089 KeystreamOutput<B> keystreamOutput(operation, output, input);
00090 word32 a, b, c, d, n1, n2, n3, n4;
00091 unsigned int p, q;
00092
00093 for (size_t iteration = 0; iteration < iterationCount; ++iteration)
00094 {
00095 #define Ttab(x) *(word32 *)((byte *)m_T.begin()+x)
00096
00097 a = m_outsideCounter ^ m_R[4*m_insideCounter];
00098 b = rotrFixed(m_outsideCounter, 8U) ^ m_R[4*m_insideCounter+1];
00099 c = rotrFixed(m_outsideCounter, 16U) ^ m_R[4*m_insideCounter+2];
00100 d = rotrFixed(m_outsideCounter, 24U) ^ m_R[4*m_insideCounter+3];
00101
00102 for (unsigned int j=0; j<2; j++)
00103 {
00104 p = a & 0x7fc;
00105 b += Ttab(p);
00106 a = rotrFixed(a, 9U);
00107
00108 p = b & 0x7fc;
00109 c += Ttab(p);
00110 b = rotrFixed(b, 9U);
00111
00112 p = c & 0x7fc;
00113 d += Ttab(p);
00114 c = rotrFixed(c, 9U);
00115
00116 p = d & 0x7fc;
00117 a += Ttab(p);
00118 d = rotrFixed(d, 9U);
00119 }
00120
00121 n1 = d, n2 = b, n3 = a, n4 = c;
00122
00123 p = a & 0x7fc;
00124 b += Ttab(p);
00125 a = rotrFixed(a, 9U);
00126
00127 p = b & 0x7fc;
00128 c += Ttab(p);
00129 b = rotrFixed(b, 9U);
00130
00131 p = c & 0x7fc;
00132 d += Ttab(p);
00133 c = rotrFixed(c, 9U);
00134
00135 p = d & 0x7fc;
00136 a += Ttab(p);
00137 d = rotrFixed(d, 9U);
00138
00139
00140 for (unsigned int i=0; i<64; i++)
00141 {
00142 p = a & 0x7fc;
00143 a = rotrFixed(a, 9U);
00144 b += Ttab(p);
00145 b ^= a;
00146
00147 q = b & 0x7fc;
00148 b = rotrFixed(b, 9U);
00149 c ^= Ttab(q);
00150 c += b;
00151
00152 p = (p+c) & 0x7fc;
00153 c = rotrFixed(c, 9U);
00154 d += Ttab(p);
00155 d ^= c;
00156
00157 q = (q+d) & 0x7fc;
00158 d = rotrFixed(d, 9U);
00159 a ^= Ttab(q);
00160 a += d;
00161
00162 p = (p+a) & 0x7fc;
00163 b ^= Ttab(p);
00164 a = rotrFixed(a, 9U);
00165
00166 q = (q+b) & 0x7fc;
00167 c += Ttab(q);
00168 b = rotrFixed(b, 9U);
00169
00170 p = (p+c) & 0x7fc;
00171 d ^= Ttab(p);
00172 c = rotrFixed(c, 9U);
00173
00174 q = (q+d) & 0x7fc;
00175 d = rotrFixed(d, 9U);
00176 a += Ttab(q);
00177
00178 keystreamOutput (b + m_S[4*i+0])
00179 (c ^ m_S[4*i+1])
00180 (d + m_S[4*i+2])
00181 (a ^ m_S[4*i+3]);
00182
00183 if (i & 1)
00184 {
00185 a += n3;
00186 b += n4;
00187 c ^= n3;
00188 d ^= n4;
00189 }
00190 else
00191 {
00192 a += n1;
00193 b += n2;
00194 c ^= n1;
00195 d ^= n2;
00196 }
00197 }
00198
00199 if (++m_insideCounter == m_iterationsPerCount)
00200 {
00201 ++m_outsideCounter;
00202 m_insideCounter = 0;
00203 }
00204 }
00205
00206 a = b = c = d = n1 = n2 = n3 = n4 = 0;
00207 p = q = 0;
00208 }
00209
00210 template class SEAL_Policy<BigEndian>;
00211 template class SEAL_Policy<LittleEndian>;
00212
00213 NAMESPACE_END
00214
00215 #endif