공부 기록

[정보보안] Block Cipher Structure

by 너나나

암호를 알아내는데 필요한 정보의 가치보다 cost가 큰 경우나 암호를 알아내는데 필요한 시간이 정보가 유효한 시간보다 오래 걸릴 경우 -> Encryption이 안전하다!!

Block Cipher Structure

: 처리 단위가 block

block cipher

일련의 round / key에 의해 controll 되는 substitutions/permutations 을 가짐!!

- Parameters and design features :

  • block size
  • key size
  • number of rounds
  • subkey generation algorithm (라운드별로 돌아가는 키값이 다름!!)
  • round function
  • fast software en/decrypt, ease of analysis

Feistel Network - confusion and diffusion

  • Confusion : ciphertext의 통계값과 encryption key values 사이에 관계를 가능한 복잡하게 만든다
  • Diffusion : plaintext와 ciphertext의 통계적인 관계를 가능한 복잡하게 만든다

Feistel Network-based Encryption and Decryption

- n-bit block processing : n-bit plaintext -> n-bit ciphertext

- # of rounds (N) : Number of repetitions of Feistel Network / 마지막 라운드에서는 swap 일어나지 않음

- Encryption

  • input plaitext를 왼쪽 오른쪽 (L0 and R0)로 나누고 최종 결과 LN과 RN은 N round processing을 통해 암호화됨
  • Round operation 

Ki : secret key K로 부터 만들어지는 subkey (라운드마다 키가 다름)

- Decryption : 암호화 process를 역방향, input과 output을 바꾸면 됨!! (사용된 키도 역방향) 외에는 동일한 구조로 실행

 

그러니까 plaintext를 오른쪽/왼쪽으로 나누고 위의 operation을 반복적으로 실행한다!! 그림으로 보자

Plaintext를 L0와 R0로 나누고 K로부터 만들어진 n개의 subKey(K1 ~ Kn)를 사용한다. 어떤 라운드에서 오른쪽부분은 그대로 내려와 다음 라운드의 왼쪽으로 가고 왼쪽은 오른쪽 부분에 Ki를 사용해 함수 f를 적용한 것과 xor한 뒤에 다음 라운드의 오른쪽으로 간다. 마지막 라운드에서는 swapping이 일어나지 않는다!!

 

구체적인 예를 들어보자!!

plaintext P를 101011, # of rounds(N)을 2라고 하자

그리고 K1을 이용한 함수 f의 Output은

- f : 000 -> 101, 001 -> 010,

      010 -> 011, 011 -> 110,

      100 -> 100, 101 -> 001,

      110 -> 111, 111 -> 000,

이라고 하면

P를 오른쪽, 왼쪽으로 나누어 L0 : 101, R0 : 011 이고 R0은 그대로 다음라운드의 L1으로, L0은 R0에 함수 f를 적용한 것과 xor한 뒤에 R1으로 갈것이다. 그러면 L1은 011, R1은 101xor110이니까 011이 돼서 1라운드를 통과한 Ciphertext는 011011이 된다. 그림으로 보면

위의 f에서 오른쪽 R0인 011에 K1을 이용한 f는 110이 된다고 했다!!!

이제 다음라운드로 가자!! K2를 사용했을때 f함수의 Output은

- f : 000 -> 100, 001 -> 000,

      010 -> 011, 011 -> 111,

      100 -> 110, 101 -> 101,

      110 -> 001, 111 -> 010,

L1 : 011, R1 : 011이다. 그러면 R1은 그대로 다음 라운드의 L2로 간다고 생각할 수 있는데 마지막 라운드에서는 swapping이 일어나지 않는다!! 따라서 R1은 그대로 그냥 R2로 내려가고 L1은 R1(011)에 함수 f를 적용한 111과 xor해서 100이 되어 L2로 내려간다. 따라서 최종 Ciphertext는 100011이 된다. 그림으로 보자!!

이제 소스코드로 나타내보자!!!

#define BLOCK_SIZE 6
#define ROUND_NUM 2
#include<stdio.h>

char F1(char input) {
	if(input==0x00) return 0x05;
	else if(input==0x01) return 0x02;
	else if(input==0x02) return 0x03;
	else if(input==0x03) return 0x06;
	else if(input==0x04) return 0x04;
	else if(input==0x05) return 0x01;
	else if(input==0x06) return 0x07;
	else if(input==0x07) return 0x00;
	else; // do nothing
	
	return 0x00; 
}

char F2(char input) {
	if(input==0x00) return 0x04;
	else if(input==0x01) return 0x00;
	else if(input==0x02) return 0x03;
	else if(input==0x03) return 0x07;
	else if(input==0x04) return 0x06;
	else if(input==0x05) return 0x05;
	else if(input==0x06) return 0x01;
	else if(input==0x07) return 0x02;
	else; // do nothing
	
	return 0x00; 
}

char Feistel_Enc(char in) {
	int i;
	char temp, left, right;

	left=(in>>3)&0x07; // 왼쪽 3개 저장 
	right=in&0x07; // 오른쪽 3개 저장 
	
	for(i=0; i<ROUND_NUM; i++) {
		if(i==0) 
			left=left^F1(right);
		else if(i=1) 
			left=left^F2(right);
		if(i!=ROUND_NUM-1) {
			temp=left; 
			left=right; 
			right=temp; // 마지막 라운드가 아니라면 swapping 
		} 
		else; // do nothing
	}

	return (left<<3)|right; 
}

char Feistel_Dec(char in) {
	int i;
	char temp, left, right;

	left=(in>>3)&0x07; 
	right=in&0x07;
	
	for(i=0; i<ROUND_NUM; i++) {
		if(i==0) 
			left=left^F2(right);
		else if(i=1) 
			left=left^F1(right);
		if(i!=ROUND_NUM-1) {
			temp=left; 
			left=right; 
			right=temp;
		} 
		else; // do nothing
	}

	return (left<<3)|right; 
}

int main(){
	char p_bit=0x2B; // 00101011
	char c_bit, d_bit; // ciphertext 저장, decrypt 
	int temp=0, i=0;
	
	printf("평문: "); 
	for(i=BLOCK_SIZE-1; i>=0; i--) {
		temp=(p_bit>>i)&0x01; // block size만큼의 수만 출력 
		printf("%d ",temp); 
	}
	printf("\n"); 
	
	c_bit=Feistel_Enc(p_bit);
	
	printf("암호문: "); 
	for(i=BLOCK_SIZE-1; i>=0; i--) {
		temp=(c_bit>>i)&0x01;
		printf("%d ",temp); 
	}
	printf("\n"); 
	
	d_bit=Feistel_Dec(c_bit);
	printf("복호문: "); 
	for(i=BLOCK_SIZE-1; i>=0; i--) {
		temp=(d_bit>>i)&0x01;
		printf("%d ",temp); 
	}
	printf("\n");

	return 0; 
} 

 

블로그의 정보

공부 기록

너나나

활동하기