RSA加密原理

首先先解決這樣一個問題,b和m已知求滿足下面條件的x,

xkb(modm)

這個問題若是沒有限制條件的話會變得很棘手,那麼假設條件變得更強讓gcd(b,m)=1;便會想到利用歐拉函數求出ϕ(m) ,之後解下面的不定方程。

xk - yϕ(m) =1

假設gcd(k,ϕ(m) )=1,那麼一定存在一組非負解x=a,y=b;使得

(xk)axx(ϕ(m)b)ba(modm)

則有
xba(modm)

則可以計算出x=bamodm ,這樣便給出了計算模m的k次冪的方法。
於是問題就轉化成了如何求 xk -yϕ(m) =1,以及ϕ(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)=(p1k1p1k11)(p2k2p2k21)...(pnknpnkn1) (p爲m的因子)
m很小時對於m的因數分解是非常容易的,但是一旦m很大時便非常困難
RSA加密的辦法就是利用以上思路,取兩個質數p q並求出ϕ(m)=(p1)(q1) 再取一個k與ϕ(m) 互素,則可以則對 任意x xkb(modm) 都可以求出一個對應的b來,b就是加密後的密文。
例如:取質數p=9973,q=10039 則m=p q=100118947 (p-1)(q-1)=100098936
在取k=364213;則構成以套加密體系:

x(364213)b(mod100118947)

假設密文M爲:GBDWG(對應關係爲A=30,B=31……Z=55)
M=3631335236;將密文分爲小於q長度的幾部分,分別爲 36313352 和36
則有
36313352(364213)66250740(mod100118947)

36(364213)35570701(mod100118947)

b=66250740與35570701就是密文
解密的過程就是求
x(364213)b(mod100118947)
的過程,上面已經說過了。
下面是實現的代碼(寫的很挫)。。。
加密:
#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]);
      }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章