- Main Page
- Namespaces
- Classes
- Files

# serpent.cpp

    00001 // serpent.cpp - written and placed in the public domain by Wei Dai
    00002
    00003 #include "pch.h"
    00004 #include "serpent.h"
    00005 #include "misc.h"
    00006
    00007 #include "serpentp.h"
    00008
    00009 NAMESPACE_BEGIN(CryptoPP)
    00010
    00011 void Serpent_KeySchedule(word32 *k, unsigned int rounds, const byte *userKey, size_t keylen)
    00012 {
    00013         FixedSizeSecBlock<word32, 8> k0;
    00014         GetUserKey(LITTLE_ENDIAN_ORDER, k0.begin(), 8, userKey, keylen);
    00015         if (keylen < 32)
    00016                 k0[keylen/4] |= word32(1) << ((keylen%4)*8);
    00017
    00018         word32 t = k0[7];
    00019         unsigned int i;
    00020         for (i = 0; i < 8; ++i)
    00021                 k[i] = k0[i] = t = rotlFixed(k0[i] ^ k0[(i+3)%8] ^ k0[(i+5)%8] ^ t ^ 0x9e3779b9 ^ i, 11);
    00022         for (i = 8; i < 4*(rounds+1); ++i)
    00023                 k[i] = t = rotlFixed(k[i-8] ^ k[i-5] ^ k[i-3] ^ t ^ 0x9e3779b9 ^ i, 11);
    00024         k -= 20;
    00025
    00026         word32 a,b,c,d,e;
    00027         for (i=0; i<rounds/8; i++)
    00028         {
    00029                 afterS2(LK); afterS2(S3); afterS3(SK);
    00030                 afterS1(LK); afterS1(S2); afterS2(SK);
    00031                 afterS0(LK); afterS0(S1); afterS1(SK);
    00032                 beforeS0(LK); beforeS0(S0); afterS0(SK);
    00033                 k += 8*4;
    00034                 afterS6(LK); afterS6(S7); afterS7(SK);
    00035                 afterS5(LK); afterS5(S6); afterS6(SK);
    00036                 afterS4(LK); afterS4(S5); afterS5(SK);
    00037                 afterS3(LK); afterS3(S4); afterS4(SK);
    00038         }
    00039         afterS2(LK); afterS2(S3); afterS3(SK);
    00040 }
    00041
    00042 void Serpent::Base::UncheckedSetKey(const byte *userKey, unsigned int keylen, const NameValuePairs &)
    00043 {
    00044         AssertValidKeyLength(keylen);
    00045         Serpent_KeySchedule(m_key, 32, userKey, keylen);
    00046 }
    00047
    00048 typedef BlockGetAndPut<word32, LittleEndian> Block;
    00049
    00050 void Serpent::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
    00051 {
    00052         word32 a, b, c, d, e;
    00053
    00054         Block::Get(inBlock)(a)(b)(c)(d);
    00055
    00056         const word32 *k = m_key;
    00057         unsigned int i=1;
    00058
    00059         do
    00060         {
    00061                 beforeS0(KX); beforeS0(S0); afterS0(LT);
    00062                 afterS0(KX); afterS0(S1); afterS1(LT);
    00063                 afterS1(KX); afterS1(S2); afterS2(LT);
    00064                 afterS2(KX); afterS2(S3); afterS3(LT);
    00065                 afterS3(KX); afterS3(S4); afterS4(LT);
    00066                 afterS4(KX); afterS4(S5); afterS5(LT);
    00067                 afterS5(KX); afterS5(S6); afterS6(LT);
    00068                 afterS6(KX); afterS6(S7);
    00069
    00070                 if (i == 4)
    00071                         break;
    00072
    00073                 ++i;
    00074                 c = b;
    00075                 b = e;
    00076                 e = d;
    00077                 d = a;
    00078                 a = e;
    00079                 k += 32;
    00080                 beforeS0(LT);
    00081         }
    00082         while (true);
    00083
    00084         afterS7(KX);
    00085
    00086         Block::Put(xorBlock, outBlock)(d)(e)(b)(a);
    00087 }
    00088
    00089 void Serpent::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
    00090 {
    00091         word32 a, b, c, d, e;
    00092
    00093         Block::Get(inBlock)(a)(b)(c)(d);
    00094
    00095         const word32 *k = m_key + 96;
    00096         unsigned int i=4;
    00097
    00098         beforeI7(KX);
    00099         goto start;
    00100
    00101         do
    00102         {
    00103                 c = b;
    00104                 b = d;
    00105                 d = e;
    00106                 k -= 32;
    00107                 beforeI7(ILT);
    00108 start:
    00109                             beforeI7(I7); afterI7(KX);
    00110                 afterI7(ILT); afterI7(I6); afterI6(KX);
    00111                 afterI6(ILT); afterI6(I5); afterI5(KX);
    00112                 afterI5(ILT); afterI5(I4); afterI4(KX);
    00113                 afterI4(ILT); afterI4(I3); afterI3(KX);
    00114                 afterI3(ILT); afterI3(I2); afterI2(KX);
    00115                 afterI2(ILT); afterI2(I1); afterI1(KX);
    00116                 afterI1(ILT); afterI1(I0); afterI0(KX);
    00117         }
    00118         while (--i != 0);
    00119
    00120         Block::Put(xorBlock, outBlock)(a)(d)(b)(e);
    00121 }
    00122
    00123 NAMESPACE_END