Crypto++
serpent.cpp
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 
9 NAMESPACE_BEGIN(CryptoPP)
10 
11 void Serpent_KeySchedule(word32 *k, unsigned int rounds, const byte *userKey, size_t keylen)
12 {
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 
42 void 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 
49 
50 void 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 
89 void 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);
108 start:
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 
123 NAMESPACE_END
interface for retrieving values given their names
Definition: cryptlib.h:225