RSA加密原理

首先先解决这样一个问题,b和m已知求满足下面条件的x,

xkb(modm) x k ≡ b ( mod m )

这个问题若是没有限制条件的话会变得很棘手,那么假设条件变得更强让gcd(b,m)=1;便会想到利用欧拉函数求出 ϕ(m) ϕ ( m ) ,之后解下面的不定方程。

xk x k - y y ϕ(m) ϕ ( m ) =1

假设gcd(k, ϕ(m) ϕ ( m ) )=1,那么一定存在一组非负解x=a,y=b;使得

(xk)axx(ϕ(m)b)ba(modm) ( x k ) a ≡ x ⋅ x ( ϕ ( m ) ⋅ b ) ≡ b a ( mod m )

则有
xba(modm) x ≡ b a ( mod m )

则可以计算出 x=bamodm x = b a m o d m ,这样便给出了计算模m的k次幂的方法。
于是问题就转化成了如何求 xk x k - y y ϕ(m) ϕ ( m ) =1,以及 ϕ(m) ϕ ( m ) 前者十分好求利用扩展欧几里得算法可以快速求出

void _exgcd(ll a,ll b,ll &x,ll &y)
{if (!b){x=1;y=0;return;}_exgcd(b,a%b,y,x);y-=x*(a/b);}

后者则要用到求 ϕ(m) ϕ ( m ) 的公式:
ϕ(m)=(p1k1p1k11)(p2k2p2k21)...(pnknpnkn1) ϕ ( m ) = ( p 1 k 1 − p 1 k 1 − 1 ) ⋅ ( p 2 k 2 − p 2 k 2 − 1 ) . . . ( p n k n − p n k n − 1 ) (p为m的因子)
m很小时对于m的因数分解是非常容易的,但是一旦m很大时便非常困难
RSA加密的办法就是利用以上思路,取两个质数p q并求出 ϕ(m)=(p1)(q1) ϕ ( m ) = ( p − 1 ) ⋅ ( q − 1 ) 再取一个k与 ϕ(m) ϕ ( m ) 互素,则可以则对 任意x xkb(modm) x k ≡ b ( mod m ) 都可以求出一个对应的b来,b就是加密后的密文。
例如:取质数p=9973,q=10039 则m=p q=100118947 (p-1)(q-1)=100098936
在取k=364213;则构成以套加密体系:

x(364213)b(mod100118947) x ( 364213 ) ≡ b ( mod 100118947 )

假设密文M为:GBDWG(对应关系为A=30,B=31……Z=55)
M=3631335236;将密文分为小于q长度的几部分,分别为 36313352 和36
则有
36313352(364213)66250740(mod100118947) 36313352 ( 364213 ) ≡ 66250740 ( mod 100118947 )

36(364213)35570701(mod100118947) 36 ( 364213 ) ≡ 35570701 ( mod 100118947 )

b=66250740与35570701就是密文
解密的过程就是求
x(364213)b(mod100118947) x ( 364213 ) ≡ b ( mod 100118947 )
的过程,上面已经说过了。
下面是实现的代码(写的很挫)。。。
加密:

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;
#define ll long long
#define M 100118947
#define K 364213
#define KK 79921
#define MM 163276871
ll pow(ll x,ll k,ll p){if(!k)return 1;if (k&1) return x*pow(x,k-1,p)%p;ll t=pow(x,k/2,p);return t*t%p;}
char str[1000000];
ll rec[10000000],rec2[10000000];
int main()
{
     ll a,b,c,p;int cnt=0;
     gets(str);
     int len=strlen(str);
     for (int i=0;i<len;i++) if (str[i]==' ') rec[i]=70;else rec[i]=str[i]-'A'+30;
     for (int i=0;i<len;i=i+4){
            for(int j=i;j<min(i+4,len);j++)
            {
             rec2[cnt]=rec2[cnt]*100+rec[j];
            }
            cnt++;
        }
        cout<<cnt<<endl;
    for (int i=0;i<cnt;i++)
    {
        cout<<pow(rec2[i],K,M)%M<<endl;
    }
}

解密

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string>
#include<string.h>
#define B 100098936
#define M 100118947
#define A 364213
#define AA 79921
#define MM 163276871
#define BB 163251312
using namespace std;
#define ll long long
#define F(x,a,b) for (ll x=a;x<=b;x++)
ll x,y,a,b;
void _exgcd(ll a,ll b,ll &x,ll &y){if (!b){x=1;y=0;return;}_exgcd(b,a%b,y,x);y-=x*(a/b);}
void check(){if ((A*x+b*y)-1){if(!(A*(-x)+b*y-1)){x=-x;return;}else{if (!((A*x+b*(-y))-1)){y=-y;return;}else {x=-x;y=-y;}}}}
ll pow(ll x,ll k,ll p){if (!k) return 1;if (k&1) return x*pow(x,k-1,p)%p;else{ll t=pow(x,k/2,p);return t*t%p;}}
int rec[10000000],rec2[10000000];
int main()
{
    ll q,p,m;
    char strr[1000000];
    int len; int cnt1=-1;int cnt2=0;
    int nn; cin>>nn;
    while (nn--)
    {
      cin>>strr;
      len=strlen(strr);
      for (int i=0;i<len;i++)
      {
         rec[cnt2]=rec[cnt2]*10+strr[i]-'0';
      }
      cnt2++;
    }
      F(o,0,cnt2-1)
     {
        b=-B;
        _exgcd(A,b,x,y);
       check();

        if (x<0) x+=abs(b);
       // if (y<0) y+=abs(A);
        ll t=pow(rec[o],x,M)%M;
        char str[10];
        cnt1=-1;
        while (t)
        {
            cnt1++;
           if (t%100!=70)
            str[cnt1]=t%100+'A'-30;
            else str[cnt1]=' ';
            t/=100;
        }
        for (int i=cnt1;i>=0;i--) printf("%c",str[i]);
      }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值