大素数的生成

强拟素数

设n为正奇数,\(b\in Z,b>1,s\in Z^+\),且\(2^s|(n-1)\),令\(t=\frac{n-1}{2^s}\),则\(b^{n-1}-1=(b^{2^0t}-1)(b^{2^0t}+1)(b^{2^1t}+1)+\cdots+(b^{2^{s-1}t}+1)\),因此若n为素数,则\(b^{n-1}-1\equiv 1\mod n\)\(Z_n\)无零因子,所以\(b^{n-1}-1\)至少有一个等于零的因式,即
\(b^{2^0t}\equiv 1,b^{2^0t}\equiv -1,b^{2^1t}\equiv -1,...,b^{2^{s-1}t}\equiv -1\mod n\)
中必有一个成立。


定义\(n\gt 1\)为奇合数,\(b\in Z,(b,n)=1\),令\(n=2^st+1\),其中t为奇数,若\(b^t\equiv 1\mod n\)或存在\(r\in Z,0\le r\lt s\),使得\(b^{2^rt}\equiv -1\mod n\),则称n为对于基b的强拟素数


定理1:存在无穷多个对于基2的强拟素数


定理2:设n是奇合数,\(b\in Z,1\le b\lt n\),那么n是对于基b的强拟素数的概率不超过\(\frac{1}{4}\)

Miller-Rabin素性检验

由上面的结论可知,可以通过增加检验的轮数使生成的素数为强拟素数的概率降低
素性检测的每一轮步骤如下
第一步:将待检测的奇数n写成\(n-1=t\cdot 2^k\)的形式,其中t为奇数
第二步:随机选取一个整数b(b>2),计算\(b_1=b^t\mod n\),如果\(b_1=\pm 1\),则检验通过直接开始下一轮检验
第三步:否则,计算\(b_{i+1}=b_i^2\mod n(n\ge 1)\),如果\(b_{i+1}=-1\),则检验通过直接开始下一轮检验;否则就继续检验下一个因式,如果所有因式都检验不通过,那么这个素数就可以判定为合数

下面是用于生成任意长度的大素数的java代码:

package BigPrimeInteger;

import java.math.BigInteger;
import java.io.*;	

public class BigPrimeInteger {
	public static void main(String[] args) {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String read = null;
		try {
			read = br.readLine();
		}catch(IOException e) {
			e.printStackTrace();
		}
		int l = Integer.parseInt(read);		//the length(bits) of Big Prime Integer 
		BigInteger n=generating(l);
		for(;!vrify(n);n=generating(l));
		System.out.println("The Big Prime Integer is "+n);
	}
	
	public static Boolean vrify(BigInteger n) {
		BigInteger t = n.subtract(BigInteger.valueOf(1));
		int s = 0;
		
		for(;(t.mod(BigInteger.valueOf(2))).compareTo(BigInteger.valueOf(0))==0;t=t.divide(BigInteger.valueOf(2)),s++);
		
		for(int i = 0;i < 16;i++) {					//Vrify in 16 turns
			int flag = 0;
			BigInteger b = BigInteger.valueOf((int)(Math.random()*1000+2));	//get a random r simply
			
			BigInteger r = modPower(b,t,n);				//r = b**t mod n
			
			for(int j = 0;j < s ;j++) {
				if(r.compareTo(n.subtract(BigInteger.valueOf(1))) == 0) { 	//r = n-1
					flag = 1;
					break;
				}else if(j==0 && r.compareTo(BigInteger.valueOf(1))==0) {	//j = 0 && r = 1  
					flag = 1;
					break;
				}
				r = (r.multiply(r)).mod(n);					//r = r ** 2
			}
			
			if(flag == 0) {
				//System.out.println("vrifying failed!");
				return false;
			}
		}
		return true;
	}
	
	public static BigInteger generating(int l){
		StringBuilder value = new StringBuilder();
		for(int i=0;i<l;i++) {
			if(i==0) {					//first bit must be 1
				value.append((char)49); 
			}else if(i==l-1) {			//last bit should be 1 to get an odd number
				value.append((char)49);
			}else {
			    int v = (int)(Math.random()*2+48);
			    value.append((char)v);
			}
		}
		String Value = value.toString();
		BigInteger Bin = new BigInteger(Value);
		
		//Invert Binary to decimal
		
		BigInteger Dec = BigInteger.valueOf(0);
		BigInteger Power = BigInteger.valueOf(1);
		for(;Bin.compareTo(BigInteger.valueOf(0)) > 0;Power=Power.multiply(BigInteger.valueOf(2)),Bin=Bin.divide(BigInteger.valueOf(10))) {
			BigInteger lsb = Bin.mod(BigInteger.valueOf(10));
			Dec = Dec.add(lsb.multiply(Power));
		}
		//System.out.println("the number is:"+Dec);
		return Dec;
		
	}
	
	//Computing r = b^n mod m
	public static BigInteger modPower(BigInteger b,BigInteger n,BigInteger m) {
		BigInteger r = new BigInteger("1");
		String binary = n.toString(2);
		for (int i = binary.length() - 1 ; i >= 0 ; i--){
			if (binary.charAt(i) == '1'){
				r = (r.multiply(b)).mod(m);
				b = (b.multiply(b)).mod(m);
			}else {
				b=(b.multiply(b)).mod(m);
			}
		}
		return r;
	}
	
}
posted @ 2020-05-05 23:03  Hang3  阅读(783)  评论(0编辑  收藏  举报