zoukankan      html  css  js  c++  java
  • BZOJ4522:[CQOI2016]密钥破解(Pollard-Rho,exgcd)

    Description

    一种非对称加密算法的密钥生成过程如下:
    1. 任选两个不同的质数 p ,q
    2. 计算 N=pq , r=(p-1)(q-1)
    3. 选取小于r ,且与 r 互质的整数 e 
    4. 计算整数 d ,使得 ed≡1 mod r
    5. 二元组 (N,e) 称为公钥,二元组 (N,d) 称为私钥

    当需要加密消息 n 时(假设 n 是一个小于 N 整数,因为任何格式的消息都可转为整数表示),使用公钥 (N,e),按照

    n^e≡c mod N 运算,可得到密文 c 。

    对密文 c 解密时,用私钥 (N,d) ,按照c^d≡n mod N 运算,可得到原文 n 。
     
    算法正确性证明省略。

    由于用公钥加密的密文仅能用对应的私钥解密,而不能用公钥解密,因此称为非对称加密算法。通常情况下,公钥由消息的接收方公开,而私钥由消息的接收方自己持有。这样任何发送消息的人都可以用公钥对消息加密,而只有消息的接收方自己能够解密消息。

    现在,你的任务是寻找一种可行的方法来破解这种加密算法,即根据公钥破解出私钥,并据此解密密文。

    Input

    输入文件内容只有一行,为空格分隔的j个正整数e,N,c。N<=2^62,c<N

    Output

    输出文件内容只有一行,为空格分隔的k个整数d,n。

    Sample Input

    3 187 45

    Sample Output

    107 12
    //样例中 p = 11, q = 17

    Solution

    一开始被题意吓到了……

    其实仔细捋一下,就按如下步骤就完了。

    因为有$N$,所以可以$Pollard-Rho$求出来$p$和$q$。

    求出来$p$和$q$,就可以求出来$r$。

    求出来$r$,就可以$exgcd$解出来$d$.

    求出来$d$,就可以用快速幂求出来$n$。

    然后这题就没了……

    Code

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 #include<algorithm>
     5 #define LL long long
     6 using namespace std;
     7 
     8 LL T,maxn,x;
     9 LL prime[10]={2,3,5,7,11,13,17,19,23};
    10 
    11 LL Mul(LL a,LL b,LL MOD)
    12 {
    13     LL tmp=a*b-(LL)((long double)a*b/MOD+0.1)*MOD;
    14     return tmp<0?tmp+MOD:tmp;
    15 }
    16 
    17 LL Qpow(LL a,LL b,LL MOD)
    18 {
    19     LL ans=1;
    20     while (b)
    21     {
    22         if (b&1) ans=Mul(ans,a,MOD);
    23         a=Mul(a,a,MOD); b>>=1;
    24     }
    25     return ans;
    26 }
    27 
    28 LL gcd(LL a,LL b) {return b==0?a:gcd(b,a%b);}
    29 
    30 bool Miller_Rabin(LL n)
    31 {
    32     if (n==2) return 1;
    33     if (n<2 || n%2==0) return 0;
    34     LL m=n-1,l=0;
    35     while (m%2==0) ++l, m>>=1;
    36     for (int i=0; i<9; ++i)
    37     {
    38         LL p=prime[i],w=Qpow(p,m,n);
    39         if (w==1 || w==n-1 || p==n) continue;
    40         for (int j=1; j<=l; ++j)
    41         {
    42             LL u=Mul(w,w,n);
    43             if (u==1 && w!=1 && w!=n-1) return 0;
    44             w=u;
    45         }
    46         if (w!=1) return 0;
    47     }
    48     return 1;
    49 }
    50 
    51 LL Pollard_Rho(LL n,LL c)
    52 {
    53     LL x=rand()%n,y=x,p=1,k=2;
    54     for (LL i=1; p==1; ++i)
    55     {
    56         x=(Mul(x,x,n)+c)%n;
    57         p=x>y?x-y:y-x;
    58         p=gcd(p,n);
    59         if (i==k) y=x,k+=k;
    60     }
    61     return p;
    62 }
    63 
    64 void Solve(LL n)
    65 {
    66     if (n==1) return;
    67     if (Miller_Rabin(n)) {maxn=max(maxn,n); return;}
    68     LL t=n;
    69     while (t==n) t=Pollard_Rho(n,rand()%(n-1)+1);
    70     Solve(t); Solve(n/t);
    71 }
    72 
    73 int main()
    74 {
    75     scanf("%lld",&T);
    76     while (T--)
    77     {
    78         scanf("%lld",&x);
    79         maxn=0;
    80         Solve(x);
    81         if (maxn==x) puts("Prime");
    82         else printf("%lld
    ",maxn);
    83     }
    84 }
  • 相关阅读:
    C#中异步和多线程的区别
    猫 老鼠 人的编程题
    C#中数组、ArrayList和List三者的区别
    经典.net面试题目
    sql有几种删除表数据的方式
    内存池的实现
    A*算法为什么是最优的
    传教士与野人问题
    d3d导致cairo不正常
    c++中的signal机制
  • 原文地址:https://www.cnblogs.com/refun/p/10116142.html
Copyright © 2011-2022 走看看