大素数的生成

强拟素数

设n为正奇数,(bin Z,b>1,sin 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}-1equiv 1mod 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 -1mod n)
中必有一个成立。

定义:设(ngt 1)为奇合数,(bin Z,(b,n)=1),令(n=2^st+1),其中t为奇数,若(b^tequiv 1mod n)或存在(rin Z,0le rlt s),使得(b^{2^rt}equiv -1mod n),则称n为对于基b的强拟素数

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

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

Miller-Rabin素性检验

由上面的结论可知,可以通过增加检验的轮数使生成的素数为强拟素数的概率降低
素性检测的每一轮步骤如下
第一步:将待检测的奇数n写成(n-1=tcdot 2^k)的形式,其中t为奇数
第二步:随机选取一个整数b(b>2),计算(b_1=b^tmod n),如果(b_1=pm 1),则检验通过直接开始下一轮检验
第三步:否则,计算(b_{i+1}=b_i^2mod n(nge 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;
	}
	
}
原文地址:https://www.cnblogs.com/TheFutureIsNow/p/12833570.html