• RSA算法


    函数入口参数

    void RSA(LL data,int mode,LL d,LL e,LL n)

      data为要加密或解密的数,mode为模式(1加密,0解密),{e,n}为公钥,完成加密,{d,n}为私钥,完成解密。

    算法流程

      1.任取两个素数p,q;

      2.计算n=p*q;

      3.计算N=(p-1)*(q-1);

      4.选取一奇数e,使得GCD(e,N)=1;

      5.计算d,使得(e*d)%N=1,d的计算方法如下:

        1)n1= N,n2=e,b1=0,b2=1
        2)求 s 和 r,使 n1 = s×n2 + r
        3)如果r≠0 则n1 =n2,n2=r,t=b2,b2=b1 - s×b2,b1=t 转2)
        4)如果n2≠1,则不存在d

        5)如果b2<0 则 b2 = b2 + N
        6)d=b2

      6.加密或解密,加密算法为C=(M^e) mod n,解密算法为M=(C^d) mod n;

    完整代码

    View Code
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    #define MAXN 1000000
    
    typedef __int64 LL;
    
    int Prime[78500];
    char Flag[MAXN];
    int Cnt;
    
    void MakePrime()
    {
        int i,j;
        for(i=2; i<MAXN; ++i)
        {
            if(!Flag[i])
            {
                Prime[Cnt++]=i;
                for(j=i<<1; j<MAXN; j+=i)
                {
                    Flag[j]=1;
                }
            }
        }
        return;
    }
    
    LL GCD(LL a,LL b)
    {
        while(b!=0)
        {
            if(a>b)
            {
                a-=b;
            }
            else
            {
                b-=a;
            }
        }
        return a;
    }
    
    LL CalD(LL r,LL e)
    {
        LL n1=r,n2=e,b1=0,b2=1,t,S,R;
        S=n1/n2;
        R=n1%n2;
        while(R)
        {
            n1=n2;
            n2=R;
            t=b2;
            b2=b1-S*b2;
            b1=t;
            S=n1/n2;
            R=n1%n2;
        }
        if(n2!=1)
        {
            return -1;
        }
        if(b2<0)
        {
            b2+=r;
        }
        return b2;
    }
    
    LL ModExp(LL A,LL N,LL M)
    {
        LL ret=1;
        while(N)
        {
            if(N&1)
            {
                ret=(ret%M*A%M)%M;
            }
            A=(A*A)%M;
            N>>=1;
        }
        return ret;
    }
    
    LL EnCode(LL M,LL e,LL n)
    {
        return ModExp(M,e,n);
    }
    
    LL DeCode(LL C,LL d,LL n)
    {
        return ModExp(C,d,n);
    }
    
    void RSA(LL data,int mode,LL d,LL e,LL n)
    {
        LL r;
        r=mode?EnCode(data,e,n):DeCode(data,d,n);
        puts(mode?"密文;":"明文:");
        printf("%I64d\n",r);
        return;
    }
    
    int main()
    {
        int p,q,M;
        LL n,r,e,d,Input;
        MakePrime();
        //srand((unsigned int)time(NULL));
        p=Prime[rand()%Cnt];
        q=Prime[rand()%Cnt];
        n=(LL)p*q;
        r=(LL)(p-1)*(q-1);
        for(e=3;; e+=2)
        {
            if(GCD(e,r)==1)
            {
                break;
            }
        }
        d=CalD(r,e);
        while(scanf("%I64d %d",&Input,&M)!=EOF)
        {
            RSA(Input,M,d,e,n);
        }
        return 0;
    }
  • 相关阅读:
    博客是一种心情
    双显示器和双鼠标
    C++ Primer Plus 第六版 代码笔记
    Bug,昂首走进2005
    让万能五笔2004免费版改首页的功能见鬼去吧。
    Gmail提供POP3和SMTP已经老长时间了
    快过年回家了,发点实用的东西给大家
    关于博客园Post的时候排版的一点小建议
    在.Net下进行MicroStation(GG)的开发(一)
    验证域的另一方法
  • 原文地址:https://www.cnblogs.com/NoSoul/p/2757290.html
Copyright © 2020-2023  润新知