Crypto++
|
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 ¶ms, 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