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 ? 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                 // generate 8192 bits
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

Generated on Sat Dec 23 02:07:10 2006 for Crypto++ by  doxygen 1.5.1-p1