发信人: ytam()
整理人: girlrong(1999-11-13 15:03:31), 站内信件
|
【 在 tsingxiao (脑袋) 的大作中提到: 】
: 关于质数的选取........
:
: 上一篇提到为了使因数分解发生困难, 所选择的质数要愈大愈好,
: 但这也意味著, 质数的选取也同样的困难......
: .......
the following is a RSA encryption program.
/*
(1) This program can effectively produce big prime reaching 90 decima l digits.
(2) Completely implement RSA algorithm
(3) Parameters: ( Set according to your requirements )
MLENGTH :LENGTH OF PRIME p,q
SKLENGTH :length of secret key
TEXTLENGTH :length of plain text and ciper text
by YTAM (i4q4ever&1收皮!)
no right reserved
(Feb 3rd,1999)
*/
#include <mem.h>
#include <dos.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#define DATALENGTH 350 /* length of the very long data */
#define MLENGTH 4 /* change this parameter */
#define TESTNUM 20
#define SKLENGTH 4
#define TEXTLENGTH 20
typedef signed char byteint[DATALENGTH];
typedef signed char mtype[MLENGTH];
mtype Model[TESTNUM];
byteint plaintext[20];
byteint cipertext[20];
byteint ONEVALUE,ZEROVALUE,TWOVALUE,EIGHTVALUE;
/* 0 contant and 1 constant */
void InitInt(void); /* initialize basic data */
void SetZero(byteint A); /* A=0 */
void IntCpy(byteint A,byteint B); /* A=B */
int IntValid(byteint validtemp); /* return the number of non zero d igits */
int PrtInt(byteint A); /* output a very large num */
int IntCmp(byteint A,byteint B); /* compare two integer */
void Plus(byteint A,byteint B,byteint C); /* C=A+B */
void Substract(byteint SA,byteint SB,byteint SC); /* SC=SA-SB */
void Multiply(byteint A,byteint B,byteint C); /* C=A*B */
void SetMode(byteint A,byteint B,byteint C,byteint D); /* C=A%B,D=A/B */
void IntRandom(byteint RondomA,int num); /* generating a big random */
int Prime(byteint Pm); /* generating a prime to Pm */
void LoadInt(byteint A,mtype B);
int ComputingPK(byteint Rvalue,byteint SK,byteint PK);
int GetPlaintext(void);
void PackInt(byteint A,int B);
/*byteint PRIME1={7,7,1,5,3,7,7,2,5,1,1,9,9,4,8,0,2,7,9,9,2,1,6,4,2,4, 9,2,3,9};
byteint PRIME2={1,0,4,2,2,4,5,8,5,2,2,1,4,0,8,2,9,6,8,9,1,3,0,9,4,4, 6,0,2,1}; /* 30 bits */
byteint PRIME3={7,2,1,7,3,3,3,6,8,3,4,7,9,3,4,2,0,6,3,6,3,8,7,1,4,7, 9,0,3,9,2,9,6,6,5,3,4,9,8,7,2,0,6,0,8,9,0,1,3,3,0,1,3,6,2,2,2,3,7,0,5, 0,9,1,1,3,7,5,1,9,9,8,2,5,9,7,3,2,6,7,0,7,6,3,2,7,1,3,1,1};
byteint PRIME4={3,3,9,0,1,5,3,8,4,7,4,2,1,3,1,3,0,4,7,9,7,7,5,4,8,8, 9,6,5,2,3,0,8,7,8,7,6,3,3,5,9,1,3,3,6,6,0,1,9,7,1,4,6,8,2,7,5,5,8,0,3, 2,3,8,4,9,7,2,3,0,3,9,6,4,3,6,3,5,2,7,8,8,9,8,7,9,5,7,5,9}; /* 90 bits */
byteint PRIME5={9,8,0,0,5,2,5,8,1,9,8,1,3,8,5,9,1,1,1,0,7,5,8,0,8,7, 0,9,0,9,8,6,7,6,0,5,5,2,4,0,8,9,0,3,6,2,5,0,6,6,6,6,2,4,6,3,6,5,6,3,0, 2,9,0,5,9,7,0,2,5};
byteint PRIME6={7,5,6,4,4,1,9,2,9,9,7,4,7,9,8,7,8,2,8,3,0,4,5,5,1,9, 9,2,3,8,7,2,1,1,6,0,0,4,0,3,0,9,0,3,0,6,1,4,7,6,0,1,3,4,9,4,3,5,3,8,0, 9,4,7,6,9,0,0,3,8};*/
void Mdata(void)
{
register i,j;
int k=MLENGTH-2;
memset(Model,0,TESTNUM*MLENGTH);
for(i=0;i<TESTNUM;i++)
{
for(j=MLENGTH-1;j>=k;j--)
Model[i][j]=rand()%10;
k-=1;
}
}
void TransBi(byteint B,signed char flag[400])
{
byteint buf,result,temp;
register i,j;
memset(flag,0,400);
i=399;
IntCpy(buf,B);
while(IntCmp(buf,ZEROVALUE)==1)
{
SetMode(buf,TWOVALUE,temp,result);
flag[i]=temp[DATALENGTH-1];
IntCpy(buf,result);
i--;
}
flag[i]=-1;
}
int PowerMode(byteint A,byteint C,byteint D,signed char flag[400])
{
/* compute A^B mod C */
byteint buf,result,temp,P;
register i,j;
IntCpy(temp,A);
if (flag[399]==1)
IntCpy(result,A);
else
IntCpy(result,ONEVALUE);
i=398;
while(flag[i]!=-1)
{
Multiply(temp,temp,buf);
SetMode(buf,C,temp,P);
if (flag[i]!=0)
{
Multiply(temp,result,buf);
SetMode(buf,C,result,P);
}
i--;
}
IntCpy(buf,C);
IntCpy(D,result);
Substract(buf,ONEVALUE,temp);
if (IntCmp(result,ONEVALUE)==0) /* p mod n=1 */
return 1;
if (IntCmp(result,temp)==0) /* p mod n=-1 */
return 2;
return 0;
}
int Prime(byteint Pm)
{
int i,j,k,ok,cnt=0;
signed char flag[400];
byteint A,B,D,buf1,buf2,result;
int pass,pass_2;
while(1)
{
pass=0;pass_2=0;
cnt++;
IntRandom(B,MLENGTH); /* try b if prime */
printf("\n %3d try:",cnt);
PrtInt(B);
IntCpy(Pm,B);
Substract(B,ONEVALUE,buf1);
SetMode(buf1,TWOVALUE,buf2,B);
TransBi(B,flag);
ok=1;
for(i=0;i<TESTNUM;i++)
{
LoadInt(A,Model[i]);
k=PowerMode(A,Pm,D,flag);
if (k!=1&&k!=2)
break;
if (k==1)
printf("\n pass the %dth test---1",pass++);
if (k==2)
{
pass_2=1;
printf("\n pass the %dth test---2",pass++);
}
}
if (ok&&pass_2) /* at least there is one p-1 */
{
printf("\n\n prime found:");
PrtInt(Pm);
return 0;
}
printf(" failure!");
}
}
void InitInt(void)
{
SetZero(ONEVALUE);
ONEVALUE[DATALENGTH-1]=1;
SetZero(ZEROVALUE);
SetZero(TWOVALUE);SetZero(EIGHTVALUE);
TWOVALUE[DATALENGTH-1]=2;
EIGHTVALUE[DATALENGTH-1]=8;
randomize();
}
int GetIp(int num)
{
return (num/10);
}
int PrtInt(byteint A)
{
register i=0;
int n,m;
while(i<DATALENGTH&&A[i]==0) i++;
if (i<DATALENGTH) m=DATALENGTH-i;
n=0;
while(i<DATALENGTH)
{
printf("%1d",A[i++]);
n++;
if (n>65)
{
n=0;
printf("\n");
}
}
return m;
}
void Multiply(byteint A,byteint B,byteint C)
{
register i,j,w;
int X,Y,Z;
int Avalid=0,Bvalid=0; /* Avalue=validating bits of A */
while(A[Avalid]==0&&Avalid<DATALENGTH)
Avalid++;
while(B[Bvalid]==0&&Bvalid<DATALENGTH)
Bvalid++;
SetZero(C);
for(i=DATALENGTH-1;i>=Avalid;i--)
for(j=DATALENGTH-1;j>=Bvalid;j--)
{
X=A[i]*B[j];
Y=GetIp(X);
Z=X-10*Y;
w=i+j-(DATALENGTH-1);
C[w]=C[w]+Z;
C[w-1]=C[w-1]+GetIp(C[w])+Y;
C[w]=C[w]-GetIp(C[w])*10;
}
}
void SetZero(byteint A)
{
register i;
for(i=0;i<DATALENGTH;i++)
A[i]=0;
}
void IntCpy(byteint A,byteint B)
{
register i;
SetZero(A);
for(i=0;i<DATALENGTH;i++)
A[i]=B[i];
}
void Plus(byteint A,byteint B,byteint C)
{
register i,w;
int X,Y,Z,m,n,valid;
m=IntValid(A);
n=IntValid(B);
valid=(m>n)?m+1:n+1;
SetZero(C);
for(i=DATALENGTH-1;i>=DATALENGTH-valid;i--)
{
X=A[i]+B[i];
Y=GetIp(X);
Z=X-10*Y;
C[i]=C[i]+Z;
C[i-1]=C[i-1]+Y;
}
}
void Substract(byteint SA,byteint SB,byteint SC)
{
byteint buf;
register i,j,w;
int X,Y,Z;
IntCpy(buf,SA);
SetZero(SC);
for(i=DATALENGTH-1;i>=0;i--)
{
if (buf[i]<SB[i])
{
buf[i]=buf[i]+10;
if (buf[i-1]>0)
(buf[i-1])--;
else
{
j=i-1;
while(buf[j]==0)
buf[j--]=9;
buf[j]=buf[j]-1;
}
}
X=buf[i]-SB[i];
SC[i]=X;
}
}
int IntCmp(byteint A,byteint B)
{
register i;
i=0;
while((A[i]==B[i])&&(i<DATALENGTH)) i++;
if (i>=DATALENGTH) return 0;
else if (A[i]>B[i]) return 1;
else return -1;
}
int IntValid(byteint validtemp)
{
register i=0;
while(validtemp[i]==0&&i<DATALENGTH)
i++;
return DATALENGTH-i;
}
void SetMode(byteint A,byteint B,byteint C,byteint D)
{
register i,j,k;
int valid_1,valid_2,valid,sbits,cmpval;
byteint buf1,buf2;
SetZero(D);
IntCpy(C,A);
valid_2=IntValid(B);
while((cmpval=IntCmp(C,B))>0)
{
valid_1=IntValid(C);
valid=valid_1-valid_2;
if (valid>0)
{
i=DATALENGTH-valid_1;
j=DATALENGTH-valid_2;
sbits=0;
for(k=j;k<DATALENGTH;k++)
{
if (C[i]>B[j]) break;
if (C[i]<B[j]) {sbits=1;break;}
i++;j++;
}
valid=valid-sbits;
SetZero(buf1);
for(i=valid;i<DATALENGTH;i++)
{
j=i-valid;
buf1[j]=B[i];
}
}
else IntCpy(buf1,B);
D[DATALENGTH-1-valid]++;
Substract(C,buf1,buf2);
IntCpy(C,buf2);
}
if (cmpval==0)
{
SetZero(C);
D[DATALENGTH-1]++;
} /* reminder = 0 */
}
void IntRandom(byteint RandomA,int num)
{
int i,x;
SetZero(RandomA);
while(!(RandomA[DATALENGTH-1]%2))
RandomA[DATALENGTH-1]=rand()%10;
while(!RandomA[DATALENGTH-num])
RandomA[DATALENGTH-num]=rand()%10;
i=DATALENGTH-2;
while(i>=DATALENGTH-num+1)
RandomA[i--]=rand()%10;
/* for(i=DATALENGTH-1;i>=DATALENGTH-num;i--)
RandomA[i]=PRIME6[DATALENGTH-1-i];*/
}
void LoadInt(byteint A,mtype B)
{
register i,j;
SetZero(A);
i=DATALENGTH-1;
j=MLENGTH-1;
while(j>=0)
A[i--]=B[j--];
}
main(void)
{
byteint p,q,R,PK,SK,Rvalue,desti,buf1,buf2;
signed char flag[400];
int num,i,k;
Mdata();
InitInt();
printf("\n RSA Encryptosystem Procedure\n");
printf("\n 1.Randomly select two prime numbers.\n");
Prime(p);Prime(q);
Multiply(p,q,R);
Substract(p,ONEVALUE,buf1);
Substract(q,ONEVALUE,buf2);
Multiply(buf1,buf2,Rvalue);
ComputingPK(Rvalue,SK,PK);
printf(" Paramenters:\n");
printf(" p= ");PrtInt(p);
printf("\n q= ");PrtInt(q);
printf("\n R= ");PrtInt(R);
printf("\n S(R)= ");PrtInt(Rvalue);
printf("\n SK= ");PrtInt(SK);
printf("\n PK= ");PrtInt(PK);
printf("\n 2.Please input plain text (format 1243,0812):");
printf(" (All data must be less than ");PrtInt(R);
k=GetPlaintext();
printf("\n\n 3.Your plain text as following:\n");
for(i=0;i<k;i++)
{
printf(" ");PrtInt(plaintext[i]);
}
printf("\n\n 4. Ciper text as following:\n");
TransBi(PK,flag);
for(i=0;i<k;i++)
{
PowerMode(plaintext[i],R,desti,flag);
PrtInt(desti);
IntCpy(cipertext[i],desti);
printf(" ");
}
printf("\n\n 5.restored plaintext as following:\n");
printf(" ");
TransBi(SK,flag);
for(i=0;i<k;i++)
{
PowerMode(cipertext[i],R,desti,flag);
PrtInt(desti);
printf(" ");
}
return 0;
}
int ComputingPK(byteint Rvalue,byteint SK,byteint PK)
{
register i,j;
byteint PA,PB,PC,buf,temp,buf2;
SetZero(PK);
while(1)
{
IntRandom(SK,SKLENGTH);
printf(" Try SK: ");
PrtInt(SK);
IntCpy(PB,SK);IntCpy(PA,Rvalue);
while(1)
{
SetMode(PA,PB,PC,PK);
i=IntCmp(PC,ONEVALUE);
if (i==0) break;
i=IntCmp(PC,ZEROVALUE);
if (i==0)
{
i=-1;break;
}
IntCpy(PA,PB);IntCpy(PB,PC);
}
if (i==0) break;
}
IntCpy(temp,ONEVALUE);IntCpy(PA,Rvalue);IntCpy(PB,PK);
while(1)
{
Multiply(PA,temp,buf);
Plus(buf,ONEVALUE,buf);
SetMode(buf2,PB,buf,PK);
if (IntCmp(buf,ZEROVALUE)==0) break;
Plus(temp,ONEVALUE,buf);
IntCpy(temp,buf);
}
return 1;
}
void PackInt(byteint A,int B)
{
register i=DATALENGTH-1;
SetZero(A);
while(B>0)
{
A[i--]=B%10;
B=B/10;
}
}
int GetPlaintext(void)
{
int i,k,num;
char str[80],*p;
k=0;
printf("\n");
gets(str);
p=str;
while(*p!=NULL)
{
while(*p<'0'||*p>'9') p++;
i=DATALENGTH-1;
while(*p>='0'&&*p<='9')
{
plaintext[k][i]=*p-'0';
i--;
p++;
}
k++;
}
return k;
}
-- ※ 来源:.月光软件站 http://www.moon-soft.com.[FROM: 202.103.137.160]
|
|