大素数生成算法,不同素数生成算法优劣(go实现)

大素数生成算法,不同素数生成算法优劣

费马小定理素数判定法

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
文章来源

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值