📄 rsaprojectdlg.cpp
字号:
// If they both exist,the input file is read and converted into numbers.
// These numbers are divided into blocks smaller the modulus n that is given by
// the public key file. Each block is then encrypted independently following the
// RSA algorithm c = m^e mod n, with e the encryption exponent fixed to 3 here.
void CRSAProjectDlg::OnEncrypt()
{
Big t,m,y,n,nr,nl;
ifstream public_key;
ifstream input_file;
ofstream output_file;
static char line[500];
static char buff[256];
static char pbname[256],ifname[256],ofname[256];
/* Open the public key file */
UpdateData(TRUE);
strcpy(ifname,m_FILE_ENC);
strcpy(pbname,m_PBK_ENC);
UpdateData(FALSE);
if (strlen(ifname) < 0) {
AfxMessageBox("The input file name or is invalid.");
return;
}
if (strlen(pbname) < 0) {
AfxMessageBox("The public key file name or is invalid. Default file chosen.");
strcpy(pbname,"");
strcat(pbname,"defaultpublic.key");
}
public_key.open(pbname);
if (!public_key) {
AfxMessageBox("Unable to open public key file.");
return;
}
/* Retrieve the modulus n from the public key file */
BOOL last;
int i,inputpt,keylength;
miracl *mip=&precision;
mip->IOBASE=16;
public_key >> n;
/* We have to find the key length that will enable us to seperate the message in acceptable blocks */
/* This method to calculate this length was found in the documentation provided by Miracl */
nr=root(n,3);
nl=nr*nr*nr-nr*nr;
keylength=bits(nl)/7;
/* Create the name for the output file. All ciphertexts are rsa files.*/
strcpy(ofname,ifname);
remove(ofname);
strcat(ofname,".rsa");
input_file.open(ifname,ios::in|ios::nocreate);
if (!input_file) {
AfxMessageBox("Unable to open input file.");
return;
}
output_file.open(ofname);
inputpt=0;
last=FALSE;
/* We start the encryption by encoding the text line by line until the end of the file. */
while (!last) {
input_file.getline(&line[inputpt],132); // We retrieve a
if (input_file.eof() || input_file.fail()) last=TRUE; // We have reached the end of the file
strcat(line,"\n");
inputpt=strlen(line);
if (inputpt<keylength && !last) continue;
/* When we have read as much as the key length, we can start to encrypt. */
while (inputpt >= keylength) {
for (i = 0; i < keylength ; i++) {
buff[i]=line[i];
}
buff[keylength]='\0';
for (i = keylength; i <= inputpt ; i++) {
line[i-keylength]=line[i];
}
inputpt -= keylength;
mip->IOBASE=128;
m=buff;
/* Encrypt the block */
t=pow(m,3,n);
mip->IOBASE=16;
output_file << t << endl;
}
/* The last block is usually smaller than the key length. */
if (last && inputpt>0) {
mip->IOBASE=128;
m=line;
/* One technique we saw in the miracl documentation was too complete with random numbers */
if (m < nr) {
m+=nr*(nr*nr-rand(nr));
}
t=pow(m,3,n);
mip->IOBASE=16;
output_file << t << endl;
}
}
AfxMessageBox("Encryption successfully ended.");
return;
}
/* Function to allow the user to visualize the ciphertext to decrypt and the decrypted text */
void CRSAProjectDlg::OnOpenDC()
{
static char buff[256];
static char pbname[256],ifname[256],ofname[256];
if(m_DCT.GetCheck() == TRUE) {
UpdateData(TRUE);
strcpy(ifname,m_FILE_DEC);
UpdateData(FALSE);
if (strlen(ifname)< 0) {
AfxMessageBox("The plaintext file name is is invalid.");
return;
}
strcat(buff, "Notepad.exe \"");
strcat(ifname,"\"");
strcat(buff,ifname);
WinExec(buff, SW_SHOWNORMAL);
strcpy(ifname,"");
strcpy(buff,"");
}
if( m_DT.GetCheck() == TRUE ) {
UpdateData(TRUE);
strcpy(ifname,m_FILE_DEC);
UpdateData(FALSE);
strcpy(ofname,ifname);
remove(ofname);
strcat(ofname,".out");
if (strlen(ofname)< 0) {
AfxMessageBox("The ciphertext file name is invalid.");
return;
}
strcat(buff, "Notepad.exe \"");
strcat(ofname,"\"");
strcat(buff,ofname);
WinExec(buff, SW_SHOWNORMAL);
strcpy(ifname,"");
strcpy(ofname,"");
strcpy(buff,"");
}
return;
}
/* Function to allow the user to visualize the plaintext and the ciphertext after encryption */
void CRSAProjectDlg::OnOpenEC()
{
static char buff[256];
static char pbname[256],ifname[256],ofname[256];
if( m_PT.GetCheck() == TRUE ) {
UpdateData(TRUE);
strcpy(ifname,m_FILE_ENC);
UpdateData(FALSE);
if (strlen(ifname)< 0) {
AfxMessageBox("The plaintext file name is is invalid.");
return;
}
strcat(buff, "Notepad.exe \"");
strcat(ifname,"\"");
strcat(buff,ifname);
WinExec(buff, SW_SHOWNORMAL);
strcpy(ifname,"");
strcpy(buff,"");
}
if( m_CT.GetCheck() == TRUE ) {
UpdateData(TRUE);
strcpy(ifname,m_FILE_ENC);
UpdateData(FALSE);
strcpy(ofname,ifname);
remove(ofname);
strcat(ofname,".rsa");
if (strlen(ofname)< 0) {
AfxMessageBox("The ciphertext file name is invalid.");
return;
}
strcat(buff, "Notepad.exe \"");
strcat(ofname,"\"");
strcat(buff,ofname);
WinExec(buff, SW_SHOWNORMAL);
strcpy(ifname,"");
strcpy(ofname,"");
strcpy(buff,"");
}
return;
}
/**** Decryption function ****/
// This function first retrieves the name of the input file to decrypt and the private files.
void CRSAProjectDlg::OnDecrypt()
{
/* Use the private keys to decrypt */
int i;
Big t,ep[NP],c,n,p[NP],d[NP],nr,nl;
ifstream private_key;
ifstream input_file;
ofstream output_file;
char prname[256],ifname[256],ofname[256];
/* Open the public key file */
UpdateData(TRUE);
strcpy(ifname,m_FILE_DEC);
strcpy(prname,m_PRK_DEC);
UpdateData(FALSE);
if (strlen(prname)<0 || strlen(ifname)< 0) {
AfxMessageBox("The input/private key file name or is invalid.");
return;
}
private_key.open(prname);
if (!private_key) {
AfxMessageBox("Unable to open private key file.");
return;
}
BOOL fout; // Boolean that helps determine whether an output name is correct or not
miracl *mip=&precision;
mip->IOBASE=16;
/* We store the private keys (prime numbers) in an array of Bigs of size 2. */
for (i=0;i<NP;i++) {
private_key >> p[i];
}
/* We calculate the modulus n = p*q */
n=1;
for (i=0;i<NP;i++) {
n*=p[i];
}
/* We know have to calculate d the decryption exponent. We know that de = 1 mod (p-1)(q-1) */
/* THanks to the Chinese Remainder Theorem, we know that d = 1/e mod (p-1) and d = 1/e mod (q-1) */
/* So the following method translates this idea with e = 3. This code was given in Miracl library*/
for (i = 0; i < NP; i++) {
d[i]=(2*(p[i]-1)+1)/3;
}
/* Like in the encryption part. We have to determine the key length to be able to divide the text */
/* into blocks that we can decrypt one by one. */
nr=root(n,3);
nl=nr*nr*nr-nr*nr;
/* We create the name of the output file that is the decrypted text. All the decrypted files are .out files.*/
strcpy(ofname,ifname);
remove(ifname);
strcat(ifname,".rsa");
remove(ofname);
strcat(ofname,".out");
fout=FALSE;
if (strlen(ofname)>0) {
fout=TRUE;
output_file.open(ofname);
}
input_file.open(ifname,ios::in|ios::nocreate);
if (!input_file) {
AfxMessageBox("Decryption: Unable to open input file.");
return;
}
Crt chinese(NP,p); /* We use chinese remainder thereom */
/* We enter an infinite loop that will only stop when we reach the end of the text c = 0 */
forever {
mip->IOBASE=16;
input_file >> c; // We retrieve a Big number from the file to decrypt
if (c==0) break; // The end of the file has been reached. We then stop.
for (i=0;i<NP;i++) {
ep[i]=pow(c,d[i],p[i]); // m1 = c^d (mod p) and m2 = c^d (mod q)
}
t = chinese.eval(ep); // We evaluate t the decrypted text with the Chinese Remainder Theorem.
// A congruence mod a composite number n can be broken into simultaneous congruences mod each prme power factor of n.
// Then we can recombine the resulting information.
if (t >= nl) t%=nr;
mip->IOBASE=128;
if (fout) output_file << t;
}
AfxMessageBox("Decryption successfully completed.");
return;
}
/* Function that calls another application that generates key files suitable for e = 3 */
/* The basic source code was provided by Miracl */
void CRSAProjectDlg::OnGenerate()
{
WinExec("PrimeGen.exe",SW_SHOWNORMAL);
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -