较为简略的RSA算法实现分享

输入注意 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有些事不可运行的
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值