go实现DSA签名算法【2-密钥生成】

341 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

接上文:go实现DSA签名算法【1-准备阶段】

密钥生成

1、生成质数p

p越大,我们的算法就越安全,但是因为数字过大,所以使用big.Int类型。

//调用DSA文件夹中的PrimeCount函数(会有点慢),可以查看上一篇文章
p:=big.NewInt(DSA.PrimeCount(15270644627))
fmt.Println("质数p",p)

//结果
质数p:15270644639

2、p-1的素因子q

我们要计算或者写代码实现q是比较有难度的。 我们就可以使用工具(人和动物最大的区别就是人会使用工具) 网站:分解质因数工具

q:=big.NewInt(449136607)
fmt.Println("素因子q",q)

//结果
素因子q:449136607

image.png

3、生成参数h(1.  h满足h<p-1,h^((p-1)/q) modp>1;)

我们需要生成一个随机数h 为了更具有个性化,我把hello使用sha256加密,将它密文前几位转换成10进制(使用工具),取前4位作为h

hash:=DSA.Sum256([]byte("hello"))
fmt.Printf("%x\n",hash)
h:=big.NewInt(1164)

4、生成参数g

g = h^((p-1)/q) mod p,h满足h < p - 1, h^((p-1)/q) mod p > 1; 在大数运算中,是不能使用符号的,得调math/big的运算包

// 减法,相当于p-1
 g1:=p.Sub(p,big.NewInt(1))
 
 //除法,相当于 g1/q=(p-1)/q
 g2:=g1.Div(g1,q)
 
 //幂运算   h^g2= h^((p-1)/q)
 g3:=h.Exp(h,g2,nil)
 
 //取余 g3%q=h^((p-1)/q) mod p
 g:=g3.Mod(g3,q)
fmt.Println("g:",g)

5、私钥x

私钥x是随机数,只需要x<q

//私钥
//使用math/rand包
rand.Seed(time.Now().UnixNano())
x := big.NewInt(int64(rand.Intn(9999))  )// 生成0~9999的随机数
fmt.Println("私钥x",x)

6、公钥y

y:y=g^x mod p,( p, q, g, y )为公钥

//公钥
g的x次方
y1:= g.Exp(g,x,nil)
//然后取余
y:=y1.Mod(y1,p)
fmt.Println("公钥y",y)

p, q, g可由一组用户共享,但在实际应用中,使用公共模数可能会带来一定的威胁