输入注意 e p q三者要满足的要求,首先p q为大素数,所以会有检验是否为素数的子函数,给出的代码没有附上,可以自行写并不难。
代码总体有三个功能函数——欧几里得获取私钥,平方乘加密,模重复解密。
完整代码给出:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
int pingfnagX_56(int a_56,int b_56,int c_56);
void MochongFU_56(int a_56,int b_56,int c_56);
int olg_56( int e_56, int h_56);
int main() {
int p, q, e, m, a, h, c, n, d;
int a1, m1, n1;
int i, j, cnt, quotient, tmp, s1 = 1, s2 = 1,mm[20];
printf("RSA加密请顺序输入公钥,两素数:e,p,q:");
scanf("%d", &e);
scanf("%d", &p);
scanf("%d", &q);
n = p * q; //计算n
h = (p - 1) * (q - 1); // 计算Eular函数值φ(n)
d = olg_56(e, h); // 计算d的值
printf("==================================================\n");
printf("计算得模数n为:%d\n", n);
printf("计算得φ(n)为:%d\n", h);
printf("计算私钥d为:%d\n", d);
printf("==================================================\n");
printf("请输入要加密的明文m:");
scanf("%d", &m);
printf("RSA加密模幂运算底数 指数 模数: %d %d %d\n",m,e,n);
c=pingfnagX_56(m,e,n);
printf("RSA解密 模幂运算底数 指数 模数:%d %d %d\n",c,d,n);
MochongFU_56(c,d,n);
}
int pingfnagX_56(int a_56,int b_56,int c_56)
{
int a1, m1, n1, a2, m2, n2;
int i, j, cnt, quotient, tmp, s1 = 1, s2 = 1;
int mm[20];
a1 = a2 = a_56;
m1 = m2 = b_56;
n1 = n2 = c_56;
quotient = m1;
for (i = 0; quotient != 0; i++)
{
mm[i] = quotient % 2;
quotient = quotient / 2;
}
j = i;
for (i = 0; i < j / 2 ; i++)
{
tmp = mm[i];
mm[i] = mm[j-i-1];
mm[j-i-1] = tmp;
}
cnt = j;
printf("平方乘算法:\n");
for (i = 0; i < j; i++)
{
s2 = (s2 * s2) % n2;
if (mm[i] == 1)
{
s2 = (s2 * a1) % n2;
}
printf("i = %d, %d\n", cnt-1, s2);
cnt--;
}
printf("加密后密文为: %d\n", s2);
return s2;
}
void MochongFU_56(int a_56,int b_56,int c_56)
{
int a1, m1, n1;
int i, j, cnt, quotient, tmp, s1 = 1, s2 = 1;
int mm[20];
a1 = a_56;
m1 = b_56;
n1 = c_56;
quotient = m1;
for (i = 0; quotient != 0; i++)
{
mm[i] = quotient % 2;
quotient = quotient / 2;
}
j = i;
printf("模重复平方根算法:\n");
for (i = 0; i < j; i++)
{
if (mm[i] == 1)
{
s1 = (s1 * a1) % n1;
}
a1 = (a1 * a1) % n1;
printf("i = %d, s = %d\n", i, s1);
}
printf("解密后的明文m为:%d\n", s1);
}
int olg_56( int e_56, int h_56) //欧几里得 辗转相除法
{
int i;
int k=1;//计算商的个数
int d;
int a[50] = { 0 }, r[50] = { 0 }, b[50] = { 0 };//a 商 r 余
a[0] = h_56/e_56; //取第一个商
r[0] = h_56%e_56; //取第一个余数
a[1] = e_56/r[0];//取第二个商
r[1] = e_56%r[0];//取第二个余数
for (i=2;;i++)
{
a[i]=r[i-2]/r[i-1];
r[i]=r[i-2]%r[i-1];
if(r[i]==0)
break;
k++;
}
b[0] = a[k];
b[1] = b[0]*a[k-1]+1;
for (i = 2; i <= k; i++)
{
b[i] = a[k-i] * b[i-1] + b[i-2];
}
if ((k-1)%2!=0) // 计算商的时候最后一个余数为零的商除去
d = h_56-b[k]; //当K-1为奇数时
if ((k-1)%2==0)
d = b[k]; //当k-1为偶数时
return d;
}
学号是 56 测试一下,注意 你输入的e p q有些事不可运行的