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

Generated on Fri Jun 1 11:11:24 2007 for Crypto++ by  doxygen 1.5.2