암호화 알고리즘
S-DES
아메숑
2019. 4. 1. 09:09
#include <stdio.h>
#include <math.h>
#define GetBit(W,n) (((W)>>(10-n)) &0x01)
#define GetBit8(W,n) (((W)>>(8-n)) &0x01)
#define GetBit4(W,n) (((W)>>(4-n)) &0x01)
#define ReturnBit(W,n,k) (((GetBit(W,n)))<<(10-k))
#define ReturnBit8(W,n,k) (((GetBit(W,n)))<<(8-k))
#define ReturnBit8_8(W,n,k) (((GetBit8(W,n)))<<(8-k))
#define ReturnBit4_8(W,n,k) (((GetBit4(W,n)))<<(8-k))
#define ReturnBit4_4(W,n,k) (((GetBit4(W,n)))<<(4-k))
#define permutation(val)\
( ReturnBit(val,3,1) | ReturnBit(val,5,2) | ReturnBit(val,2,3) | \
ReturnBit(val,7,4) | ReturnBit(val,4,5) | ReturnBit(val,10,6) | \
ReturnBit(val,1,7) | ReturnBit(val,9,8) | ReturnBit(val,8,9) | \
ReturnBit(val,6,10))
#define permutation8(val)\
( ReturnBit8(val,6,1) | ReturnBit8(val,3,2) | ReturnBit8(val,7,3) | \
ReturnBit8(val,4,4) | ReturnBit8(val,8,5) | ReturnBit8(val,5,6) | \
ReturnBit8(val,10,7) | ReturnBit8(val,9,8))
#define IP(val)\
( ReturnBit8_8(val,2,1) | ReturnBit8_8(val,6,2) | ReturnBit8_8(val,3,3) | \
ReturnBit8_8(val,1,4) | ReturnBit8_8(val,4,5) | ReturnBit8_8(val,8,6) | \
ReturnBit8_8(val,5,7) | ReturnBit8_8(val,7,8))
#define rIP(val)\
( ReturnBit8_8(val,4,1) | ReturnBit8_8(val,1,2) | ReturnBit8_8(val,3,3) | \
ReturnBit8_8(val,5,4) | ReturnBit8_8(val,7,5) | ReturnBit8_8(val,2,6) | \
ReturnBit8_8(val,8,7) | ReturnBit8_8(val,6,8))
#define EP(val)\
( ReturnBit4_8(val,4,1) | ReturnBit4_8(val,1,2) | ReturnBit4_8(val,2,3) | \
ReturnBit4_8(val,3,4) | ReturnBit4_8(val,2,5) | ReturnBit4_8(val,3,6) | \
ReturnBit4_8(val,4,7) | ReturnBit4_8(val,1,8))
#define permutation4(val)\
( ReturnBit4_4(val,2,1) | ReturnBit4_4(val,4,2) | ReturnBit4_4(val,3,3) | \
ReturnBit4_4(val,1,4))
#define _setval(u8,val) u8.left = (val>>4); \
u8.right = val;
#define _print(pu8)printf(#pu8" : 0x%x%x\n",pu8.left,pu8.right);
#define ROR(N,W,i) (((W)>>(i)) | ((W)<<(N-(i))))
#define ROL(N,W,i) (((W)<<(i)) | ((W)>>(N-(i))))
int chartodecimal(char bin[])
{
int i;
int bin2[10];
for(i=0;i<10;i++)
bin2[i] = bin[i]-'0';
int sum=0;
int j = strlen(bin) - 1;
for(i=0;i<strlen(bin);i++)
{
sum += bin2[i] * pow(2,j);
j--;
}
return sum;
}
typedef struct bit10{
unsigned p10:10;
unsigned p8:8;
unsigned left:5;
unsigned right:5;
}p10;
typedef struct plain{
unsigned p8:8;
unsigned p4:4;
unsigned left:4;
unsigned right:4;
unsigned templeft:4;
unsigned tempright:4;
}p8;
char *uintToBinary(p10 i) {
static char s[11];
int count = 10;
do { s[--count] = '0' + (char) (i.p10 & 1);
i.p10 = i.p10 >> 1;
} while (count);
return s;
}
char *uintToBinary8(p10 i) {
static char s[9];
int count = 8;
do { s[--count] = '0' + (char) (i.p8 & 1);
i.p8 = i.p8 >> 1;
} while (count);
return s;
}
char *uintToBinaryplain8(p8 i) {
static char s[9];
int count = 8;
do { s[--count] = '0' + (char) (i.p8 & 1);
i.p8 = i.p8 >> 1;
} while (count);
return s;
}
char *uintToBinaryplain4(p8 i) {
static char s[5];
int count = 4;
do { s[--count] = '0' + (char) (i.p4 & 1);
i.p4 = i.p4 >> 1;
} while (count);
return s;
}
char *uintToBinary2(p10 i) {
static char s[5] = { '0', };
int count = 5;
do { s[--count] = '0' + (char) (i.left & 1);
i.left = i.left >> 1;
} while (count);
return s;
}
char *uintToBinary3(p10 i) {
static char s[5] = { '0', };
int count = 5;
do { s[--count] = '0' + (char) (i.right & 1);
i.right = i.right >> 1;
} while (count);
return s;
}
char *uintToBinarykey(int a) {
static char s[8] = { '0', };
int count = 8;
do { s[--count] = '0' + (char) (a & 1);
a = a >> 1;
} while (count);
return s; //나중에 지워
}
int *s0s1(p8 i)
{
int s0[4][4] ={{1,0,3,2},
{3,2,1,0},
{0,2,1,3},
{3,1,3,2}};
int s1[4][4] ={{1,0,2,3},
{2,0,1,3},
{3,0,1,0},
{2,1,0,3}};
int x,y,z,w;
x = GetBit4(i.left,1);
y = GetBit4(i.left,2);
z = GetBit4(i.left,3);
w = GetBit4(i.left,4);
int x1,y1,z1,w1;
x1 = GetBit4(i.right,1);
y1 = GetBit4(i.right,2);
z1 = GetBit4(i.right,3);
w1 = GetBit4(i.right,4);
printf("%d %d %d %d %d %d %d %d \n",x,y,z,w,x1,y1,z1,w1);
int l2,r2;
l2 = s0[x*2+w][y*2+z];
r2 = s1[x1*2+w1][y1*2+z1];
printf("s0 s1 :%d %d\n",l2,r2);
i.p4 = l2*4 + r2;
printf("4bit : %d\n",i.p4);
return i.p4;
}
int main(void){
p10 initKey;
char key[10];
//scanf("%s",key); //0x282
//initKey.p10=chartodecimal(key);
initKey.p10= 0b1100001110;
printf("p10 : %s \n",uintToBinary(initKey));
p10 permutate;
permutate.p10 = permutation(initKey.p10);
printf("p10 : %s \n",uintToBinary(permutate));
permutate.right = permutate.p10 ;
permutate.left = ROR(10,permutate.p10,5);
printf("왼쪽 5비트 p10 : %s \n",uintToBinary2(permutate));
printf("오른쪽 5비트 p10 : %s \n",uintToBinary3(permutate));
permutate.left = ROL(5,permutate.left,1);
permutate.right = ROL(5,permutate.right,1);
printf("왼쪽 5비트 p10 shift: %s \n",uintToBinary2(permutate));
printf("오른쪽 5비트 p10 shift : %s \n",uintToBinary3(permutate));
permutate.p10 = ROL(10,permutate.left,5)|permutate.right;
printf("p10 : %s \n",uintToBinary(permutate));
permutate.p8 = permutation8(permutate.p10);
printf("k1 : %s \n",uintToBinary8(permutate));
int key1 = permutate.p8;
//printf("k1 : %s \n",uintToBinarykey(key1));
permutate.left = ROL(5,permutate.left,2);
permutate.right = ROL(5,permutate.right,2);
permutate.p10 = ROL(10,permutate.left,5)|permutate.right;
permutate.p8 = permutation8(permutate.p10);
printf("k2 : %s \n",uintToBinary8(permutate));
int key2 = permutate.p8;
p8 plain;
char plaintext[10];
//printf("plaintext :");
//scanf("%s",plaintext); //0x282
//plain.p10=chartodecimal(plaintext);
plain.p8= 0b10101010;
plain.p8 = IP(plain.p8);
printf("after IP plain : %s \n",uintToBinaryplain8(plain));
plain.templeft = ROR(8,plain.p8,4);
int plainright = plain.p8;
plain.right = plain.p8;
plain.p8 = EP(plain.right);
printf("after E/P plain : %s \n",uintToBinaryplain8(plain));
plain.p8 ^= key1;
printf("after exclusive OR with k1 plain : %s \n",uintToBinaryplain8(plain));
plain.left = ROR(8,plain.p8,4);
plain.right = plain.p8;
plain.p4 = s0s1(plain);
printf("after s0s1 plain : %s \n",uintToBinaryplain4(plain));
plain.p4 = permutation4(plain.p4);
printf("after p4 plain : %s \n",uintToBinaryplain4(plain));
plain.p4 ^= plain.templeft;
printf("after exclusive plain : %s \n",uintToBinaryplain4(plain));
plain.templeft = plainright;
plain.p8 = ROL(8,plain.templeft,4)+ plain.p4;
printf("after SW plain : %s \n",uintToBinaryplain8(plain));
plain.templeft = ROR(8,plain.p8,4);
plainright = plain.p4;
plain.p8 = EP(plain.p4);
plain.p8 ^= key2;
plain.left = ROR(8,plain.p8,4);
plain.right = plain.p8;
plain.p4 = s0s1(plain);
plain.p4 = permutation4(plain.p4);
plain.p4 ^= plain.templeft;
plain.templeft = plainright;
plain.p8 = ROL(8,plain.p4,4) | plain.templeft;
plain.p8 = rIP(plain.p8);
printf("ciphertext : %s \n",uintToBinaryplain8(plain));
//여기까지 암호화 이제부터 복호화 --------------------------------------------
plain.p8 = IP(plain.p8);
plain.tempright = plain.p8;
plain.templeft = plain.p8 / 16;
plain.p8 = EP(plain.tempright) ^ key2;
plain.right = plain.p8;
plain.left = plain.p8 / 16;
plain.p4 = s0s1(plain);
plain.p4 = permutation4(plain.p4);
plain.left = plain.templeft ^ plain.p4;
plain.p8 = ROL(8,plain.tempright,4)+ plain.left;
plain.tempright = plain.p8;
plain.templeft = plain.p8 / 16;
plain.p8 = EP(plain.tempright) ^ key1;
plain.right = plain.p8;
plain.left = plain.p8 / 16;
plain.p4 = s0s1(plain);
plain.p4 = permutation4(plain.p4);
plain.left = plain.templeft ^ plain.p4;
plain.p8 = plain.left * 16 + plain.tempright;
plain.p8 = rIP(plain.p8);
printf("plaintext : %s \n",uintToBinaryplain8(plain));
return 0;
}