📄 rsaview.cpp
字号:
i=398;
while(flag[i]!=-1) //判断是否已经到达指数尽头
{
Multiply(temp,temp,buf); //temp*temp->buf
SetMode(buf,C,temp,P); //buf%c余数->temp,商->p
if(flag[i]!=0) //如果该位不是0,则将其和前一步低一位的结果进行乘法运算
{ //否则,将其作为该位的模,在高一位的运算中,只要进行一次
Multiply(temp,result,buf); //平方运算,就可以得到高一位的模
SetMode(buf,C,result,P);
}
i--;
} //result中存放的是最终结果
IntCpy(buf,C);
IntCpy(D,result);
Substract(buf,ONEVALUE,temp);
if(IntCmp(result,ONEVALUE)==0) //p mod n=1,判断是否有A^B=1(mod C)
return 1;
if(IntCmp(result,temp)==0) //p mod n=-1[p-1=-1(mod p)],判断是否有A^B=p-1(mod C)
return 2;
return 0;
}
/*---------------------------------------------------------------------------
功能:计算公钥PK
入口参数:$(r)的值在Rvalue中,私钥SK,公钥PK
返回值:成功找到,返回1
----------------------------------------------------------------------------*/
int ComputingPK(byteint Rvalue,byteint SK,byteint PK)
{
register i;
byteint PA,PB,PC,buf1,temp,buf2;
SetZero(PK); SetZero(PA); SetZero(PB); SetZero(PC); SetZero(buf1); //清零初始化
SetZero(temp); SetZero(buf2);
while(1)
{
IntRandom(SK,SKLENGTH); //随机产生一个大数奇数作为Generated secret key
IntCpy(PB,SK);
IntCpy(PA,Rvalue);
while(1)
{
SetMode(PA,PB,PC,PK); //PA=PB*PK+PC
i=IntCmp(PC,ONEVALUE);
if(i==0) //PC=1, i=0
break; //满足条件,是互质的
i=IntCmp(PC,ZEROVALUE);
if(i==0)
{
i=-1; //PC=0,i=-1
break; //不满足互质条件,跳出循环,从新生成一个随机数
}
IntCpy(PA,PB); //按照欧几里的定理继续判断
IntCpy(PB,PC);
}
if(i==0) //满足,跳出查找循环
break;
}
IntCpy(temp,ONEVALUE);
IntCpy(PA,Rvalue);
IntCpy(PB,SK);
while(1)
{
Multiply(PA,temp,buf1); //buf1=PA*temp
Plus(buf1,ONEVALUE,buf2);//buf2=(PA*temp)+1
SetMode(buf2,PB,buf1,PK);//buf=((PA*temp)+1)%PB
if(IntCmp(buf1,ZEROVALUE)==0)
break;
Plus(temp,ONEVALUE,buf1);
IntCpy(temp,buf1);
}
return 1; //SK and PK found
}
/*---------------------------------------------------------------------------
功能:计算模R
入口参数:产生的质数p,q,模R
返回值:无
----------------------------------------------------------------------------*/
void ComputingR(byteint p,byteint q,byteint R)
{
Multiply(p,q,R); // R=p*q, public mode number
}
/*---------------------------------------------------------------------------
功能:计算欧拉函数值$(r)
入口参数:质数p,质数q,模$(r)放在Rvalue
返回值:无
----------------------------------------------------------------------------*/
void ComputingRvalue(byteint p,byteint q,byteint Rvalue)
{
byteint buf1,buf2;
SetZero(buf1); SetZero(buf2);
Substract(p,ONEVALUE,buf1); // buf1=p-1
Substract(q,ONEVALUE,buf2); // buf2=q-1
Multiply(buf1,buf2,Rvalue); // Rvalue=(p-1)*(q-1)
}
/*---------------------------------------------------------------------------
功能:将接受的字符串转换为大数类型
入口参数:大数result,字符串input
返回值:数的长度
----------------------------------------------------------------------------*/
int Getinput(byteint result,CString input)
{
int i=DATALENGTH,m=0;
long strlen;
strlen=input.GetLength();
if(strlen==0) return 0;
else
{
for(int j=0;j<strlen;j++)
{
result[i-strlen+j] = (input.GetAt(j)-'0');
}
return j;
}
}
/*---------------------------------------------------------------------------
功能:实现加密,解密运算功能
入口参数:明文(大数类型source),模R,秘钥key,结果desti
返回值:无
----------------------------------------------------------------------------*/
void RsaDo(byteint source,byteint R,byteint key,byteint desti)
{
TransBi(key,flag);
PowerMode(source,R,desti,flag);
}
/*---------------------------------------------------------------------------
功能:将长整形的数转换为大数类型
入口参数:大数类型result,长整形input
返回值:成功,返回数的长度,否则返回0;
----------------------------------------------------------------------------*/
int Getinput1(byteint result,unsigned long input)
{
int i=DATALENGTH-1,m=0;
long j=0;
int k=0;
if(input)
{
do
{
j=input/10;
k=input-j*10;
result[i]=k;
i--;
m++;
input=j;
}while(j);
return m;
}
else
return 0;
}
/*---------------------------------------------------------------------------
功能:将十六进制的串转换为数值
入口参数:字符串指针
返回值:成功,返回数
----------------------------------------------------------------------------*/
unsigned long Os2ip(unsigned char* pstr)
{
unsigned long ch=0;
unsigned int j=0;
unsigned long k=1;
for(int i=0;i<4;i++)
{
j = (unsigned int) (*(pstr+3-i));
ch += j*k;
k*=256;
}
return ch;
}
/*---------------------------------------------------------------------------
功能:将数串转换为相应的字符串
入口参数:字符串str
返回值:返回转换的结果;
----------------------------------------------------------------------------*/
CString Ip2os(CString str)
{
int strlen=str.GetLength(),quotient=0,remainder=0;
unsigned long num=0,temp=0;
unsigned int k=1;
CString strResult="";
for(int i=strlen;i>0;i--) //得到相应的数字串,存放在num中
{
temp = (str.GetAt(i-1) - '0');
num += temp*k;
k *= 10;
}
//采用模除的方式,求得相应的十六进制数
for(int j=0;j<4;j++)
{
quotient = num/256;
remainder = num - quotient*256;
strResult.Insert(0,(unsigned char)remainder);
num = quotient;
}
return strResult;
}
/*---------------------------------------------------------------------------
功能:实现加密功能接口
入口参数:明文字符串source,模字符串R,秘钥字符串key,结果字符串数组result
返回值:无
----------------------------------------------------------------------------*/
int RsaEncrypt(CString& source,const char* key,const char* R,CStringArray& result)
{
unsigned char* pstr;
int j;//sourcelen,j;
byteint m_key,m_R,desti,aa;
SetZero(desti); //将大数变量清零初始化
SetZero(aa);
//SetZero(bb);
SetZero(m_key);
SetZero(m_R);
pstr = (unsigned char*)(LPCTSTR)source; //得到字符串数据的指针
j = source.GetLength()/4; //得到数组的元素个数
result.SetSize(j,1);
Getinput(m_key,key); //将字符串转换为大数类型
Getinput(m_R,R);
for(int i=0;i<j;i++)
{
Getinput1(desti,Os2ip(pstr)); //将四个字节的输入转换为大数类型数值
RsaDo(desti,m_R,m_key,aa); //进行加密运算
result.SetAt(i,PrtInt(aa)); //将结果存放到数组中
SetZero(desti); SetZero(aa);
pstr += 4;
}
return j;
}
/*---------------------------------------------------------------------------
功能:实现解密功能接口
入口参数:密文字符串数组source,秘钥字符串sk,模字符串R,
返回值:结果字符串数组result
----------------------------------------------------------------------------*/
CString RsaDecrypt(CStringArray& source,const char* sk,const char* R)
{
int index=0;
CString result;
byteint m_sk,m_r,desti,aa;
SetZero(m_sk); SetZero(m_r); SetZero(desti); SetZero(aa); //SetZero(bb);
index=source.GetSize(); //得到数组的元素个数
Getinput(m_sk,sk); //将字符串转换为大数类型
Getinput(m_r,R);
for(int i=0;i<index;i++)
{
Getinput(desti,source.GetAt(i)); //将加密结果转换为大数类型
RsaDo(desti,m_r,m_sk,aa); //解密运算
result += Ip2os(PrtInt(aa)); //组合初始明文
SetZero(aa); SetZero(desti);
}
return result; //返回明文串
}
void LoadKeysFromFile(CString& r,CString& sk,CString& pk)
{
int j=10,len;
char *pbuffer;
unsigned char strlen1;
CFile file;
CFileException e;
CString strFileName;
if(file.Open("c:\\key.txt",CFile::modeRead)==0)
{
AfxMessageBox("File(key.txt)could not be opened" );
}
file.Read(&strlen1,1); //读出R长度
len = (int)strlen1;
pbuffer = new char[len+1];
pbuffer[len]='\0';
file.Read(pbuffer,len); //读出R
r=pbuffer;
delete pbuffer;
file.Read(&strlen1,1); //读出SK长度
len = (int)strlen1;
pbuffer = new char[len+1];
pbuffer[len]='\0';
file.Read(pbuffer,len); //读出SK
sk=pbuffer;
delete pbuffer;
file.Read(&strlen1,1); //读出PK长度
len = (int)strlen1;
pbuffer = new char[len+1];
pbuffer[len]='\0';
file.Read(pbuffer,len); //读出PK
pk=pbuffer;
delete pbuffer;
file.Close();
}
void CRSAView::OnButtonP()
{
// TODO: Add your control notification handler code here
int a[110]={2,3},ok,i,k=2,t;
bool f=true;
signed char flag[400];
byteint A,B,D,buf1,buf2;
SetZero(A); SetZero(B); SetZero(D); SetZero(buf1); SetZero(buf2);
UpdateData(TRUE);
t=atoi(m_sel_p.GetBuffer(m_sel_p.GetLength()));
Mdata(t);
while(1) //一直循环直到找到一个素数为止
{
int pass=0;
/*
//====计算梅森(Mersenne)伪素数========
for(i=0;i<110;i++)
{
Getinput1(A,2);
Getinput1(B,2);
for(j=0;j<a[i];j++)
{
Multiply(A,B,buf1);
IntCpy(B,buf1);
}
Getinput1(buf1,1);
// Substract(B,buf1,A);
B[DATALENGTH-1]=B[DATALENGTH-1]-1;
// IntCpy(B,A);
if(t<=IntValid(B))
break;
}
*/
srand( (unsigned)time( NULL ) ); //初始化srand
IntRandom(B,t); //随机产生一个大数B try b if prime,B是一个奇数
//====费尔马小定理素性检测============
IntCpy(P,B); //将B拷贝到prm中 C=N result prime
Substract(B,ONEVALUE,buf1); //将B-ONEVALUE的结果放到buf1中
SetMode(buf1,TWOVALUE,buf2,B); //B=(B-1)/2的商,buf2=(B-1)/2的余数=0
TransBi(B,flag); //将B转换为二进制大数
ok=1;
for(i=0;i<TESTNUM;i++)
{
LoadInt(A,Model[i]); //将数组Model中的第i+1个数读取到A中
k=PowerMode(A,P,D,flag); //(A^flag) mod Prm ->D
if(k!=1 && k!=2) //不符合判定规则
{
ok=0;
break;
}
if(k==1) //判定条件1,G=A^(n-1)/2=1
{
}
if(k==2) //判定条件2,G=A^(n-1)/2=p-1
{
}
}
if (ok)//if(ok && pass_2)
{
break;
}//for循环用来检测IntRandom(B,MLENGTH)产生的数B是否是一个素数
}
m_p=PrtInt(P);
UpdateData(FALSE);
}
void CRSAView::OnButtonQ()
{
// TODO: Add your control notification handler code here
int a[110]={2,3},ok,i,k=2,t;
bool f=true;
signed char flag[400];
byteint A,B,D,buf1,buf2;
SetZero(A); SetZero(B); SetZero(D); SetZero(buf1); SetZero(buf2);
UpdateData(TRUE);
t=atoi(m_sel_q.GetBuffer(m_sel_q.GetLength()));
Mdata(t);
while(1) //一直循环直到找到一个素数为止
{
int pass=0;
srand( (unsigned)time( NULL ) ); //初始化srand
IntRandom(B,t); //随机产生一个大数B try b if prime,B是一个奇数
//====费尔马小定理素性检测============
IntCpy(Q,B); //将B拷贝到prm中 C=N result prime
Substract(B,ONEVALUE,buf1); //将B-ONEVALUE的结果放到buf1中
SetMode(buf1,TWOVALUE,buf2,B); //B=(B-1)/2的商,buf2=(B-1)/2的余数=0
TransBi(B,flag); //将B转换为二进制大数
ok=1;
for(i=0;i<TESTNUM;i++)
{
LoadInt(A,Model[i]); //将数组Model中的第i+1个数读取到A中
k=PowerMode(A,Q,D,flag); //(A^flag) mod Prm ->D
if(k!=1 && k!=2) //不符合判定规则
{
ok=0;
break;
}
if(k==1) //判定条件1,G=A^(n-1)/2=1
{
}
if(k==2) //判定条件2,G=A^(n-1)/2=p-1
{
}
}
if (ok)//if(ok && pass_2)
{
break;
}//for循环用来检测IntRandom(B,MLENGTH)产生的数B是否是一个素数
}
m_q=PrtInt(Q);
UpdateData(FALSE);
}
void CRSAView::OnButtonE()
{
// TODO: Add your control notification handler code here
int i;
signed char flag[400];
ComputingR(P,Q,N);
m_n=PrtInt(N);
TransBi(N,flag); //将N转换为二进制大数
for(i=0;flag[i]==0;i++);
i=400-i;
m_g_bit.Format("%d",i);
ComputingRvalue(P,Q,eL_N); //计算欧拉函数值
m_eln=PrtInt(eL_N);
ComputingPK(eL_N,SK,PK); //计算密钥对
m_e=PrtInt(SK);
m_d=PrtInt(PK);
UpdateData(FALSE);
}
void CRSAView::OnButtonMc()
{
// TODO: Add your control notification handler code here
int i;
UpdateData(TRUE);
RsaEncrypt(m_mt1,PrtInt(SK),PrtInt(N),m_strEncryptStringArray);
int index=0;
CString strTempEncrypt="";
index=m_strEncryptStringArray.GetSize();
for(i=0;i<index;i++)
{
strTempEncrypt=strTempEncrypt+m_strEncryptStringArray.GetAt(i);
}
m_ct=strTempEncrypt;
UpdateData(FALSE);
}
void CRSAView::OnButtonCm()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
m_mt2=RsaDecrypt(m_strEncryptStringArray,PrtInt(PK),PrtInt(N));
UpdateData(FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -