A5/1 แแ ฎแแ งแซ(C++)
A5/1 แแ ฎแแ งแซ(C++)
Stream Cipher ์ค ํ๋์ธ A5/1๋ฅผ C++๋ก ๊ตฌํํ๊ณ ์ํธํ์ ๋ณตํธํ๋ฅผ ํด๋ณด์์ต๋๋ค.
๊ตฌํ ๊ณผ์
ํค ๊ตฌํ ๋ฐฉ์ ์ ๋ ฅ๋ฐ๊ธฐ
printf("------------------------------------------------------------------\n");
printf("-----------------------------A5/1 ๊ตฌํ------------------------------\n");
printf("ํค๋ฅผ ์ง์ ์
๋ ฅํ์๊ฒ ์ต๋๊น?(์
๋ ฅํ์ค๊บผ๋ฉด 1, ๋๋คํ ํค๋ 2๋ฒ) -> ");
cin >> ans;
while(true){
if(ans==1){
char str[65];
cin >> str;
for(int i=0;i<64;i++){
key[i]=str[i]-'0';
}
break;
}
else if(ans==2){
srand((unsigned int)time(0));
for(int i=0;i<64;i++){
key[i] = rand()%2;
}
cout << "๋๋คํ๊ฒ ์์ฑ๋ ํค ๊ฐ์ ";
for(int i=0;i<64;i++) cout << key[i];
cout << " ์
๋๋ค!\n";
break;
}
else{
printf("์ ๋ชป ์
๋ ฅํ์
จ์ต๋๋ค. ๋ค์ ์
๋ ฅํด์ฃผ์ธ์! -> ");
cin >> ans;
continue;
}
}
์ฐ์ ์ฌ์ฉ์๊ฐ ํค๋ฅผ ์ง์ ์
๋ ฅํ๊ฑฐ๋ ๋๋คํ๊ฒ ์์ฑ ๋ ํค๋ฅผ ๋ฐ๋ ๊ฒ์ ์
๋ ฅ์ ํตํด ์ ํ ์ ์๋๋ก ํ์ต๋๋ค.
1๋ฒ์ ์
๋ ฅํ๋ฉด ํค๋ฅผ ์
๋ ฅํ ์ ์๊ณ 2๋ฒ์ ์
๋ ฅํ๋ฉด ๋๋ค ํ ํค๋ฅผ ๋ฐ์ ์ ์์ต๋๋ค.
๋ง ์ฝ 1์ด๋ 2๊ฐ ์๋ ๋ค๋ฅธ ์๊ฐ ์
๋ ฅ๋๋ค๋ฉด ์ฌ๋ฐ๋ฅธ ์
๋ ฅ ๊ฐ์ ๋ฐ์ ๋๊น์ง ์
๋ ฅ์ ๋ฐ์ ์ ์๊ฒ ํ์ต๋๋ค.
ํ๋ฌธ ์ ๋ ฅ๋ฐ๊ธฐ
cout << "ํ๋ฌธ์ ์
๋ ฅํด์ฃผ์ธ์! ";
char empty[2];
cin.getline(empty,2,'\n');
cin.getline(pText,1000,'\n');
sizeVal=strlen(pText);
int bitCnt=0;
for(int i=0;i<sizeVal;i++){
for(int j=7;j>=0;j--){
pTextBool[bitCnt] = bitset<8>(pText[i])[j];
bitCnt++;
}
}
sizeVal*=8;
makeKeySteam();
ํ๋ฌธ์ ์ผ๋จ ๋ฌธ์์ด๋ก ์
๋ ฅ๋ฐ์ ๋ค, boolํ ํ๋ฌธ ๋ฐฐ์ด์ ๋ง๋ค์ด์ค๋๋ค.
๋ฌธ์์ด ํ๋ํ๋๋ฅผ bitset ํจ์๋ฅผ ์ด์ฉํด 8๋นํธ๋ก ๋ณํํด ์ฃผ๊ณ bool ํ ํ๋ฌธ ๋ฐฐ์ด์ ์ ์ฅํฉ๋๋ค.
๊ทธ ๋ค์ ํค์คํธ๋ฆผ์ ๋ง๋๋ ํจ์๋ฅผ ํธ์ถํฉ๋๋ค.
ํค์คํธ๋ฆผ ์์ฑ ํจ์
void makeKeySteam(){
int cnt = 0;
int st =0;
for(int i=0;i<64;i++){
if(i==19 || i==41) cnt=0;
if(i<19) x[cnt]=key[i];
else if(i<41) y[cnt]=key[i];
else z[cnt] = key[i];
cnt++;
}
cnt=sizeVal;
while(cnt--) {
int maj = chkMaj(x[8], y[10], z[10]);
if (x[8] == maj) excuteX();
if (y[10] == maj) excuteY();
if (z[10] == maj) excuteZ();
keyStream[st] = x[18]^y[21]^z[22];
st++;
}
}
ํค์คํธ๋ฆผ์ ๋ง๋๋ ํจ์์
๋๋ค.
์ฐ์ ์์์ ์์ฑ๋ ํค๊ฐ์ x,y,z์ ๋ถ๋ฐฐ๋ฅผ ํด์ค๋๋ค.
๊ทธ ๋ค์ ๋ค์๊ฒฐ ํจ์๋ฅผ ์ด์ฉํด ๋ค์๊ฒฐ ์๋ฅผ ๊ฒฐ์ ํ๊ณ ๋ค์๊ฒฐ ์๋ฅผ ํ์ธํ๋ฉฐ x,y,z๋ฅผ ํ์ธํด ์ฃผ๊ณ ๋ค์๊ฒฐ ํจ์์ ๊ฐ ํด๋น ๋นํธ๊ฐ ์ผ์นํ๋ค๋ฉด ๊ฐ๊ฐ์์ ํจ์๋ฅผ ๋ถ๋ฌ ๋ณํํ๋ ๊ณผ์ ์ ์คํํฉ๋๋ค.
maj ํ์ธ, excute X,Y,Z
bool chkMaj(bool x, bool y, bool z){
int arr[2] = {0,0};
arr[x]++;
arr[y]++;
arr[z]++;
if(arr[1]>arr[0]) return true;
return false;
}
void excuteX(){
bool tempZero = x[13] ^ x[16] ^ x[17] ^ x[18];
for(int i=19;i>0;i--){
x[i]=x[i-1];
}
x[0]=tempZero;
}
void excuteY(){
bool tempZero = y[20]^y[21];
for(int i=21;i>0;i--){
y[i] = y[i-1];
}
y[0] = tempZero;
}
void excuteZ(){
bool tempZero = z[7]^z[20]^z[21]^z[22];
for(int i=22;i>0;i--){
z[i]=z[i-1];
}
z[0]=tempZero;
}
maj๋ฅผ ํ์ธํ๋ ํจ์์ x,y,z์์ ๋ณํํ๋ ํจ์์ ๋๋ค.
ํค์คํธ๋ฆผ ์ถ๋ ฅ
cout << "์์ฑ๋ ํค์คํธ๋ฆผ์ ";
for(int i=0;i<sizeVal;i++){
cout << keyStream[i];
}
cout << " ์
๋๋ค.\n\n";
์์ makeKeyStream์ ํตํด ์์ฑ๋ ํค์คํธ๋ฆผ์ ์ถ๋ ฅํ์ฌ ์ฝ์ ์ฐฝ์์ ๋ณด์ฌ์ค๋๋ค.
์ํธํ ๋ ์ด์ง์, ๋ฌธ์ ์ถ๋ ฅ
cout << "ํค์คํธ๋ฆผ์ผ๋ก ์ํธํ๋ฅผ ํ ์ด์ง์๋ ";
for(int i=0;i<sizeVal;i++){
cTextBool[i]=pTextBool[i]^keyStream[i];
cout << cTextBool[i];
}
cout << " ์
๋๋ค.\n";
cout << "๊ธ์๊ฐ ๊นจ์ง ์๋ ์์ง๋ง ์ํธํ๋ก ๋ ์ด์ง์๋ฅผ ๋ฌธ์๋ก ๋ฐ๊พผ๋ค๋ฉด ";
bitCnt= 0;
int now = 0;
for(int i=0;i<sizeVal;i++){
now+=cTextBool[i]*pow(2,7-bitCnt);
bitCnt++;
if(bitCnt==8){
bitCnt=0;
char pr = now;
cout << pr;
now=0;
}
}
cout << "์
๋๋ค.\n";
ํค์คํธ๋ฆผ์ผ๋ก ์ํธํ ํ ์ด์ง์๋ฅผ ๊ตฌํ๊ธฐ ์ํด ์์์ ๋ง๋ bool ํ๋ฌธ ๋ฐฐ์ด๊ณผ ํค์คํธ๋ฆผ์ xor ์ฐ์ฐํ์ฌ ๋ณด์ฌ์ค๋๋ค.
๋ ํ ํด๋น ๋ฐฐ์ด์ 8๋นํธ ๊ธฐ์ค์ผ๋ก ๋ฌธ์์ด๋ก ๋ณํํ๋ ๊ณผ์ ์ ๋ณด์ฌ์ฃผ๊ธฐ ์ํด 8๋นํธ ์ฉ ๋๋ ์ ๊ฐ ์๋ฆฌ์ ๋ง๋ ์๋ฅผ ๊ณฑํด ์์คํค์ฝ๋๋ก ์ถ๋ ฅํฉ๋๋ค.
๋ณตํธํ ๋ฌธ์ ์ถ๋ ฅ
cout << "์ด๋ฅผ ๋ค์ ๋ณตํธํ ํ๋ค๋ฉด ";
bitCnt=0;
now=0;
for(int i=0;i<sizeVal;i++){
finalTextBool[i]=cTextBool[i]^keyStream[i];
now+=finalTextBool[i]*pow(2,7-bitCnt);
bitCnt++;
if(bitCnt==8){
bitCnt=0;
char pr = now;
cout << pr;
now=0;
}
}
cout << " ์
๋๋ค.\n";
๋ณตํธํ ํ๋ ๊ณผ์ ๋ ๋ง์ฐฌ๊ฐ์ง๋ก ์์์ ๋ง๋ค์๋ ์ํธํ๋ ์ด์ง์์ ํค์คํธ๋ฆผ์ xor ์ฐ์ฐํ์ฌ ๋ค์ ๋ณตํธํ ํฉ๋๋ค.
๋ ์ด ๋ณตํธํ ํ ๋ฐฐ์ด์ ๋ค์ 8๋นํธ ๊ธฐ์ค์ผ๋ก ๊ณ์ฐํ์ฌ ์์คํค์ฝ๋๋ก ์ถ๋ ฅํด ์ค๋๋ค.
์คํํ๋ฉด
์ ์ฒด ์์ค์ฝ๋
#include <iostream>
#include <algorithm>
#include <ctime>
#include <cmath>
#include <cstring>
#include <bitset>
using namespace std;
int keyStream[8001];
int ans;
bool key[64];
bool x[19];
bool y[22];
bool z[23];
char pText[8001];
bool pTextBool[8001];
bool cTextBool[8001];
bool finalTextBool[8001];
void excuteX();
void excuteY();
void excuteZ();
int sizeVal;
void makeKeySteam();
bool chkMaj(bool x,bool y, bool z);
int main(){
printf("-----------------------------------------------------------------------------------------------------------\n");
printf("--------------------------------------------------A5/1 ๊ตฌํ--------------------------------------------------\n");
printf("ํค๋ฅผ ์ง์ ์
๋ ฅํ์๊ฒ ์ต๋๊น?(์
๋ ฅํ์ค๊บผ๋ฉด 1, ๋๋คํ ํค๋ 2๋ฒ) -> ");
cin >> ans;
while(true){
if(ans==1){
char str[65];
cin >> str;
for(int i=0;i<64;i++){
key[i]=str[i]-'0';
}
break;
}
else if(ans==2){
srand((unsigned int)time(0));
for(int i=0;i<64;i++){
key[i] = rand()%2;
}
cout << "๋๋คํ๊ฒ ์์ฑ๋ ํค ๊ฐ์ ";
for(int i=0;i<64;i++) cout << key[i];
cout << " ์
๋๋ค!\n";
break;
}
else{
printf("์ ๋ชป ์
๋ ฅํ์
จ์ต๋๋ค. ๋ค์ ์
๋ ฅํด์ฃผ์ธ์! -> ");
cin >> ans;
continue;
}
}
cout << "ํ๋ฌธ์ ์
๋ ฅํด์ฃผ์ธ์! ";
char empty[2];
cin.getline(empty,2,'\n');
cin.getline(pText,1000,'\n');
sizeVal=strlen(pText);
int bitCnt=0;
for(int i=0;i<sizeVal;i++){
for(int j=7;j>=0;j--){
pTextBool[bitCnt] = bitset<8>(pText[i])[j];
bitCnt++;
}
}
sizeVal*=8;
makeKeySteam();
cout << "์์ฑ๋ ํค์คํธ๋ฆผ์ ";
for(int i=0;i<sizeVal;i++){
cout << keyStream[i];
}
cout << " ์
๋๋ค.\n\n";
cout << "ํค์คํธ๋ฆผ์ผ๋ก ์ํธํ๋ฅผ ํ ์ด์ง์๋ ";
for(int i=0;i<sizeVal;i++){
cTextBool[i]=pTextBool[i]^keyStream[i];
cout << cTextBool[i];
}
cout << " ์
๋๋ค.\n";
cout << "๊ธ์๊ฐ ๊นจ์ง ์๋ ์์ง๋ง ์ํธํ๋ก ๋ ์ด์ง์๋ฅผ ๋ฌธ์๋ก ๋ฐ๊พผ๋ค๋ฉด ";
bitCnt= 0;
int now = 0;
for(int i=0;i<sizeVal;i++){
now+=cTextBool[i]*pow(2,7-bitCnt);
bitCnt++;
if(bitCnt==8){
bitCnt=0;
char pr = now;
cout << pr;
now=0;
}
}
cout << "์
๋๋ค.\n";
cout << "์ด๋ฅผ ๋ค์ ๋ณตํธํ ํ๋ค๋ฉด ";
bitCnt=0;
now=0;
for(int i=0;i<sizeVal;i++){
finalTextBool[i]=cTextBool[i]^keyStream[i];
now+=finalTextBool[i]*pow(2,7-bitCnt);
bitCnt++;
if(bitCnt==8){
bitCnt=0;
char pr = now;
cout << pr;
now=0;
}
}
cout << " ์
๋๋ค.\n";
}
void makeKeySteam(){
int cnt = 0;
int st =0;
for(int i=0;i<64;i++){
if(i==19 || i==41) cnt=0;
if(i<19) x[cnt]=key[i];
else if(i<41) y[cnt]=key[i];
else z[cnt] = key[i];
cnt++;
}
cnt=sizeVal;
while(cnt--) {
int maj = chkMaj(x[8], y[10], z[10]);
if (x[8] == maj) excuteX();
if (y[10] == maj) excuteY();
if (z[10] == maj) excuteZ();
keyStream[st] = x[18]^y[21]^z[22];
st++;
}
}
bool chkMaj(bool x, bool y, bool z){
int arr[2] = {0,0};
arr[x]++;
arr[y]++;
arr[z]++;
if(arr[1]>arr[0]) return true;
return false;
}
void excuteX(){
bool tempZero = x[13] ^ x[16] ^ x[17] ^ x[18];
for(int i=19;i>0;i--){
x[i]=x[i-1];
}
x[0]=tempZero;
}
void excuteY(){
bool tempZero = y[20]^y[21];
for(int i=21;i>0;i--){
y[i] = y[i-1];
}
y[0] = tempZero;
}
void excuteZ(){
bool tempZero = z[7]^z[20]^z[21]^z[22];
for(int i=22;i>0;i--){
z[i]=z[i-1];
}
z[0]=tempZero;
}