📄 rsa.c
字号:
/* program: rsa.c */
#include <stdio.h>
#include <string.h>
#include "integer.h"
#include "fun.h"
void doit(FILE *f, char *valstr, MPI *Eptr, MPI *Rptr)
/*
* The string consisting of up to 4 juxtaposed ascii numbers is sent
* to file f.
*/
{
char *s;
MPI *Temp, *Mptr;
unsigned int n;
printf("juxtaposition of 4 ascii numbers :%s\n",valstr);
s = valstr;
Mptr = ZEROI();
while (*s != '\0')
{
Temp = Mptr;
Mptr = MULT_I(Temp, 10);
FREEMPI(Temp);
n = (unsigned int)(*s - '0');
Temp = Mptr;
Mptr = ADD0_I(Temp, n);
FREEMPI(Temp);
s++;
}
Temp = MPOWER(Mptr, Eptr, Rptr);
printf("encoded number : ");PRINTI(Temp);printf("\n");
FPRINTI(f, Temp);
fprintf(f, "\n");
FREEMPI(Temp);
FREEMPI(Mptr);
}
void undoit(FILE *f, char *unencstr, MPI *Dptr, MPI *Rptr)
/*
* The numbers in file "encoded.out" are inputted as strings.
* Each string is decomposed into up to 4 ascii numbers.
* The corresponding characters are concatenated to reconstruct the
* original message.
*/
{
char *s,*s1;
MPI *Temp, *Mptr;
unsigned int u;
char tmpstr[100], valstr[500];
int newval;
while (1)
{
Mptr = FINPUTI(f, &u);
if (Mptr->S == -1 && Mptr->V[0] == 1)
{
FREEMPI(Mptr);
break;
}
if (Mptr->S == -1 && Mptr->V[0] == 2)
{
FREEMPI(Mptr);
strcat(unencstr,"\n");
continue;
}
printf("Encoded number = :" );PRINTI(Mptr);printf("\n");
Temp = MPOWER(Mptr, Dptr, Rptr);
FREEMPI(Mptr);
SPRINTI(valstr, Temp);
FREEMPI(Temp);
printf("decoded juxtaposition of 4 ascii numbers = %s\n",valstr);
newval=0;
s = valstr;
s1=tmpstr;
while(*s!='\0')
{
newval=newval*10+(*s)-'0';
if(newval>31)
{
printf("ascii number %d\n",newval);
*s1++ =newval;
newval=0;
}
s++;
}
if(newval)
{
printf("ascii number %d\n",newval);
*s1++ =newval;
}
*s1='\0';
strcat(unencstr,tmpstr);
}
return;
}
void ENCODE(MPI *Eptr, MPI *Rptr)
/*
* *Rptr is the encryption modulus, *Eptr is the enciphering key.
* The user is prompted to input a string of <= 500 characters (not control
* characters). Each character is converted to its ASCII equivalent.
* The resulting numbers lie in the range 32-126. They are concatenated in
* blocks of 4. Each block is then raised to the exponent *Eptr (mod *Rptr)
* and sent to the file "encoded.out", with one number per line.
* 355143^2 > 126126126126 > 355142^2. So *Rptr is assumed to be composed of
* two primes, each greater than 355142.
*/
{
char str[500], valstr[50], tmp[50], em[20];
char *cp;
int ctr, n;
FILE * outfile;
MPI *Temp, *Temp1;
int resp;
char junk[200];
char fname[100];
int ok;
FILE *ifile;
ifile = 0;
strcpy(em, "encoded.out");
n = 0;
do
{
printf("Please type 1 for keyboard input, 2 for file....");
scanf("%d",&resp);
(void)fgets(junk,200,stdin); /* read in the newline and any other junk */
}
while(resp!=1 && resp!=2);
if(resp==2)
{
do
{
printf("What is the name of the file to be encoded? ");
scanf("%s",fname);
(void)fgets(junk,200,stdin); /* read in the newline and any other junk */
if(!(ifile=fopen(fname,"r")))
ok=0;
else
ok=1;
if(!ok)
printf("Missing file %s! Please try again.\n",fname);
}
while(!ok);
}
outfile = fopen(em, "w");
while(1)
{
if(resp==1)
{
printf("Please type some text, followed by return. \n");
fgets(str,500,stdin);
}
else
{
if(!fgets(str,500,ifile))
break;
cp=str;
while(*cp && *cp!='\n')
cp++;
*cp=0;
}
cp=str;
ctr=0;
valstr[0]='\0';
while(*cp)
{
sprintf(tmp,"%d",*cp);
strcat(valstr,tmp);
ctr++;
if(ctr==4)
{
doit(outfile, valstr, Eptr, Rptr);
n++;
ctr=0;
valstr[0]='\0';
}
cp++;
}
if(ctr)
{
doit(outfile, valstr, Eptr, Rptr);
n++;
}
Temp = MINUS_ONEI();
Temp1 = ADDI(Temp,Temp);
FPRINTI(outfile, Temp1);
fprintf(outfile, "\n");
FREEMPI(Temp);
FREEMPI(Temp1);
if(resp==1)
break;
}
Temp = MINUS_ONEI();
FPRINTI(outfile, Temp);
fprintf(outfile, "\n");
FREEMPI(Temp);
fclose(outfile);
printf("counter = %u\n", n);
printf("encoded message sent to file 'encoded.out'\n");
return;
}
void DECODE(MPI *Dptr, MPI *Rptr)
/*
* Inputs each number from the file "encoded.out", raises it to the
* deciphering modulus *Dptr (mod *Rptr) and splits up the resulting
* number into 4 ASCII numbers. The decrypted message is printed on the
* screen, as well as being sent to a file called "decoded.out".
*/
{
FILE * outfile, *infile;
char unencstr[500], dm[20], em[20];
strcpy(em, "encoded.out");
infile = fopen(em, "r");
unencstr[0]=0;
printf("about to undoit\n");
undoit(infile, unencstr, Dptr, Rptr);
fclose(infile);
strcpy(dm, "decoded.out");
printf("Unencoded string (sent to file 'decoded.out'):\n%s\n",unencstr);
outfile = fopen(dm, "w");
fprintf(outfile, "%s",unencstr);
fclose(outfile);
return;
}
MPI *RSAEX(MPI *Pptr, MPI *Qptr)
/* Checks that p and q are primes > 355142, before calling RSAE below. */
{
MPI *X, *Y;
X = CHANGE(355142UL);
if(RSV(Pptr, X) <= 0 || RSV(Qptr, X) <= 0){
FREEMPI(X);
return(NULL);
}
FREEMPI(X);
X = LUCASX(Pptr);
Y = LUCASX(Qptr);
if(X == NULL || Y == NULL){
return(NULL);
}else{
return(RSAE(Pptr, Qptr));
}
}
MPI *RSAE(MPI *Pptr, MPI *Qptr)
/*
* The least integer e which is relatively prime to (p-1)*(q-1) and
* which satisfies 32^e >= 16*((pq)->D+1) is returned as an MPI*.
*/
{
MPI *Rptr, *Tmp1, *Tmp2, *Tmp3, *Eptr, *G;
USI e = 3;
Rptr = MULTI(Pptr, Qptr);
Tmp1 = SUB0_I(Pptr, 1);
Tmp2 = SUB0_I(Qptr, 1);
Tmp3 = MULTI(Tmp1, Tmp2);
FREEMPI(Tmp1);
FREEMPI(Tmp2);
while (1)
{
Eptr = CHANGE(e);
G = GCD(Eptr, Tmp3);
if (EQONEI(G) && (5 * e >= 16 * (1 + Rptr->D)))
{
FREEMPI(G);
break;
}
FREEMPI(G);
FREEMPI(Eptr);
e=e+2;
}
FREEMPI(Tmp3);
FREEMPI(Rptr);
return (Eptr);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -