上一篇博客已经简单的完成了RSA加密,建议看完上一篇博客再来查看本文章:
https://blog.youkuaiyun.com/Watery________1314/article/details/96719658
这次我们将对之前的简单加密进行优化,实现大数加密,还有一部分性能优化。
首先要添加外部依赖库boost库,具体添加库方法请见:
https://blog.youkuaiyun.com/Watery________1314/article/details/96981400
添加好boost库后我们就可以对之前的数据进行优化了,这里引入以下三个头文件:
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/random.hpp>
#include <boost/multiprecision/miller_rabin.hpp>
先将之前的数据类型long替换成int1024_t,其次对产生素数函数produce_prime()和生成dkey函数produce_dkey()分别进行优化。
1.产生素数函数produce_prime()
bm::int1024_t RSA::produce_prime()
{
//srand(time(nullptr));
bm::int1024_t prime = 0;
//mt19937:一种随机数产生器
boost::random::mt19937 gen(time(nullptr));
//指定随机数的范围 2 ~ (1<<128)
boost::random::uniform_int_distribution<bm::int1024_t> dist(2, bm::int1024_t(1) << 128);
while (1)
{
prime = dist(gen);
if (is_prime_bigInt(prime))
break;
}
return prime;
}
这里使用了boost库中的mt19937(一种随机数产生器)来产生一个随机数,这里的随机数范围发生了变化,我们这里让它最大可以到(1<<128),这里的判断是否为素数也进行一个优化,如下代码:
bool RSA::is_prime_bigInt(const bm::int1024_t digit)
{
boost::random::mt11213b gen(time(nullptr));
if (miller_rabin_test(digit, 25, gen)) //素数测试算法miller_rabin_test()
{
if (miller_rabin_test((digit - 1) / 2, 25, gen))
{
return true;
}
}
return false;
}
这里的判断是否是素数,并不是按照之前的那种从2开始一个个模运算来判断的方法,这里使用了素数测试算法Miller-Rabin,这个算法我看了一下,没有理解的很深刻,如果有需要可以去看看其他博客。
2.生成ekey函数produce_ekey()
bm::int1024_t RSA::produce_dkey(bm::int1024_t ekey, bm::int1024_t orla)
{
bm::int1024_t x, y;
exgcd(ekey, orla, x, y);
return (x % orla + orla) % orla;
}
/*
扩展的欧几里得算法
x = y1; y = x1 - [a/b]*y1
*/
bm::int1024_t RSA::exgcd(bm::int1024_t ekey, bm::int1024_t orla,
bm::int1024_t &x, bm::int1024_t &y)
{
if (orla == 0)
{
x = 1;
y = 0;
return ekey;
}
bm::int1024_t ret = exgcd(orla, ekey % orla, x, y);
bm::int1024_t x1 = x, y1 = y;
x = y1;
y = x1 - (ekey / orla) * y1;
return ret;
}
这里就需要看一下扩展的欧几里得算法:
扩展的欧几里得算法:不仅要求出(a,b)的最大公约数gcd,也要求出其中的一组解(x,y), 满足等式ax + by = gcd。