[CQOI2018] Crack DH protocol

topic background

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.

Topic description

Assuming that the two communicating parties 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 need not be kept secret.

  2. Alice generates a random number a, calculates  A=g^a\;mod\;P A = g a m o d P , and sends A to Bob through an insecure channel.

  3. Bob generates a random number b, and calculates  B=g^b\;mod\;P B = g b m o d P , and sends B to Alice through an insecure channel.

  4. Bob calculates  K=A^b\;mod\;P K = A b m o d P according to the received A, while Alice calculates  K=B^a\;mod\;P K = B a m o d P .

  5. Both parties get the same K, namely  g^{ab}\;mod\;P g a b m o d P . K is the encryption key that can be used 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, 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 ​​smaller than  2^{31} 2 3 1 in order to avoid implementing large number operations, then it would be easier to crack their keys.

Input and output format

Input format:

 

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, which represent the values ​​of A and B that were tapped in a certain connection.

 

Output format:

 

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

 

Input and output example

Input example #1: 
3 31
3
27 16
21 3
9 26
Sample output #1: 
4
21
25

illustrate

For 30% of the data,  2≤A,B,P≤1000 2 A , B , P 1 0 0 0

For 100% data,  2≤A,B<P<2^{31},2≤g<20,1≤n≤20 2 A , B < P < 2 3 1 , 2 g < 2 0 , 1 n 2 0

 

 

   naked bsgs.

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=100005;
map<int,int> mmp;
int g,P,n,A,B,C,sz;
inline int ksm(int x,int y){ int an=1; for(;y;y>>=1,x=x*(ll)x%P) if(y&1) an=an*(ll)x%P; return an;}

inline void init(){
	for(int i=0,now=1;i<sz;i++,now=now*(ll)g%P) if(!mmp.count(now)) mmp[now]=i;
	C=ksm(ksm(g,sz),P-2);
}

inline void solve(){
	int X,Y;
	for(int i=0;;i++,A=A*(ll)C%P) if(mmp.count(A)){
		X=i*sz+mmp[A];
		break;
	}
	for(int i=0;;i++,B=B*(ll)C%P) if(mmp.count(B)){
		Y=i*sz+mmp[B];
		break;
	}	
	
	printf("%d\n",ksm(g,X*(ll)Y%(P-1)));
}

int main(){
	scanf("%d%d%d",&g,&P,&n),sz=sqrt(P)+1,init();
	while(n--) scanf("%d%d",&A,&B),solve();
	return 0;
}

  

Guess you like

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