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