KGC_TEST/miracl/source/crdecode.cpp

141 lines
3.0 KiB
C++

/*
* Cramer-Shoup public Key system - Hybrid Implementation
*
* This program decrypts the contents of the file xxx.crs to the screen
* usng the AES key recovered from xxx.key using the Cramer-Shoup
* private key from private.crs
*
* Requires: big.cpp
*/
#include <iostream>
#include <fstream>
#include "big.h"
#include <cstring>
using namespace std;
Miracl precision(300,256);
void strip(char *name)
{ /* strip extension off filename */
int i;
for (i=0;name[i]!='\0';i++)
{
if (name[i]!='.') continue;
name[i]='\0';
break;
}
}
void hash(sha *s,Big x)
{ /* hash in a big number */
int ch;
while (x!=0)
{
ch=x%256; x/=256;
shs_process(s,ch);
}
}
int main()
{
int i,bits;
static char ifname[100];
ifstream common("common.crs"); // construct file I/O streams
ifstream private_key("private.crs");
ifstream key_file,ciphertext,ct;
Big p,q,g1,g2,x1,x2,y1,y2,z,u1,u2,e,v,m,e1,e2,alpha;
char ch,H[20],iv[16],block[16];
miracl *mip=&precision;
sha sh;
aes a;
// get common data
mip->IOBASE=16;
common >> bits;
common >> q >> p >> g1 >> g2;
// get private key
private_key >> x1 >> x2 >> y1 >> y2 >> z;
// figure out where input is coming from
cout << "file to be decoded = ";
cin >> ifname;
strip(ifname); // open key file
strcat(ifname,".key");
key_file.open(ifname,ios::in);
if (!key_file)
{
cout << "Key file " << ifname << " not found\n";
return 0;
}
strip(ifname); // open ciphertext
strcat(ifname,".crs");
ciphertext.open(ifname,ios::binary|ios::in);
if (!ciphertext)
{
cout << "Unable to open file " << ifname << "\n";
return 0;
}
mip->IOBASE=16;
key_file >> u1 >> u2 >> v;
shs_init(&sh);
hash(&sh,u1);
hash(&sh,u2);
// first pass - scan in ciphertext, and calculate alpha=H(u1,u2,ciphertext)
cout << "Checking ciphertext validity\n" ;
forever
{
ciphertext.get(ch);
if (ciphertext.eof()) break;
shs_process(&sh,ch);
}
ciphertext.close();
shs_hash(&sh,H);
mip->INPLEN=20;
mip->IOBASE=256;
alpha=(char *)H; // alpha=H(u1,u2,ciphertext);
e1=(x1+y1*alpha)%q;
e2=(x2+y2*alpha)%q;
// check validity of ciphertext
if (v!=pow(u1,e1,u2,e2,p))
{
cout << "*** Cipher text is rejected ***" << endl;
return 0;
}
shs_init(&sh);
hash(&sh,pow(u1,z,p));
shs_hash(&sh,H); // H=hash(u1^z mod p) = AES Key
for (i=0;i<16;i++) iv[i]=i; // Set CFB IV
aes_init(&a,MR_PCFB1,16,H,iv); // Set 128 bit AES Key
// decrypt file on second pass
ct.open(ifname,ios::binary|ios::in);
cout << "decoding message\n";
forever
{ // decrypt input ..
ct.get(ch);
if (ct.eof()) break;
aes_decrypt(&a,&ch);
cout << ch;
}
aes_end(&a);
ct.close();
return 0;
}