用gmp大整数库实现简单的elgamal加密,求生成元的方法利用了拉格朗日定理,直接上代码
#include <iostream>
#include <gmp.h>
#include<time.h>
const char *start="10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000";
int main()
{
mpz_t q,p,g,g1,g2,x_a,y_a,k,k_c,c1,c2,m; //define the variables
gmp_randstate_t state;
mpz_init_set_str(q,start,10); //init the variables
mpz_inits(p,g,g1,g2,x_a,y_a,k,k_c,c1,c2,m,NULL);
gmp_randinit_mt (state);
gmp_randseed_ui(state,(unsigned int)(time(NULL)));
mpz_add(p,q,q); //calculate p=2*q+1
mpz_add_ui(p,p,1);
while(mpz_probab_prime_p(p,30)==0) //loop to find q which is not a non-prime
{
mpz_nextprime(q,q);
mpz_add(p,q,q); //calculate p=2*q+1 again
mpz_add_ui(p,p,1);
}
mpz_urandomm (g, state, p);
mpz_powm_ui(g1,g,2,p); //calculate g^2modp
mpz_powm(g2,g,q,p); //calculate g^pmodp
while(g==0||mpz_cmp_ui(g1,1)==0||mpz_cmp_ui(g2,1)==0) //Lagrange 定理,
{
mpz_urandomm (g, state, p);
mpz_powm_ui(g1,g,2,p); //calculate g^2modp
mpz_powm(g2,g,q,p); //calculate g^pmodpf
}
mpz_urandomm (x_a, state, p); //generate the x_a
mpz_powm(y_a,g,x_a,p); //generate the y_a
//encryption
mpz_urandomm (m, state, p); //generate the plaintext
gmp_printf("The plaintext is:%Zd\n", m);
mpz_urandomm (k, state, p);
mpz_powm(k_c,y_a,k,p); //K=(Y_A)^k%p
mpz_powm(c1,g,k,p); //c1=g^k%p
mpz_mul(c2,k_c,m); //c2=k*m%p
mpz_mod(c2,c2,p);
gmp_printf("The pair of ciphertext is:\n(%Zd\n,%Zd)\n", c1,c2);
//decrytion
mpz_powm(k_c,c1,x_a,p); //K=(c1)^x_a%p
mpz_invert(k_c,k_c,p); //find the inverse of the K
mpz_mul(c2,c2,k_c); //m=c2*k^-1%p
mpz_mod(c2,c2,p);
gmp_printf("The plaintext after decrption is:%Zd\n", c2);
mpz_clears(q,p,g,g1,g2,x_a,y_a,k,k_c,c1,c2,m,NULL); //free the memories
return 0;
}
gmp库请自行官网下载