#include <ctime>
#include <iostream>
#include <cstdlib>
using namespace std;
struct public_key
{
int n;
int x;
};
struct private_key
{
int p;
int q;
};
int power(int x,int y,int m)//cal x^y%m
{
if(y==0)return 1%m;
int ret=x%m;
for(int i=0;i<y-1;i++)
ret=(ret*x)%m;
return ret;
}
int get_x(int p,int q)
{
for(int i=1;i<p*q;i++)
{
if (power(i,(p-1)/2,p)==p-1&&power(i,(q-1)/2,q)==q-1)
{
cout<<"get x:"<<i<<endl;
return i;
}
}
}
void get_key(public_key* bk,private_key* rk,int p,int q)
{
bk->n=p*q;
bk->x=get_x(p,q);
rk->p=p;
rk->q=q;
}
int get_random(int n)
{
srand(unsigned(time(0)));
int ret=rand()%1000;
int max,min;
if(ret>=n)
{
max=ret;
min=n;
}
else
{
max=n;
min=ret;
}
while(min)
{
int tmp=max%min;
if(tmp==1)return ret;
max=min;
min=tmp;
}
}
int encrypt(int src,int n,int x)
{
int y=get_random(n);
cout<<"get y:"<<y<<endl;
return (power(y,2,n)*power(x,src,n))%n;
}
int decode(int src,int p,int q)
{
int cp=power(src,(p-1)/2,p);
int cq=power(src,(q-1)/2,q);
cout<<"c/p="<<cp<<endl;
cout<<"c/q="<<cq<<endl;
if(cp==1&&cq==1)
return 0;
else
return 1;
}
int main()
{
public_key* bk=new public_key;
private_key* rk=new private_key;
int p=613,q=827;
get_key(bk,rk,p,q);
int src=1;
cout<<"1:\n";
int enc=encrypt(src,bk->n,bk->x);
cout<<"encrypt:"<<enc<<endl;
cout<<"m':"<<decode(enc,rk->p,rk->q)<<endl;
src=0;
cout<<"0:\n";
enc=encrypt(src,bk->n,bk->x);
cout<<"encrypt:"<<enc<<endl;
cout<<"m':"<<decode(enc,rk->p,rk->q)<<endl;
return 0;
}