大素数生成算法,不同素数生成算法优劣
费马小定理素数判定法
Fermat 定理: n是一个奇素数,a是任何整数(1≤ a≤n-1) ,则 a^(n-1)≡1(mod n)。
给出n如果1<a<=n-1都有a^n≡a(mod n),则认为n为素数
package main
import (
"fmt"
"math/big"
"math/rand"
"time"
)
// 用于提供长度为n的数,用于提取大素数,
func GenerateBigRange(n int64) *big.Int {
//将go默认类型转化为big.Int类型
length := new(big.Int).SetInt64(n)
//设置strng为int并给基数解释
re, _ := new(big.Int).SetString("10", 10)
//返回re**length%nil,这里为nil则不取模
re.Exp(re, length, nil)
return re
}
//利用费马小定理判断,如果a是素数,则(a ^ (n - 1)) % n恒等于1
func fmod(n *big.Int, a int64) bool {
one, _ := new(big.Int).SetString("1", 10)
n_ := new(big.Int).Sub(n, one)
result := new(big.Int).Exp(new(big.Int).SetInt64(a), n_, n)
if result.String() != "1" {
return false //此时出错 返回false 结果必须要为1
}
return true
}
//生成大数
func GenerateBigNum(n int64) *big.Int {
numRange := GenerateBigRange(n)
ran := rand.New(rand.NewSource(time.Now().UnixNano())) //创建的时候需要初始化其中一个值 用于生成随机数
ran.Seed(time.Now().UnixNano())
p := new(big.Int).Rand(ran, numRange)
return p
}
//素性检测
func Fermat_Prime(n *big.Int, length int64) bool {
i := 0
for i = 0; i < 100; i++ {
if !fmod(n, GenerateBigNum(length).Int64()) {
break
}
}
if i < 100 {
return false
} else {
return true
}
}
func main() {
flag := false
for {
n := GenerateBigNum(20)
flag = Fermat_Prime(n, 20)
if flag {
fmt.Println(n.String())
break
}
}
}
米勒拉宾素数判定算法
package main
import (
"fmt"
"math/big"
"math/rand"
"time"
)
var one = new(big.Int).SetInt64(1)
var zero = new(big.Int).SetInt64(0)
/*
用于提供长度为n的数,用于提取大素数,
*/
func GenerateBigRange(n int64) *big.Int {
//将go默认类型转化为big.Int类型
length := new(big.Int).SetInt64(n)
//设置strng为int并给基数解释
re, _ := new(big.Int).SetString("10", 10)
//返回re**length%nil,这里为nil则不取模
re.Exp(re, length, nil)
return re
}
//生成大数
func GenerateBigNum(n int64) *big.Int {
numRange := GenerateBigRange(n)
ran := rand.New(rand.NewSource(time.Now().UnixNano())) //创建的时候需要初始化其中一个值 用于生成随机数
ran.Seed(time.Now().UnixNano())
p := new(big.Int).Rand(ran, numRange)
return p
}
func GenerateA(n *big.Int) *big.Int {
a := new(big.Int)
for {
ran := rand.New(rand.NewSource(time.Now().UnixNano())) //创建的时候需要初始化其中一个值 用于生成随机数
ran.Seed(time.Now().UnixNano())
a.Rand(ran, new(big.Int).Sub(n, one))
if a.Cmp(new(big.Int).SetInt64(2)) == -1 {
continue
}
break
}
return a
}
func miller(n *big.Int, t int64) bool {
// 将n表示为2^s*d
s := 0
temp := new(big.Int).Sub(n, one)
for new(big.Int).And(temp, one) == zero && temp.Cmp(zero) == 0 {
temp.Div(temp, new(big.Int).SetInt64(2))
s += 1
}
d := temp
for t != 0 {
t--
//生成2<=a<n-1随机数
a := GenerateA(n)
result1 := new(big.Int).Exp(a, d, n)
if result1.Cmp(one) == 0 || result1.Cmp(new(big.Int).Sub(n, one)) == 0 {
return true
}
for r := 1; r <= s-1 && result1.Cmp(new(big.Int).Sub(n, one)) != 0; r++ {
result1.Exp(result1, new(big.Int).SetInt64(2), n)
if result1.Cmp(one) == 0 {
return false
}
}
if result1.Cmp(new(big.Int).Sub(n, one)) != 0 {
return false
}
}
return true
}
func main() {
var flag bool
for {
Randomint := GenerateBigNum(10)
flag = miller(Randomint, 100)
if flag {
fmt.Println(Randomint.String())
break
}
}
}
两种算法特点
①Miller-Rabin算法是目前主流的基于概率的素数测试算法,在构建密码安全体系中占有重要的地位。
②通过比较各种素数测试算法和对Miller-Rabin算法进行的仔细研究,证明在计算机中构建密码安全体系时, Miller-Rabin算法是完成素数测试的最佳选择。
③通过对Miller-Rabin 算法底层运算的优化,可以取得较以往实现更好的性能,这也是费马素性测试再无用武之地的原因。
参考博客https://blog.csdn.net/weixin_46447549/article/details/120770716
文章来源