赞
踩
C/C++语言使用GMP大数运算库实现Paillier算法_Paidx.的博客-CSDN博客_c++ gmp
想要使用中国剩余定理,则需要提前知道p,q的值,如果不知道p,q的值则不能够使用中国剩余定理进行加速解密的过程。大数的模幂运算在计算机中是耗时的,如果使用硬算的方法则会消耗大量时间,如果使用中国剩余定理进行优化则会提高解密效率。
按照Paillier算法的要求进行加密,得到密文c,需要进行下面的数学原理进行划分:
上述中的CRT(m_p,m_q) mod pq如何进行计算呢,请看下述讲解。
对于第二步中计算的m_q,m_p直接带入第三步最后一步的推到即可,即带入如下方程:
(1)求乘法逆元
调用GMP库中的gmp_invert()函数能够直接求出来。
想要理解乘法逆元的概念,要先想想倒数的概念,3 * =1。举个例子:
此时显然是不能直接求得,需要先mod 5的乘法逆元,设乘法逆元为x,通过倒数的理解我们知道x 和在mod 5 的情况下同于于1。此时你直接看成 2 是一样的。计算x * 2 mod 5 =1,就可以知道x是多少了,显然x取3。这个是咱们手算,使用gmp_invert()方法咋求呢,该方法一共三个参数展示如下gmp_invert(result,2,5),第一个坑位放求得的逆元值,第二个坑是你求谁的逆元,第三个是mod谁。
(2)第二步的L_p是一个函数。
这个地方直接把数带进去计算就可以了,可以直接算乘法,应为是能够整除的。
但是h_p那个地方那个-1操作不能直接除法做,要求逆元,因为后面是mod一个数,可以直接求出一个逆元,不能看做是除法。就是如下展示的地方,不能看做除法,要用gmp_invert()来求逆元。
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<gmpxx.h>
- #include<gmp.h>
- #include<iostream>
- #include<time.h>
-
- int main(){
- //设置随机数种子
- clock_t time=clock();
- gmp_randstate_t grt;
- gmp_randinit_default(grt);
- gmp_randseed_ui(grt, time);
-
- //p、q初始化
- mpz_t p,q,p1,q1;
-
- mpz_init(p);
- mpz_init(q);
- mpz_init(p1);
- mpz_init(q1);
-
- //p、q的的范围在0~2^128-1
- mpz_urandomb(p, grt, 128);
- mpz_urandomb(q, grt, 128);
-
- //生成p,q大素数
- mpz_nextprime(p, p);
- mpz_nextprime(q, q);
-
- //判断生成的是否是素数得到的结果为2则确定为大素数
- int su1,su2;//如果为1则在判断次数内大概率确定是大素数,为0则不是
- su1=mpz_probab_prime_p(p,10);
- su2=mpz_probab_prime_p(q,10);
- //printf("判断生成的是否是素数 :p=%d q=%d\n",su1,su2);
- //求p,q的乘积 n,以及n的平方n2
- mpz_t n,n2;
-
- mpz_init(n);
- mpz_init(n2);
- mpz_mul(n,p,q);
- mpz_mul(n2,n,n);
-
- //设置g,取值g=n+1
- mpz_t g,j;
-
- mpz_init(g);
- mpz_init_set_ui(j,1);
- //mpz_urandomb(g, grt, 128);
- mpz_add(g,n,j);
-
- //设置明文m
- mpz_t m;
- mpz_init_set_str(m,"123456",10);
- mpz_t r;//设置r,r为随机数
- mpz_urandomb(r, grt, 128);
-
- //设置密文c
- mpz_t c;
-
- mpz_init(c);
- //设置密文c
-
- mpz_powm(c,g,m,n2);
- mpz_powm(r,r,n,n2);
- mpz_mul(c,c,r);
- mpz_mod(c,c,n2);
-
- //解密过程
- //先求λ,是p、q的最小公倍数,y3代表λ
- mpz_t y1,y2,y3;
-
- mpz_init(y1);
- mpz_init(y2);
- mpz_init(y3);
-
- mpz_sub(p1,p,j);
- mpz_sub(q1,q,j);
- mpz_lcm(y3,p1,q1);//y3代表λ
-
- //输出明文m,g
- //十进制输出是%Zd,十六进制输出是%ZX,folat使用&Ff
- gmp_printf("明文m = %Zd\n\n", m);
- //gmp_printf("p = %Zd\n\n", p);
- //gmp_printf("q = %Zd\n\n", q);
- //gmp_printf("r = %Zd\n\n", r);
- //gmp_printf("g = %Zd\n\n", g);
- //gmp_printf("λ = %Zd\n\n", y3);
- //输出密文
- gmp_printf("密文c = %Zd\n\n",c);
-
- clock_t start, finish;
- start = clock();
- //y1代表c的λ次方摸n平方
- mpz_powm(y1,c,y3,n2);
- mpz_sub(y1,y1,j);
- mpz_div(y1,y1,n);
-
- //y2代表g的λ次方摸n平方
- mpz_powm(y2,g,y3,n2);
- mpz_sub(y2,y2,j);
- mpz_div(y2,y2,n);
-
- mpz_t x_y;
- mpz_init(x_y);
- mpz_invert(x_y,y2,n);//至关重要的一步,取逆
-
- mpz_mul(x_y,x_y,y1);
- mpz_mod(x_y,x_y,n);
-
- finish = clock();
- printf("time is :%fms\n",(double)(finish - start));
- //输出明文
- gmp_printf("解密得到明文m = %Zd\n\n",x_y);
- mpz_clear(p);
- mpz_clear(q);
- mpz_clear(n);
- mpz_clear(n2);
- mpz_clear(p1);
- mpz_clear(q1);
- mpz_clear(c);
- mpz_clear(g);
- mpz_clear(j);
- mpz_clear(r);
- mpz_clear(m);
- mpz_clear(y2);
- mpz_clear(y1);
- mpz_clear(y3);
- mpz_clear(x_y);
-
- return 0;
- }
- #include<stdio.h>
- #include<stdlib.h>
- #include<string.h>
- #include<gmpxx.h>
- #include<gmp.h>
- #include<iostream>
- #include<time.h>
-
- //g++ test_1.c -o test1 -lgmp -lm
- //./test1
-
- int main(){
- //设置随机数种子
- clock_t time=clock();
- gmp_randstate_t grt;
- gmp_randinit_default(grt);
- gmp_randseed_ui(grt, time);
-
- //p、q初始化
- mpz_t p,q,p1,q1;
-
- mpz_init(p);
- mpz_init(q);
- mpz_init(p1);
- mpz_init(q1);
-
- //p、q的的范围在0~2^128-1
- mpz_urandomb(p, grt, 128);
- mpz_urandomb(q, grt, 128);
-
- //生成p,q大素数
- mpz_nextprime(p, p);
- mpz_nextprime(q, q);
-
- //求p,q的乘积 n,以及n的平方n2
- mpz_t n,n2;
-
- mpz_init(n);
- mpz_init(n2);
- mpz_mul(n,p,q);
- mpz_mul(n2,n,n);
-
- //设置g,取值g=n+1
- mpz_t g,j;
-
- mpz_init(g);
- mpz_init_set_ui(j,1);
- mpz_add(g,n,j);
-
- //设置明文m
- mpz_t m;
- mpz_init_set_str(m,"123456",10);
- mpz_t r;//设置r,r为随机数
- mpz_urandomb(r, grt, 128);
-
- //设置密文c,c1,需要对这两个密文做同态加法
- mpz_t c;
-
- mpz_init(c);
- //设置密文c
-
- mpz_powm(c,g,m,n2);
- mpz_powm(r,r,n,n2);
- mpz_mul(c,c,r);
- mpz_mod(c,c,n2);
- //输出密文
- gmp_printf("明文m = %Zd\n\n", m);
- gmp_printf("密文c = %Zd\n\n",c);
-
- //中国剩余定理做paillier
- mpz_sub(p1,p,j);
- mpz_sub(q1,q,j);
- mpz_t m_p,m_q,p_2,q_2,mp_y1,mp_y2,mq_y1,mq_y2,p_ni,q_ni,q_p;
- mpz_init(m_p);
- mpz_init(q_p);
- mpz_init(p_ni);
- mpz_init(q_ni);
- mpz_init(m_q);
- mpz_init(p_2);
- mpz_init(q_2);
- mpz_init(mp_y1);
- mpz_init(mp_y2);
- mpz_init(mq_y1);
- mpz_init(mq_y2);
-
- mpz_mul(p_2,p,p);
- mpz_mul(q_2,q,q);
- mpz_invert(p_ni,p,p);
- mpz_invert(q_ni,q,q);
-
- //count time
- clock_t start, finish;
- start = clock();
- //m_p
- mpz_powm(mp_y1,c,p1,p_2);
- mpz_sub(mp_y1,mp_y1,j);
- mpz_div(mp_y1,mp_y1,p);
-
- mpz_powm(mp_y2,g,p1,p_2);
- mpz_sub(mp_y2,mp_y2,j);
- mpz_div(mp_y2,mp_y2,p);
- mpz_invert(mp_y2,mp_y2,p);
- mpz_mod(mp_y2,mp_y2,p);
- mpz_mul(mp_y1,mp_y1,mp_y2);
- mpz_mod(m_p,mp_y1,p);
-
- //m_q
- mpz_powm(mq_y1,c,q1,q_2);
- mpz_sub(mq_y1,mq_y1,j);
- mpz_div(mq_y1,mq_y1,q);
-
- mpz_powm(mq_y2,g,q1,q_2);
- mpz_sub(mq_y2,mq_y2,j);
- mpz_div(mq_y2,mq_y2,q);
- mpz_invert(mq_y2,mq_y2,q);
- mpz_mod(mq_y2,mq_y2,q);
- mpz_mul(mq_y1,mq_y1,mq_y2);
- mpz_mod(m_q,mq_y1,q);
-
- //CRT
- mpz_t p_q,result;
- mpz_init(p_q);
- mpz_init(result);
-
- mpz_sub(p_q,m_q,m_p);
- mpz_mul(p_q,p_q,p_ni);
- mpz_mod(p_q,p_q,q);
- mpz_mul(p_q,p_q,p);
- mpz_add(result,m_p,p_q);
-
- finish = clock();
- printf("time is :%fms\n",(double)(finish - start));
- gmp_printf("解密得到明文m = %Zd\n\n",result);
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。