// serpent.cpp - originally written and placed in the public domain by Wei Dai #include "pch.h" #include "serpent.h" #include "secblock.h" #include "misc.h" #include "serpentp.h" NAMESPACE_BEGIN(CryptoPP) void Serpent_KeySchedule(word32 *k, unsigned int rounds, const byte *userKey, size_t keylen) { FixedSizeSecBlock k0; GetUserKey(LITTLE_ENDIAN_ORDER, k0.begin(), 8, userKey, keylen); if (keylen < 32) k0[keylen/4] |= word32(1) << ((keylen%4)*8); word32 t = k0[7]; unsigned int i; for (i = 0; i < 8; ++i) k[i] = k0[i] = t = rotlConstant<11>(k0[i] ^ k0[(i + 3) % 8] ^ k0[(i + 5) % 8] ^ t ^ 0x9e3779b9 ^ i); for (i = 8; i < 4*(rounds+1); ++i) k[i] = t = rotlConstant<11>(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i); k -= 20; word32 a,b,c,d,e; for (i=0; i Block; void Serpent::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const { word32 a, b, c, d, e; Block::Get(inBlock)(a)(b)(c)(d); const word32 *k = m_key; unsigned int i=1; do { beforeS0(KX); beforeS0(S0); afterS0(LT); afterS0(KX); afterS0(S1); afterS1(LT); afterS1(KX); afterS1(S2); afterS2(LT); afterS2(KX); afterS2(S3); afterS3(LT); afterS3(KX); afterS3(S4); afterS4(LT); afterS4(KX); afterS4(S5); afterS5(LT); afterS5(KX); afterS5(S6); afterS6(LT); afterS6(KX); afterS6(S7); if (i == 4) break; ++i; c = b; b = e; e = d; d = a; a = e; k += 32; beforeS0(LT); } while (true); afterS7(KX); Block::Put(xorBlock, outBlock)(d)(e)(b)(a); } void Serpent::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const { word32 a, b, c, d, e=0; Block::Get(inBlock)(a)(b)(c)(d); const word32 *k = m_key + 96; unsigned int i=4; beforeI7(KX); goto start; do { c = b; b = d; d = e; k -= 32; beforeI7(ILT); start: beforeI7(I7); afterI7(KX); afterI7(ILT); afterI7(I6); afterI6(KX); afterI6(ILT); afterI6(I5); afterI5(KX); afterI5(ILT); afterI5(I4); afterI4(KX); afterI4(ILT); afterI4(I3); afterI3(KX); afterI3(ILT); afterI3(I2); afterI2(KX); afterI2(ILT); afterI2(I1); afterI1(KX); afterI1(ILT); afterI1(I0); afterI0(KX); } while (--i != 0); Block::Put(xorBlock, outBlock)(a)(d)(b)(e); } NAMESPACE_END