📄 mars.c
字号:
b -= rotl(l, r)
// For a 32 bit word (x) generate a mask (m) such that a bit in
// m is set to 1 if and only if the corresponding bit in x is:
//
// 1. in a sequence of 10 or more adjacent '0' bits
// 2. in a sequence of 10 or more adjacent '1' bits
// 3. but is not either endpoint of such a sequence
//
// The top and bot1om bits of words must be endpoints and are
// hence always set to zero in this process. My thanks go to
// Shai Halevi of IBM for the way of finding the sequences of
// '0's and '1's at the same time.
#if(0)
// Now implemented in line but this code kept for documentation
// purposes
STATIC u4byte gen_mask(u4byte x)
{ u4byte m;
// if m{bn} stands for bit number bn of m, set m{bn} = 1 if
// x{bn} == x{bn+1} for 0 <= bn <= 30. That is, set a bit
// in m if the corresponding bit and the next higher bit in
// x are equal in value (set m{31} = 0).
m = (~x ^ (x >> 1)) & 0x7fffffff;
// Sequences of 9 '1' bits in m now correspond to sequences
// of 10 '0's or 10 '1' bits in x. Shift and 'and' bits in
// m to find sequences of 9 or more '1' bits. As a result
// bits in m are set if they are at the bot1om of sequences
// of 10 adjacent '0's or 10 adjacent '1's in x.
m &= (m >> 1) & (m >> 2); m &= (m >> 3) & (m >> 6);
if(!m) // return if mask is empty - no key fixing needed
// is this early return worthwhile?
return 0;
// We need the internal bits in each continuous sequence of
// matching bits (that is the bits less the two endpoints).
// We thus propagate each set bit into the 8 internal bits
// that it represents, starting 1 left and finsihing 8 left
// of its position.
m <<= 1; m |= (m << 1); m |= (m << 2); m |= (m << 4);
return m & 0xfffffffc;
}
#endif
#ifdef __cplusplus
} // end of anonymous namespace
#endif
char* MARS(name(void))
{
return "mars";
}
void MARS(set_key(const u1byte in_key[], const u4byte key_bits, const enum dir_flag f))
{ u4byte i, j, m, t1, t2, *kp;
m = key_bits / 32;
if(m < 4 || m > 14)
return;
for(i = 0; i < m; ++i)
t_key[i] = u4byte_in(in_key + 4 * i);
t_key[i++] = m;
for(; i < 15; ++i)
t_key[i] = 0;
kp = MARS(l_key);
#define tk1(j) t1 = t_key[j] ^= rotl(t1 ^ t_key[(j + 8) % 15], 3) ^ (i + 4 * j)
#define tk2(j) t2 = t_key[j] ^= rotl(t2 ^ t_key[(j + 8) % 15], 3) ^ (i + 4 * j)
#define tk3(j) t_key[j] = t1 = rotl(t_key[j] + s_box[t1 & 511], 9)
for(i = 0; i < 4; ++i)
{
t1 = t_key[13]; t2 = t_key[14];
tk1( 0); tk2( 1); tk1( 2); tk2( 3); tk1( 4); tk2( 5); tk1( 6); tk2( 7);
tk1( 8); tk2( 9); tk1(10); tk2(11); tk1(12); tk2(13); tk1(14);
tk3( 0); tk3( 1); tk3( 2); tk3( 3); tk3( 4); tk3( 5); tk3( 6); tk3( 7);
tk3( 8); tk3( 9); tk3(10); tk3(11); tk3(12); tk3(13); tk3(14);
tk3( 0); tk3( 1); tk3( 2); tk3( 3); tk3( 4); tk3( 5); tk3( 6); tk3( 7);
tk3( 8); tk3( 9); tk3(10); tk3(11); tk3(12); tk3(13); tk3(14);
tk3( 0); tk3( 1); tk3( 2); tk3( 3); tk3( 4); tk3( 5); tk3( 6); tk3( 7);
tk3( 8); tk3( 9); tk3(10); tk3(11); tk3(12); tk3(13); tk3(14);
tk3( 0); tk3( 1); tk3( 2); tk3( 3); tk3( 4); tk3( 5); tk3( 6); tk3( 7);
tk3( 8); tk3( 9); tk3(10); tk3(11); tk3(12); tk3(13); tk3(14);
*kp++ = t_key[ 0]; *kp++ = t_key[ 4]; *kp++ = t_key[ 8]; *kp++ = t_key[12];
*kp++ = t_key[ 1]; *kp++ = t_key[ 5]; *kp++ = t_key[ 9]; *kp++ = t_key[13];
*kp++ = t_key[ 2]; *kp++ = t_key[ 6];
}
for(i = 5; i < 37; i += 2)
{
j = MARS(l_key)[i] | 3;
m = (~j ^ (j >> 1)) & 0x7fffffff;
m &= (m >> 1) & (m >> 2); m &= (m >> 3) & (m >> 6);
if(m)
{
m <<= 1; m |= (m << 1); m |= (m << 2); m |= (m << 4);
m &= 0xfffffffc;
j ^= (rotl(b_tab[MARS(l_key)[i] & 3], MARS(l_key)[i - 1]) & m);
}
MARS(l_key)[i] = j;
}
return;
}
// ARM C compiler fails in attempting to optimise common sub-expressions
// the following code - turn it off
#if defined(__arm)
# pragma no_optimize_cse
#endif
void MARS(encrypt(const u1byte in_blk[16], u1byte out_blk[16]))
{ u4byte a, b, c, d, l, m, r;
a = u4byte_in(in_blk ) + MARS(l_key)[0]; b = u4byte_in(in_blk + 4) + MARS(l_key)[1];
c = u4byte_in(in_blk + 8) + MARS(l_key)[2]; d = u4byte_in(in_blk + 12) + MARS(l_key)[3];
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);
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);
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);
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);
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);
u4byte_out(out_blk, a - MARS(l_key)[36]); u4byte_out(out_blk + 4, b - MARS(l_key)[37]);
u4byte_out(out_blk + 8, c - MARS(l_key)[38]); u4byte_out(out_blk + 12, d - MARS(l_key)[39]);
}
void MARS(decrypt(const u1byte in_blk[16], u1byte out_blk[16]))
{ u4byte a, b, c, d, l, m, r;
d = u4byte_in(in_blk ) + MARS(l_key)[36]; c = u4byte_in(in_blk + 4) + MARS(l_key)[37];
b = u4byte_in(in_blk + 8) + MARS(l_key)[38]; a = u4byte_in(in_blk + 12) + MARS(l_key)[39];
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);
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);
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);
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);
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);
u4byte_out(out_blk, d - MARS(l_key)[0]); u4byte_out(out_blk + 4, c - MARS(l_key)[1]);
u4byte_out(out_blk + 8, b - MARS(l_key)[2]); u4byte_out(out_blk + 12, a - MARS(l_key)[3]);
}
#if defined(__arm)
# pragma optimize_cse
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -