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