URAL 1141. RSA Attack(欧拉定理+扩展欧几里得+快速幂模)

题目链接

题意 : 给你n,e,c,并且知道me ≡ c (mod n),而且n = p*q,pq都为素数。

思路 : 这道题的确与题目名字很相符,是个RSA算法,目前地球上最重要的加密算法。RSA算法原理 。

看到这个算法之后,就知道这个题是求cd≡m(mod n),要求m,就要先求d,而d则是e的模反元素。

如果两个正整数a和n互质,那么一定可以找到整数b,使得 ab-1 被n整除,或者说ab被n除的余数是1。这时,b就叫做a的模反元素。

由模反元素可知,ed≡1(mod Phi[n])(phi[n]代表n的欧拉函数)。

根据欧拉函数性质可知,phi[n] = (p-1)*(q-1)。

求e的逆元d需要用扩展欧几里得,ed+k*phi[n]=1.要注意处理求出的d是负数的情况。

最后求cd就要用到快速幂模,然后再MOD n 就是所求m。

#include <stdio.h>

#include <string.h>

#include <iostream>

typedef long long  LL ;



using namespace std ;



bool isprime(int n)

{

    for(int i = 2 ; i * i <= n ; i++)

    {

        if(n % i == 0) return false ;

    }

    return true ;

}

int multimod(int a,int n,int m)

{

    int tmp = a , res = 1 ;



    while(n)

    {

        //printf("11\n") ;

        if(n & 1)

        {

            res *= tmp ;

            res %= m ;

        }

        tmp *= tmp ;

        tmp %= m ;

        n >>= 1 ;

        //printf("%d\n",n) ;

    }

    return res ;

}

void exde(int a,int b,int &x,int& y)

{

    int t ;

    if(b == 0)

    {

        x = 1 ;

        y = 0 ;

        return ;

        //return a;

    }

     exde(b,a%b,x,y) ;

    t = x ;

    x = y ;

    y = t-(a/b)*y;

    //return d ;

}

int main()

{

    int T ,e,c,n;

    scanf("%d",&T) ;

    while(T--)

    {

        scanf("%d %d %d",&e,&n,&c) ;

        int p,q ,x,y;

        //printf("1\n");

        for(int i = 2 ; i * i <= n ; i++)

        {

            if((n % i == 0) && isprime(i) && isprime(n / i))

            {

                p = i ;

                q = n / i ;

                break ;

            }

        }

        //printf("p = %d q = %d\n",p,q) ;

        exde(e,(p-1)*(q-1),x,y);

        //printf("%d %d\n",p,q) ;

        int d = x ;

        //printf("%d\n",d+(p-1)*(q-1)) ;

        if(d < 0)

            d = (d+(p-1)*(q-1)) %((p-1)*(q-1)) ;

        //printf("%d\n",d) ;

        int ans = multimod(c,d,n) ;

        printf("%d\n",ans) ;

    }

    return 0 ;

}
View Code

 

你可能感兴趣的:(rsa)