rsawang1.cpp
上传用户:len888
上传日期:2015-03-06
资源大小:59k
文件大小:50k
源码类别:

CA认证

开发平台:

Visual C++

  1. //
  2. #include "stdafx.h"
  3. //#include "RSATest1.h"
  4. #include "Rsawang1.h"
  5. #ifdef _DEBUG
  6. #define new DEBUG_NEW
  7. #undef THIS_FILE
  8. static char THIS_FILE[] = __FILE__;
  9. #endif
  10. /////////////////////////////////////////////////////////////////////////////
  11. // CRsaA
  12. IMPLEMENT_DYNCREATE(CRsaA, CCmdTarget)
  13. CRsaA::CRsaA()
  14. {
  15. InitInt();
  16. }
  17. CRsaA::~CRsaA()
  18. {
  19. }
  20. BEGIN_MESSAGE_MAP(CRsaA, CCmdTarget)
  21. //{{AFX_MSG_MAP(CRsaA)
  22. // NOTE - the ClassWizard will add and remove mapping macros here.
  23. //}}AFX_MSG_MAP
  24. //ON_MESSAGE(WM_COMPUTING,OnComputing)
  25. END_MESSAGE_MAP()
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CRsaA message handlers
  28. /*----------------------------------------------------------------------------
  29. 功能:进行相关大数的初始化
  30. 入口参数:无
  31. 返回值:无
  32. ----------------------------------------------------------------------------*/
  33. void CRsaA::InitInt(void)
  34. {
  35. SetZero(ZEROVALUE); //对大数变量zerovalue清零
  36. memset(mZEROVALUE,0,MLENGTH);
  37. SetZero(ONEVALUE);                      //对大数变量ONEVALUE进行清零
  38. ONEVALUE[DATALENGTH-1]=1; //ONEVALUE的最后一位为1
  39. SetZero(TWOVALUE); //将TOWVALUE进行清零
  40.     TWOVALUE[DATALENGTH-1]=2; //TOWVALUE的最后一位为2
  41. SetZero(EIGHTVALUE); //对EIGHTVALUE进行清零
  42.     EIGHTVALUE[DATALENGTH-1]=8; //最后一位为8
  43. return ;
  44. }
  45. /*---------------------------------------------------------------------------
  46. 功能:将一个大数A转换为相应的字符串形式
  47. 入口参数:大数A
  48. 返回值:相对应的字符串
  49. ----------------------------------------------------------------------------*/
  50. CString CRsaA::PrtInt(byteint A)
  51. {
  52. register i=0;
  53. int m,n;
  54. while(i<DATALENGTH && A[i]==0)          //跳过大数开始的空白0
  55. i++;
  56. if(i<DATALENGTH)
  57. m=DATALENGTH-i;                     //求出有用的大数长度
  58. n=0;
  59. //注意到这里的i已经是数组中第一个非零元素的对应位置,
  60. CString str=""; //因此下面的循环就是从数组中
  61. //存放的数的最高位开始输出。
  62. while(i<DATALENGTH)
  63. {
  64. str += (A[i++]+'0');
  65. }
  66. return str;
  67. }
  68. /*---------------------------------------------------------------------------
  69. 功能:大数A与大数B相乘,结果放入C中 A×B->C
  70. 入口参数:被乘数A和乘数B,结果C
  71. 返回值:无
  72. ----------------------------------------------------------------------------*/
  73. void CRsaA::Multiply(byteint A,byteint B,byteint C)
  74. {
  75. register i,j,w;
  76. int X,Y,Z;
  77. int Avalid=0; //Avalid=validating bits of A
  78. int Bvalid=0; //Avalid=validating bits of B
  79. while (A[Avalid]==0 && Avalid<DATALENGTH)
  80. Avalid++; //计算Avalid
  81. while (B[Bvalid]==0 && Bvalid<DATALENGTH)
  82. Bvalid++; //计算Bvalid
  83. SetZero(C); //将C清零初始化
  84. for(i=DATALENGTH-1;i>=Avalid;i--)
  85. for(j=DATALENGTH-1;j>=Bvalid;j--)       //逐位进行相乘运算
  86. {
  87. X=A[i]*B[j];        
  88. Y=X/10;
  89. Z=X-10*Y;
  90. w=i+j-(DATALENGTH-1);
  91. C[w]=C[w]+Z;
  92. C[w-1]=C[w-1]+(C[w]/10)+Y;
  93. C[w]=C[w]-(C[w]/10)*10;
  94. }
  95. return;
  96. }
  97. /*---------------------------------------------------------------------------
  98. 功能:将指定的自定义的大数进行0初始化
  99. 入口参数:大数A名
  100. 返回值:无
  101. ----------------------------------------------------------------------------*/
  102. void CRsaA::SetZero(byteint A)  
  103. {
  104. memset(A,0,DATALENGTH);                    //调用系统函数进行初始化
  105. }
  106. /*---------------------------------------------------------------------------
  107. 功能:将大数B拷贝到大数A中
  108. 入口参数:大数A,大数B
  109. 返回值:无
  110. ----------------------------------------------------------------------------*/
  111. void CRsaA::IntCpy(byteint A,byteint B)
  112. {
  113. memcpy(A,B,DATALENGTH);                    //调用系统函数完成拷贝
  114. }
  115. /*---------------------------------------------------------------------------
  116. 功能:A+B的结果送C
  117. 入口参数:大数A,B,C
  118. 返回值:无
  119. ----------------------------------------------------------------------------*/
  120. void CRsaA::Plus(byteint A,byteint B,byteint C)
  121. {
  122. register i;//,w;
  123. int X,Y,Z,m,n,valid;
  124. m=IntValid(A);                 //计算A的长度         
  125. n=IntValid(B);                 //计算B的长度
  126. valid=(m>n)?m+1:n+1;           //计算时要以最长的数为准
  127. SetZero(C);                    //将C清零
  128. for(i=DATALENGTH-1;i>=DATALENGTH-valid;i--)
  129. {
  130. X=A[i]+B[i];               //按位相加
  131. Y=X/10;
  132. Z=X-10*Y;
  133. C[i]=C[i]+Z;               //计算进位
  134. C[i-1]=C[i-1]+Y;
  135. }
  136. }
  137. /*---------------------------------------------------------------------------
  138. 功能:大数SA减去大数SB,结果放入SC
  139. 入口参数:被减数SA,减数SB,差SC
  140. 返回值:无
  141. ----------------------------------------------------------------------------*/
  142. void CRsaA::Substract(byteint SA,byteint SB,byteint SC)
  143. {
  144. byteint buf;
  145. register i,j;
  146. int X;
  147. IntCpy(buf,SA);                  //将SA的内容拷贝到buf中
  148. SetZero(SC);                 //SC清零初始化
  149. for(i=DATALENGTH-1;i>=0;i--)
  150. {
  151. if(buf[i]<SB[i])             //如果最低位不够减
  152. {
  153. buf[i]=buf[i]+10;        //向高位借1
  154. if(buf[i-1]>0)           //如果高位够减,直接减1
  155. (buf[i-1])--;    
  156. else                     //否则一直找到够减的位
  157. {
  158. j=i-1;
  159. while(buf[j]==0)     //j不会出现越界,是因为保证了最高位不为0
  160. buf[j--]=9;
  161. buf[j]=buf[j]-1;
  162. }
  163. }
  164. X=buf[i]-SB[i];              //将各位减的结果存入SC中
  165. SC[i]=X;
  166. }
  167. }
  168. /*---------------------------------------------------------------------------
  169. 功能:比较两个大数A和B的大小
  170. 入口参数:大数A和大数B
  171. 返回值:A>B:return 1 ; A=B:return 0 ; A<B:return -1
  172. ----------------------------------------------------------------------------*/
  173. int CRsaA::IntCmp(byteint A,byteint B)
  174. {
  175. int stat;
  176. stat=memcmp(A,B,DATALENGTH);    //系统函数
  177. if(stat==0)
  178. return 0;
  179. if(stat>0)
  180. return 1;
  181. return -1;
  182. }
  183. /*---------------------------------------------------------------------------
  184. 功能:得到一个大数的非零位数
  185. 入口参数:大数validtemp
  186. 返回值:大数中非零的位数
  187. ----------------------------------------------------------------------------*/
  188. int CRsaA::IntValid(byteint validtemp)
  189. {
  190. register i=0;
  191. while(validtemp[i]==0 && i<DATALENGTH)
  192. i++;
  193. return DATALENGTH-i;
  194. }
  195. /*---------------------------------------------------------------------------
  196. 功能:计算大数A÷B的结果,余数放在C中,商在D中
  197. 入口参数:被除数A,除数B,余数C,商D
  198. 返回值:无
  199. ----------------------------------------------------------------------------*/
  200. void CRsaA::SetMode(byteint A,byteint B,byteint C,byteint D)
  201. {
  202. register i,j,k;
  203. int valid_1,valid_2,valid,sbits,cmpval;
  204. byteint buf1,buf2;
  205.     
  206. SetZero(buf1);  SetZero(buf2);
  207. SetZero(D);                       //将大数D进行清零初始化
  208.     IntCpy(C,A);                      //将被除数A拷贝到C中
  209. valid_2=IntValid(B);              //计算B(除数)的位数,
  210. while((cmpval=IntCmp(C,B))>0)     //变除法为减法,每减一次就判断是否有C>B,如果满足就继续减。
  211. {
  212. valid_1=IntValid(C);          //计算C(被除数)的位数,因为它的位数在循环过程中是变化的
  213.                               //做减法后(C-B)仍然存放在C中
  214. valid=valid_1-valid_2;        //C的长度与B的长度的差(该值最小为0)
  215. if(valid>0)                   //如果被除数比除数的位数多
  216. {
  217. i=DATALENGTH-valid_1;     //被除数前导零的个数
  218. j=DATALENGTH-valid_2;     //除数前导零的个数,作下标指示器
  219. sbits=0;
  220. for(k=j;k<DATALENGTH;k++)
  221. {
  222. if(C[i]>B[j])         //从C和B的最高位开始依次比较对应位的大小,判断是否够减
  223. break;
  224. if(C[i]<B[j])
  225. {
  226. sbits=1;          //如果不够减,那么C就退一位,再做减法
  227. break;
  228. }
  229. i++;j++;              //当C和B的最高位相等时,就比较二者的次高位
  230. }
  231. valid=valid-sbits;
  232. SetZero(buf1);            //buf1清零
  233. for(i=valid;i<DATALENGTH;i++)
  234. {
  235. j=i-valid;
  236. buf1[j]=B[i];         //buf1中存放的是B左移若干位之后得到的值
  237.                       //如果够减,则B左移后最高位与C的最高位对齐,
  238.                       //否则与C的次高位对齐
  239. }
  240. }
  241. else
  242. IntCpy(buf1,B);           //当C和B的位数相同时,就直接把B放入缓冲区buf1中
  243. D[DATALENGTH-1-valid]++;      //这里保存的是在某一位上所做的减法的次数,每做一次就加1
  244. Substract(C,buf1,buf2);       //不论C的长度与B的长度的差是否大于0,都要做减法,直到C<=B
  245. IntCpy(C,buf2);
  246. }
  247. if(cmpval==0)                     //两个数相等
  248. {
  249. SetZero(C);                   //余数为0
  250. D[DATALENGTH-1]++;            //商为1
  251. }
  252. }
  253. /*---------------------------------------------------------------------------
  254. 功能:随机地产生一个大数奇数,长度为num,最高位不是0,存放在RandomA中
  255. 入口参数:大数A,长度num
  256. 返回值:无
  257. ----------------------------------------------------------------------------*/
  258. void CRsaA::IntRandom(byteint RandomA,int num)
  259. {
  260. int i;
  261. SetZero(RandomA);                     //将RandomA清零
  262. while(!(RandomA[DATALENGTH-1]%2))     //判断条件保证RandomA的最后一位数是奇数
  263. RandomA[DATALENGTH-1]=rand()%10;  //如果最后一位是偶数,则从新产生最后一位
  264.     while(!(RandomA[DATALENGTH-num]))     //判断条件保证RandomA最高位不是0
  265. RandomA[DATALENGTH-num]=rand()%10;//如果最高位是0,则从新产生最高位
  266. i=DATALENGTH-2;
  267. while(i>=DATALENGTH-num+1)            //循环产生从次低位开始到次高位的所有位上的数
  268. RandomA[i--]=rand()%10;
  269. }
  270. /*---------------------------------------------------------------------------
  271. 功能:将质数类型B拷贝到A中,实现类型转换
  272. 入口参数:大数A,质数类型B
  273. 返回值:无
  274. ----------------------------------------------------------------------------*/
  275. //功能:将数B拷贝到大数A,实现类型转换
  276. void CRsaA::LoadInt(byteint A,mtype B)
  277. {
  278. register i,j;
  279. SetZero(A);                  //A进行清零初始化
  280. i=DATALENGTH-1;
  281. j=MLENGTH-1;
  282. while(j>0)                   //循环拷贝各位数字
  283. {
  284. A[i--]=B[j--];
  285. }
  286. }
  287. /*---------------------------------------------------------------------------
  288. 功能:该函数用来从集合[1,b-1]中产生若干个用于检测的数,存放在Model[]中
  289. 入口参数:无
  290. 返回值:无
  291. ----------------------------------------------------------------------------*/
  292. void CRsaA::Mdata()
  293. {
  294. register i,j;                     //Randomly choose a set of 100 numbers in [1,b-1]
  295. int k=MLENGTH-2;
  296. memset(Model,0,TESTNUM*MLENGTH);  //这个函数在这里用来将整个数组清零,进行初始化
  297. srand( (unsigned)time( NULL ) );  //进行随机函数的初始化
  298. for(i=0;i<TESTNUM;i++)            //TESTNUM为需要产生的个数
  299. {
  300. for(j=MLENGTH-1;j>=k;j--)
  301. {
  302. Model[i][j]=rand()%10;    //注意这里与测试素数的程序中的区别,
  303. }
  304. if((memcmp(Model[i],mZEROVALUE,MLENGTH))==0)  
  305. i--;
  306. k--;                          //保证所产生的数不为0
  307. if (k<0) k=MLENGTH-2;
  308. }
  309. }
  310. /*---------------------------------------------------------------------------
  311. 功能:该函数用来将十进制的大整数转换成二进制的数
  312. 入口参数:需转换的大数B,二进制结果flag[400]
  313. 返回值:无
  314. ----------------------------------------------------------------------------*/
  315. void CRsaA::TransBi(byteint B,signed char flag[400])
  316. {
  317. byteint buf;
  318. byteint result;
  319. byteint temp;
  320. register i;
  321. SetZero(buf);  SetZero(result);  SetZero(temp);
  322. memset(flag,0,400);                     //将flag数组清零
  323. i=399;
  324. IntCpy(buf,B);                          //将B拷贝到buf中
  325. while(IntCmp(buf,ZEROVALUE)==1)         //如果buf内容为0
  326. {
  327. SetMode(buf,TWOVALUE,temp,result);  //将buf进行大数的模2运算,商在result中,余数temp
  328. flag[i]=temp[DATALENGTH-1];         
  329. IntCpy(buf,result);                 //对商继续进行模2运算
  330. i--;
  331. }
  332. flag[i]=-1;                             //设置一个标志位,表明二进制数的开始
  333. }
  334. /*---------------------------------------------------------------------------
  335. 功能:该函数用来进行模幂算法,A为底数,模为c,二进制的指数B存放在数组flag中
  336. 入口参数:底数A,模C,结果D,二进制质数flag[400]
  337. 返回值:A^B=1(mod C),返回1;A^B=p-1(mod C),返回2;否则返回0
  338. ----------------------------------------------------------------------------*/
  339. int CRsaA::PowerMode(byteint A,byteint C,byteint D,signed char flag[400])
  340. {
  341. byteint buf;
  342. byteint result;
  343. byteint temp,P;
  344. register i;
  345. SetZero(D);   SetZero(buf); SetZero(result); SetZero(temp); SetZero(P);  //将D清零
  346. IntCpy(temp,A);                       //将A的值拷贝到temp中
  347. if(flag[399]==1)                      //最低位为1,拷贝本身,flag[i]只有1或者0两种情况
  348. IntCpy(result,A);
  349. else   //最低位为0,则幂为1
  350. IntCpy(result,ONEVALUE);
  351. i=398;
  352. while(flag[i]!=-1)                    //判断是否已经到达指数尽头
  353. {
  354. Multiply(temp,temp,buf);          //temp*temp->buf 
  355. SetMode(buf,C,temp,P);            //buf%c余数->temp,商->p
  356. if(flag[i]!=0)                    //如果该位不是0,则将其和前一步低一位的结果进行乘法运算
  357. {                                 //否则,将其作为该位的模,在高一位的运算中,只要进行一次
  358. Multiply(temp,result,buf);    //平方运算,就可以得到高一位的模
  359. SetMode(buf,C,result,P);
  360. }
  361. i--;
  362. }                                     //result中存放的是最终结果
  363. IntCpy(buf,C);
  364. IntCpy(D,result);
  365. Substract(buf,ONEVALUE,temp);
  366. if(IntCmp(result,ONEVALUE)==0)        //p mod n=1,判断是否有A^B=1(mod C)
  367. return 1;
  368. if(IntCmp(result,temp)==0)            //p mod n=-1[p-1=-1(mod p)],判断是否有A^B=p-1(mod C)
  369. return 2;
  370. return 0;
  371. }
  372. /*---------------------------------------------------------------------------
  373. 功能:产生一个质数
  374. 入口参数:大数Prm
  375. 返回值:产生成功,返回0
  376. ----------------------------------------------------------------------------*/
  377. int CRsaA::Prime(byteint Prm)
  378. {
  379. int i,k,ok;
  380. signed char flag[400];
  381. byteint A,B,D,buf1,buf2;
  382. SetZero(A); SetZero(B); SetZero(D); SetZero(buf1); SetZero(buf2);
  383. while(1)                                 //一直循环直到找到一个素数为止
  384. {
  385. int pass=0;
  386. srand( (unsigned)time( NULL ) );     //初始化srand
  387. IntRandom(B,MLENGTH);                //随机产生一个大数B  try b if prime,B是一个奇数
  388. IntCpy(Prm,B);                       //将B拷贝到prm中 C=N result prime
  389. Substract(B,ONEVALUE,buf1);          //将B-ONEVALUE的结果放到buf1中
  390. SetMode(buf1,TWOVALUE,buf2,B);       //B=(B-1)/2的商,buf2=(B-1)/2的余数=0
  391. TransBi(B,flag);                     //将B转换为二进制大数
  392. ok=1;
  393. for(i=0;i<TESTNUM;i++)
  394. {
  395. LoadInt(A,Model[i]);             //将数组Model中的第i+1个数读取到A中
  396. k=PowerMode(A,Prm,D,flag);       //(A^flag) mod Prm ->D
  397. if(k!=1 && k!=2)                 //不符合判定规则
  398. {
  399. ok=0;
  400. break;
  401. }
  402. if(k==1)                         //判定条件1,G=A^(n-1)/2=1
  403. {
  404. }
  405. if(k==2)                         //判定条件2,G=A^(n-1)/2=p-1
  406. {
  407. }
  408. }
  409. if (ok)//if(ok && pass_2)
  410. {
  411. return 0;
  412. }//for循环用来检测IntRandom(B,MLENGTH)产生的数B是否是一个素数
  413. }
  414. }
  415. /*---------------------------------------------------------------------------
  416. 功能:计算公钥PK
  417. 入口参数:$(r)的值在Rvalue中,私钥SK,公钥PK
  418. 返回值:成功找到,返回1
  419. ----------------------------------------------------------------------------*/
  420. int CRsaA::ComputingPK(byteint Rvalue,byteint SK,byteint PK)
  421. {
  422. register i;
  423. byteint PA,PB,PC,buf1,temp,buf2;
  424. SetZero(PK); SetZero(PA); SetZero(PB); SetZero(PC); SetZero(buf1);   //清零初始化
  425. SetZero(temp); SetZero(buf2);
  426. while(1)
  427. {
  428. IntRandom(SK,SKLENGTH);        //随机产生一个大数奇数作为Generated secret key
  429. IntCpy(PB,SK);
  430. IntCpy(PA,Rvalue);
  431. while(1)
  432. {
  433. SetMode(PA,PB,PC,PK);     //PA=PB*PK+PC
  434. i=IntCmp(PC,ONEVALUE);
  435. if(i==0)                  //PC=1, i=0
  436. break;                //满足条件,是互质的
  437. i=IntCmp(PC,ZEROVALUE);
  438. if(i==0)
  439. {
  440. i=-1;                 //PC=0,i=-1
  441. break;                //不满足互质条件,跳出循环,从新生成一个随机数
  442. }
  443. IntCpy(PA,PB);            //按照欧几里的定理继续判断
  444. IntCpy(PB,PC);
  445. }
  446. if(i==0)                      //满足,跳出查找循环
  447. break;
  448. }
  449. IntCpy(temp,ONEVALUE);
  450. IntCpy(PA,Rvalue);
  451. IntCpy(PB,SK);
  452. while(1)
  453. {
  454. Multiply(PA,temp,buf1);  //buf1=PA*temp
  455. Plus(buf1,ONEVALUE,buf2);//buf2=(PA*temp)+1
  456. SetMode(buf2,PB,buf1,PK);//buf=((PA*temp)+1)%PB
  457. if(IntCmp(buf1,ZEROVALUE)==0)
  458. break;
  459. Plus(temp,ONEVALUE,buf1);
  460. IntCpy(temp,buf1);
  461. }
  462. return 1;                   //SK and PK found
  463. }
  464. /*---------------------------------------------------------------------------
  465. 功能:计算模R
  466. 入口参数:产生的质数p,q,模R
  467. 返回值:无
  468. ----------------------------------------------------------------------------*/
  469. void CRsaA::ComputingR(byteint p,byteint q,byteint R)
  470. {
  471. Multiply(p,q,R);              // R=p*q, public mode number
  472. }
  473. /*---------------------------------------------------------------------------
  474. 功能:计算$(r)
  475. 入口参数:质数p,质数q,模$(r)放在Rvalue
  476. 返回值:无
  477. ----------------------------------------------------------------------------*/
  478. void CRsaA::ComputingRvalue(byteint p,byteint q,byteint Rvalue)
  479. {
  480. byteint buf1,buf2;
  481. SetZero(buf1); SetZero(buf2);
  482. Substract(p,ONEVALUE,buf1);   // buf1=p-1
  483. Substract(q,ONEVALUE,buf2);   // buf2=q-1
  484. Multiply(buf1,buf2,Rvalue);   // Rvalue=(p-1)*(q-1)
  485. }
  486. /*---------------------------------------------------------------------------
  487. 功能:将接受的字符串转换为大数类型
  488. 入口参数:大数result,字符串input
  489. 返回值:数的长度
  490. ----------------------------------------------------------------------------*/
  491. int CRsaA::Getinput(byteint result,CString input)
  492. {
  493. int i=DATALENGTH,m=0;
  494. long strlen;
  495. strlen=input.GetLength();
  496. if(strlen==0) return 0;
  497. else
  498. {
  499. for(int j=0;j<strlen;j++)
  500. {
  501. result[i-strlen+j] = (input.GetAt(j)-'0');
  502. }
  503. return j;
  504. }
  505. }
  506. /*---------------------------------------------------------------------------
  507. 功能:实现加密,解密运算功能
  508. 入口参数:明文(大数类型source),模R,秘钥key,结果desti
  509. 返回值:无
  510. ----------------------------------------------------------------------------*/
  511. void CRsaA::RsaDo(byteint source,byteint R,byteint key,byteint desti)
  512. {
  513. TransBi(key,flag);
  514. PowerMode(source,R,desti,flag);
  515. }
  516. /*---------------------------------------------------------------------------
  517. 功能:将长整形的数转换为大数类型
  518. 入口参数:大数类型result,长整形input
  519. 返回值:成功,返回数的长度,否则返回0;
  520. ----------------------------------------------------------------------------*/
  521. int CRsaA::Getinput1(byteint result,unsigned long input)
  522. {
  523. int i=DATALENGTH-1,m=0;
  524. long j=0;
  525. int k=0;
  526. if(input)
  527. {
  528. do
  529. {
  530. j=input/10;
  531. k=input-j*10;
  532. result[i]=k;
  533. i--;
  534. m++;
  535. input=j;
  536. }while(j);
  537. return m;
  538. }
  539. else
  540. return 0;
  541. }
  542. /*---------------------------------------------------------------------------
  543. 功能:将十六进制的串转换为数值
  544. 入口参数:字符串指针
  545. 返回值:成功,返回数
  546. ----------------------------------------------------------------------------*/
  547. unsigned long CRsaA::Os2ip(unsigned char* pstr)
  548. {
  549. unsigned long ch=0;
  550. unsigned int j=0;
  551. unsigned long k=1;
  552. for(int i=0;i<4;i++)
  553. {
  554. j = (unsigned int) (*(pstr+3-i));
  555. /* if( (*(pstr+3-i))>='0'&&(*(pstr+3-i))<='9')
  556. j = (*(pstr+3-i)) - '0';
  557. if( (*(pstr+3-i))>='a'&&(*(pstr+3-i))<='f') 
  558. j = (*(pstr+3-i)) - 'a'+10;
  559. if( (*(pstr+3-i))>='A'&&(*(pstr+3-i))<='F')
  560. j = (*(pstr+3-i)) - 'A'+10;*/
  561. ch += j*k;
  562. k*=256;
  563. }
  564. return ch;
  565. /*---------------------------------------------------------------------------
  566. 功能:将数串转换为相应的字符串
  567. 入口参数:字符串str
  568. 返回值:返回转换的结果;
  569. ----------------------------------------------------------------------------*/
  570. CString CRsaA::Ip2os(CString str)
  571. {
  572. int strlen=str.GetLength(),quotient=0,remainder=0;
  573. unsigned long num=0,temp=0;
  574. unsigned int k=1;
  575. CString strResult="";
  576. for(int i=strlen;i>0;i--)  //得到相应的数字串,存放在num中
  577. {
  578. temp = (str.GetAt(i-1) - '0');
  579. num += temp*k;
  580. k *= 10;
  581. }
  582. //采用模除的方式,求得相应的十六进制数
  583. for(int j=0;j<4;j++)
  584. {
  585. quotient = num/256;
  586. remainder = num - quotient*256;
  587. /*if(remainder>=0&&remainder<=9)
  588. strResult.Insert(0,(remainder+'0'));
  589. if(remainder>=10&&remainder<=15)
  590. strResult.Insert(0,(remainder-10+'a'));*/
  591. strResult.Insert(0,(unsigned char)remainder);
  592. num = quotient;
  593. }
  594. return strResult; 
  595. }
  596. /*---------------------------------------------------------------------------
  597. 功能:产生RSA秘钥对
  598. 入口参数:存放结果的字符串地址 
  599. 返回值:无
  600. ----------------------------------------------------------------------------*/
  601. void CRsaA::GenKeys(CString& pk,CString& sk,CString& R)
  602. {
  603. byteint m_p,m_q,m_R,m_Rvalue,m_PK,m_SK;
  604. SetZero(m_p);      //对大数变量进行清零初始化
  605. SetZero(m_q);
  606.     SetZero(m_R);
  607.     SetZero(m_Rvalue);
  608.     SetZero(m_PK);
  609.     SetZero(m_SK);
  610. Mdata();         //生成比较数表
  611. AfxMessageBox("开始计算质数P...");
  612. Prime(m_p);        //生成素数p q
  613. AfxMessageBox("开始计算质数Q...");
  614. Prime(m_q);
  615. AfxMessageBox("开始计算模R...");
  616. ComputingR(m_p,m_q,m_R); //计算模R
  617. AfxMessageBox("开始计算模r");
  618. ComputingRvalue(m_p,m_q,m_Rvalue);  //计算r
  619. AfxMessageBox("开始计算秘钥SK,PK");
  620. ComputingPK(m_Rvalue,m_PK,m_SK);    // Generate PK and SK
  621. //CGenKeyBusyDlg dlg1;
  622. //g1.DoModal();
  623. R=PrtInt(m_R);
  624. pk=PrtInt(m_PK);
  625. sk=PrtInt(m_SK);
  626. return ;
  627. }
  628. /*---------------------------------------------------------------------------
  629. 功能:实现加密功能接口
  630. 入口参数:明文字符串source,模字符串R,秘钥字符串key,结果字符串数组result
  631. 返回值:无
  632. ----------------------------------------------------------------------------*/
  633. int CRsaA::RsaEncrypt(CString& source,const char *key,const char *R,CStringArray& result)
  634. {
  635. unsigned char* pstr;
  636. int j;//sourcelen,j;
  637. byteint m_key,m_R,desti,aa;
  638. SetZero(desti);              //将大数变量清零初始化
  639. SetZero(aa);
  640. //SetZero(bb);
  641. SetZero(m_key);
  642. SetZero(m_R);
  643. pstr = (unsigned char*)(LPCTSTR)source;               //得到字符串数据的指针
  644. j = source.GetLength()/4;    //得到数组的元素个数
  645. result.SetSize(j,1);
  646. Getinput(m_key,key);             //将字符串转换为大数类型
  647. Getinput(m_R,R);
  648. for(int i=0;i<j;i++)
  649. {
  650. Getinput1(desti,Os2ip(pstr));    //将四个字节的输入转换为大数类型数值
  651. RsaDo(desti,m_R,m_key,aa);  //进行加密运算
  652. result.SetAt(i,PrtInt(aa));          //将结果存放到数组中
  653. SetZero(desti);  SetZero(aa);
  654. pstr += 4;
  655. }
  656. return j;
  657. }
  658. /*---------------------------------------------------------------------------
  659. 功能:实现解密功能接口
  660. 入口参数:密文字符串数组source,秘钥字符串sk,模字符串R,
  661. 返回值:结果字符串数组result
  662. ----------------------------------------------------------------------------*/
  663. CString CRsaA::RsaDecrypt(CStringArray& source,const char* sk,const char* R)
  664. {
  665. int index=0;
  666. CString result;
  667. byteint m_sk,m_r,desti,aa;
  668. SetZero(m_sk);  SetZero(m_r); SetZero(desti); SetZero(aa);  //SetZero(bb);
  669. index=source.GetSize();   //得到数组的元素个数
  670. Getinput(m_sk,sk);        //将字符串转换为大数类型
  671. Getinput(m_r,R);
  672. for(int i=0;i<index;i++)
  673. {
  674. Getinput(desti,source.GetAt(i));   //将加密结果转换为大数类型
  675. RsaDo(desti,m_r,m_sk,aa);          //解密运算
  676. result += Ip2os(PrtInt(aa));       //组合初始明文
  677. SetZero(aa);  SetZero(desti);
  678. }
  679. return result;        //返回明文串
  680. }
  681. /*---------------------------------------------------------------------------
  682. 功能:生成一个秘钥存贮文件
  683. 入口参数:无
  684. 返回值:无
  685. ----------------------------------------------------------------------------*/
  686. void CRsaA::GenKeysTable()
  687. {
  688. CStringArray RArray,SKArray,PKArray;
  689. CString r,pk,sk;
  690. int j=1,i;      //参数j表示产生的秘钥对的个数
  691. unsigned char strlength;
  692. //设置数组的元素个数
  693. RArray.SetSize(j,1); SKArray.SetSize(j,1); PKArray.SetSize(j,1);
  694. /*-----------------------------------------------------------------------
  695. 文件格式为:
  696. 长度   秘钥   长度   秘钥......
  697. ----   ----   ----   ----
  698. 1byte  nbyte  1byte  nbyte       (中间无空格,R,SK,PK)
  699. */
  700. CFile file;
  701. for(i=0;i<j;i++)
  702. {
  703. GenKeys(pk,sk,r);  //循环产生秘钥
  704. RArray.SetAt(i,r); SKArray.SetAt(i,sk); PKArray.SetAt(i,pk);
  705. }
  706. if(file.Open("c:\key.txt",CFile::modeCreate|CFile::modeReadWrite)==0)
  707. {
  708. AfxMessageBox("open file error!");  //打开文件失败
  709. return;
  710. }
  711. for(i=0;i<j;i++)
  712. {                //循环写入结果
  713. strlength = (unsigned char)(RArray.GetAt(i)).GetLength();
  714. file.Write(&strlength,1);
  715. file.Write(RArray.GetAt(i),(RArray.GetAt(i)).GetLength());
  716. strlength = (unsigned char)(SKArray.GetAt(i)).GetLength();
  717. file.Write(&strlength,1);
  718. file.Write(SKArray.GetAt(i),(SKArray.GetAt(i)).GetLength());
  719. strlength = (unsigned char)(PKArray.GetAt(i)).GetLength();
  720. file.Write(&strlength,1);
  721. file.Write(PKArray.GetAt(i),(PKArray.GetAt(i)).GetLength());
  722. }
  723. file.Close();
  724. }
  725. void CRsaA::LoadKeysFromFile(CString& r,CString& sk,CString& pk)
  726. {
  727. int            j=10,len;
  728. char           *pbuffer;
  729. unsigned char  strlen1;
  730. CFile          file;
  731. CFileException e;
  732. CString        strFileName;
  733. if(file.Open("c:\key.txt",CFile::modeRead)==0)
  734. {
  735. AfxMessageBox("File(key.txt)could not be opened" );
  736. }
  737. file.Read(&strlen1,1);  //读出R长度
  738. len = (int)strlen1;
  739. pbuffer = new char[len+1];
  740. pbuffer[len]='';
  741. file.Read(pbuffer,len);  //读出R
  742. r=pbuffer;
  743. delete pbuffer;
  744. file.Read(&strlen1,1);  //读出SK长度
  745. len = (int)strlen1;
  746. pbuffer = new char[len+1];
  747. pbuffer[len]='';
  748. file.Read(pbuffer,len);  //读出SK
  749. sk=pbuffer;
  750. delete pbuffer;
  751. file.Read(&strlen1,1);  //读出PK长度
  752. len = (int)strlen1;
  753. pbuffer = new char[len+1];
  754. pbuffer[len]='';
  755. file.Read(pbuffer,len);  //读出PK
  756. pk=pbuffer;
  757. delete pbuffer;
  758. file.Close();
  759. }//
  760. #include "stdafx.h"
  761. //#include "RSATest1.h"
  762. #include "Rsawang1.h"
  763. #ifdef _DEBUG
  764. #define new DEBUG_NEW
  765. #undef THIS_FILE
  766. static char THIS_FILE[] = __FILE__;
  767. #endif
  768. /////////////////////////////////////////////////////////////////////////////
  769. // CRsaA
  770. IMPLEMENT_DYNCREATE(CRsaA, CCmdTarget)
  771. CRsaA::CRsaA()
  772. {
  773. InitInt();
  774. }
  775. CRsaA::~CRsaA()
  776. {
  777. }
  778. BEGIN_MESSAGE_MAP(CRsaA, CCmdTarget)
  779. //{{AFX_MSG_MAP(CRsaA)
  780. // NOTE - the ClassWizard will add and remove mapping macros here.
  781. //}}AFX_MSG_MAP
  782. //ON_MESSAGE(WM_COMPUTING,OnComputing)
  783. END_MESSAGE_MAP()
  784. /////////////////////////////////////////////////////////////////////////////
  785. // CRsaA message handlers
  786. /*----------------------------------------------------------------------------
  787. 功能:进行相关大数的初始化
  788. 入口参数:无
  789. 返回值:无
  790. ----------------------------------------------------------------------------*/
  791. void CRsaA::InitInt(void)
  792. {
  793. SetZero(ZEROVALUE); //对大数变量zerovalue清零
  794. memset(mZEROVALUE,0,MLENGTH);
  795. SetZero(ONEVALUE);                      //对大数变量ONEVALUE进行清零
  796. ONEVALUE[DATALENGTH-1]=1; //ONEVALUE的最后一位为1
  797. SetZero(TWOVALUE); //将TOWVALUE进行清零
  798.     TWOVALUE[DATALENGTH-1]=2; //TOWVALUE的最后一位为2
  799. SetZero(EIGHTVALUE); //对EIGHTVALUE进行清零
  800.     EIGHTVALUE[DATALENGTH-1]=8; //最后一位为8
  801. return ;
  802. }
  803. /*---------------------------------------------------------------------------
  804. 功能:将一个大数A转换为相应的字符串形式
  805. 入口参数:大数A
  806. 返回值:相对应的字符串
  807. ----------------------------------------------------------------------------*/
  808. CString CRsaA::PrtInt(byteint A)
  809. {
  810. register i=0;
  811. int m,n;
  812. while(i<DATALENGTH && A[i]==0)          //跳过大数开始的空白0
  813. i++;
  814. if(i<DATALENGTH)
  815. m=DATALENGTH-i;                     //求出有用的大数长度
  816. n=0;
  817. //注意到这里的i已经是数组中第一个非零元素的对应位置,
  818. CString str=""; //因此下面的循环就是从数组中
  819. //存放的数的最高位开始输出。
  820. while(i<DATALENGTH)
  821. {
  822. str += (A[i++]+'0');
  823. }
  824. return str;
  825. }
  826. /*---------------------------------------------------------------------------
  827. 功能:大数A与大数B相乘,结果放入C中 A×B->C
  828. 入口参数:被乘数A和乘数B,结果C
  829. 返回值:无
  830. ----------------------------------------------------------------------------*/
  831. void CRsaA::Multiply(byteint A,byteint B,byteint C)
  832. {
  833. register i,j,w;
  834. int X,Y,Z;
  835. int Avalid=0; //Avalid=validating bits of A
  836. int Bvalid=0; //Avalid=validating bits of B
  837. while (A[Avalid]==0 && Avalid<DATALENGTH)
  838. Avalid++; //计算Avalid
  839. while (B[Bvalid]==0 && Bvalid<DATALENGTH)
  840. Bvalid++; //计算Bvalid
  841. SetZero(C); //将C清零初始化
  842. for(i=DATALENGTH-1;i>=Avalid;i--)
  843. for(j=DATALENGTH-1;j>=Bvalid;j--)       //逐位进行相乘运算
  844. {
  845. X=A[i]*B[j];        
  846. Y=X/10;
  847. Z=X-10*Y;
  848. w=i+j-(DATALENGTH-1);
  849. C[w]=C[w]+Z;
  850. C[w-1]=C[w-1]+(C[w]/10)+Y;
  851. C[w]=C[w]-(C[w]/10)*10;
  852. }
  853. return;
  854. }
  855. /*---------------------------------------------------------------------------
  856. 功能:将指定的自定义的大数进行0初始化
  857. 入口参数:大数A名
  858. 返回值:无
  859. ----------------------------------------------------------------------------*/
  860. void CRsaA::SetZero(byteint A)  
  861. {
  862. memset(A,0,DATALENGTH);                    //调用系统函数进行初始化
  863. }
  864. /*---------------------------------------------------------------------------
  865. 功能:将大数B拷贝到大数A中
  866. 入口参数:大数A,大数B
  867. 返回值:无
  868. ----------------------------------------------------------------------------*/
  869. void CRsaA::IntCpy(byteint A,byteint B)
  870. {
  871. memcpy(A,B,DATALENGTH);                    //调用系统函数完成拷贝
  872. }
  873. /*---------------------------------------------------------------------------
  874. 功能:A+B的结果送C
  875. 入口参数:大数A,B,C
  876. 返回值:无
  877. ----------------------------------------------------------------------------*/
  878. void CRsaA::Plus(byteint A,byteint B,byteint C)
  879. {
  880. register i;//,w;
  881. int X,Y,Z,m,n,valid;
  882. m=IntValid(A);                 //计算A的长度         
  883. n=IntValid(B);                 //计算B的长度
  884. valid=(m>n)?m+1:n+1;           //计算时要以最长的数为准
  885. SetZero(C);                    //将C清零
  886. for(i=DATALENGTH-1;i>=DATALENGTH-valid;i--)
  887. {
  888. X=A[i]+B[i];               //按位相加
  889. Y=X/10;
  890. Z=X-10*Y;
  891. C[i]=C[i]+Z;               //计算进位
  892. C[i-1]=C[i-1]+Y;
  893. }
  894. }
  895. /*---------------------------------------------------------------------------
  896. 功能:大数SA减去大数SB,结果放入SC
  897. 入口参数:被减数SA,减数SB,差SC
  898. 返回值:无
  899. ----------------------------------------------------------------------------*/
  900. void CRsaA::Substract(byteint SA,byteint SB,byteint SC)
  901. {
  902. byteint buf;
  903. register i,j;
  904. int X;
  905. IntCpy(buf,SA);                  //将SA的内容拷贝到buf中
  906. SetZero(SC);                 //SC清零初始化
  907. for(i=DATALENGTH-1;i>=0;i--)
  908. {
  909. if(buf[i]<SB[i])             //如果最低位不够减
  910. {
  911. buf[i]=buf[i]+10;        //向高位借1
  912. if(buf[i-1]>0)           //如果高位够减,直接减1
  913. (buf[i-1])--;    
  914. else                     //否则一直找到够减的位
  915. {
  916. j=i-1;
  917. while(buf[j]==0)     //j不会出现越界,是因为保证了最高位不为0
  918. buf[j--]=9;
  919. buf[j]=buf[j]-1;
  920. }
  921. }
  922. X=buf[i]-SB[i];              //将各位减的结果存入SC中
  923. SC[i]=X;
  924. }
  925. }
  926. /*---------------------------------------------------------------------------
  927. 功能:比较两个大数A和B的大小
  928. 入口参数:大数A和大数B
  929. 返回值:A>B:return 1 ; A=B:return 0 ; A<B:return -1
  930. ----------------------------------------------------------------------------*/
  931. int CRsaA::IntCmp(byteint A,byteint B)
  932. {
  933. int stat;
  934. stat=memcmp(A,B,DATALENGTH);    //系统函数
  935. if(stat==0)
  936. return 0;
  937. if(stat>0)
  938. return 1;
  939. return -1;
  940. }
  941. /*---------------------------------------------------------------------------
  942. 功能:得到一个大数的非零位数
  943. 入口参数:大数validtemp
  944. 返回值:大数中非零的位数
  945. ----------------------------------------------------------------------------*/
  946. int CRsaA::IntValid(byteint validtemp)
  947. {
  948. register i=0;
  949. while(validtemp[i]==0 && i<DATALENGTH)
  950. i++;
  951. return DATALENGTH-i;
  952. }
  953. /*---------------------------------------------------------------------------
  954. 功能:计算大数A÷B的结果,余数放在C中,商在D中
  955. 入口参数:被除数A,除数B,余数C,商D
  956. 返回值:无
  957. ----------------------------------------------------------------------------*/
  958. void CRsaA::SetMode(byteint A,byteint B,byteint C,byteint D)
  959. {
  960. register i,j,k;
  961. int valid_1,valid_2,valid,sbits,cmpval;
  962. byteint buf1,buf2;
  963.     
  964. SetZero(buf1);  SetZero(buf2);
  965. SetZero(D);                       //将大数D进行清零初始化
  966.     IntCpy(C,A);                      //将被除数A拷贝到C中
  967. valid_2=IntValid(B);              //计算B(除数)的位数,
  968. while((cmpval=IntCmp(C,B))>0)     //变除法为减法,每减一次就判断是否有C>B,如果满足就继续减。
  969. {
  970. valid_1=IntValid(C);          //计算C(被除数)的位数,因为它的位数在循环过程中是变化的
  971.                               //做减法后(C-B)仍然存放在C中
  972. valid=valid_1-valid_2;        //C的长度与B的长度的差(该值最小为0)
  973. if(valid>0)                   //如果被除数比除数的位数多
  974. {
  975. i=DATALENGTH-valid_1;     //被除数前导零的个数
  976. j=DATALENGTH-valid_2;     //除数前导零的个数,作下标指示器
  977. sbits=0;
  978. for(k=j;k<DATALENGTH;k++)
  979. {
  980. if(C[i]>B[j])         //从C和B的最高位开始依次比较对应位的大小,判断是否够减
  981. break;
  982. if(C[i]<B[j])
  983. {
  984. sbits=1;          //如果不够减,那么C就退一位,再做减法
  985. break;
  986. }
  987. i++;j++;              //当C和B的最高位相等时,就比较二者的次高位
  988. }
  989. valid=valid-sbits;
  990. SetZero(buf1);            //buf1清零
  991. for(i=valid;i<DATALENGTH;i++)
  992. {
  993. j=i-valid;
  994. buf1[j]=B[i];         //buf1中存放的是B左移若干位之后得到的值
  995.                       //如果够减,则B左移后最高位与C的最高位对齐,
  996.                       //否则与C的次高位对齐
  997. }
  998. }
  999. else
  1000. IntCpy(buf1,B);           //当C和B的位数相同时,就直接把B放入缓冲区buf1中
  1001. D[DATALENGTH-1-valid]++;      //这里保存的是在某一位上所做的减法的次数,每做一次就加1
  1002. Substract(C,buf1,buf2);       //不论C的长度与B的长度的差是否大于0,都要做减法,直到C<=B
  1003. IntCpy(C,buf2);
  1004. }
  1005. if(cmpval==0)                     //两个数相等
  1006. {
  1007. SetZero(C);                   //余数为0
  1008. D[DATALENGTH-1]++;            //商为1
  1009. }
  1010. }
  1011. /*---------------------------------------------------------------------------
  1012. 功能:随机地产生一个大数奇数,长度为num,最高位不是0,存放在RandomA中
  1013. 入口参数:大数A,长度num
  1014. 返回值:无
  1015. ----------------------------------------------------------------------------*/
  1016. void CRsaA::IntRandom(byteint RandomA,int num)
  1017. {
  1018. int i;
  1019. SetZero(RandomA);                     //将RandomA清零
  1020. while(!(RandomA[DATALENGTH-1]%2))     //判断条件保证RandomA的最后一位数是奇数
  1021. RandomA[DATALENGTH-1]=rand()%10;  //如果最后一位是偶数,则从新产生最后一位
  1022.     while(!(RandomA[DATALENGTH-num]))     //判断条件保证RandomA最高位不是0
  1023. RandomA[DATALENGTH-num]=rand()%10;//如果最高位是0,则从新产生最高位
  1024. i=DATALENGTH-2;
  1025. while(i>=DATALENGTH-num+1)            //循环产生从次低位开始到次高位的所有位上的数
  1026. RandomA[i--]=rand()%10;
  1027. }
  1028. /*---------------------------------------------------------------------------
  1029. 功能:将质数类型B拷贝到A中,实现类型转换
  1030. 入口参数:大数A,质数类型B
  1031. 返回值:无
  1032. ----------------------------------------------------------------------------*/
  1033. //功能:将数B拷贝到大数A,实现类型转换
  1034. void CRsaA::LoadInt(byteint A,mtype B)
  1035. {
  1036. register i,j;
  1037. SetZero(A);                  //A进行清零初始化
  1038. i=DATALENGTH-1;
  1039. j=MLENGTH-1;
  1040. while(j>0)                   //循环拷贝各位数字
  1041. {
  1042. A[i--]=B[j--];
  1043. }
  1044. }
  1045. /*---------------------------------------------------------------------------
  1046. 功能:该函数用来从集合[1,b-1]中产生若干个用于检测的数,存放在Model[]中
  1047. 入口参数:无
  1048. 返回值:无
  1049. ----------------------------------------------------------------------------*/
  1050. void CRsaA::Mdata()
  1051. {
  1052. register i,j;                     //Randomly choose a set of 100 numbers in [1,b-1]
  1053. int k=MLENGTH-2;
  1054. memset(Model,0,TESTNUM*MLENGTH);  //这个函数在这里用来将整个数组清零,进行初始化
  1055. srand( (unsigned)time( NULL ) );  //进行随机函数的初始化
  1056. for(i=0;i<TESTNUM;i++)            //TESTNUM为需要产生的个数
  1057. {
  1058. for(j=MLENGTH-1;j>=k;j--)
  1059. {
  1060. Model[i][j]=rand()%10;    //注意这里与测试素数的程序中的区别,
  1061. }
  1062. if((memcmp(Model[i],mZEROVALUE,MLENGTH))==0)  
  1063. i--;
  1064. k--;                          //保证所产生的数不为0
  1065. if (k<0) k=MLENGTH-2;
  1066. }
  1067. }
  1068. /*---------------------------------------------------------------------------
  1069. 功能:该函数用来将十进制的大整数转换成二进制的数
  1070. 入口参数:需转换的大数B,二进制结果flag[400]
  1071. 返回值:无
  1072. ----------------------------------------------------------------------------*/
  1073. void CRsaA::TransBi(byteint B,signed char flag[400])
  1074. {
  1075. byteint buf;
  1076. byteint result;
  1077. byteint temp;
  1078. register i;
  1079. SetZero(buf);  SetZero(result);  SetZero(temp);
  1080. memset(flag,0,400);                     //将flag数组清零
  1081. i=399;
  1082. IntCpy(buf,B);                          //将B拷贝到buf中
  1083. while(IntCmp(buf,ZEROVALUE)==1)         //如果buf内容为0
  1084. {
  1085. SetMode(buf,TWOVALUE,temp,result);  //将buf进行大数的模2运算,商在result中,余数temp
  1086. flag[i]=temp[DATALENGTH-1];         
  1087. IntCpy(buf,result);                 //对商继续进行模2运算
  1088. i--;
  1089. }
  1090. flag[i]=-1;                             //设置一个标志位,表明二进制数的开始
  1091. }
  1092. /*---------------------------------------------------------------------------
  1093. 功能:该函数用来进行模幂算法,A为底数,模为c,二进制的指数B存放在数组flag中
  1094. 入口参数:底数A,模C,结果D,二进制质数flag[400]
  1095. 返回值:A^B=1(mod C),返回1;A^B=p-1(mod C),返回2;否则返回0
  1096. ----------------------------------------------------------------------------*/
  1097. int CRsaA::PowerMode(byteint A,byteint C,byteint D,signed char flag[400])
  1098. {
  1099. byteint buf;
  1100. byteint result;
  1101. byteint temp,P;
  1102. register i;
  1103. SetZero(D);   SetZero(buf); SetZero(result); SetZero(temp); SetZero(P);  //将D清零
  1104. IntCpy(temp,A);                       //将A的值拷贝到temp中
  1105. if(flag[399]==1)                      //最低位为1,拷贝本身,flag[i]只有1或者0两种情况
  1106. IntCpy(result,A);
  1107. else   //最低位为0,则幂为1
  1108. IntCpy(result,ONEVALUE);
  1109. i=398;
  1110. while(flag[i]!=-1)                    //判断是否已经到达指数尽头
  1111. {
  1112. Multiply(temp,temp,buf);          //temp*temp->buf 
  1113. SetMode(buf,C,temp,P);            //buf%c余数->temp,商->p
  1114. if(flag[i]!=0)                    //如果该位不是0,则将其和前一步低一位的结果进行乘法运算
  1115. {                                 //否则,将其作为该位的模,在高一位的运算中,只要进行一次
  1116. Multiply(temp,result,buf);    //平方运算,就可以得到高一位的模
  1117. SetMode(buf,C,result,P);
  1118. }
  1119. i--;
  1120. }                                     //result中存放的是最终结果
  1121. IntCpy(buf,C);
  1122. IntCpy(D,result);
  1123. Substract(buf,ONEVALUE,temp);
  1124. if(IntCmp(result,ONEVALUE)==0)        //p mod n=1,判断是否有A^B=1(mod C)
  1125. return 1;
  1126. if(IntCmp(result,temp)==0)            //p mod n=-1[p-1=-1(mod p)],判断是否有A^B=p-1(mod C)
  1127. return 2;
  1128. return 0;
  1129. }
  1130. /*---------------------------------------------------------------------------
  1131. 功能:产生一个质数
  1132. 入口参数:大数Prm
  1133. 返回值:产生成功,返回0
  1134. ----------------------------------------------------------------------------*/
  1135. int CRsaA::Prime(byteint Prm)
  1136. {
  1137. int i,k,ok;
  1138. signed char flag[400];
  1139. byteint A,B,D,buf1,buf2;
  1140. SetZero(A); SetZero(B); SetZero(D); SetZero(buf1); SetZero(buf2);
  1141. while(1)                                 //一直循环直到找到一个素数为止
  1142. {
  1143. int pass=0;
  1144. srand( (unsigned)time( NULL ) );     //初始化srand
  1145. IntRandom(B,MLENGTH);                //随机产生一个大数B  try b if prime,B是一个奇数
  1146. IntCpy(Prm,B);                       //将B拷贝到prm中 C=N result prime
  1147. Substract(B,ONEVALUE,buf1);          //将B-ONEVALUE的结果放到buf1中
  1148. SetMode(buf1,TWOVALUE,buf2,B);       //B=(B-1)/2的商,buf2=(B-1)/2的余数=0
  1149. TransBi(B,flag);                     //将B转换为二进制大数
  1150. ok=1;
  1151. for(i=0;i<TESTNUM;i++)
  1152. {
  1153. LoadInt(A,Model[i]);             //将数组Model中的第i+1个数读取到A中
  1154. k=PowerMode(A,Prm,D,flag);       //(A^flag) mod Prm ->D
  1155. if(k!=1 && k!=2)                 //不符合判定规则
  1156. {
  1157. ok=0;
  1158. break;
  1159. }
  1160. if(k==1)                         //判定条件1,G=A^(n-1)/2=1
  1161. {
  1162. }
  1163. if(k==2)                         //判定条件2,G=A^(n-1)/2=p-1
  1164. {
  1165. }
  1166. }
  1167. if (ok)//if(ok && pass_2)
  1168. {
  1169. return 0;
  1170. }//for循环用来检测IntRandom(B,MLENGTH)产生的数B是否是一个素数
  1171. }
  1172. }
  1173. /*---------------------------------------------------------------------------
  1174. 功能:计算公钥PK
  1175. 入口参数:$(r)的值在Rvalue中,私钥SK,公钥PK
  1176. 返回值:成功找到,返回1
  1177. ----------------------------------------------------------------------------*/
  1178. int CRsaA::ComputingPK(byteint Rvalue,byteint SK,byteint PK)
  1179. {
  1180. register i;
  1181. byteint PA,PB,PC,buf1,temp,buf2;
  1182. SetZero(PK); SetZero(PA); SetZero(PB); SetZero(PC); SetZero(buf1);   //清零初始化
  1183. SetZero(temp); SetZero(buf2);
  1184. while(1)
  1185. {
  1186. IntRandom(SK,SKLENGTH);        //随机产生一个大数奇数作为Generated secret key
  1187. IntCpy(PB,SK);
  1188. IntCpy(PA,Rvalue);
  1189. while(1)
  1190. {
  1191. SetMode(PA,PB,PC,PK);     //PA=PB*PK+PC
  1192. i=IntCmp(PC,ONEVALUE);
  1193. if(i==0)                  //PC=1, i=0
  1194. break;                //满足条件,是互质的
  1195. i=IntCmp(PC,ZEROVALUE);
  1196. if(i==0)
  1197. {
  1198. i=-1;                 //PC=0,i=-1
  1199. break;                //不满足互质条件,跳出循环,从新生成一个随机数
  1200. }
  1201. IntCpy(PA,PB);            //按照欧几里的定理继续判断
  1202. IntCpy(PB,PC);
  1203. }
  1204. if(i==0)                      //满足,跳出查找循环
  1205. break;
  1206. }
  1207. IntCpy(temp,ONEVALUE);
  1208. IntCpy(PA,Rvalue);
  1209. IntCpy(PB,SK);
  1210. while(1)
  1211. {
  1212. Multiply(PA,temp,buf1);  //buf1=PA*temp
  1213. Plus(buf1,ONEVALUE,buf2);//buf2=(PA*temp)+1
  1214. SetMode(buf2,PB,buf1,PK);//buf=((PA*temp)+1)%PB
  1215. if(IntCmp(buf1,ZEROVALUE)==0)
  1216. break;
  1217. Plus(temp,ONEVALUE,buf1);
  1218. IntCpy(temp,buf1);
  1219. }
  1220. return 1;                   //SK and PK found
  1221. }
  1222. /*---------------------------------------------------------------------------
  1223. 功能:计算模R
  1224. 入口参数:产生的质数p,q,模R
  1225. 返回值:无
  1226. ----------------------------------------------------------------------------*/
  1227. void CRsaA::ComputingR(byteint p,byteint q,byteint R)
  1228. {
  1229. Multiply(p,q,R);              // R=p*q, public mode number
  1230. }
  1231. /*---------------------------------------------------------------------------
  1232. 功能:计算$(r)
  1233. 入口参数:质数p,质数q,模$(r)放在Rvalue
  1234. 返回值:无
  1235. ----------------------------------------------------------------------------*/
  1236. void CRsaA::ComputingRvalue(byteint p,byteint q,byteint Rvalue)
  1237. {
  1238. byteint buf1,buf2;
  1239. SetZero(buf1); SetZero(buf2);
  1240. Substract(p,ONEVALUE,buf1);   // buf1=p-1
  1241. Substract(q,ONEVALUE,buf2);   // buf2=q-1
  1242. Multiply(buf1,buf2,Rvalue);   // Rvalue=(p-1)*(q-1)
  1243. }
  1244. /*---------------------------------------------------------------------------
  1245. 功能:将接受的字符串转换为大数类型
  1246. 入口参数:大数result,字符串input
  1247. 返回值:数的长度
  1248. ----------------------------------------------------------------------------*/
  1249. int CRsaA::Getinput(byteint result,CString input)
  1250. {
  1251. int i=DATALENGTH,m=0;
  1252. long strlen;
  1253. strlen=input.GetLength();
  1254. if(strlen==0) return 0;
  1255. else
  1256. {
  1257. for(int j=0;j<strlen;j++)
  1258. {
  1259. result[i-strlen+j] = (input.GetAt(j)-'0');
  1260. }
  1261. return j;
  1262. }
  1263. }
  1264. /*---------------------------------------------------------------------------
  1265. 功能:实现加密,解密运算功能
  1266. 入口参数:明文(大数类型source),模R,秘钥key,结果desti
  1267. 返回值:无
  1268. ----------------------------------------------------------------------------*/
  1269. void CRsaA::RsaDo(byteint source,byteint R,byteint key,byteint desti)
  1270. {
  1271. TransBi(key,flag);
  1272. PowerMode(source,R,desti,flag);
  1273. }
  1274. /*---------------------------------------------------------------------------
  1275. 功能:将长整形的数转换为大数类型
  1276. 入口参数:大数类型result,长整形input
  1277. 返回值:成功,返回数的长度,否则返回0;
  1278. ----------------------------------------------------------------------------*/
  1279. int CRsaA::Getinput1(byteint result,unsigned long input)
  1280. {
  1281. int i=DATALENGTH-1,m=0;
  1282. long j=0;
  1283. int k=0;
  1284. if(input)
  1285. {
  1286. do
  1287. {
  1288. j=input/10;
  1289. k=input-j*10;
  1290. result[i]=k;
  1291. i--;
  1292. m++;
  1293. input=j;
  1294. }while(j);
  1295. return m;
  1296. }
  1297. else
  1298. return 0;
  1299. }
  1300. /*---------------------------------------------------------------------------
  1301. 功能:将十六进制的串转换为数值
  1302. 入口参数:字符串指针
  1303. 返回值:成功,返回数
  1304. ----------------------------------------------------------------------------*/
  1305. unsigned long CRsaA::Os2ip(unsigned char* pstr)
  1306. {
  1307. unsigned long ch=0;
  1308. unsigned int j=0;
  1309. unsigned long k=1;
  1310. for(int i=0;i<4;i++)
  1311. {
  1312. j = (unsigned int) (*(pstr+3-i));
  1313. /* if( (*(pstr+3-i))>='0'&&(*(pstr+3-i))<='9')
  1314. j = (*(pstr+3-i)) - '0';
  1315. if( (*(pstr+3-i))>='a'&&(*(pstr+3-i))<='f') 
  1316. j = (*(pstr+3-i)) - 'a'+10;
  1317. if( (*(pstr+3-i))>='A'&&(*(pstr+3-i))<='F')
  1318. j = (*(pstr+3-i)) - 'A'+10;*/
  1319. ch += j*k;
  1320. k*=256;
  1321. }
  1322. return ch;
  1323. /*---------------------------------------------------------------------------
  1324. 功能:将数串转换为相应的字符串
  1325. 入口参数:字符串str
  1326. 返回值:返回转换的结果;
  1327. ----------------------------------------------------------------------------*/
  1328. CString CRsaA::Ip2os(CString str)
  1329. {
  1330. int strlen=str.GetLength(),quotient=0,remainder=0;
  1331. unsigned long num=0,temp=0;
  1332. unsigned int k=1;
  1333. CString strResult="";
  1334. for(int i=strlen;i>0;i--)  //得到相应的数字串,存放在num中
  1335. {
  1336. temp = (str.GetAt(i-1) - '0');
  1337. num += temp*k;
  1338. k *= 10;
  1339. }
  1340. //采用模除的方式,求得相应的十六进制数
  1341. for(int j=0;j<4;j++)
  1342. {
  1343. quotient = num/256;
  1344. remainder = num - quotient*256;
  1345. /*if(remainder>=0&&remainder<=9)
  1346. strResult.Insert(0,(remainder+'0'));
  1347. if(remainder>=10&&remainder<=15)
  1348. strResult.Insert(0,(remainder-10+'a'));*/
  1349. strResult.Insert(0,(unsigned char)remainder);
  1350. num = quotient;
  1351. }
  1352. return strResult; 
  1353. }
  1354. /*---------------------------------------------------------------------------
  1355. 功能:产生RSA秘钥对
  1356. 入口参数:存放结果的字符串地址 
  1357. 返回值:无
  1358. ----------------------------------------------------------------------------*/
  1359. void CRsaA::GenKeys(CString& pk,CString& sk,CString& R)
  1360. {
  1361. byteint m_p,m_q,m_R,m_Rvalue,m_PK,m_SK;
  1362. SetZero(m_p);      //对大数变量进行清零初始化
  1363. SetZero(m_q);
  1364.     SetZero(m_R);
  1365.     SetZero(m_Rvalue);
  1366.     SetZero(m_PK);
  1367.     SetZero(m_SK);
  1368. Mdata();         //生成比较数表
  1369. AfxMessageBox("开始计算质数P...");
  1370. Prime(m_p);        //生成素数p q
  1371. AfxMessageBox("开始计算质数Q...");
  1372. Prime(m_q);
  1373. AfxMessageBox("开始计算模R...");
  1374. ComputingR(m_p,m_q,m_R); //计算模R
  1375. AfxMessageBox("开始计算模r");
  1376. ComputingRvalue(m_p,m_q,m_Rvalue);  //计算r
  1377. AfxMessageBox("开始计算秘钥SK,PK");
  1378. ComputingPK(m_Rvalue,m_PK,m_SK);    // Generate PK and SK
  1379. //CGenKeyBusyDlg dlg1;
  1380. //g1.DoModal();
  1381. R=PrtInt(m_R);
  1382. pk=PrtInt(m_PK);
  1383. sk=PrtInt(m_SK);
  1384. return ;
  1385. }
  1386. /*---------------------------------------------------------------------------
  1387. 功能:实现加密功能接口
  1388. 入口参数:明文字符串source,模字符串R,秘钥字符串key,结果字符串数组result
  1389. 返回值:无
  1390. ----------------------------------------------------------------------------*/
  1391. int CRsaA::RsaEncrypt(CString& source,const char *key,const char *R,CStringArray& result)
  1392. {
  1393. unsigned char* pstr;
  1394. int j;//sourcelen,j;
  1395. byteint m_key,m_R,desti,aa;
  1396. SetZero(desti);              //将大数变量清零初始化
  1397. SetZero(aa);
  1398. //SetZero(bb);
  1399. SetZero(m_key);
  1400. SetZero(m_R);
  1401. pstr = (unsigned char*)(LPCTSTR)source;               //得到字符串数据的指针
  1402. j = source.GetLength()/4;    //得到数组的元素个数
  1403. result.SetSize(j,1);
  1404. Getinput(m_key,key);             //将字符串转换为大数类型
  1405. Getinput(m_R,R);
  1406. for(int i=0;i<j;i++)
  1407. {
  1408. Getinput1(desti,Os2ip(pstr));    //将四个字节的输入转换为大数类型数值
  1409. RsaDo(desti,m_R,m_key,aa);  //进行加密运算
  1410. result.SetAt(i,PrtInt(aa));          //将结果存放到数组中
  1411. SetZero(desti);  SetZero(aa);
  1412. pstr += 4;
  1413. }
  1414. return j;
  1415. }
  1416. /*---------------------------------------------------------------------------
  1417. 功能:实现解密功能接口
  1418. 入口参数:密文字符串数组source,秘钥字符串sk,模字符串R,
  1419. 返回值:结果字符串数组result
  1420. ----------------------------------------------------------------------------*/
  1421. CString CRsaA::RsaDecrypt(CStringArray& source,const char* sk,const char* R)
  1422. {
  1423. int index=0;
  1424. CString result;
  1425. byteint m_sk,m_r,desti,aa;
  1426. SetZero(m_sk);  SetZero(m_r); SetZero(desti); SetZero(aa);  //SetZero(bb);
  1427. index=source.GetSize();   //得到数组的元素个数
  1428. Getinput(m_sk,sk);        //将字符串转换为大数类型
  1429. Getinput(m_r,R);
  1430. for(int i=0;i<index;i++)
  1431. {
  1432. Getinput(desti,source.GetAt(i));   //将加密结果转换为大数类型
  1433. RsaDo(desti,m_r,m_sk,aa);          //解密运算
  1434. result += Ip2os(PrtInt(aa));       //组合初始明文
  1435. SetZero(aa);  SetZero(desti);
  1436. }
  1437. return result;        //返回明文串
  1438. }
  1439. /*---------------------------------------------------------------------------
  1440. 功能:生成一个秘钥存贮文件
  1441. 入口参数:无
  1442. 返回值:无
  1443. ----------------------------------------------------------------------------*/
  1444. void CRsaA::GenKeysTable()
  1445. {
  1446. CStringArray RArray,SKArray,PKArray;
  1447. CString r,pk,sk;
  1448. int j=1,i;      //参数j表示产生的秘钥对的个数
  1449. unsigned char strlength;
  1450. //设置数组的元素个数
  1451. RArray.SetSize(j,1); SKArray.SetSize(j,1); PKArray.SetSize(j,1);
  1452. /*-----------------------------------------------------------------------
  1453. 文件格式为:
  1454. 长度   秘钥   长度   秘钥......
  1455. ----   ----   ----   ----
  1456. 1byte  nbyte  1byte  nbyte       (中间无空格,R,SK,PK)
  1457. */
  1458. CFile file;
  1459. for(i=0;i<j;i++)
  1460. {
  1461. GenKeys(pk,sk,r);  //循环产生秘钥
  1462. RArray.SetAt(i,r); SKArray.SetAt(i,sk); PKArray.SetAt(i,pk);
  1463. }
  1464. if(file.Open("c:\key.txt",CFile::modeCreate|CFile::modeReadWrite)==0)
  1465. {
  1466. AfxMessageBox("open file error!");  //打开文件失败
  1467. return;
  1468. }
  1469. for(i=0;i<j;i++)
  1470. {                //循环写入结果
  1471. strlength = (unsigned char)(RArray.GetAt(i)).GetLength();
  1472. file.Write(&strlength,1);
  1473. file.Write(RArray.GetAt(i),(RArray.GetAt(i)).GetLength());
  1474. strlength = (unsigned char)(SKArray.GetAt(i)).GetLength();
  1475. file.Write(&strlength,1);
  1476. file.Write(SKArray.GetAt(i),(SKArray.GetAt(i)).GetLength());
  1477. strlength = (unsigned char)(PKArray.GetAt(i)).GetLength();
  1478. file.Write(&strlength,1);
  1479. file.Write(PKArray.GetAt(i),(PKArray.GetAt(i)).GetLength());
  1480. }
  1481. file.Close();
  1482. }
  1483. void CRsaA::LoadKeysFromFile(CString& r,CString& sk,CString& pk)
  1484. {
  1485. int            j=10,len;
  1486. char           *pbuffer;
  1487. unsigned char  strlen1;
  1488. CFile          file;
  1489. CFileException e;
  1490. CString        strFileName;
  1491. if(file.Open("c:\key.txt",CFile::modeRead)==0)
  1492. {
  1493. AfxMessageBox("File(key.txt)could not be opened" );
  1494. }
  1495. file.Read(&strlen1,1);  //读出R长度
  1496. len = (int)strlen1;
  1497. pbuffer = new char[len+1];
  1498. pbuffer[len]='';
  1499. file.Read(pbuffer,len);  //读出R
  1500. r=pbuffer;
  1501. delete pbuffer;
  1502. file.Read(&strlen1,1);  //读出SK长度
  1503. len = (int)strlen1;
  1504. pbuffer = new char[len+1];
  1505. pbuffer[len]='';
  1506. file.Read(pbuffer,len);  //读出SK
  1507. sk=pbuffer;
  1508. delete pbuffer;
  1509. file.Read(&strlen1,1);  //读出PK长度
  1510. len = (int)strlen1;
  1511. pbuffer = new char[len+1];
  1512. pbuffer[len]='';
  1513. file.Read(pbuffer,len);  //读出PK
  1514. pk=pbuffer;
  1515. delete pbuffer;
  1516. file.Close();
  1517. }