1// serpent.cpp - written and placed in the public domain by Wei Dai 2 3#include "pch.h" 4#include "serpent.h" 5#include "misc.h" 6 7#include "serpentp.h" 8 9NAMESPACE_BEGIN(CryptoPP) 10 11void Serpent_KeySchedule(word32 *k, unsigned int rounds, const byte *userKey, size_t keylen) 12{ 13 FixedSizeSecBlock<word32, 8> k0; 14 GetUserKey(LITTLE_ENDIAN_ORDER, k0.begin(), 8, userKey, keylen); 15 if (keylen < 32) 16 k0[keylen/4] |= word32(1) << ((keylen%4)*8); 17 18 word32 t = k0[7]; 19 unsigned int i; 20 for (i = 0; i < 8; ++i) 21 k[i] = k0[i] = t = rotlFixed(k0[i] ^ k0[(i+3)%8] ^ k0[(i+5)%8] ^ t ^ 0x9e3779b9 ^ i, 11); 22 for (i = 8; i < 4*(rounds+1); ++i) 23 k[i] = t = rotlFixed(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11); 24 k -= 20; 25 26 word32 a,b,c,d,e; 27 for (i=0; i<rounds/8; i++) 28 { 29 afterS2(LK); afterS2(S3); afterS3(SK); 30 afterS1(LK); afterS1(S2); afterS2(SK); 31 afterS0(LK); afterS0(S1); afterS1(SK); 32 beforeS0(LK); beforeS0(S0); afterS0(SK); 33 k += 8*4; 34 afterS6(LK); afterS6(S7); afterS7(SK); 35 afterS5(LK); afterS5(S6); afterS6(SK); 36 afterS4(LK); afterS4(S5); afterS5(SK); 37 afterS3(LK); afterS3(S4); afterS4(SK); 38 } 39 afterS2(LK); afterS2(S3); afterS3(SK); 40} 41 42void Serpent::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &) 43{ 44 AssertValidKeyLength(keylen); 45 Serpent_KeySchedule(m_key, 32, userKey, keylen); 46} 47 48typedef BlockGetAndPut<word32, LittleEndian> Block; 49 50void Serpent::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 51{ 52 word32 a, b, c, d, e; 53 54 Block::Get(inBlock)(a)(b)(c)(d); 55 56 const word32 *k = m_key; 57 unsigned int i=1; 58 59 do 60 { 61 beforeS0(KX); beforeS0(S0); afterS0(LT); 62 afterS0(KX); afterS0(S1); afterS1(LT); 63 afterS1(KX); afterS1(S2); afterS2(LT); 64 afterS2(KX); afterS2(S3); afterS3(LT); 65 afterS3(KX); afterS3(S4); afterS4(LT); 66 afterS4(KX); afterS4(S5); afterS5(LT); 67 afterS5(KX); afterS5(S6); afterS6(LT); 68 afterS6(KX); afterS6(S7); 69 70 if (i == 4) 71 break; 72 73 ++i; 74 c = b; 75 b = e; 76 e = d; 77 d = a; 78 a = e; 79 k += 32; 80 beforeS0(LT); 81 } 82 while (true); 83 84 afterS7(KX); 85 86 Block::Put(xorBlock, outBlock)(d)(e)(b)(a); 87} 88 89void Serpent::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const 90{ 91 word32 a, b, c, d, e; 92 93 Block::Get(inBlock)(a)(b)(c)(d); 94 95 const word32 *k = m_key + 96; 96 unsigned int i=4; 97 98 beforeI7(KX); 99 goto start; 100 101 do 102 { 103 c = b; 104 b = d; 105 d = e; 106 k -= 32; 107 beforeI7(ILT); 108start: 109 beforeI7(I7); afterI7(KX); 110 afterI7(ILT); afterI7(I6); afterI6(KX); 111 afterI6(ILT); afterI6(I5); afterI5(KX); 112 afterI5(ILT); afterI5(I4); afterI4(KX); 113 afterI4(ILT); afterI4(I3); afterI3(KX); 114 afterI3(ILT); afterI3(I2); afterI2(KX); 115 afterI2(ILT); afterI2(I1); afterI1(KX); 116 afterI1(ILT); afterI1(I0); afterI0(KX); 117 } 118 while (--i != 0); 119 120 Block::Put(xorBlock, outBlock)(a)(d)(b)(e); 121} 122 123NAMESPACE_END 124