记一次使用快速幂与Miller-Rabin的大素数生成算法
大家都知道RSA的加密的安全性就是能够找到一个合适的大素数,而现在判断大素数的办法有许多,比如Fermat素性测试或者Miller-Rabin素性测试,而这里我用了Miller-Rabin素性测试的算法,具体的理论我写到下面。
算法的理论基础:
Fermat定理:若n是奇素数,a是任意正整数(1≤ a≤ n−1),则 a^(n-1) ≡ 1 mod n。
2. 如果n是一个奇素数,将n−1表示成2^s*r的形式,r是奇数,a与n是互素的任何随机整数,那么a^r ≡ 1 mod n或者对某个j (0 ≤ j≤ s−1, j∈Z) 等式a^(2jr) ≡ −1 mod n 成立。
实验需要根据这个算法的理论来实现对素数的判定功能,而我将上述理论用C++的 形式写了出来,然后在一些细节的算法上少做润色,成功实现了对素数的生成和判定。
一、实验代码:
#include
#include
#include
#include
using namespace std;
typedef unsigned long long ll;
long long q_mul( long long a, long long b, long long mod )
{
long long ans = 0;
while(b)
{
if(b & 1)
{
b--;
ans =(ans+ a)%mod;
}
b /= 2;
a = (a + a) % mod;
}
return ans;
}
long long q_pow( long long a, long long b, long long mod )
{
long long ans = 1;
while(b)
{
if(b & 1)
{
ans = q_mul( ans, a, mod );
}
b /= 2;
a = q_mul( a, a, mod );
}
return ans;
}
//long long q_pow(ll a,ll b,ll mod){
// ll base=a;
// ll ans = 1;
// while(b!=0){
// if(b&1) ans = (ans*base)%mod;
// base = (base*base)%mod;
// b>>=1;
// }
// return ans;
//}
int Miller_Rabin(ll n) {
if(n<2) return 0;
if(n==2) return 1;
ll k=0,q=n-1;
while(q%2==0){
q=q/2;
k++;
}
ll a = rand(); //要保证a在(1,n-1)之间,开区间
a=(a%(n-2))+2;
ll result1 = q_pow(a,q,n);
if(result1 == 1||result1 == n-1){
return 1;
}
while(k--){
result1 = q_mul(result1,2,n);
if(result1 == n-1) return 1;
}
return 0;
}
bool True_Miller_Rabin(ll n){
int times = 10;
while(times){
times--;
if(Miller_Rabin(n)==0) return false;
}
return true;
}
int main()
{
srand((unsigned)time(NULL));
ll num;
// while(1){
// cin>>num;
// if(Miller_Rabin(num)==1)
// cout<<"为素数"< // else{ // cout<<"是合数"< // } // } for(ll i=1000000;i<=1005000;i++){ int a =0; if(True_Miller_Rabin(i)){ cout<< i<<"是素数"< } } return 0; }