Pedersen 哈希算法

本文介绍了Pedersen哈希算法,它通过组合椭圆曲线上的点来实现加密哈希过程,使其在零知识证明(ZKP)系统中特别有用。文章解释了Pedersen哈希的基本原理,包括如何将输入消息分解为多个块,并使用这些块基于生成器点生成一系列椭圆曲线点,最后将生成的点相加得到哈希值。

Pedersen哈希

密码学哈希过程通常涉及某种形式的复杂操作,例如挤压和调整数据位,以及缺少代数方法的内容。另一方面,Pedersen哈希涉及几个椭圆曲线点的组合。这使得它们在零知识证明(ZKP)系统中实现哈希函数非常有用。

Pedersen哈希基于Torben P Pedersen关于承诺方案的工作 [1]:

在Zcash团队在其Sapling协议的zk-SNARK电路中实现它之后,该方法重新获得了关注[ 这里]:

方法

以最简单的形式,Pedersen哈希基本上是一种将值的哈希固定到椭圆曲线点的方法:

Hash(x) = x.G

其中G是椭圆曲线上的一个点。 这样,我们应该无法将x.G的值反转回x。以更完整的形式,我们可以将输入消息分成_k_块(m 1, m 2 … mk),然后使用这些块基于多个生成器点(G 1, G 2 … Gk)生成一系列椭圆曲线点。 然后,哈希是所创建点的总和:

H = m 1. G 1+ m 2. G 2+ m 3. G 3

如果我们使用三个块,则消息分为三个:

在你的收件箱中获取Prof Bill Buchanan OBE FRSE的故事

免费加入Medium,获取该作者的最新信息。

m = m 1|| m 2|| m 3

然后,我们生成三个间隔良好的生成器点:

G 1, G 2, G 3

Pedersen哈希是:

Hash =( m 1). G 1+( m 2). G 2+( m 3). G 3

其中(m 1). G 1,(m 2). G 2和(m 3). G 3是曲线上的点。让我们在Tiny Jubjub曲线上取三个点[ 在曲线上查找点]:

gx1,_ := new(big.Int).SetString("18930368022820495955728484915491405972470733850014661777449844430438130630919",10 )
gy1,_ := new(big.Int).SetString("0",10)

gx2,_ := new(big.Int).SetString("12576558175125128246374296641007938322302911659474853157208587689687229831284",10 )
gy2,_ := new(big.Int).SetString("3",10)

gx3,_ := new(big.Int).SetString("18869612826929474874643025262839512853875949931275176402223244870011103237908",10 )
gy3,_ := new(big.Int).SetString("5",10)

然后我们可以使用以下方法计算哈希[ 这里]:

package main

import (
 "fmt"
 "github.com/iden3/go-iden3-crypto/v2/babyjub"
 "math/big"
 "encoding/hex"
 "os"
)
func splitMessage(inStr string, size int) []string { // 分割消息
   var elements []string
   elementSize := len(inStr) / size
   for i := 0; i < size; i++ {
      start := i * elementSize
      end := start + elementSize
      if i == size-1 {
         end = len(inStr)
      }
      elements = append(elements, inStr[start:end])
   }
   return elements
}
func main() {
// Baby Jubjub曲线上的三个生成器值:
//19763400273586758549882294695966112539108188722254631372974345487113325868230, 13
//12576558175125128246374296641007938322302911659474853157208587689687229831284, 3
//18869612826929474874643025262839512853875949931275176402223244870011103237908, 5

 str:="Testing 123"
 argCount := len(os.Args[1:])
 if (argCount>0) {str= string(os.Args[1])}
 fmt.Printf("Input message: %s\n\n",str) // 输入消息
 value := hex.EncodeToString([]byte(str))
 res:= splitMessage(value,3)
 gx1,_ := new(big.Int).SetString("19763400273586758549882294695966112539108188722254631372974345487113325868230",10 )
 gy1,_ := new(big.Int).SetString("13",10)
 gx2,_ := new(big.Int).SetString("12576558175125128246374296641007938322302911659474853157208587689687229831284",10 )
 gy2,_ := new(big.Int).SetString("3",10)

 gx3,_ := new(big.Int).SetString("18869612826929474874643025262839512853875949931275176402223244870011103237908",10 )
 gy3,_ := new(big.Int).SetString("5",10)

 G1 := &babyjub.Point{X: gx1, Y: gy1}
 G2 := &babyjub.Point{X: gx2, Y: gy2}
 G3 := &babyjub.Point{X: gx3, Y: gy3}

 fmt.Printf("G1 (%s, %s)\n",G1.X.String(),G1.Y.String())
 fmt.Printf("G2 (%s, %s)\n",G2.X.String(),G2.Y.String())
 fmt.Printf("G3 (%s, %s)\n\n",G3.X.String(),G3.Y.String())

 m_1,_:=hex.DecodeString(res[0])
 m_2,_:=hex.DecodeString(res[1])
 m_3,_:=hex.DecodeString(res[2])
 M1:=new(big.Int).SetBytes(m_1)
 M2:=new(big.Int).SetBytes(m_2)
 M3:=new(big.Int).SetBytes(m_3)

  M1_G1 := babyjub.NewPoint().Mul(M1,G1)
  M2_G2 := babyjub.NewPoint().Mul(M2,G2)
  M3_G3 := babyjub.NewPoint().Mul(M3,G3)
 M1_G1_M2_G2 := babyjub.NewPoint().Projective().Add(M1_G1.Projective(),M2_G2.Projective())
 M1_G1_M2_G2_M3_G3 := babyjub.NewPoint().Projective().Add(M1_G1_M2_G2,M3_G3.Projective())

 fmt.Printf("(%d).G1 Point (%s, %s)\n",M1,M1_G1.X.String(),M1_G1.Y.String())
 fmt.Printf("(%d).G2 Point (%s, %s)\n",M2,M2_G2.X.String(),M2_G2.Y.String())
 fmt.Printf("(%d).G3 Point (%s, %s)\n\n",M3,M3_G3.X.String(),M3_G3.Y.String())
 fmt.Printf("Result: (%s, %s)\n\n",M1_G1_M2_G2_M3_G3.X.String(),M1_G1_M2_G2_M3_G3.Y.String())
 fmt.Printf("Pedersen Hash: %s\n",M1_G1_M2_G2_M3_G3.X.String()) // Pedersen哈希

}

结果是 [ 这里]:

Input message (in hex): 010203040506070809

G1 (19763400273586758549882294695966112539108188722254631372974345487113325868230, 13)
G2 (12576558175125128246374296641007938322302911659474853157208587689687229831284, 3)
G3 (18869612826929474874643025262839512853875949931275176402223244870011103237908, 5)

(66051).G1 Point (16037773783835146438558403421260836675868272902364849599426875451057520106906, 14728403640743494614641112385959960394789183729111213630842711014573474773378)
(263430).G2 Point (11852499477985754981114582499827808786287610741986412935345795152171632055691, 2674722056485308817737914684425248014914348605929003485370677590616611371783)
(460809).G3 Point (7621534404334108830225350985637201742729050263412910533478640032004698408257, 3768640800306573992890050298007966758509235918251221830887953108815318470075)

Result: (8246050116631628695869530651297899884448852706174930565536327904583775502268, 21660911736906458468630355032769751803544552633662219825808465470014769680600)

Pedersen Hash: 8246050116631628695869530651297899884448852706174930565536327904583775502268

当然,在现实生活中,我们会将生成器点分隔开。

参考

[1] Pedersen, T. P. (1991, August). Non-interactive and information-theoretic secure verifiable secret sharing. In 年度国际密码学会议 (pp. 129–140). Berlin, Heidelberg: Springer Berlin Heidelberg.

  • 原文链接: billatnapier.medium.com/...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
billatnapier
billatnapier
江湖只有他的大名,没有他的介绍。