TOJ1196: RSA Signing

题不在多,大概是多了也可能就是菜逼

1196: RSA Signing 

Time Limit(Common/Java):3000MS/30000MS     Memory Limit:65536KByte
Total Submit: 20            Accepted:5

Description

 

In cryptography, RSA is an algorithm for public-key cryptography. It was the first algorithm known to be suitable for signing as well as encryption, and one of the first great advances in public key cryptography. RSA is widely used in electronic commerce protocols, and is believed to be secure given sufficiently long keys and the use of up-to-date implementations.

    RSA involves a public key and a private key. The public key can be known to everyone and is used for encrypting messages. Messages encrypted with the public key can only be decrypted using the private key. The keys for the RSA algorithm are generated the following way:

 

  1. Choose two distinct large random prime numbers p and q
  2. Compute n = p * q
  3. Compute the totient: φ(n) = (p-1) * (q-1)
  4. Choose an integer e such that 1 < e < φ(n), and e and φ(n) share no factors other than 1
  5. Compute d to satisfy the congruence relation d * e ≡ 1 mod (φ(n))

    The public key consists of the modulus n, and the public (or encryption) exponent e. The private key consists of the modulus n, and the private (or decryption) exponent d, which must be kept secret.

Encrypting messages:
    Alice transmits her public key (n,e), to Bob and keeps the private key secret. Bob then wishes to send message M to Alice. He first turns M into a number m < n. Then computes the ciphertext c, corresponding to:
    c = me mod n
This can be done quickly using the method of exponentiation by squaring. Bob then transmits c, to Alice.

Decrypting messages:
Alice can recover m from c, by using her private key exponent d, by the following computation:
    m = cd mod n
Given m, she can recover the original message M.

    Suppose Alice uses Bob's public key to send him an encrypted message. In the message, she can claim to be Alice but Bob has no way of verifying that the message was actually from Alice since anyone can use Bob's public key to send him encrypted messages. So, in order to verify the origin of a message, RSA can also be used to sign a message. Suppose Alice wishes to send a signed message to Bob. She can use her own private key to do so. She produces a hash value of the message m, raises it to the power of d mod n (as she does when decrypting a message), and attaches it as a "signature" to the message. When Bob receives the signed message, he uses the same hash algorithm in conjunction with Alice's public key. He raises the signature to the power of e mod n (as he does when encrypting a message), and compares the resulting hash value with the message's actual hash value. If the two agree, he knows that the author of the message was in possession of Alice's secret key, and that the message has not been tampered with since.

    Now you got Alice's public key, and you want to pretend to be Alice in order to send a message to Bob, how can you fake her signature if her key is weak?

 

Input

The first line in the input is one integer T, indicates the number of test cases. Each test case contains three positive integers n, e, m (0 < m < n, 0 < e < n, 0 < n < 260).

Output

 

For each test case, The Output should contains the signature for message m in a single line.

 

Sample Input

 

1
55 7 15

Sample Output

 20

Source

HNU 2008

上面一大坨就是告诉你RSA是怎么生成的
其实就是求得p q,exgcd求得d,然后次幂

 

#include <bits/stdc++.h>
using namespace std;
typedef __int64 ll;
ll mul(ll x,ll y,ll p)
{
    ll res=0;
    for(; y; x=2*x%p,y>>=1)
        if(y&1)res=(res+x)%p;
    return res;
}
ll po(ll x,ll y,ll p)
{
    ll res=1;
    for(; y; x=mul(x,x,p),y>>=1)
        if(y&1)res=mul(res,x,p);
    return res;
}
void exgcd(ll a,ll b,ll &d,ll &x,ll &y)
{
    if(!b)
    {
        d=a,x=1,y=0;
        return;
    }
    exgcd(b,a%b,d,y,x);
    y-=a/b*x;
}
ll pollard_rho(ll n)
{
    ll x=rand()%(n-1)+1,y=x,d,i=1,k=2;
    for(;;)
    {
        i++;
        x=((mul(x,x,n)+10007)%n+n)%n;
        d=__gcd(y-x+n,n);
        if(d>1&&d<n)return d;
        if(x==y) return n;
        if(i==k) y=x,k<<=1;
    }
}
int main()
{
    srand(time(NULL));
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ll m,e,n;
        scanf("%I64d%I64d%I64d",&n,&e,&m);
        ll p=pollard_rho(n);
        ll q=n/p;
        ll t=(p-1)*(q-1),d,x,y;
        exgcd(e,t,d,x,y);
        x=(x%t+t)%t;
        printf("%I64d\n",po(m,x,n));
    }
    return 0;
}

 

 

 

posted @ 2018-08-27 11:47  暴力都不会的蒟蒻  阅读(330)  评论(0编辑  收藏  举报