00001
00002
00003
00004
00005 #include "pch.h"
00006 #include "mars.h"
00007 #include "misc.h"
00008
00009 NAMESPACE_BEGIN(CryptoPP)
00010
00011 void MARS::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &)
00012 {
00013 AssertValidKeyLength(length);
00014
00015
00016 FixedSizeSecBlock<word32, 15> T;
00017 GetUserKey(LITTLE_ENDIAN_ORDER, T.begin(), 15, userKey, length);
00018 T[length/4] = length/4;
00019
00020 for (unsigned int j=0; j<4; j++)
00021 {
00022 unsigned int i;
00023
00024 for (i=0; i<15; i++)
00025 T[i] = T[i] ^ rotlFixed(T[(i+8)%15] ^ T[(i+13)%15], 3) ^ (4*i+j);
00026
00027
00028 for (unsigned int k=0; k<4; k++)
00029 for (i=0; i<15; i++)
00030 T[i] = rotlFixed(T[i] + Sbox[T[(i+14)%15]%512], 9);
00031
00032
00033 for (i=0; i<10; i++)
00034 m_k[10*j+i] = T[4*i%15];
00035 }
00036
00037
00038 for(unsigned int i = 5; i < 37; i += 2)
00039 {
00040 word32 m, w = m_k[i] | 3;
00041 m = (~w ^ (w<<1)) & (~w ^ (w>>1)) & 0x7ffffffe;
00042 m &= m>>1; m &= m>>2; m &= m>>4;
00043 m |= m<<1; m |= m<<2; m |= m<<4;
00044 m &= 0x7ffffffc;
00045 w ^= rotlMod(Sbox[265 + (m_k[i] & 3)], m_k[i-1]) & m;
00046 m_k[i] = w;
00047 }
00048 }
00049
00050 #define S(a) Sbox[(a)&0x1ff]
00051 #define S0(a) Sbox[(a)&0xff]
00052 #define S1(a) Sbox[((a)&0xff) + 256]
00053
00054 typedef BlockGetAndPut<word32, LittleEndian> Block;
00055
00056 void MARS::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00057 {
00058 unsigned int i;
00059 word32 a, b, c, d, l, m, r, t;
00060 const word32 *k = m_k;
00061
00062 Block::Get(inBlock)(a)(b)(c)(d);
00063
00064 a += k[0]; b += k[1]; c += k[2]; d += k[3];
00065
00066 for (i=0; i<8; i++)
00067 {
00068 b = (b ^ S0(a)) + S1(a>>8);
00069 c += S0(a>>16);
00070 a = rotrFixed(a, 24);
00071 d ^= S1(a);
00072 a += (i%4==0) ? d : 0;
00073 a += (i%4==1) ? b : 0;
00074 t = a; a = b; b = c; c = d; d = t;
00075 }
00076
00077 for (i=0; i<16; i++)
00078 {
00079 t = rotlFixed(a, 13);
00080 r = rotlFixed(t * k[2*i+5], 10);
00081 m = a + k[2*i+4];
00082 l = rotlMod((S(m) ^ rotrFixed(r, 5) ^ r), r);
00083 c += rotlMod(m, rotrFixed(r, 5));
00084 (i<8 ? b : d) += l;
00085 (i<8 ? d : b) ^= r;
00086 a = b; b = c; c = d; d = t;
00087 }
00088
00089 for (i=0; i<8; i++)
00090 {
00091 a -= (i%4==2) ? d : 0;
00092 a -= (i%4==3) ? b : 0;
00093 b ^= S1(a);
00094 c -= S0(a>>24);
00095 t = rotlFixed(a, 24);
00096 d = (d - S1(a>>16)) ^ S0(t);
00097 a = b; b = c; c = d; d = t;
00098 }
00099
00100 a -= k[36]; b -= k[37]; c -= k[38]; d -= k[39];
00101
00102 Block::Put(xorBlock, outBlock)(a)(b)(c)(d);
00103 }
00104
00105 void MARS::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
00106 {
00107 unsigned int i;
00108 word32 a, b, c, d, l, m, r, t;
00109 const word32 *k = m_k;
00110
00111 Block::Get(inBlock)(d)(c)(b)(a);
00112
00113 d += k[36]; c += k[37]; b += k[38]; a += k[39];
00114
00115 for (i=0; i<8; i++)
00116 {
00117 b = (b ^ S0(a)) + S1(a>>8);
00118 c += S0(a>>16);
00119 a = rotrFixed(a, 24);
00120 d ^= S1(a);
00121 a += (i%4==0) ? d : 0;
00122 a += (i%4==1) ? b : 0;
00123 t = a; a = b; b = c; c = d; d = t;
00124 }
00125
00126 for (i=0; i<16; i++)
00127 {
00128 t = rotrFixed(a, 13);
00129 r = rotlFixed(a * k[35-2*i], 10);
00130 m = t + k[34-2*i];
00131 l = rotlMod((S(m) ^ rotrFixed(r, 5) ^ r), r);
00132 c -= rotlMod(m, rotrFixed(r, 5));
00133 (i<8 ? b : d) -= l;
00134 (i<8 ? d : b) ^= r;
00135 a = b; b = c; c = d; d = t;
00136 }
00137
00138 for (i=0; i<8; i++)
00139 {
00140 a -= (i%4==2) ? d : 0;
00141 a -= (i%4==3) ? b : 0;
00142 b ^= S1(a);
00143 c -= S0(a>>24);
00144 t = rotlFixed(a, 24);
00145 d = (d - S1(a>>16)) ^ S0(t);
00146 a = b; b = c; c = d; d = t;
00147 }
00148
00149 d -= k[0]; c -= k[1]; b -= k[2]; a -= k[3];
00150
00151 Block::Put(xorBlock, outBlock)(d)(c)(b)(a);
00152 }
00153
00154 NAMESPACE_END