www.pudn.com > calc.rar > rsa.c


/* program: rsa.c */ 
 
#include  
#include  
#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); 
}