zoukankan      html  css  js  c++  java
  • 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
    ") ;
            if(n & 1)
            {
                res *= tmp ;
                res %= m ;
            }
            tmp *= tmp ;
            tmp %= m ;
            n >>= 1 ;
            //printf("%d
    ",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
    ");
            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
    ",p,q) ;
            exde(e,(p-1)*(q-1),x,y);
            //printf("%d %d
    ",p,q) ;
            int d = x ;
            //printf("%d
    ",d+(p-1)*(q-1)) ;
            if(d < 0)
                d = (d+(p-1)*(q-1)) %((p-1)*(q-1)) ;
            //printf("%d
    ",d) ;
            int ans = multimod(c,d,n) ;
            printf("%d
    ",ans) ;
        }
        return 0 ;
    }
    View Code
  • 相关阅读:
    Java中的枚举与values()方法
    为什么要使用双亲委派机制?
    java中finalize()方法
    jdk中rt.jar的作用
    IDEA查看maven依赖树,找出冲突jar包,以及 exclusion 冲突的包
    Linux 环境下SQLPLUS 回退键无法使用处理方法
    Hive字段注释会显示成from deserializer
    LinkedList类的poll、pop等方法
    static代码块执行顺序
    机器学习--线性回归
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/4077184.html
Copyright © 2011-2022 走看看