정보보안
Toy Cipher 알고리즘 (C 구현)
coty
2022. 6. 29. 01:45
Toy cipher - C 구현
Key : 01234567891011121314150123
Plaintext : 10,000쌍의 16진수
Ciphertext : Toy cipher로 암호화한 10,000쌍의 16진수
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
void Make_random_Input(int *str);
void s_box(int *str);
void Subkey_mixing(int *str, int key[][4], int row);
void Permutation(int *str, int a[4][4]);
void Total_pairs(int *str);
void PrintValue(int key[][4]);
int block[4] = {0};
int plain_pairs[10000] = {0};
int cipher_pairs[10000] = {0};
int num = 0;
int check = 0;
int main(int argc, char *argv[])
{
srand(time(NULL));
// key 값
int key[][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3};
int a[4][4] = {0};
for (int ch = 0; ch < 2500; ch++)
{ // 1 block(16진수 4개)씩 생산. -> 10000 pairs를 위해선 2500번 반복
Make_random_Input(block);
for (int round = 0; round < 3; round++)
{ // round 1 ~ 3
Subkey_mixing(block, key, round);
s_box(block);
Permutation(block, a);
}
Subkey_mixing(block, key, 3); // round 4
s_box(block);
Subkey_mixing(block, key, 4); // round 5
Total_pairs(block);
} // for
PrintValue(key);
return 0;
}
void Make_random_Input(int *str)
{ // 1 block(16진수 4개)씩 plain_pairs에 저장, block에 4개의 16진수 저장
for (int a = 0; a < 4; a++)
{
str[a] = rand() % 16;
plain_pairs[num] = str[a];
num++;
}
}
void Total_pairs(int *str)
{ // 1 block(16진수 4개)씩 cipher_pairs에 저장
for (int a = 0; a < 4; a++)
{
cipher_pairs[check] = str[a];
check++;
}
}
void PrintValue(int key[][4])
{ // plaintext & key & ciphertext 출력
printf("\n");
printf("** Toy Cipher ** \n\n");
printf(" * Plaintext : \n\n");
for (int w = 0; w < 10000; w++)
{ // plaintext 출력
printf(" %X", plain_pairs[w]);
}
printf("\n\n * Key value : ");
for (int j = 0; j < 5; j++)
{ // key값 출력
for (int i = 0; i < 4; i++)
{
printf("%X", key[j][i]);
}
}
printf("\n\n * Ciphertext : \n\n");
for (int w = 0; w < 10000; w++)
{ // ciphertext 출력
printf(" %X", cipher_pairs[w]);
}
printf("\n");
}
void Permutation(int *str, int a[4][4])
{
int b[4][4] = {0};
for (int k = 0; k < 4; k++)
{ // 10진수를 2진수로 변환
for (int j = 3; j >= 0; j--)
{
a[k][j] = str[k] % 2;
str[k] /= 2;
}
} // for
for (int o = 0; o < 4; o++)
{ // permutation 과정
for (int p = 0; p < 4; p++)
{
b[p][o] = a[o][p];
}
} // for
int temp = 0, q = 0;
for (int e = 0; e < 4; e++)
{ // 2진수를 10진수로 변환
for (int f = 3; f >= 0; f--)
{
temp += (b[e][f] * pow(2, q));
q++;
}
block[e] = temp;
temp = 0, q = 0;
} // for
}
void s_box(int *str)
{ // s_box 치환, 각 16진수에 대해서 다른 값으로 치환
for (int i = 0; i < 4; i++)
{
if (str[i] == 0)
str[i] = 14;
else if (str[i] == 1)
str[i] = 4;
else if (str[i] == 2)
str[i] = 13;
else if (str[i] == 3)
str[i] = 1;
else if (str[i] == 4)
str[i] = 2;
else if (str[i] == 5)
str[i] = 15;
else if (str[i] == 6)
str[i] = 11;
else if (str[i] == 7)
str[i] = 8;
else if (str[i] == 8)
str[i] = 3;
else if (str[i] == 9)
str[i] = 10;
else if (str[i] == 10)
str[i] = 6;
else if (str[i] == 11)
str[i] = 12;
else if (str[i] == 12)
str[i] = 5;
else if (str[i] == 13)
str[i] = 9;
else if (str[i] == 14)
str[i] = 0;
else if (str[i] == 15)
str[i] = 7;
} // for
}
void Subkey_mixing(int *str, int key[][4], int row)
{ // subkey key mixing (XOR연산 : ^)
for (int count = 0; count < 4; count++)
{
str[count] ^= key[row][count];
}
}