• Mr. Panda and Kakin (RSA 解密+解同余方程+O(1)快速乘)


    Mr. Panda and Kakin

    题意:给了两个数(n,c),(n=p*q),(p)和(q)是一个未知的数(x)前后的两个质数,(c = f^{2^{30}+3} mod n)。让求(f)的值。

    题解:参考大佬博客

    我们先来了解一下(RSA解密)

    再回头来看这个式子(c = f^{2^{30}+3} mod n),让求(f)是不是就是给了原来的数字,让求密文?

    对应着上面的,我们就有设(e = 2^{30}+3),那么(c = f^{e} mod n),(f = c^{d}modn),到这儿我们就发现了,我们不知道(d)是什么;

    根据上面(RSA)加密的描述可以知道(left ( d*e ight ) mod left [ left ( p-1 ight )left ( q-1 ight ) ight ]equiv 1)

    设(r = left ( p-1 ight )left ( q-1 ight )),就是(left ( d*e ight )mod r equiv 1)

    求解方程 (a*xequiv bleft ( mod n ight )x未知) 相当于求解方程 (ax+ny=b,所以这里我们相当于求解方程ex+ry=1),解线性同余方程即可得出(d)。

    问题又来了(r)我们不知道是啥......

    看上面我们设的(r = left ( p-1 ight )left ( q-1 ight )),那么求(r)的问题变成了求(p,q)的问题,(n=p*q),(n)题目已经给了,我们可以在(sqrtleft ( n ight ))附近找(p,q)

    综上所述,我们先求出(p,q),再求出(d),最后求出(f)

     AC_Code:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 typedef long double ld;
     5 #define endl '
    '
     6 const int inf=0x3f3f3f3f;
     7 const int maxn=2e5+10;
     8 const ll maxm=1073741827;
     9 
    10 
    11 ll n,c;
    12 
    13 ll exgcd(ll a,ll b,ll &x,ll &y){
    14     if( b==0 ){
    15         x=1;y=0;
    16         return a;
    17     }
    18     ll d=exgcd(b,a%b,y,x);
    19     y-=a/b*x;
    20     return d;
    21 }
    22 
    23 ll qpow(ll a,ll b,ll mod){
    24     ll res=1;
    25     while( b ){
    26         if( b&1 ) res=res*a%mod;
    27         a=a*a%mod;
    28         b>>=1;
    29     }
    30     return res;
    31 }
    32 
    33 ll mul(ll a,ll b,ll c){
    34     return (a*b-(ll)((ld)a*b/c)*c+c)%c;
    35 }
    36 
    37 ll pw(ll x, ll n, ll mod) {
    38     ll ret = 1;
    39     while(n) {
    40         if(n&1) ret = mul(ret,x,mod);
    41         x = mul(x,x,mod);
    42         n >>= 1;
    43     }
    44     return ret;
    45 }
    46 
    47 int main()
    48 {
    49     int T,cas=0; scanf("%d",&T);
    50     while( T-- ){
    51         scanf("%lld%lld",&n,&c);
    52 
    53         ll p=sqrt(n);
    54         while( n%p!=0 ) p--;
    55         ll q=n/p;
    56         ll r=(p-1)*(q-1);
    57 
    58         ll a,b,x,y;
    59         a=(1<<30)+3;
    60         b=r;
    61         exgcd(a,b,x,y);
    62         x = ((x%b)+b)%b;    //保证是整数
    63 //        ll f=qpow(c,x,n);   //错,因为c,n都太大了这样直接快速幂的话中间会有溢出
    64         ll f=pw(c,x,n);     //要用这个O(1)的快速乘
    65         printf("Case %d: %lld
    ",++cas,f);
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    分布式系统的架构思路
    Dubbo分布式服务框架的简单理解
    Java Worker 设计模式
    进程和线程
    alibaba-Java开发手册心得-一编程规约-6并发处理
    swagger的简单了解
    alibaba-Java开发手册心得-一编程规约-5集合处理
    serialVersionUID的简单理解
    java序列化对象简单理解
    最简单的调用freetype库实现在控制台输出文字显示
  • 原文地址:https://www.cnblogs.com/wsy107316/p/13492682.html
Copyright © 2020-2023  润新知