📄 des3r.cpp
字号:
/* DES3r.cpp *//* Implementacija DES kriptosustava *//* 2004. godina *//* Autor: Darko Poljak *//* Modifikacija 2005. : reduciran DES na 3 runde */#include "DES3r.h"bit LHS;bit k1_22;bit k3_22;void DES3r::rotateLeft(bit *a,size_t size,size_t r) { bit temp; for(int i=0;i<r;++i) { temp=a[0]; for(int j=0;j<size-1;++j) { a[j]=a[j+1]; } a[size-1]=temp; }}void DES3r::computeKiPerm(bit input[64],bit output[56]) { for(int i=0;i<56;++i) { output[i]=input[DES_KiPerm[i]-1]; }}void DES3r::splitBlock(bit input[],size_t insize,bit left[],bit right[]) { int n=insize/2; for(int i=0;i<n;++i) { left[i]=input[i]; right[i]=input[i+n]; }}void DES3r::concatBlock(bit left[],bit right[],size_t halfsize,bit output[]) { for(int j=0;j<halfsize;++j) { output[j]=left[j]; output[j+halfsize]=right[j]; }}void DES3r::computeKi(bit input[56],bit output[48]) { for(int j=0;j<48;++j) { output[j]=input[DES_Ki[j]-1]; }}void DES3r::keySchedule() { bit _keyplus[56]; bit Ci[17][28]; bit Di[17][28]; bit CiDi[16][56];
int i; computeKiPerm(_key,_keyplus); splitBlock(_keyplus,56,Ci[0],Di[0]); for(i=1;i<=3;++i) { /* reducirano na 3 runde */ for(int j=0;j<28;++j) { Ci[i][j]=Ci[i-1][j]; Di[i][j]=Di[i-1][j]; } rotateLeft(Ci[i],28,DES_rot[i-1]); rotateLeft(Di[i],28,DES_rot[i-1]); concatBlock(Ci[i],Di[i],28,CiDi[i-1]); } for(i=0;i<3;++i) { /* reducirano na 3 runde */ computeKi(CiDi[i],_subkey[i]); }}void DES3r::computeGroup(bit *dest,bit *src,uint16 table) { uint row=src[0]*2+src[5]; uint col=src[1]*2*2*2+src[2]*2*2+ src[3]*2+src[4]; uint n=DES_s[table][row*16+col]; // n u binarni bit u dest for(int i=3;i>=0;--i) { dest[i]=n%2; n>>=1; // n/=2; }}void DES3r::computeIP(bit input[64],bit output[64]) { for(int i=0;i<64;++i) { output[i]=input[DES_IP[i]-1]; }}void DES3r::computeF(bit input[32],bit key[48],bit output[32]) { bit G[32]; bit S[48]; computeEBSel(input,S); for(int j=0;j<48;++j) { S[j]^=key[j]; } for(int groupi=0;groupi<8;++groupi) { computeGroup(&G[groupi*4],&S[groupi*6],groupi); } computeP(G,output);}void DES3r::computeEBSel(bit input[32],bit output[48]) { for(int j=0;j<48;++j) { output[j]=input[DES_EBSel[j]-1]; }}void DES3r::computeP(bit input[32],bit output[32]) { for(int i=0;i<32;++i) { output[i]=input[DES_P[i]-1]; }}void DES3r::computeIPInv(bit input[64],bit output[64]) { for(int i=0;i<64;++i) { output[i]=input[DES_IPInv[i]-1]; }}string DES3r::encrypt(const string& block,const string& key) { string cipher; bit IP[64]; bit _plain[64]; bit _cipher[64]; bit L[32]; bit R[32]; bit temp[32]; bit F[32]; bit RL[64];
int i,j; if(block.length()!=8) { throw string("Invalid block size!"); } if(key.length()!=8) { throw string("Invalid key size!"); } // otvoreni blok u polje bitova for(i=0;i<8;++i) { uint ch=(unsigned char)block[i]; for(j=0;j<8;++j) { _plain[(i*8+7)-j]=ch%2; ch>>=1; // ch/=2; } } // kljuc u polje bitova for(i=0;i<8;++i) { uint ch=(unsigned char)key[i]; for(j=0;j<8;++j) { _key[(i*8+7)-j]=ch%2; ch>>=1; } } keySchedule(); k1_22=_subkey[0][47-22]; k3_22=_subkey[2][47-22]; computeIP(_plain,IP); /* dio linearne aproksimacije */ LHS=IP[63-15]^IP[31-7]^IP[31-18]^IP[31-24]^IP[31-29]; splitBlock(IP,64,L,R); for(int round=0;round<3;++round) { /* reducirano na 3 runde */ for(j=0;j<32;++j) { temp[j]=L[j]; L[j]=R[j]; } computeF(R,_subkey[round],F); for(j=0;j<32;++j) { R[j]=temp[j] ^ F[j]; } } concatBlock(R,L,32,RL); /* dio linearne aproksimacije */ LHS = LHS^RL[63-15]^RL[31-7]^RL[31-18]^RL[31-24]^RL[31-29]; computeIPInv(RL,_cipher); // polje bitova kriptiranog teksta u string for(i=0;i<8;++i) { int ch=0; for(j=0;j<8;++j) { ch=ch*2+_cipher[i*8+j]; } cipher+=(unsigned char)ch; } return cipher;}bool DES3r::isBadKey(const string& key) { string hexKey=CryptoSystem::toHexString(key); for(int i=0;i<16;++i) { string cmp(BAD_KEYS[i]); if(hexKey==cmp) { return true; } } return false;}string DES3r::decrypt(const string& block,const string& key) { string plain; bit IP[64]; bit _plain[64]; bit _cipher[64]; bit L[32]; bit R[32]; bit temp[32]; bit F[32]; bit RL[64];
int i,j; if(block.length()!=8) { throw string("Invalid block size!"); } if(key.length()!=8) { throw string("Invalid key size!"); } // kriptirani tekst u polje bitova for(i=0;i<8;++i) { uint ch=(unsigned char)block[i]; for(j=0;j<8;++j) { _cipher[(i*8+7)-j]=ch%2; ch>>=1; } } // kljuc u polje bitova for(i=0;i<8;++i) { uint ch=(unsigned char)key[i]; for(j=0;j<8;++j) { _key[(i*8+7)-j]=ch%2; ch>>=1; } } keySchedule(); computeIP(_cipher,IP); splitBlock(IP,64,L,R); for(int round=2;round>=0;--round) { /* reducirano na 3 runde */ for(j=0;j<32;++j) { temp[j]=L[j]; L[j]=R[j]; } computeF(R,_subkey[round],F); for(j=0;j<32;++j) { R[j]=temp[j] ^ F[j]; } } concatBlock(R,L,32,RL); computeIPInv(RL,_plain); // polje bitova otvorenog teksta u string for(i=0;i<8;++i) { int ch=0; for(j=0;j<8;++j) { ch=ch*2+_plain[i*8+j]; } plain+=(unsigned char)ch; } return plain;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -