typedef unsigned char uchar;typedef unsigned long ulong;typedef unsigned long long uvlong;#include "des.h" static uchar initperm[] = {58, 50, 42, 34, 26, 18, 10, 2,60, 52, 44, 36, 28, 20, 12, 4,62, 54, 46, 38, 30, 22, 14, 6,64, 56, 48, 40, 32, 24, 16, 8,57, 49, 41, 33, 25, 17, 9, 1,59, 51, 43, 35, 27, 19, 11, 3,61, 53, 45, 37, 29, 21, 13, 5,63, 55, 47, 39, 31, 23, 15, 7,}; static uchar finalperm[] = {40, 8, 48, 16, 56, 24, 64, 32,39, 7, 47, 15, 55, 23, 63, 31,38, 6, 46, 14, 54, 22, 62, 30,37, 5, 45, 13, 53, 21, 61, 29,36, 4, 44, 12, 52, 20, 60, 28,35, 3, 43, 11, 51, 19, 59, 27,34, 2, 42, 10, 50, 18, 58, 26,33, 1, 41, 9, 49, 17, 57, 25,}; /* expand, for round function */static uchar eperm[] = {32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13,12, 13, 14, 15, 16, 17,16, 17, 18, 19, 20, 21,20, 21, 22, 23, 24, 25,24, 25, 26, 27, 28, 29,28, 29, 30, 31, 32, 1,}; /* permute, for round function */static uchar pperm[] = {16, 7, 20, 21,29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14,32, 27, 3, 9,19, 13, 30, 6,22, 11, 4, 25,}; static uchar sbox[8][64] = {{ /* s1 */ 14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1, 3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8, 4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7, 15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13,},{ /* s2 */ 15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14, 9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5, 0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2, 5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9,},{ /* s3 */ 10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10, 1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1, 13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7, 11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12,},{ /* s4 */ 7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3, 1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9, 10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8, 15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14,},{ /* s5 */ 2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1, 8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6, 4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13, 15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3,},{ /* s6 */ 12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5, 0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8, 9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10, 7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13,},{ /* s7 */ 4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10, 3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6, 1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7, 10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12,},{ /* s8 */ 13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4, 10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2, 7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13, 0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11,},}; /* key permutation 1 for c */static uchar pc1perm0[] = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18,10, 2, 59, 51, 43, 35, 27,19, 11, 3, 60, 52, 44, 36,}; /* key permutation 1 for d */static uchar pc1perm1[] = {63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22,14, 6, 61, 53, 45, 37, 29,21, 13, 5, 28, 20, 12, 4,}; /* key permutation 2 */static uchar pc2perm[] = {14, 17, 11, 24, 1, 5, 3, 28, 15, 6, 21, 10,23, 19, 12, 4, 26, 8,16, 7, 27, 20, 13, 2,41, 52, 31, 37, 47, 55,30, 40, 51, 45, 33, 48,44, 49, 39, 56, 34, 53,46, 42, 50, 36, 29, 32,}; static uchar keyshifts[] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,}; enum { Mask6 = (1<<6)-1, Mask7 = (1<<7)-1, Mask28 = (1<<28)-1,}; static ulongg32(uchar *p){ ulong v; v = 0; v = (v<<8)|*p++; v = (v<<8)|*p++; v = (v<<8)|*p++; v = (v<<8)|*p++; return v;} static voidp32(uchar *p, ulong v){ *p++ = v>>24; *p++ = v>>16; *p++ = v>>8; *p++ = v>>0;} /* input 32 bit, output 6 bit */static ucharperm6(ulong r, uchar *index){ uchar v; int i; v = 0; for(i = 0; i < 6; i++) v |= ((r>>(32-index[i]))&1)<<(6-1-i); return v;} /* input 32 bit, output 32 bit */static ulongperm32(ulong r, uchar *index){ ulong v; int i; v = 0; for(i = 0; i < 32; i++) v |= ((r>>(32-index[i]))&1)<<(32-1-i); return v;} /* input 64 bit, output 28 bit */static ulongperm28(uvlong r, uchar *index){ ulong v; int i; v = 0; for(i = 0; i < 28; i++) v |= ((r>>(64-index[i]))&1)<<(28-1-i); return v;} /* input 56 bit, output 48 bit */static uvlongperm56(uvlong r, uchar *index){ uvlong v; int i; v = 0; for(i = 0; i < 48; i++) v |= ((r>>(56-index[i]))&1)<<(48-1-i); return v;} /* input 64 bit, output 64 bit */static uvlongperm64(uvlong r, uchar *index){ uvlong v; int i; v = 0; for(i = 0; i < 64; i++) v |= ((r>>(64-index[i]))&1)<<(64-1-i); return v;} static ulongf(ulong r, uvlong k){ ulong p; uchar ei, ki; int i, j; p = 0; for(i = 0; i < 8; i++) { j = 7-i; ei = perm6(r, eperm+i*6); ki = (k>>(j*6))&Mask6; p |= (ulong)sbox[i][ei^ki]<<(j*4); } return perm32(p, pperm);} static ulongrotateleft28(ulong v, int i){ ulong left, right; left = (v<<i)&Mask28; right = (v>>(28-i))&((1<<i)-1); return left|right;} static voiddeskey(Desks *ks, uvlong k64){ ulong c, d; int i; c = perm28(k64, pc1perm0); d = perm28(k64, pc1perm1); for(i = 0; i < 16; i++) { c = rotateleft28(c, keyshifts[i]); d = rotateleft28(d, keyshifts[i]); ks->keys[i] = perm56(((uvlong)c<<28)|d, pc2perm); }} static voiddescrypt(Desks *ks, void *buf, int s, int e, int delta){ ulong l, r, tmp; uvlong v; int i; v = g32(buf); v = (v<<32)|g32(buf+4); v = perm64(v, initperm); l = v>>32; r = v; for(i = s; i != e; i += delta) { tmp = r; r = l^f(r, ks->keys[i]); l = tmp; } v = r; v = (v<<32)|l; v = perm64(v, finalperm); p32(buf, v>>32); p32(buf+4, v);} voiddeskey56(Desks *ks, uchar *k56){ uvlong t, k; int i, j; t = 0; for(i = 0; i < 7; i++) t = (t<<8)|*k56++; k = 0; for(i = 0; i < 8; i++) { j = 8-1-i; k |= ((t>>(j*7))&Mask7)<<(j*8+1); } deskey(ks, k);} voiddeskey64(Desks *ks, uchar *k64){ uvlong k; int i; k = 0; for(i = 0; i < 8; i++) k = (k<<8)|*k64++; deskey(ks, k);} voiddesenc(Desks *ks, void *buf){ descrypt(ks, buf, 0, 16, 1);} voiddesdec(Desks *ks, void *buf){ descrypt(ks, buf, 15, -1, -1);}
typedef unsigned char uchar;
typedef unsigned long ulong;
typedef unsigned long long uvlong;
#include "des.h"
static uchar initperm[] = {
58, 50, 42, 34, 26, 18, 10, 2,
60, 52, 44, 36, 28, 20, 12, 4,
62, 54, 46, 38, 30, 22, 14, 6,
64, 56, 48, 40, 32, 24, 16, 8,
57, 49, 41, 33, 25, 17, 9, 1,
59, 51, 43, 35, 27, 19, 11, 3,
61, 53, 45, 37, 29, 21, 13, 5,
63, 55, 47, 39, 31, 23, 15, 7,
};
static uchar finalperm[] = {
40, 8, 48, 16, 56, 24, 64, 32,
39, 7, 47, 15, 55, 23, 63, 31,
38, 6, 46, 14, 54, 22, 62, 30,
37, 5, 45, 13, 53, 21, 61, 29,
36, 4, 44, 12, 52, 20, 60, 28,
35, 3, 43, 11, 51, 19, 59, 27,
34, 2, 42, 10, 50, 18, 58, 26,
33, 1, 41, 9, 49, 17, 57, 25,
};
/* expand, for round function */
static uchar eperm[] = {
32, 1, 2, 3, 4, 5,
4, 5, 6, 7, 8, 9,
8, 9, 10, 11, 12, 13,
12, 13, 14, 15, 16, 17,
16, 17, 18, 19, 20, 21,
20, 21, 22, 23, 24, 25,
24, 25, 26, 27, 28, 29,
28, 29, 30, 31, 32, 1,
};
/* permute, for round function */
static uchar pperm[] = {
16, 7, 20, 21,
29, 12, 28, 17,
1, 15, 23, 26,
5, 18, 31, 10,
2, 8, 24, 14,
32, 27, 3, 9,
19, 13, 30, 6,
22, 11, 4, 25,
};
static uchar sbox[8][64] = {
{ /* s1 */
14, 0, 4, 15, 13, 7, 1, 4, 2, 14, 15, 2, 11, 13, 8, 1,
3, 10, 10, 6, 6, 12, 12, 11, 5, 9, 9, 5, 0, 3, 7, 8,
4, 15, 1, 12, 14, 8, 8, 2, 13, 4, 6, 9, 2, 1, 11, 7,
15, 5, 12, 11, 9, 3, 7, 14, 3, 10, 10, 0, 5, 6, 0, 13,
},
{ /* s2 */
15, 3, 1, 13, 8, 4, 14, 7, 6, 15, 11, 2, 3, 8, 4, 14,
9, 12, 7, 0, 2, 1, 13, 10, 12, 6, 0, 9, 5, 11, 10, 5,
0, 13, 14, 8, 7, 10, 11, 1, 10, 3, 4, 15, 13, 4, 1, 2,
5, 11, 8, 6, 12, 7, 6, 12, 9, 0, 3, 5, 2, 14, 15, 9,
},
{ /* s3 */
10, 13, 0, 7, 9, 0, 14, 9, 6, 3, 3, 4, 15, 6, 5, 10,
1, 2, 13, 8, 12, 5, 7, 14, 11, 12, 4, 11, 2, 15, 8, 1,
13, 1, 6, 10, 4, 13, 9, 0, 8, 6, 15, 9, 3, 8, 0, 7,
11, 4, 1, 15, 2, 14, 12, 3, 5, 11, 10, 5, 14, 2, 7, 12,
},
{ /* s4 */
7, 13, 13, 8, 14, 11, 3, 5, 0, 6, 6, 15, 9, 0, 10, 3,
1, 4, 2, 7, 8, 2, 5, 12, 11, 1, 12, 10, 4, 14, 15, 9,
10, 3, 6, 15, 9, 0, 0, 6, 12, 10, 11, 1, 7, 13, 13, 8,
15, 9, 1, 4, 3, 5, 14, 11, 5, 12, 2, 7, 8, 2, 4, 14,
},
{ /* s5 */
2, 14, 12, 11, 4, 2, 1, 12, 7, 4, 10, 7, 11, 13, 6, 1,
8, 5, 5, 0, 3, 15, 15, 10, 13, 3, 0, 9, 14, 8, 9, 6,
4, 11, 2, 8, 1, 12, 11, 7, 10, 1, 13, 14, 7, 2, 8, 13,
15, 6, 9, 15, 12, 0, 5, 9, 6, 10, 3, 4, 0, 5, 14, 3,
},
{ /* s6 */
12, 10, 1, 15, 10, 4, 15, 2, 9, 7, 2, 12, 6, 9, 8, 5,
0, 6, 13, 1, 3, 13, 4, 14, 14, 0, 7, 11, 5, 3, 11, 8,
9, 4, 14, 3, 15, 2, 5, 12, 2, 9, 8, 5, 12, 15, 3, 10,
7, 11, 0, 14, 4, 1, 10, 7, 1, 6, 13, 0, 11, 8, 6, 13,
},
{ /* s7 */
4, 13, 11, 0, 2, 11, 14, 7, 15, 4, 0, 9, 8, 1, 13, 10,
3, 14, 12, 3, 9, 5, 7, 12, 5, 2, 10, 15, 6, 8, 1, 6,
1, 6, 4, 11, 11, 13, 13, 8, 12, 1, 3, 4, 7, 10, 14, 7,
10, 9, 15, 5, 6, 0, 8, 15, 0, 14, 5, 2, 9, 3, 2, 12,
},
{ /* s8 */
13, 1, 2, 15, 8, 13, 4, 8, 6, 10, 15, 3, 11, 7, 1, 4,
10, 12, 9, 5, 3, 6, 14, 11, 5, 0, 0, 14, 12, 9, 7, 2,
7, 2, 11, 1, 4, 14, 1, 7, 9, 4, 12, 10, 14, 8, 2, 13,
0, 15, 6, 12, 10, 9, 13, 0, 15, 3, 3, 5, 5, 6, 8, 11,
},
};
/* key permutation 1 for c */
static uchar pc1perm0[] = {
57, 49, 41, 33, 25, 17, 9,
1, 58, 50, 42, 34, 26, 18,
10, 2, 59, 51, 43, 35, 27,
19, 11, 3, 60, 52, 44, 36,
};
/* key permutation 1 for d */
static uchar pc1perm1[] = {
63, 55, 47, 39, 31, 23, 15,
7, 62, 54, 46, 38, 30, 22,
14, 6, 61, 53, 45, 37, 29,
21, 13, 5, 28, 20, 12, 4,
};
/* key permutation 2 */
static uchar pc2perm[] = {
14, 17, 11, 24, 1, 5,
3, 28, 15, 6, 21, 10,
23, 19, 12, 4, 26, 8,
16, 7, 27, 20, 13, 2,
41, 52, 31, 37, 47, 55,
30, 40, 51, 45, 33, 48,
44, 49, 39, 56, 34, 53,
46, 42, 50, 36, 29, 32,
};
static uchar keyshifts[] = {
1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1,
};
enum {
Mask6 = (1<<6)-1,
Mask7 = (1<<7)-1,
Mask28 = (1<<28)-1,
};
static ulong
g32(uchar *p)
{
ulong v;
v = 0;
v = (v<<8)|*p++;
v = (v<<8)|*p++;
v = (v<<8)|*p++;
v = (v<<8)|*p++;
return v;
}
static void
p32(uchar *p, ulong v)
{
*p++ = v>>24;
*p++ = v>>16;
*p++ = v>>8;
*p++ = v>>0;
}
/* input 32 bit, output 6 bit */
static uchar
perm6(ulong r, uchar *index)
{
uchar v;
int i;
v = 0;
for(i = 0; i < 6; i++)
v |= ((r>>(32-index[i]))&1)<<(6-1-i);
return v;
}
/* input 32 bit, output 32 bit */
static ulong
perm32(ulong r, uchar *index)
{
ulong v;
int i;
v = 0;
for(i = 0; i < 32; i++)
v |= ((r>>(32-index[i]))&1)<<(32-1-i);
return v;
}
/* input 64 bit, output 28 bit */
static ulong
perm28(uvlong r, uchar *index)
{
ulong v;
int i;
v = 0;
for(i = 0; i < 28; i++)
v |= ((r>>(64-index[i]))&1)<<(28-1-i);
return v;
}
/* input 56 bit, output 48 bit */
static uvlong
perm56(uvlong r, uchar *index)
{
uvlong v;
int i;
v = 0;
for(i = 0; i < 48; i++)
v |= ((r>>(56-index[i]))&1)<<(48-1-i);
return v;
}
/* input 64 bit, output 64 bit */
static uvlong
perm64(uvlong r, uchar *index)
{
uvlong v;
int i;
v = 0;
for(i = 0; i < 64; i++)
v |= ((r>>(64-index[i]))&1)<<(64-1-i);
return v;
}
static ulong
f(ulong r, uvlong k)
{
ulong p;
uchar ei, ki;
int i, j;
p = 0;
for(i = 0; i < 8; i++) {
j = 7-i;
ei = perm6(r, eperm+i*6);
ki = (k>>(j*6))&Mask6;
p |= (ulong)sbox[i][ei^ki]<<(j*4);
}
return perm32(p, pperm);
}
static ulong
rotateleft28(ulong v, int i)
{
ulong left, right;
left = (v<<i)&Mask28;
right = (v>>(28-i))&((1<<i)-1);
return left|right;
}
static void
deskey(Desks *ks, uvlong k64)
{
ulong c, d;
int i;
c = perm28(k64, pc1perm0);
d = perm28(k64, pc1perm1);
for(i = 0; i < 16; i++) {
c = rotateleft28(c, keyshifts[i]);
d = rotateleft28(d, keyshifts[i]);
ks->keys[i] = perm56(((uvlong)c<<28)|d, pc2perm);
}
}
static void
descrypt(Desks *ks, void *buf, int s, int e, int delta)
{
ulong l, r, tmp;
uvlong v;
int i;
v = g32(buf);
v = (v<<32)|g32(buf+4);
v = perm64(v, initperm);
l = v>>32;
r = v;
for(i = s; i != e; i += delta) {
tmp = r;
r = l^f(r, ks->keys[i]);
l = tmp;
}
v = r;
v = (v<<32)|l;
v = perm64(v, finalperm);
p32(buf, v>>32);
p32(buf+4, v);
}
void
deskey56(Desks *ks, uchar *k56)
{
uvlong t, k;
int i, j;
t = 0;
for(i = 0; i < 7; i++)
t = (t<<8)|*k56++;
k = 0;
for(i = 0; i < 8; i++) {
j = 8-1-i;
k |= ((t>>(j*7))&Mask7)<<(j*8+1);
}
deskey(ks, k);
}
void
deskey64(Desks *ks, uchar *k64)
{
uvlong k;
int i;
k = 0;
for(i = 0; i < 8; i++)
k = (k<<8)|*k64++;
deskey(ks, k);
}
void
desenc(Desks *ks, void *buf)
{
descrypt(ks, buf, 0, 16, 1);
}
void
desdec(Desks *ks, void *buf)
{
descrypt(ks, buf, 15, -1, -1);
}