- Main Page
- Namespaces
- Classes
- Files

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