암호학/알고리즘

[암호 코딩] SEED 코딩

controlpro 2021. 1. 8. 17:59
728x90

알고리즘 공부하면서 SEED 코딩을 직접해보았다. 

 

옛날에 AES암호를 코딩할 때 보다 코드를 보는 눈이라던가, 코딩 실력이 많이 는거 같다. 

 

저번에 SEED공부할 때 쓰던 문서와 같이 보면 좋을 거같다. 

 

Block 암호 코딩 할때 항상 생각해야하는게 평문의 길이라던가 한 블록의 크기 인데 128bit를 담을 만한 크기의 변수 공간이 없어서 unsigned long 형을 4개 이어 붙였다. (L[0] , L[1] , R[0] , R[1])

 

시나리오. 

1. 16bytes 평문을 파일로 받아서 읽고, 16bytes 암호문을 파일에 저장한다. 

 

1. F 함수 

void SEED_F(ULONG L[2], ULONG R[2], ULONG k[2]) { // L이 return 값 //R이 수행값 R[0] = C , R[1] = D K[0] = 32BIT
	ULONG temp[2]; // 16비트
	temp[0] = R[0] ^ k[0];
	temp[1] = R[1] ^ k[1];

	temp[1] ^= temp[0];

	SEED_G(temp + 1); // temp[1]의 pointer를 전달
	temp[0] += temp[1];

	SEED_G(temp);
	temp[1] += temp[0];

	SEED_G(temp + 1);
	temp[0] += temp[1];


	L[0] ^= temp[0];
	L[1] ^= temp[1]; // SEED 전체 구조도에 있는 마지막 L과 F(R)을 XOR하는 과정이 여기에 포함되어 있음
	
}

일단 F함수 구조도를 보면 딱히 구현하는 데 어려움은 없었다. 근데 Round 당 돌아가는 함수가 아래 사진과 같은데 굳이

마지막에 XOR 연산하는 부분을 따로 구현해주기 힘들어서 F함수에 포함 시켰다. 

2. G 함수

void SEED_G(ULONG *s) { // s는 그전에 넘어온것 s = 32bit  x0 = 8bit
	ULONG z[4];
	UCHAR y[4];
	ULONG temp = 0;

	y[0] = SEED_S1box[((*s) >> 0) & 0xff];
	y[1] = SEED_S2box[((*s) >> 8) & 0xff];
	y[2] = SEED_S1box[((*s) >> 16) & 0xff];
	y[3] = SEED_S2box[((*s) >> 24) & 0xff];

	z[3] = (y[0] & m[3]) ^ (y[1] & m[0]) ^ (y[2] & m[1]) ^ (y[3] & m[2]); // 0x3f 0xfc 0xf3 0xcf
	z[2] = (y[0] & m[2]) ^ (y[1] & m[3]) ^ (y[2] & m[0]) ^ (y[3] & m[1]); // 0xcf 0x3f 0xfc 0xf3
	z[1] = (y[0] & m[1]) ^ (y[1] & m[2]) ^ (y[2] & m[3]) ^ (y[3] & m[0]); // 0xf3 0xcf 0x3f 0xfc 
	z[0] = (y[0] & m[0]) ^ (y[1] & m[1]) ^ (y[2] & m[2]) ^ (y[3] & m[3]); // 0xfc 0xf3 0xcf 0x3f

	temp ^= z[0];
	temp ^= (z[1] << 8);
	temp ^= (z[2] << 16);
	temp ^= (z[3] << 24);
	*s = temp;
}

조금 헷갈렸던 부분이다. 사실 수식을 보면 어렵지 않은 계산인데 bit연산 자체가 뭔가 값이 이상하게 전달되서 고민을 해본 결과 temp에 따로 변수를 잡아주고 넘어온 32bit에 넣어주는 것이 뭔가 더 편했다. 부채널 공격자 입장에서 본다면 저번 AES암호를 공격해볼때는 Sbox가 하나 밖에 없었다면, 이번에는 각 블록마다(Y블록) 사용하는 Sbox 종류가 달라서 이점을 유의 하면서 SEED를 공격해보면 될 것 같다. 

 

 

3. KEYGEN 함수

void KeyGen(ULONG A , ULONG B, ULONG C, ULONG D ,ULONG R,ULONG RK[][2]) {
	ULONG T0;
	ULONG T1;

	T0 = A + C - SEED_KC[R];
	T1 = B - D + SEED_KC[R];
	RK[R][0] = T0;
	RK[R][1] = T1;
	SEED_G(RK[R]);
	SEED_G(RK[R] + 1);

}

사실 이 함수도 별게 없다 그냥 계산한 부분 그대로 넣어주면 됐다. 

 

4. 소감 

사실 저번주에 AES 부채널 공격을 직접 구현하면서 구현실력이 많이는 거 같다. 코드는 하루만에 다짰는데 다음날 3시간 동안 오류만 잡았던 것 같다. 별거 아닌 오류인데 변수에 리틀엔디안 방식으로 값을 넣어버려서... 값이 계속해서 이상하게 나왔다...(해킹을 하고 코딩을 하지말자..) 구현실력이 늘어서 기분 좋은 것같당. 

 

전체 코드 및 설명 문의 controlpro@naver.com

 

728x90
반응형