// seal.cpp - originally written and placed in the public domain by Wei Dai // updated to SEAL 3.0 by Leonard Janke #include "pch.h" #include "seal.h" #include "cpu.h" #include "sha.h" #include "misc.h" #include "secblock.h" NAMESPACE_BEGIN(CryptoPP) #if defined(CRYPTOPP_DEBUG) && !defined(CRYPTOPP_DOXYGEN_PROCESSING) void SEAL_TestInstantiations() { SEAL<>::Encryption x; } #endif struct SEAL_Gamma { SEAL_Gamma(const byte *key) : H(5), Z(5), D(16), lastIndex(0xffffffff) { GetUserKey(BIG_ENDIAN_ORDER, H.begin(), 5, key, 20); std::memset(D, 0, 64); } word32 Apply(word32 i); SecBlock H, Z, D; word32 lastIndex; }; word32 SEAL_Gamma::Apply(word32 i) { word32 shaIndex = i/5; if (shaIndex != lastIndex) { std::memcpy(Z, H, 20); D[0] = shaIndex; SHA1::Transform(Z, D); lastIndex = shaIndex; } return Z[i%5]; } template void SEAL_Policy::CipherSetKey(const NameValuePairs ¶ms, const byte *key, size_t length) { CRYPTOPP_UNUSED(length); m_insideCounter = m_outsideCounter = m_startCount = 0; unsigned int L = params.GetIntValueWithDefault("NumberOfOutputBitsPerPositionIndex", 32*1024); m_iterationsPerCount = L / 8192; SEAL_Gamma gamma(key); unsigned int i; for (i=0; i<512; i++) m_T[i] = gamma.Apply(i); for (i=0; i<256; i++) m_S[i] = gamma.Apply(0x1000+i); m_R.New(4*(L/8192)); for (i=0; i void SEAL_Policy::CipherResynchronize(byte *keystreamBuffer, const byte *IV, size_t length) { CRYPTOPP_UNUSED(keystreamBuffer), CRYPTOPP_UNUSED(IV), CRYPTOPP_UNUSED(length); CRYPTOPP_ASSERT(length==4); m_outsideCounter = IV ? GetWord(false, BIG_ENDIAN_ORDER, IV) : 0; m_startCount = m_outsideCounter; m_insideCounter = 0; } template void SEAL_Policy::SeekToIteration(lword iterationCount) { m_outsideCounter = m_startCount + (unsigned int)(iterationCount / m_iterationsPerCount); m_insideCounter = (unsigned int)(iterationCount % m_iterationsPerCount); } template void SEAL_Policy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount) { word32 a, b, c, d, n1, n2, n3, n4; unsigned int p, q; CRYPTOPP_ASSERT(IsAlignedOn(m_T.begin(),GetAlignmentOf())); for (size_t iteration = 0; iteration < iterationCount; ++iteration) { #define Ttab(x) *(word32 *)(void*)((byte *)m_T.begin()+x) a = m_outsideCounter ^ m_R[4*m_insideCounter]; b = rotrConstant<8>(m_outsideCounter) ^ m_R[4*m_insideCounter+1]; c = rotrConstant<16>(m_outsideCounter) ^ m_R[4 * m_insideCounter + 2]; d = rotrConstant<24>(m_outsideCounter) ^ m_R[4 * m_insideCounter + 3]; for (unsigned int j=0; j<2; j++) { p = a & 0x7fc; b += Ttab(p); a = rotrConstant<9>(a); p = b & 0x7fc; c += Ttab(p); b = rotrConstant<9>(b); p = c & 0x7fc; d += Ttab(p); c = rotrConstant<9>(c); p = d & 0x7fc; a += Ttab(p); d = rotrConstant<9>(d); } n1 = d, n2 = b, n3 = a, n4 = c; p = a & 0x7fc; b += Ttab(p); a = rotrConstant<9>(a); p = b & 0x7fc; c += Ttab(p); b = rotrConstant<9>(b); p = c & 0x7fc; d += Ttab(p); c = rotrConstant<9>(c); p = d & 0x7fc; a += Ttab(p); d = rotrConstant<9>(d); // generate 8192 bits for (unsigned int i=0; i<64; i++) { p = a & 0x7fc; a = rotrConstant<9>(a); b += Ttab(p); b ^= a; q = b & 0x7fc; b = rotrConstant<9>(b); c ^= Ttab(q); c += b; p = (p+c) & 0x7fc; c = rotrConstant<9>(c); d += Ttab(p); d ^= c; q = (q+d) & 0x7fc; d = rotrConstant<9>(d); a ^= Ttab(q); a += d; p = (p+a) & 0x7fc; b ^= Ttab(p); a = rotrConstant<9>(a); q = (q+b) & 0x7fc; c += Ttab(q); b = rotrConstant<9>(b); p = (p+c) & 0x7fc; d ^= Ttab(p); c = rotrConstant<9>(c); q = (q+d) & 0x7fc; d = rotrConstant<9>(d); a += Ttab(q); #define SEAL_OUTPUT(x) \ CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 0, b + m_S[4*i+0]);\ CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 1, c ^ m_S[4*i+1]);\ CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 2, d + m_S[4*i+2]);\ CRYPTOPP_KEYSTREAM_OUTPUT_WORD(x, B::ToEnum(), 3, a ^ m_S[4*i+3]); CRYPTOPP_KEYSTREAM_OUTPUT_SWITCH(SEAL_OUTPUT, 4*4); if (i & 1) { a += n3; b += n4; c ^= n3; d ^= n4; } else { a += n1; b += n2; c ^= n1; d ^= n2; } } if (++m_insideCounter == m_iterationsPerCount) { ++m_outsideCounter; m_insideCounter = 0; } } a = b = c = d = n1 = n2 = n3 = n4 = 0; p = q = 0; } template class SEAL_Policy; template class SEAL_Policy; NAMESPACE_END