一、RSA介绍:
1)利用素数生成函数产生两个大素数p,q,构造出模数N
2)计算欧拉函数φ(n)=(p−1)∗(q−1)
3) 计算E的值(1 < E < φ(n), gcd(E,φ(n)) E 和 φ(n)的最大公约数为1 (E 和 φ(n) 互质)
要找出满足 gcd(E, φ(n)) = 1 的数,还是要使用伪随机数生成器。通过伪随机数生成器在 1 < E < L 的范围内生成 E 的候选数,然后再判断其是否满足 gcd(E, φ(n)) = 1 这个条件。
4)计算D的值(D = E^(-1) (mod φ(n))) ,(1 < D < φ(n), E * D = 1 mod N),
5 ) 加密:密文=明文^E mod N (E,N)->>公钥
6) 解密:明文=密文^D mod N (D,N)->>私钥
二、利用gmp实现RSA算法
2.1 GMP开发环境配置
2.2 GMP是基于C语言的开源库,官方文档:gmp
2.3 代码函数介绍
void mpz_init(mpz_t x); //mpz_t类型变量被使用前必须手动进行初始化,且不允许对已初始化变量初始化
void mpz_init_set_ui(mpz_t rop, unsigned long int op);//初始化rop
int mpz_init_set_str (mpz_t rop, const char *str, int base);//初始化rop,并赋值rop = str,其中str是一个表示base进制整数的字符数组
void mpz_clear(mpz_t x); //释放x所占用的内存空间
void mpz_clears(mpz_t x,mpz_t y,...,NULL);//释放多个变量的内存空间
void mpz_sub_ui (mpz_t rop, const mpz_t op1, unsigned long int op2);//计算rop =op1 – op2,
void mpz_mul (mpz_t rop, const mpz_t op1, const mpz_t op2);//计算rop =op1 * op2,
void gmp_randinit_default (gmp_randstate_t state);//设置state的随机数生成算法,默认为梅森旋转算法
void gmp_randseed_ui (gmp_randstate_t state, unsigned long int seed);//设置state的随机化种子为seed
void mpz_urandomb (mpz_t rop, gmp_randstate_t state, mp_bitcnt_t n);//根据state生成范围0~2^n-1内均匀分布整数,结果保存在rop中
char * mpz_get_str (char *str, int base, const mpz_t op)//将op以base进制的形式保存到字符数组中,该函数要求指针str为NULL
int gmp_printf (const char *fmt, ...)//例如fmt=”%Zd”时,表示输出一个10进制的多精度整型。
int mpz_probab_prime_p (const mpz_t n, int reps)//检测n是否为素数。
2.4 算法代码:(RSA code and gmp RSA)
#include <gmp.h>
#include <iostream>
using namespace std;
int main(void)
{
//变量声明
mpz_t p,q;//大素数p,q
mpz_t n; //模数
mpz_t f; //欧拉函数值
mpz_t d,e;//公私钥中的e,d
mpz_t pt,ct;//明文,密文
gmp_randstate_t grt; //
gmp_randinit_default(grt);//默认随机化算法
gmp_randseed_ui(grt,time(NULL));//随机化种子
mpz_init(p);
mpz_init(q);
mpz_urandomb(p,grt,1024);//选择0-2^1024-1的值
mpz_urandomb(q,grt,1024);
mpz_nextprime(q,q); //素数
mpz_nextprime(p,p);
//1、n=p*q;
mpz_init(n);
mpz_mul(n,p,q);
//2、f=(p-1)*(q-1)
mpz_init(f);
mpz_sub_ui(p,p,1);
mpz_sub_ui(q,q,1);
mpz_mul(f,p,q);
//3、计算e
mpz_init(e);
mpz_set_ui(e,65537);
gmp_printf("%s (%Zd %Zd)\n\n","public key is :",n,e);
//计算d d = e^-1 mod f
mpz_init(d);
mpz_invert(d,e,f);
gmp_printf("%s (%Zd %Zd)\n\n","private key is :",n,d);
mpz_init(pt);
mpz_init(ct);
mpz_set_ui(pt,1234);
//ct = pt ^ e mod n;
mpz_powm(ct,pt,e,n);
gmp_printf("%s %Zd\n","the cipertext is:",ct);
//pt = ct^d mod n
mpz_powm(pt,ct,d,n);
gmp_printf("%s %Zd\n","the plaintext is:",pt);
mpz_clears(p,q,n,e,d,f,pt,ct,NULL);
return 0;
}