📄 mars.c
字号:
c -= s_box[r & 255]; \
r = rotl(a, 16); \
a = rotl(a, 24); \
d -= s_box[(r & 255) + 256]; \
d ^= s_box[a & 255]
#define f_ktr(a,b,c,d,i) \
m = a + l_key[i]; \
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 unless such */
/* an endpoint is at the top bit (bit 31) of a word and is */
/* in a sequence of '0' bits. */
/* */
/* The only situation in which a sequence endpoint is included */
/* in the mask is hence when the endpoint is at bit 31 and is */
/* the endpoint of a sequence of '0' bits. My thanks go to Shai */
/* Halevi of IBM for the neat trick (which I missed) of finding */
/* the '0' and '1' sequences at the same time. */
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);
/* m is now correct except for the odd behaviour of bit 31, */
/* that is, it will be set if it is in a sequence of 10 or */
/* more '0's and clear otherwise. */
m |= (m << 1) & ~x & 0x80000000;
return m & 0xfffffffc;
};
/* My thanks to Louis Granboulan for spotting an error in the */
/* previous version of set_key. */
u4byte *set_key(const u4byte in_key[], const u4byte key_len)
{ u4byte i, j, m, w;
m = key_len / 32 - 1;
for(i = j = 0; i < 39; ++i)
{
vk[i + 7] = rotl(vk[i] ^ vk[i + 5], 3) ^ in_key[j] ^ i;
j = (j == m ? 0 : j + 1);
}
vk[46] = key_len / 32;
for(j = 0; j < 7; ++j)
{
for(i = 1; i < 40; ++i)
vk[i + 7] = rotl(vk[i + 7] + s_box[vk[i + 6] & 511], 9);
vk[7] = rotl(vk[7] + s_box[vk[46] & 511], 9);
}
for(i = j = 0; i < 40; ++i)
{
l_key[j] = vk[i + 7];
j = (j < 33 ? j + 7 : j - 33);
}
for(i = 5; i < 37; i += 2)
{
w = l_key[i] | 3;
if(m = gen_mask(w))
w ^= (rotl(s_box[265 + (l_key[i] & 3)], l_key[i + 3] & 31) & m);
l_key[i] = w;
}
return l_key;
};
void encrypt(const u4byte in_blk[4], u4byte out_blk[4])
{ u4byte a, b, c, d, l, m, r;
a = in_blk[0] + l_key[0]; b = in_blk[1] + l_key[1];
c = in_blk[2] + l_key[2]; d = in_blk[3] + 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);
out_blk[0] = a - l_key[36]; out_blk[1] = b - l_key[37];
out_blk[2] = c - l_key[38]; out_blk[3] = d - l_key[39];
};
void decrypt(const u4byte in_blk[4], u4byte out_blk[4])
{ u4byte a, b, c, d, l, m, r;
d = in_blk[0] + l_key[36]; c = in_blk[1] + l_key[37];
b = in_blk[2] + l_key[38]; a = in_blk[3] + 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);
out_blk[0] = d - l_key[0]; out_blk[1] = c - l_key[1];
out_blk[2] = b - l_key[2]; out_blk[3] = a - l_key[3];
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -