[CQOI2018] Crack DH protocol

[CQOI2018] Crack DH protocol

Topic description

Diffie-Hellman key exchange protocol is a simple and effective key exchange method.
It allows both parties to establish a secure key K through an insecure channel (which may be eavesdropped) without prior agreement on a key (password), which is used to encrypt the content of the communication afterward.
Assuming that the two parties of the communication are named Alice and Bob, the working process of the protocol is described as follows (where mod represents the modulo operation):
1. The protocol specifies a fixed prime number P, and a primitive root g modulo P. The values ​​of P and g are public and do not need to be kept secret.
2. Alice generates a random number a, calculates A=g^a mod P, and sends A to Bob through the insecure channel.
3. Bob generates a random number b, calculates B=g^b mod P, and sends B to Alice through the insecure channel.
4. Bob calculates K=A^b mod P based on the received A, and Alice calculates K=B^a mod P based on the received B.
5. Both sides get the same K, which is g^(a*b) mod P. K can be used as an encryption key for subsequent communications.
It can be seen that only A and B may be eavesdropped in this process, while a, b, and K are kept secret. And according to the four numbers of A, B, P, and g, K cannot be easily calculated
, so K can be used as a secure key.
Of course, security is relative. The security of this protocol depends on the size of the value. Usually, a, b, and P all select large integers with more than hundreds of digits to avoid being cracked. However,
if Alice and Bob were lazy in their programming and chose values ​​less than 2^31 to avoid implementing large numbers, then it would be easier to crack their keys.

Input

The first line of the input file contains two space-separated positive integers g and P.
The second line is a positive integer n, indicating that Alice and Bob have made n connections (that is, run the protocol n times).
The next n lines, each line contains two positive integers A and B separated by spaces, indicating the values ​​of A and B that were eavesdropped in a connection.
2≤A, B<P<231, 2≤g<20, n<=20

Output

The output contains n lines, each with 1 positive integer K, the key you crack for each connection.

Sample Input

3 31

3

27 16

21 3

9 26

Sample Output

4

21

25

answer

Typical BSGS

For this problem, you can first solve the value of a, and then quickly get the power of B^a.

#include<bits/stdc++.h>

using namespace std;

const int MAXN = 1e7 + 10;

typedef long long ll;

inline ll read()
{
    char ch;
    ll fl=1;
    ll x=0;
    do{
      ch= getchar();
      if(ch=='-')
        fl=-1;
    }while(ch<'0'||ch>'9');
    do{
        x=(x<<3)+(x<<1)+ch-'0';
        ch=getchar();
    }while(ch>='0'&&ch<='9');
    return x*fl;
}

ll g,p;

ll n;

map<ll,int>ma;

inline ll Pow(ll a,ll b)
{
    ll ans = 1;
    ll mul = a;
    while(b)
    {
        if(b&1) ans*=mul,ans%=p;
        mul * = mul; mul% = p;
        b>>=1; 
    }
    return ans%p;
}

inline int BSGS(int y,int z)
{
    ma.clear();
    ll m= sqrt(p)+1;
    ll cj = z;
    for(int i=0;i<m;i++)
    {
        ma [cj] = i;
        cj = cj*y%p;
    }
    ll now = Pow(y,m);
    cj = 1;
    for(int i=1;i<=m+1;i++)
    {
        cj = cj*now%p;
        if(ma.count(cj))
        {
            return i*m-ma[cj];
        }
    }
}

intmain ()
{
    g = read(), p = read();
    n = read();
    for(int i=1;i<=n;i++)
    {
        ll A = read(),B = read();
        ll ans =BSGS(g,A);
        cout<<Pow(B,ans)<<endl;
    }
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325105291&siteId=291194637