E N D
단순 DES 암호화와 복호화
비트-필트 (Bit-field ) 비트 필드는 새로운 데이터 구조라기보다는 구조체와 공용체의 조합에서 약간의 내용이 추가된 것 각 구조체 멤버를 비트 단위로 나눌 수 있어, 더욱 더 세밀한 데이터 조정이 가능 struct 구조체-tag { <데이터 형> <비트필드 멤버 이름> : 비트수 .. .. .. <데이터 형> <비트필드 멤버 이름> : 비트수 } 구조체 변수; ※ 비트필드를 사용하는 주된 이유는 메모리를 절약하는데 있다. 4 바이트 워드를 갖는 기계에서 1 비트 변수를 저장할 경우 비트 필드를 사용하면 한 워드에 32 개의 변수를 저장할 수 있고, char형 변수는 4 개를 저장할 수 있다. ==> 따라서 비트 필드는 가능한 작은 공간에 정보를 압축해 놓을 때 매우 유용하다. //Save 1bit Struct typedef struct DES des; struct DES{ unsigned key: 1; }; //Save Key1 and Key2 des ck1[8], ck2[8];
//product K1 and K2 void key_generation(des *ptr, des *ky1, des *ky2) { int i; des temp[10], key1[5], key2[5]; //Relocate key temp[0].key = (ptr+2)->key; temp[1].key = (ptr+4)->key; temp[2].key = (ptr+1)->key; temp[3].key = (ptr+6)->key; temp[4].key = (ptr+3)->key; temp[5].key = (ptr+9)->key; temp[6].key = (ptr)->key; temp[7].key = (ptr+8)->key; temp[8].key = (ptr+7)->key; temp[9].key = (ptr+5)->key; //Separate key for(i=0; i<10; i++) { if (i<5) key1[i].key = temp[i].key; else key2[i-5].key = temp[i].key; } 1 0 0 1 0 0 1 1 1 0 1 2 3 4 5 6 7 8 9 10 35 2 7 4 10 1 9 8 6 0 0 0 1 1 0 1 1 1 0
//Circular Left Shift of key1 Circular_Left_Shift(key1); //Circular Left Shift of key2 Circular_Left_Shift(key2); //Combine key for(i=0; i<10; i++) { if (i<5) temp[i].key = key1[i].key; else temp[i].key = key2[i-5].key; } //Relocate key and product K1 ky1->key = temp[5].key; (ky1+1)->key = temp[2].key; (ky1+2)->key = temp[6].key; (ky1+3)->key = temp[3].key; (ky1+4)->key = temp[7].key; (ky1+5)->key = temp[4].key; (ky1+6)->key = temp[9].key; (ky1+7)->key = temp[8].key; 0 0 0 1 1 0 1 1 1 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 1 1 1 0 0 1 2 3 4 5 6 7 8 9 10 6 3 7 4 8 5 10 9 1 1 1 1 1 0 0 0
//Circular Left Shift of key1 Circular_Left_Shift(key1); //Circular Left Shift of key2 Circular_Left_Shift(key2); //Combine key for(i=0; i<10; i++) { if (i<5) temp[i].key = key1[i].key; else temp[i].key = key2[i-5].key; } //Relocate key and product K2 ky2->key = temp[5].key; (ky2+1)->key = temp[2].key; (ky2+2)->key = temp[6].key; (ky2+3)->key = temp[3].key; (ky2+4)->key = temp[7].key; (ky2+5)->key = temp[4].key; (ky2+6)->key = temp[9].key; (ky2+7)->key = temp[8].key; return; } 0 0 1 1 0 1 1 1 0 0 0 1 1 0 0 1 1 0 0 1 0 1 1 0 0 1 1 0 0 1 1 2 3 4 5 6 7 8 9 10 6 3 7 4 8 5 10 9 1 1 1 0 0 0 1 0
//Encryption Key void encryption(int *ptr) { int i, j, k; des plain[9][8], temp[9][8], sk1[4], sk2[4], exk[8], tmp[8], ex[4], sw[4]; //Conversion to binary for(i=0;i<9;i++) for(j=0;j<8;j++) { switch(j) { case 0: plain[i][j+7].key = *(ptr+i); break; case 1: plain[i][j+5].key = *(ptr+i) = *(ptr+i) >> 1; break; case 2: plain[i][j+3].key = *(ptr+i) = *(ptr+i) >> 1; break; case 3: plain[i][j+1].key = *(ptr+i) = *(ptr+i) >> 1; break; case 4: plain[i][j-1].key = *(ptr+i) = *(ptr+i) >> 1; break; case 5: plain[i][j-3].key = *(ptr+i) = *(ptr+i) >> 1; break; case 6: plain[i][j-5].key = *(ptr+i) = *(ptr+i) >> 1; break; case 7: plain[i][j-7].key = *(ptr+i) = *(ptr+i) >> 1; break; } }
//Processing IP for(i=0;i<9;i++) { temp[i][0].key = plain[i][1].key; temp[i][1].key = plain[i][5].key; temp[i][2].key = plain[i][2].key; temp[i][3].key = plain[i][0].key; temp[i][4].key = plain[i][3].key; temp[i][5].key = plain[i][7].key; temp[i][6].key = plain[i][4].key; temp[i][7].key = plain[i][6].key; } //According to the order in Plaintext for(j=0; j<9; j++) { //Separate key for(k=0; k<8; k++) { if (k<4) sk1[k].key = temp[j][k].key; else sk2[k-4].key = temp[j][k].key; } • 입력 8비트 • L (Left most 4 bits) • R (Right most 4 bits)
//Expansion key expansion_key(sk2, exk); //Processing X-OR for(i=0; i<8; i++) { tmp[i].key = exk[i].key ^ ck1[i].key; } //Expansion Key void expansion_key(des *ptr, des *ex) { (ex+1)->key = (ex+7)->key = ptr->key; (ex+2)->key = (ex+4)->key = (ptr+1)->key; (ex+3)->key = (ex+5)->key = (ptr+2)->key; (ex)->key = (ex+6)->key = (ptr+3)->key; } 12 34
//S-box generation s_box(tmp, ex); //Processing X-OR for(i=0; i<4; i++) { sk1[i].key = sk1[i].key ^ ex[i].key; }
//Choose S-Box void s_box(des *ptr, des *exp) { des temp[4]; int i, s0, s1, arr[8], x, y, w, z; //0 1 2 3 short int sbox0[4][4]= {{1, 0, 3, 2}, //0 {3, 2, 1, 0}, //1 {0, 2, 1, 3}, //2 {3, 1, 3, 2}}; //3 //0 1 2 3 short int sbox1[4][4]= {{0, 1, 2, 3}, //0 {2, 0, 1, 3}, //1 {3, 0, 1, 0}, //2 {2, 1, 0, 3}}; //3 //Replace key for(i=0; i<8; i++) arr[i] = (ptr+i)->key; x = (arr[0]*2) + arr[3]; y = (arr[1]*2) + arr[2]; w = (arr[4]*2) + arr[7]; z = (arr[5]*2) + arr[6]; s0 = sbox0[x][y]; s1 = sbox1[w][z]; temp[1].key = s0; temp[0].key = s0 >> 1; temp[3].key = s1; temp[2].key = s1 >> 1; //Permutation exp->key = temp[1].key; (exp+1)->key = temp[3].key; (exp+2)->key = temp[2].key; (exp+3)->key = temp[0].key; } • S-Box • 입력 : 4비트 ( 1 0 1 0 ) • 처리 • 행 : 1 번째와 4번째 비트 ( 1 0 ) • 열 : 2 번째와 3번째 비트 ( 0 1 )
//Separate key for(i=0; i<8; i++) { if (i<4) temp[j][i].key = sk1[i].key; else temp[j][i].key = sk2[i-4].key; } } //swich key for(i=0; i<4; i++) { sw[i] = sk1[i]; sk1[i] = sk2[i]; sk2[i] = sw[i]; } //Expansion key expansion_key(sk2, exk); //Processing X-OR for(i=0; i<8; i++) { tmp[i].key = exk[i].key ^ ck2[i].key; } //S-box generation s_box(tmp, ex); for(i=0; i<4; i++) { sk1[i].key = sk1[i].key ^ ex[i].key; }
//Processing IP-1 for(i=0;i<9;i++) { plain[i][0].key = temp[i][3].key; plain[i][1].key = temp[i][0].key; plain[i][2].key = temp[i][2].key; plain[i][3].key = temp[i][4].key; plain[i][4].key = temp[i][6].key; plain[i][5].key = temp[i][1].key; plain[i][6].key = temp[i][7].key; plain[i][7].key = temp[i][5].key; } 입력 : 1 2 3 4 5 6 7 8
//Conversion to integer for(i=0;i<9;i++) { *(ptr+i) = 0; for(j=0;j<8;j++) { switch(j) { case 0: *(ptr+i) = *(ptr+i) + plain[i][j].key * 128; break; case 1: *(ptr+i) = *(ptr+i) + plain[i][j].key * 64; break; case 2: *(ptr+i) = *(ptr+i) + plain[i][j].key * 32; break; case 3: *(ptr+i) = *(ptr+i) + plain[i][j].key * 16; break; case 4: *(ptr+i) = *(ptr+i) + plain[i][j].key * 8; break; case 5: *(ptr+i) = *(ptr+i) + plain[i][j].key * 4; break; case 6: *(ptr+i) = *(ptr+i) + plain[i][j].key * 2; break; case 7: *(ptr+i) = *(ptr+i) + plain[i][j].key; break; } } } } // encription 함수의 끝부분
//Decryption Key void decryption(int *ptr) { ………………….. 생략…………….. //Processing X-OR for(i=0; i<8; i++) { tmp[i].key = exk[i].key ^ ck2[i].key; } //Processing X-OR for(i=0; i<4; i++) { sk1[i].key = sk1[i].key ^ ex[i].key; } ………………….. 생략…………….. }
void main() { char Plaintext[9], Chiphertext[9]; int i, temp[9]; short int tmp1, tmp2; des des_key[10] ,k1[8] ,k2[8]; //Initialize Key des_key[0].key = 1; des_key[1].key = 0; des_key[2].key = 0; des_key[3].key = 1; des_key[4].key = 0; des_key[5].key = 0; des_key[6].key = 1; des_key[7].key = 1; des_key[8].key = 1; des_key[9].key = 0; //Initialize Plaintext Plaintext[0] = '7'; Plaintext[1] = '8'; Plaintext[2] = '1'; Plaintext[3] = '1'; Plaintext[4] = '1'; Plaintext[5] = '3'; Plaintext[6] = 'k'; Plaintext[7] = 'y'; Plaintext[8] = 's'; //Generate Key key_generation(des_key, k1, k2); //Save Key for(i=0;i<8;i++) { ck1[i].key = k1[i].key; ck2[i].key = k2[i].key; } //copy Plaintext for(i=0;i<9;i++) temp[i] = (int)Plaintext[i]; //Generate Chiphertext encryption(temp); //Conversion to Hex for(i=0;i<9;i++) { tmp1 = tmp2 = 0; tmp1 = temp[i] / 16; tmp2 = temp[i] % 16; Chiphertext[i] = (tmp1 << 4) | tmp2; }
//Generate Plaintext decryption(temp); //Conversion to Hex for(i=0;i<9;i++) { tmp1 = tmp2 = 0; tmp1 = temp[i] / 16; tmp2 = temp[i] % 16; Chiphertext[i] = (tmp1 << 4) | tmp2; } ………출력 부분 생략……… }