• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

mars.cpp

00001 // mars.cpp - written and placed in the public domain by Wei Dai
00002 
00003 // includes IBM's key setup "tweak" proposed in August 1999 (http://www.research.ibm.com/security/key-setup.txt)
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         // Initialize T[] with the key data
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++)        // compute 10 words of K[] in each iteration
00021         {
00022                 unsigned int i;
00023                 // Do linear transformation
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                 // Do four rounds of stirring
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                 // Store next 10 key words into K[]
00033                 for (i=0; i<10; i++)
00034                         m_k[10*j+i] = T[4*i%15];
00035         }
00036 
00037         // Modify multiplication key-words
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

Generated on Mon Aug 9 2010 15:56:34 for Crypto++ by  doxygen 1.7.1