summaryrefslogtreecommitdiff
path: root/mars.cpp
diff options
context:
space:
mode:
authorweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2009-03-28 03:08:27 +0000
committerweidai <weidai@57ff6487-cd31-0410-9ec3-f628ee90f5f0>2009-03-28 03:08:27 +0000
commitfcec4bd3021b0124d8a38c19246735340a0e1cd0 (patch)
treeedc665bb430df13f81c30b87dcc021223804c80a /mars.cpp
parent56096382619053be6c753901ae3cf850606f3473 (diff)
downloadcryptopp-fcec4bd3021b0124d8a38c19246735340a0e1cd0.tar.gz
fix EC2N skipping of optional seed, switch to public domain MARS code, deliver vc80.pdb to OutDir
git-svn-id: svn://svn.code.sf.net/p/cryptopp/code/trunk/c5@461 57ff6487-cd31-0410-9ec3-f628ee90f5f0
Diffstat (limited to 'mars.cpp')
-rw-r--r--mars.cpp228
1 files changed, 86 insertions, 142 deletions
diff --git a/mars.cpp b/mars.cpp
index 06811b5..fe9b118 100644
--- a/mars.cpp
+++ b/mars.cpp
@@ -1,18 +1,6 @@
-// mars.cpp - modified by Sean Woods from Brian Gladman's mars6.c for Crypto++
-// key setup updated by Wei Dai to reflect IBM's "tweak" proposed in August 1999
-
-/* This is an independent implementation of the MARS encryption */
-/* algorithm designed by a team at IBM as a candidate for the US */
-/* NIST Advanced Encryption Standard (AES) effort. The algorithm */
-/* is subject to Patent action by IBM, who intend to offer royalty */
-/* free use if a Patent is granted. */
-/* */
-/* Copyright in this implementation is held by Dr B R Gladman but */
-/* I hereby give permission for its free direct or derivative use */
-/* subject to acknowledgment of its origin and compliance with any */
-/* constraints that IBM place on the use of the MARS algorithm. */
-/* */
-/* Dr Brian Gladman (gladman@seven77.demon.co.uk) 4th October 1998 */
+// mars.cpp - written and placed in the public domain by Wei Dai
+
+// includes IBM's key setup "tweak" proposed in August 1999 (http://www.research.ibm.com/security/key-setup.txt)
#include "pch.h"
#include "mars.h"
@@ -20,24 +8,6 @@
NAMESPACE_BEGIN(CryptoPP)
-ANONYMOUS_NAMESPACE_BEGIN
-static word32 gen_mask(word32 x)
-{
- word32 m;
-
- m = (~x ^ (x >> 1)) & 0x7fffffff;
- m &= (m >> 1) & (m >> 2); m &= (m >> 3) & (m >> 6);
-
- if(!m)
- return 0;
-
- m <<= 1; m |= (m << 1); m |= (m << 2); m |= (m << 4);
- m |= (m << 1) & ~x & 0x80000000;
-
- return m & 0xfffffffc;
-};
-NAMESPACE_END
-
void MARS::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const NameValuePairs &)
{
AssertValidKeyLength(length);
@@ -61,148 +31,122 @@ void MARS::Base::UncheckedSetKey(const byte *userKey, unsigned int length, const
// Store next 10 key words into K[]
for (i=0; i<10; i++)
- EK[10*j+i] = T[4*i%15];
+ m_k[10*j+i] = T[4*i%15];
}
// Modify multiplication key-words
for(unsigned int i = 5; i < 37; i += 2)
{
- word32 w = EK[i] | 3;
- word32 m = gen_mask(w);
- if(m)
- w ^= (rotlMod(Sbox[265 + (EK[i] & 3)], EK[i-1]) & m);
- EK[i] = w;
+ word32 m, w = m_k[i] | 3;
+ m = (~w ^ (w<<1)) & (~w ^ (w>>1)) & 0x7ffffffe;
+ m &= m>>1; m &= m>>2; m &= m>>4;
+ m |= m<<1; m |= m<<2; m |= m<<4;
+ m &= 0x7ffffffc;
+ w ^= rotlMod(Sbox[265 + (m_k[i] & 3)], m_k[i-1]) & m;
+ m_k[i] = w;
}
}
-#define f_mix(a,b,c,d) \
- r = rotrFixed(a, 8); \
- b ^= Sbox[a & 255]; \
- b += Sbox[(r & 255) + 256]; \
- r = rotrFixed(a, 16); \
- a = rotrFixed(a, 24); \
- c += Sbox[r & 255]; \
- d ^= Sbox[(a & 255) + 256]
-
-#define b_mix(a,b,c,d) \
- r = rotlFixed(a, 8); \
- b ^= Sbox[(a & 255) + 256]; \
- c -= Sbox[r & 255]; \
- r = rotlFixed(a, 16); \
- a = rotlFixed(a, 24); \
- d -= Sbox[(r & 255) + 256]; \
- d ^= Sbox[a & 255]
-
-#define f_ktr(a,b,c,d,i) \
- m = a + EK[i]; \
- a = rotlFixed(a, 13); \
- r = a * EK[i + 1]; \
- l = Sbox[m & 511]; \
- r = rotlFixed(r, 5); \
- l ^= r; \
- c += rotlMod(m, r); \
- r = rotlFixed(r, 5); \
- l ^= r; \
- d ^= r; \
- b += rotlMod(l, r)
-
-#define r_ktr(a,b,c,d,i) \
- r = a * EK[i + 1]; \
- a = rotrFixed(a, 13); \
- m = a + EK[i]; \
- l = Sbox[m & 511]; \
- r = rotlFixed(r, 5); \
- l ^= r; \
- c -= rotlMod(m, r); \
- r = rotlFixed(r, 5); \
- l ^= r; \
- d ^= r; \
- b -= rotlMod(l, r)
+#define S(a) Sbox[(a)&0x1ff]
+#define S0(a) Sbox[(a)&0xff]
+#define S1(a) Sbox[((a)&0xff) + 256]
typedef BlockGetAndPut<word32, LittleEndian> Block;
void MARS::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
- word32 a, b, c, d, l, m, r;
+ unsigned int i;
+ word32 a, b, c, d, l, m, r, t;
+ const word32 *k = m_k;
Block::Get(inBlock)(a)(b)(c)(d);
- a += EK[0];
- b += EK[1];
- c += EK[2];
- d += EK[3];
-
- int i;
- for (i = 0; i < 2; i++) {
- f_mix(a,b,c,d);
- a += d;
- f_mix(b,c,d,a);
- b += c;
- f_mix(c,d,a,b);
- f_mix(d,a,b,c);
+ a += k[0]; b += k[1]; c += k[2]; d += k[3];
+
+ for (i=0; i<8; i++)
+ {
+ b = (b ^ S0(a)) + S1(a>>8);
+ c += S0(a>>16);
+ a = rotrFixed(a, 24);
+ d ^= S1(a);
+ a += (i%4==0) ? d : 0;
+ a += (i%4==1) ? b : 0;
+ t = a; a = b; b = c; c = d; d = t;
+ }
+
+ for (i=0; i<16; i++)
+ {
+ t = rotlFixed(a, 13);
+ r = rotlFixed(t * k[2*i+5], 10);
+ m = a + k[2*i+4];
+ l = rotlMod((S(m) ^ rotrFixed(r, 5) ^ r), r);
+ c += rotlMod(m, rotrFixed(r, 5));
+ (i<8 ? b : d) += l;
+ (i<8 ? d : b) ^= r;
+ a = b; b = c; c = d; d = t;
}
- f_ktr(a,b,c,d, 4); f_ktr(b,c,d,a, 6); f_ktr(c,d,a,b, 8); f_ktr(d,a,b,c,10);
- f_ktr(a,b,c,d,12); f_ktr(b,c,d,a,14); f_ktr(c,d,a,b,16); f_ktr(d,a,b,c,18);
- f_ktr(a,d,c,b,20); f_ktr(b,a,d,c,22); f_ktr(c,b,a,d,24); f_ktr(d,c,b,a,26);
- f_ktr(a,d,c,b,28); f_ktr(b,a,d,c,30); f_ktr(c,b,a,d,32); f_ktr(d,c,b,a,34);
-
- for (i = 0; i < 2; i++) {
- b_mix(a,b,c,d);
- b_mix(b,c,d,a);
- c -= b;
- b_mix(c,d,a,b);
- d -= a;
- b_mix(d,a,b,c);
+ for (i=0; i<8; i++)
+ {
+ a -= (i%4==2) ? d : 0;
+ a -= (i%4==3) ? b : 0;
+ b ^= S1(a);
+ c -= S0(a>>24);
+ t = rotlFixed(a, 24);
+ d = (d - S1(a>>16)) ^ S0(t);
+ a = b; b = c; c = d; d = t;
}
- a -= EK[36];
- b -= EK[37];
- c -= EK[38];
- d -= EK[39];
+ a -= k[36]; b -= k[37]; c -= k[38]; d -= k[39];
Block::Put(xorBlock, outBlock)(a)(b)(c)(d);
}
void MARS::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
{
- word32 a, b, c, d, l, m, r;
+ unsigned int i;
+ word32 a, b, c, d, l, m, r, t;
+ const word32 *k = m_k;
Block::Get(inBlock)(d)(c)(b)(a);
- d += EK[36];
- c += EK[37];
- b += EK[38];
- a += EK[39];
-
- int i;
- for (i = 0; i < 2; i++) {
- f_mix(a,b,c,d);
- a += d;
- f_mix(b,c,d,a);
- b += c;
- f_mix(c,d,a,b);
- f_mix(d,a,b,c);
+ d += k[36]; c += k[37]; b += k[38]; a += k[39];
+
+ for (i=0; i<8; i++)
+ {
+ b = (b ^ S0(a)) + S1(a>>8);
+ c += S0(a>>16);
+ a = rotrFixed(a, 24);
+ d ^= S1(a);
+ a += (i%4==0) ? d : 0;
+ a += (i%4==1) ? b : 0;
+ t = a; a = b; b = c; c = d; d = t;
}
- r_ktr(a,b,c,d,34); r_ktr(b,c,d,a,32); r_ktr(c,d,a,b,30); r_ktr(d,a,b,c,28);
- r_ktr(a,b,c,d,26); r_ktr(b,c,d,a,24); r_ktr(c,d,a,b,22); r_ktr(d,a,b,c,20);
- r_ktr(a,d,c,b,18); r_ktr(b,a,d,c,16); r_ktr(c,b,a,d,14); r_ktr(d,c,b,a,12);
- r_ktr(a,d,c,b,10); r_ktr(b,a,d,c, 8); r_ktr(c,b,a,d, 6); r_ktr(d,c,b,a, 4);
-
- for (i = 0; i < 2; i++) {
- b_mix(a,b,c,d);
- b_mix(b,c,d,a);
- c -= b;
- b_mix(c,d,a,b);
- d -= a;
- b_mix(d,a,b,c);
+ for (i=0; i<16; i++)
+ {
+ t = rotrFixed(a, 13);
+ r = rotlFixed(a * k[35-2*i], 10);
+ m = t + k[34-2*i];
+ l = rotlMod((S(m) ^ rotrFixed(r, 5) ^ r), r);
+ c -= rotlMod(m, rotrFixed(r, 5));
+ (i<8 ? b : d) -= l;
+ (i<8 ? d : b) ^= r;
+ a = b; b = c; c = d; d = t;
+ }
+
+ for (i=0; i<8; i++)
+ {
+ a -= (i%4==2) ? d : 0;
+ a -= (i%4==3) ? b : 0;
+ b ^= S1(a);
+ c -= S0(a>>24);
+ t = rotlFixed(a, 24);
+ d = (d - S1(a>>16)) ^ S0(t);
+ a = b; b = c; c = d; d = t;
}
- d -= EK[0];
- c -= EK[1];
- b -= EK[2];
- a -= EK[3];
+ d -= k[0]; c -= k[1]; b -= k[2]; a -= k[3];
Block::Put(xorBlock, outBlock)(d)(c)(b)(a);
}