Fabcoin Core  0.16.2
P2P Digital Currency
mars.cpp
Go to the documentation of this file.
1 // mars.cpp - written and placed in the public domain by Wei Dai
2 
3 // includes IBM's key setup "tweak" proposed in August 1999 (http://www.research.ibm.com/security/key-setup.txt)
4 
5 #include "pch.h"
6 #include "mars.h"
7 #include "misc.h"
8 
10 
11 void MARS::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &)
12 {
13  AssertValidKeyLength(length);
14 
15  // Initialize T[] with the key data
17  GetUserKey(LITTLE_ENDIAN_ORDER, T.begin(), 15, userKey, length);
18  T[length/4] = length/4;
19 
20  for (unsigned int j=0; j<4; j++) // compute 10 words of K[] in each iteration
21  {
22  unsigned int i;
23  // Do linear transformation
24  for (i=0; i<15; i++)
25  T[i] = T[i] ^ rotlFixed(T[(i+8)%15] ^ T[(i+13)%15], 3) ^ (4*i+j);
26 
27  // Do four rounds of stirring
28  for (unsigned int k=0; k<4; k++)
29  for (i=0; i<15; i++)
30  T[i] = rotlFixed(T[i] + Sbox[T[(i+14)%15]%512], 9);
31 
32  // Store next 10 key words into K[]
33  for (i=0; i<10; i++)
34  m_k[10*j+i] = T[4*i%15];
35  }
36 
37  // Modify multiplication key-words
38  for(unsigned int i = 5; i < 37; i += 2)
39  {
40  word32 m, w = m_k[i] | 3;
41  m = (~w ^ (w<<1)) & (~w ^ (w>>1)) & 0x7ffffffe;
42  m &= m>>1; m &= m>>2; m &= m>>4;
43  m |= m<<1; m |= m<<2; m |= m<<4;
44  m &= 0x7ffffffc;
45  w ^= rotlMod(Sbox[265 + (m_k[i] & 3)], m_k[i-1]) & m;
46  m_k[i] = w;
47  }
48 }
49 
50 #define S(a) Sbox[(a)&0x1ff]
51 #define S0(a) Sbox[(a)&0xff]
52 #define S1(a) Sbox[((a)&0xff) + 256]
53 
55 
56 void MARS::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
57 {
58  unsigned int i;
59  word32 a, b, c, d, l, m, r, t;
60  const word32 *k = m_k;
61 
62  Block::Get(inBlock)(a)(b)(c)(d);
63 
64  a += k[0]; b += k[1]; c += k[2]; d += k[3];
65 
66  for (i=0; i<8; i++)
67  {
68  b = (b ^ S0(a)) + S1(a>>8);
69  c += S0(a>>16);
70  a = rotrFixed(a, 24);
71  d ^= S1(a);
72  a += (i%4==0) ? d : 0;
73  a += (i%4==1) ? b : 0;
74  t = a; a = b; b = c; c = d; d = t;
75  }
76 
77  for (i=0; i<16; i++)
78  {
79  t = rotlFixed(a, 13);
80  r = rotlFixed(t * k[2*i+5], 10);
81  m = a + k[2*i+4];
82  l = rotlMod((S(m) ^ rotrFixed(r, 5) ^ r), r);
83  c += rotlMod(m, rotrFixed(r, 5));
84  (i<8 ? b : d) += l;
85  (i<8 ? d : b) ^= r;
86  a = b; b = c; c = d; d = t;
87  }
88 
89  for (i=0; i<8; i++)
90  {
91  a -= (i%4==2) ? d : 0;
92  a -= (i%4==3) ? b : 0;
93  b ^= S1(a);
94  c -= S0(a>>24);
95  t = rotlFixed(a, 24);
96  d = (d - S1(a>>16)) ^ S0(t);
97  a = b; b = c; c = d; d = t;
98  }
99 
100  a -= k[36]; b -= k[37]; c -= k[38]; d -= k[39];
101 
102  Block::Put(xorBlock, outBlock)(a)(b)(c)(d);
103 }
104 
105 void MARS::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
106 {
107  unsigned int i;
108  word32 a, b, c, d, l, m, r, t;
109  const word32 *k = m_k;
110 
111  Block::Get(inBlock)(d)(c)(b)(a);
112 
113  d += k[36]; c += k[37]; b += k[38]; a += k[39];
114 
115  for (i=0; i<8; i++)
116  {
117  b = (b ^ S0(a)) + S1(a>>8);
118  c += S0(a>>16);
119  a = rotrFixed(a, 24);
120  d ^= S1(a);
121  a += (i%4==0) ? d : 0;
122  a += (i%4==1) ? b : 0;
123  t = a; a = b; b = c; c = d; d = t;
124  }
125 
126  for (i=0; i<16; i++)
127  {
128  t = rotrFixed(a, 13);
129  r = rotlFixed(a * k[35-2*i], 10);
130  m = t + k[34-2*i];
131  l = rotlMod((S(m) ^ rotrFixed(r, 5) ^ r), r);
132  c -= rotlMod(m, rotrFixed(r, 5));
133  (i<8 ? b : d) -= l;
134  (i<8 ? d : b) ^= r;
135  a = b; b = c; c = d; d = t;
136  }
137 
138  for (i=0; i<8; i++)
139  {
140  a -= (i%4==2) ? d : 0;
141  a -= (i%4==3) ? b : 0;
142  b ^= S1(a);
143  c -= S0(a>>24);
144  t = rotlFixed(a, 24);
145  d = (d - S1(a>>16)) ^ S0(t);
146  a = b; b = c; c = d; d = t;
147  }
148 
149  d -= k[0]; c -= k[1]; b -= k[2]; a -= k[3];
150 
151  Block::Put(xorBlock, outBlock)(d)(c)(b)(a);
152 }
153 
void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
Definition: misc.h:1879
uint8_t byte
Definition: Common.h:57
Utility functions for the Crypto++ library.
PutBlock< T, B, PA > Put
Definition: misc.h:2237
T rotlFixed(T x, unsigned int y)
Performs a left rotate.
Definition: misc.h:1263
#define T(i, x)
#define NAMESPACE_BEGIN(x)
Definition: config.h:200
static GetBlock< T, B, GA > Get(const void *block)
Definition: misc.h:2236
#define c(i)
Access a block of memory.
Definition: misc.h:2233
byte order is little-endian
Definition: cryptlib.h:126
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
Encrypt or decrypt a block.
Definition: mars.cpp:56
#define a(i)
Classes for the MARS block cipher (IBM AES submission)
#define S0(a)
Definition: mars.cpp:51
BlockGetAndPut< word32, LittleEndian > Block
Definition: mars.cpp:54
FixedSizeSecBlock< word32, 40 > m_k
Definition: mars.h:34
Fixed size stack-based SecBlock.
Definition: secblock.h:753
#define b(i, j)
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:499
void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
Encrypt or decrypt a block.
Definition: mars.cpp:105
#define NAMESPACE_END
Definition: config.h:201
#define S1(a)
Definition: mars.cpp:52
#define d(i)
Definition: sha.cpp:732
#define S(a)
Definition: mars.cpp:50
unsigned int word32
Definition: config.h:231
T rotlMod(T x, unsigned int y)
Performs a left rotate.
Definition: misc.h:1340
T rotrFixed(T x, unsigned int y)
Performs a right rotate.
Definition: misc.h:1285
MARS block cipher.
Definition: mars.h:24
Interface for retrieving values given their names.
Definition: cryptlib.h:279