Crypto++ 8.9
Free C++ class library of cryptographic schemes
mars.cpp
1// mars.cpp - originally 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
9NAMESPACE_BEGIN(CryptoPP)
10
11void 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] ^ rotlConstant<3>(T[(i + 8) % 15] ^ T[(i + 13) % 15]) ^ (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] = rotlConstant<9>(T[i] + Sbox[T[(i + 14) % 15] % 512]);
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
56void 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 = rotrConstant<24>(a);
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 = rotlConstant<13>(a);
80 r = rotlConstant<10>(t * k[2 * i + 5]);
81 m = a + k[2*i+4];
82 l = rotlMod((S(m) ^ rotrConstant<5>(r) ^ r), r);
83 c += rotlMod(m, rotrConstant<5>(r));
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 = rotlConstant<24>(a);
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
105void 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 = rotrConstant<24>(a);
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 = rotrConstant<13>(a);
129 r = rotlConstant<10>(a * k[35 - 2 * i]);
130 m = t + k[34-2*i];
131 l = rotlMod((S(m) ^ rotrConstant<5>(r) ^ r), r);
132 c -= rotlMod(m, rotrConstant<5>(r));
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 = rotlConstant<24>(a);
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
154NAMESPACE_END
Fixed size stack-based SecBlock.
Definition secblock.h:1246
Interface for retrieving values given their names.
Definition cryptlib.h:327
Access a block of memory.
Definition misc.h:3016
unsigned int word32
32-bit unsigned datatype
Definition config_int.h:72
@ LITTLE_ENDIAN_ORDER
byte order is little-endian
Definition cryptlib.h:150
Classes for the MARS block cipher (IBM AES submission)
Utility functions for the Crypto++ library.
void GetUserKey(ByteOrder order, T *out, size_t outlen, const byte *in, size_t inlen)
Copy bytes in a buffer to an array of elements in big-endian order.
Definition misc.h:2500
T rotlMod(T x, unsigned int y)
Performs a left rotate.
Definition misc.h:1894
Crypto++ library namespace.
Precompiled header file.
Access a block of memory.
Definition misc.h:3053