📄 mars.cpp
字号:
a = rotl(a, 13); \
r = a * l_key[i + 1]; \
l = s_box[m & 511]; \
r = rotl(r, 5); \
c += rotl(m, r); \
l ^= r; \
r = rotl(r, 5); \
l ^= r; \
d ^= r; \
b += rotl(l, r)
#define r_ktr(a,b,c,d,i) \
r = a * l_key[i + 1]; \
a = rotr(a, 13); \
m = a + l_key[i]; \
l = s_box[m & 511]; \
r = rotl(r, 5); \
l ^= r; \
c -= rotl(m, r); \
r = rotl(r, 5); \
l ^= r; \
d ^= r; \
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 bottom 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
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 bottom 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
} // end of anonymous namespace
char *mars::name(void)
{
return "mars";
}
void mars::set_key(const u1byte in_key[], const u4byte key_bits)
{ u4byte i, j, m;
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[m] = m;
for(i = m + 1; i < 15; ++i)
t_key[i] = 0;
for(i = 0; i < 4; ++i)
{
for(j = 0; j < 15; ++j)
t_key[j] ^= rotl(t_key[im7[j]] ^ t_key[im2[j]], 3) ^ (4 * j + i);
for(m = 0; m < 4; ++m)
for(j = 0; j < 15; ++j)
t_key[j] = rotl(t_key[j] + s_box[t_key[im1[j]] & 511], 9);
for(j = 0; j < 10; ++j)
l_key[10 * i + j] = t_key[i4m[j]];
}
for(i = 5; i < 37; i += 2)
{
j = 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[l_key[i] & 3], l_key[i - 1]) & m);
}
l_key[i] = j;
}
return;
}
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 ) + l_key[0]; b = u4byte_in(in_blk + 4) + l_key[1];
c = u4byte_in(in_blk + 8) + l_key[2]; d = u4byte_in(in_blk + 12) + 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 - l_key[36]); u4byte_out(out_blk + 4, b - l_key[37]);
u4byte_out(out_blk + 8, c - l_key[38]); u4byte_out(out_blk + 12, d - 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 ) + l_key[36]; c = u4byte_in(in_blk + 4) + l_key[37];
b = u4byte_in(in_blk + 8) + l_key[38]; a = u4byte_in(in_blk + 12) + 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 - l_key[0]); u4byte_out(out_blk + 4, c - l_key[1]);
u4byte_out(out_blk + 8, b - l_key[2]); u4byte_out(out_blk + 12, a - l_key[3]);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -