Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

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 #include "seal.h"
00006 #include "sha.h"
00007 
00008 NAMESPACE_BEGIN(CryptoPP)
00009 
00010 ANONYMOUS_NAMESPACE_BEGIN
00011         struct Gamma
00012         {
00013                 Gamma(const byte *key);
00014                 word32 Apply(word32 i);
00015 
00016                 SecBlock<word32> H, Z, D;
00017                 word32 lastIndex;
00018         };
00019 
00020         Gamma::Gamma(const byte *key)
00021                 : lastIndex(0xffffffff), H(5), Z(5), D(16)
00022         {
00023                 GetUserKeyBigEndian(H.ptr, 5, key, 20);
00024                 memset(D, 0, 64);
00025         }
00026 
00027         word32 Gamma::Apply(word32 i)
00028         {
00029                 word32 shaIndex = i/5;
00030                 if (shaIndex != lastIndex)
00031                 {
00032                         memcpy(Z, H, 20);
00033                         D[0] = shaIndex;
00034                         SHA::Transform(Z, D);
00035                         lastIndex = shaIndex;
00036                 }
00037                 return Z[i%5];
00038         }
00039 NAMESPACE_END
00040 
00041 SEAL::SEAL(const byte *key, word32 counter, unsigned int L)
00042         : L(L), R(4*L/8192), S(256), T(512), 
00043         startCount(counter), counter(counter), position(0), buffer(L/8)
00044 {
00045         assert(L%8192 == 0);
00046 
00047         Gamma gamma(key);
00048         unsigned int i;
00049 
00050         for (i=0; i<512; i++)
00051                 T[i] = gamma.Apply(i);
00052 
00053         for (i=0; i<256; i++)
00054                 S[i] = gamma.Apply(0x1000+i);
00055 
00056         for (i=0; i<4*(L/8192); i++)
00057                 R[i] = gamma.Apply(0x2000+i);
00058 
00059         Generate(counter, buffer);
00060 }
00061 
00062 byte SEAL::GenerateByte()
00063 {
00064         if (position == L/8)
00065                 IncrementCounter();
00066         return buffer[position++];
00067 }
00068 
00069 void SEAL::ProcessString(byte *outString, const byte *inString, unsigned int length)
00070 {
00071         while (length >= L/8-position)
00072         {
00073                 xorbuf(outString, inString, buffer+position, L/8-position);
00074                 length -= L/8-position;
00075                 inString += L/8-position;
00076                 outString += L/8-position;
00077                 IncrementCounter();
00078         }
00079 
00080         xorbuf(outString, inString, buffer+position, length);
00081         position += length;
00082 }
00083 
00084 void SEAL::Seek(unsigned long seekPosition)
00085 {
00086         counter = startCount + seekPosition/(L/8);
00087         position = seekPosition%(L/8);
00088         Generate(counter, buffer);
00089 }
00090 
00091 void SEAL::IncrementCounter()
00092 {
00093         counter++;
00094         position = 0;
00095         Generate(counter, buffer);
00096 }
00097 
00098 void SEAL::Generate(word32 in, byte *out) const
00099 {
00100         word32 a, b, c, d, n1, n2, n3, n4;
00101         unsigned int p, q;
00102         word32 *wout = (word32 *)out;
00103 
00104         for (unsigned int l=0; l<L/8192; l++)
00105         {
00106                 a = in ^ R[4*l];
00107                 b = rotrFixed(in, 8U) ^ R[4*l+1];
00108                 c = rotrFixed(in, 16U) ^ R[4*l+2];
00109                 d = rotrFixed(in, 24U) ^ R[4*l+3];
00110 
00111 #define Ttab(x) *(word32 *)((byte *)T.ptr+x)
00112         
00113                 for (unsigned int j=0; j<2; j++)
00114                 {
00115                         p = a & 0x7fc;
00116                         b += Ttab(p);
00117                         a = rotrFixed(a, 9U);
00118         
00119                         p = b & 0x7fc;
00120                         c += Ttab(p);
00121                         b = rotrFixed(b, 9U);
00122         
00123                         p = c & 0x7fc;
00124                         d += Ttab(p);
00125                         c = rotrFixed(c, 9U);
00126         
00127                         p = d & 0x7fc;
00128                         a += Ttab(p);
00129                         d = rotrFixed(d, 9U);
00130                 }
00131 
00132                 n1 = d; n2 = b; n3 = a; n4 = c;
00133         
00134                 p = a & 0x7fc;
00135                 b += Ttab(p);
00136                 a = rotrFixed(a, 9U);
00137         
00138                 p = b & 0x7fc;
00139                 c += Ttab(p);
00140                 b = rotrFixed(b, 9U);
00141         
00142                 p = c & 0x7fc;
00143                 d += Ttab(p);
00144                 c = rotrFixed(c, 9U);
00145         
00146                 p = d & 0x7fc;
00147                 a += Ttab(p);
00148                 d = rotrFixed(d, 9U);
00149                 
00150                 // generate 8192 bits
00151                 for (unsigned int i=0; i<64; i++)
00152                 {
00153                         p = a & 0x7fc;
00154                         a = rotrFixed(a, 9U);
00155                         b += Ttab(p);
00156                         b ^= a;
00157         
00158                         q = b & 0x7fc;
00159                         b = rotrFixed(b, 9U);
00160                         c ^= Ttab(q);
00161                         c += b;
00162         
00163                         p = (p+c) & 0x7fc;
00164                         c = rotrFixed(c, 9U);
00165                         d += Ttab(p);
00166                         d ^= c;
00167         
00168                         q = (q+d) & 0x7fc;
00169                         d = rotrFixed(d, 9U);
00170                         a ^= Ttab(q);
00171                         a += d;
00172         
00173                         p = (p+a) & 0x7fc;
00174                         b ^= Ttab(p);
00175                         a = rotrFixed(a, 9U);
00176         
00177                         q = (q+b) & 0x7fc;
00178                         c += Ttab(q);
00179                         b = rotrFixed(b, 9U);
00180         
00181                         p = (p+c) & 0x7fc;
00182                         d ^= Ttab(p);
00183                         c = rotrFixed(c, 9U);
00184         
00185                         q = (q+d) & 0x7fc;
00186                         d = rotrFixed(d, 9U);
00187                         a += Ttab(q);
00188 
00189 #ifdef IS_LITTLE_ENDIAN
00190                         wout[0] = byteReverse(b + S[4*i+0]);
00191                         wout[1] = byteReverse(c ^ S[4*i+1]);
00192                         wout[2] = byteReverse(d + S[4*i+2]);
00193                         wout[3] = byteReverse(a ^ S[4*i+3]);
00194 #else
00195                         wout[0] = b + S[4*i+0];
00196                         wout[1] = c ^ S[4*i+1];
00197                         wout[2] = d + S[4*i+2];
00198                         wout[3] = a ^ S[4*i+3];
00199 #endif
00200                         wout += 4;
00201         
00202                         if (i & 1)
00203                         {
00204                                 a += n3;
00205                                 b += n4;
00206                                 c ^= n3;
00207                                 d ^= n4;
00208                         }
00209                         else
00210                         {
00211                                 a += n1;
00212                                 b += n2;        
00213                                 c ^= n1;
00214                                 d ^= n2;
00215                         }
00216                 }
00217         }
00218 
00219         a = b = c = d = n1 = n2 = n3 = n4 = 0;
00220         p = q = 0;
00221 }
00222 
00223 NAMESPACE_END

Generated at Mon Jan 15 01:16:36 2001 for Crypto++ by doxygen1.2.4 written by Dimitri van Heesch, © 1997-2000