int范围内的RSA

这些话加在前面吧,因为这是修改的内容

程序出现了BUG

在计算幂取模的时候出现了错误

其实最重要的是私钥d可能会是负数,我并没有取整数的模(一直错在这,我以为可以。。。。)

其实此次学习最重要的是发现了-1右移等于-1吧。。。

代码我就直接替换掉新的了。。。

花了几天的时间终于搞定了NSGA-II,周三晚开完会讨论之后无误就来发表

今晚烦燥,就来复习信安基础了,做了个简单的RSA

只能计算Int范围内的,即p,q的选取在int范围内而且p*q不能超过int

写了也算一个学习经历吧,就到这里记录一下

代码里Miller_Robin是不需要的,只是写一下

Miller_Robin和Prime_Linear函数都是直接贴模板的,稍微作了点改动吧~

其实一看就知道,没注释的就是我写的,注释的就不是我的(太懒了,不喜欢写注释,反正这个写着自己看Orz)

其实为了自己看的懂,还做了“无用功”,有些输入的提示

下面是结果

p=11,q=17

e=7   --->通过扩展欧几里得求出 d=23

明文M=88   --->C=11

密文C=11   --->M=88

如果哪位对弱菜我的小程序感兴趣,测试之后发现有BUG还望提出啊Orz.........................

下面就上代码了~~~~

#include<cstdio>
#include<cstring>
#include<ctime>
#include<cstdlib>


const int maxn = 10000000;
bool IsNotPrime[maxn]; // 判断是否为素数.
int PrimeList[maxn]; // 素数列表.
int PrimeNum;

void Prime_Linear(void)
{ // 速度比朴素筛法快2倍以上,该筛法进行稍微修改即可用于求欧拉函数Phi[].
    int i, j;
    memset(IsNotPrime, 0, sizeof(IsNotPrime)); // 初始赋值所有数都是素数.
    IsNotPrime[1] = 1; IsNotPrime[0] = 1; // 0和1不是素数.
    PrimeList[0]=2;
    for (i = 4; i < maxn; i += 2) IsNotPrime[i] = 1; // 除2以外的所有偶数都不是素数.
    PrimeNum = 1;
    for (i = 3; i < maxn; i += 2)
    {
        if (!IsNotPrime[i])
        { // 如果是素数则加入素数列表.
            PrimeList[PrimeNum++] = i;
        }
        // 注意:这里与朴素筛法不同,即使合数也要进行筛.
        // 因为这里素数只筛它的素数倍,那么有些合数就可能没被筛掉.
        // 而这些合数就需要合数来晒,而且只要筛到它的最小质因子倍即可(想想为什么?).
        for (j = 0; j < PrimeNum && i * PrimeList[j] < maxn; j++)
        {
            IsNotPrime[i * PrimeList[j]] = 1;
            if (i % PrimeList[j] == 0)
            { // 说明PrimeList[j]是i的最小质因子,即i * PrimeList[j]的最小质因子,则跳出.
                break;
            }
        }
    }
}

int Modular_Exponent(int a, int b, int MOD)
{ // a ^ b mod MOD.
    int temp(1);
    int aa(a);
    while (b)
    {
        if (b & 1) temp = 1LL * temp * aa % MOD;
        aa = 1LL * aa * aa % MOD;
        b >>= 1;
    }
    return temp;
}

// Carmicheal number: 561,41041,825265,321197185
bool Miller_Rabin(int n, int time = 20)
{ // 如果是素数,则返回1,否则返回0.
    if (n == 1 || (n != 2 && !(n % 2)) || (n != 3 && !(n % 3))
        || (n != 5 && !(n % 5)) || (n != 7 && !(n % 7)))
        return 0;
    while (time--)
    {
        if (Modular_Exponent(((rand() & 0x7fff << 16) +
            rand() & 0x7fff + rand() & 0x7fff) % (n-1) + 1, n - 1, n) != 1)
            return 0;
    }
    return 1;
}
void ext_gcd(int a,int b,int&x,int&y){
    if(!b){
        x=1,y=0;
        return;
    }
    ext_gcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=t-a/b*y;
}
int gcd(int a,int b){return b?gcd(b,a%b):a;}
int init(int p,int q,int &e){
    //Prime_Linear();
    int eular_n=(p-1)*(q-1);
    puts("please input a prime nunber as your public key");
    while(true){
        scanf("%d",&e);
        if(IsNotPrime[e] || gcd(e,eular_n)!=1){
            puts("wrong input,please input again~");
            continue;
        }
        break;
    }
    int d,y;
    ext_gcd(e,eular_n,d,y);
    return (d+eular_n)%eular_n;
}
void exponent(int a,const int e,int n,int select){
    int ret=1;
    int b=e;
    for(;b;b=(b==-1)?0:(b>>1),a=(int)((long long)a)*a%n)
    //for(;b;b/=2,a=(int)((long long)a)*a%n)
        if(b&1)
            ret=(int)((long long)ret)*a%n;
    switch(select){
    case 1:printf("your ciphertext is %d\n",ret%n);break;
    case 2:printf("your plaintext is %d\n",ret%n);
    }
}

int main(){
    Prime_Linear();//初始化,素数打表
    //for(int i=0;i<10;i++)printf("%d\n",PrimeList[i]);
    //for(int i=0;i<10;i++)printf("%d\n",IsNotPrime[i]);
    int p,q,e;
loop:
    puts("please input two prime number");
    scanf("%d%d",&p,&q);
    //if(!Miller_Rabin(p)||!Miller_Rabin(q) ||
    if(IsNotPrime[p] || IsNotPrime[q] ||
        (long long)p+(long long)q>(~0U>>1)){
            puts("your inputs is wrong,please input again~");
            goto loop;
    }
    int d=init(p,q,e);
    //printf("%d\n",d);
    int select;
    while(true){
        puts("please select it");
        puts("1:  encryption");
        puts("2:  decryption");
        while(true){
            scanf("%d",&select);
            if(select!=1 && select!=2){
                puts("wrong input,please input again~");
                continue;
            }
            break;
        }
        //puts("yes");
        switch(select){
        case 1:puts("please input a message");break;
        case 2:puts("please input a cyphertext");
        }
        int m;
        scanf("%d",&m);
        switch(select){
        case 1:exponent(m,e,p*q,select);break;
        case 2:exponent(m,d,p*q,select);
        }
    }

}
原文地址:https://www.cnblogs.com/louzhang/p/2476498.html