[암호 코딩] SEED 코딩
알고리즘 공부하면서 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