seal.cpp

00001 // seal.cpp - written and placed in the public domain by Wei Dai
00002 // updated to SEAL 3.0 by Leonard Janke
00003 
00004 #include "pch.h"
00005 
00006 // prevent Sun's CC compiler from including this file automatically
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 &params, 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 ? GetWord<word32>(false, 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         word32 a, b, c, d, n1, n2, n3, n4;
00090         unsigned int p, q;
00091 
00092         for (size_t iteration = 0; iteration < iterationCount; ++iteration)
00093         {
00094 #define Ttab(x) *(word32 *)((byte *)m_T.begin()+x)
00095 
00096                 a = m_outsideCounter ^ m_R[4*m_insideCounter];
00097                 b = rotrFixed(m_outsideCounter, 8U) ^ m_R[4*m_insideCounter+1];
00098                 c = rotrFixed(m_outsideCounter, 16U) ^ m_R[4*m_insideCounter+2];
00099                 d = rotrFixed(m_outsideCounter, 24U) ^ m_R[4*m_insideCounter+3];
00100 
00101                 for (unsigned int j=0; j<2; j++)
00102                 {
00103                         p = a & 0x7fc;
00104                         b += Ttab(p);
00105                         a = rotrFixed(a, 9U);
00106 
00107                         p = b & 0x7fc;
00108                         c += Ttab(p);
00109                         b = rotrFixed(b, 9U);
00110 
00111                         p = c & 0x7fc;
00112                         d += Ttab(p);
00113                         c = rotrFixed(c, 9U);
00114 
00115                         p = d & 0x7fc;
00116                         a += Ttab(p);
00117                         d = rotrFixed(d, 9U);
00118                 }
00119 
00120                 n1 = d, n2 = b, n3 = a, n4 = c;
00121 
00122                 p = a & 0x7fc;
00123                 b += Ttab(p);
00124                 a = rotrFixed(a, 9U);
00125 
00126                 p = b & 0x7fc;
00127                 c += Ttab(p);
00128                 b = rotrFixed(b, 9U);
00129 
00130                 p = c & 0x7fc;
00131                 d += Ttab(p);
00132                 c = rotrFixed(c, 9U);
00133 
00134                 p = d & 0x7fc;
00135                 a += Ttab(p);
00136                 d = rotrFixed(d, 9U);
00137                 
00138                 // generate 8192 bits
00139                 for (unsigned int i=0; i<64; i++)
00140                 {
00141                         p = a & 0x7fc;
00142                         a = rotrFixed(a, 9U);
00143                         b += Ttab(p);
00144                         b ^= a;
00145 
00146                         q = b & 0x7fc;
00147                         b = rotrFixed(b, 9U);
00148                         c ^= Ttab(q);
00149                         c += b;
00150 
00151                         p = (p+c) & 0x7fc;
00152                         c = rotrFixed(c, 9U);
00153                         d += Ttab(p);
00154                         d ^= c;
00155 
00156                         q = (q+d) & 0x7fc;
00157                         d = rotrFixed(d, 9U);
00158                         a ^= Ttab(q);
00159                         a += d;
00160 
00161                         p = (p+a) & 0x7fc;
00162                         b ^= Ttab(p);
00163                         a = rotrFixed(a, 9U);
00164 
00165                         q = (q+b) & 0x7fc;
00166                         c += Ttab(q);
00167                         b = rotrFixed(b, 9U);
00168 
00169                         p = (p+c) & 0x7fc;
00170                         d ^= Ttab(p);
00171                         c = rotrFixed(c, 9U);
00172 
00173                         q = (q+d) & 0x7fc;
00174                         d = rotrFixed(d, 9U);
00175                         a += Ttab(q);
00176 
00177 #define SEAL_OUTPUT(x)  \
00178         CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, b + m_S[4*i+0]);\
00179         CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 1, c ^ m_S[4*i+1]);\
00180         CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 2, d + m_S[4*i+2]);\
00181         CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 3, a ^ m_S[4*i+3]);
00182 
00183                         CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SEAL_OUTPUT, 4*4);
00184 
00185                         if (i & 1)
00186                         {
00187                                 a += n3;
00188                                 b += n4;
00189                                 c ^= n3;
00190                                 d ^= n4;
00191                         }
00192                         else
00193                         {
00194                                 a += n1;
00195                                 b += n2;        
00196                                 c ^= n1;
00197                                 d ^= n2;
00198                         }
00199                 }
00200 
00201                 if (++m_insideCounter == m_iterationsPerCount)
00202                 {
00203                         ++m_outsideCounter;
00204                         m_insideCounter = 0;
00205                 }
00206         }
00207 
00208         a = b = c = d = n1 = n2 = n3 = n4 = 0;
00209         p = q = 0;
00210 }
00211 
00212 template class SEAL_Policy<BigEndian>;
00213 template class SEAL_Policy<LittleEndian>;
00214 
00215 NAMESPACE_END
00216 
00217 #endif

Generated on Fri Jun 1 11:11:24 2007 for Crypto++ by  doxygen 1.5.2