정보보안

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];
        }
}