Browse Source

got merkle proof traversal working

main
Kevin Jue 2 years ago
parent
commit
460709f65d
6 changed files with 49 additions and 24 deletions
  1. +8
    -0
      field/field.go
  2. +1
    -1
      go.mod
  3. +2
    -2
      go.sum
  4. +9
    -10
      plonky2_verifier/deserialize.go
  5. +18
    -11
      plonky2_verifier/fri.go
  6. +11
    -0
      plonky2_verifier/utils.go

+ 8
- 0
field/field.go

@ -1,6 +1,7 @@
package field package field
import ( import (
"fmt"
"math/big" "math/big"
"github.com/consensys/gnark-crypto/ecc" "github.com/consensys/gnark-crypto/ecc"
@ -36,3 +37,10 @@ var r EmulatedField
func EmulatedFieldModulus() *big.Int { func EmulatedFieldModulus() *big.Int {
return r.Modulus() return r.Modulus()
} }
func PrintHash(f frontend.API, h Hash) {
for i := 0; i < 4; i++ {
fmt.Println("Hash Limb", i)
f.Println(h[i])
}
}

+ 1
- 1
go.mod

@ -30,4 +30,4 @@ require (
// For now, use a forked version of gnark so that the emaulated fields are // For now, use a forked version of gnark so that the emaulated fields are
// mod'ed when printed. See here: https://github.com/kevjue/gnark/commit/0b216679a380b4b8d29f10dd96f34e8a5702463e // mod'ed when printed. See here: https://github.com/kevjue/gnark/commit/0b216679a380b4b8d29f10dd96f34e8a5702463e
replace github.com/consensys/gnark v0.7.2-0.20220921094618-a121a3074ee8 => github.com/kevjue/gnark v0.7.2-0.20221031212238-0b216679a380
replace github.com/consensys/gnark v0.7.2-0.20220921094618-a121a3074ee8 => github.com/kevjue/gnark v0.7.2-0.20221109003544-edd49e7202a7

+ 2
- 2
go.sum

@ -16,8 +16,8 @@ github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1 h1:8pyqKJvrJqUYaKS851Ule26pwWvey6IDMiczaBLDKLQ= github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1 h1:8pyqKJvrJqUYaKS851Ule26pwWvey6IDMiczaBLDKLQ=
github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1/go.mod h1:gSuNB+gJaOiQKLEZ+q+PK9Mq3SOzhRcw2GsGS/FhYDk= github.com/google/pprof v0.0.0-20220729232143-a41b82acbcb1/go.mod h1:gSuNB+gJaOiQKLEZ+q+PK9Mq3SOzhRcw2GsGS/FhYDk=
github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/kevjue/gnark v0.7.2-0.20221031212238-0b216679a380 h1:AaxoOsAa/6HME7IIZ8XF0RsFNaDjy4WhRX7iK290YqM=
github.com/kevjue/gnark v0.7.2-0.20221031212238-0b216679a380/go.mod h1:iN7/IRE6Eu2QKnTJEsoS48suBV0O5XrM+Nzo1ipp6Zw=
github.com/kevjue/gnark v0.7.2-0.20221109003544-edd49e7202a7 h1:pU9438pFjuTjtDA4iV/oOPcdnzL7KelKXp4aHuqn2o4=
github.com/kevjue/gnark v0.7.2-0.20221109003544-edd49e7202a7/go.mod h1:iN7/IRE6Eu2QKnTJEsoS48suBV0O5XrM+Nzo1ipp6Zw=
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=

+ 9
- 10
plonky2_verifier/deserialize.go

@ -59,19 +59,18 @@ type MerkleProofRaw struct {
} }
func (m *MerkleProofRaw) UnmarshalJSON(data []byte) error { func (m *MerkleProofRaw) UnmarshalJSON(data []byte) error {
var siblingDict map[string]interface{}
if err := json.Unmarshal(data, &siblingDict); err != nil {
type SiblingObject struct {
Siblings []map[string][]uint64 // "siblings"
}
var siblings SiblingObject
if err := json.Unmarshal(data, &siblings); err != nil {
panic(err) panic(err)
} }
siblings := siblingDict["siblings"].([]interface{})
m.hash = make([][]uint64, len(siblings))
for siblingIdx, sibling := range siblings {
siblingHash := sibling.(map[string]interface{})["elements"].([]interface{})
m.hash[siblingIdx] = make([]uint64, 4)
for siblingElementIdx, siblingElement := range siblingHash {
m.hash[siblingIdx][siblingElementIdx] = uint64(siblingElement.(float64))
}
m.hash = make([][]uint64, len(siblings.Siblings))
for siblingIdx, sibling := range siblings.Siblings {
m.hash[siblingIdx] = sibling["elements"]
} }
return nil return nil

+ 18
- 11
plonky2_verifier/fri.go

@ -100,30 +100,37 @@ func (f *FriChip) hashOrNoop(data []F) Hash {
func (f *FriChip) verifyMerkleProofToCapWithCapIndex(leafData []F, leafIndexBits []frontend.Variable, capIndex F, merkleCap MerkleCap, proof *MerkleProof) { func (f *FriChip) verifyMerkleProofToCapWithCapIndex(leafData []F, leafIndexBits []frontend.Variable, capIndex F, merkleCap MerkleCap, proof *MerkleProof) {
currentDigest := f.hashOrNoop(leafData) currentDigest := f.hashOrNoop(leafData)
if len(leafIndexBits) != len(proof.Siblings) {
panic("len(leafIndexBits) != len(proof.Siblings)")
}
fourZeros := [4]F{f.qe.ZERO_F, f.qe.ZERO_F, f.qe.ZERO_F, f.qe.ZERO_F} fourZeros := [4]F{f.qe.ZERO_F, f.qe.ZERO_F, f.qe.ZERO_F, f.qe.ZERO_F}
for i, bit := range leafIndexBits {
sibling := proof.Siblings[i]
field.PrintHash(f.field, currentDigest)
for i, sibling := range proof.Siblings {
bit := leafIndexBits[i]
var leftSiblingState poseidon.PoseidonState var leftSiblingState poseidon.PoseidonState
copy(leftSiblingState[0:4], sibling[0:4]) copy(leftSiblingState[0:4], sibling[0:4])
copy(leftSiblingState[4:8], currentDigest[0:4]) copy(leftSiblingState[4:8], currentDigest[0:4])
copy(leftSiblingState[8:12], fourZeros[0:4]) copy(leftSiblingState[8:12], fourZeros[0:4])
leftHash := f.poseidonChip.Poseidon(leftSiblingState) leftHash := f.poseidonChip.Poseidon(leftSiblingState)
leftHashCompress := leftHash[0:4]
var leftHashCompress Hash
leftHashCompress[0] = leftHash[0]
leftHashCompress[1] = leftHash[1]
leftHashCompress[2] = leftHash[2]
leftHashCompress[3] = leftHash[3]
var rightSiblingState poseidon.PoseidonState var rightSiblingState poseidon.PoseidonState
copy(rightSiblingState[0:4], currentDigest[0:4]) copy(rightSiblingState[0:4], currentDigest[0:4])
copy(rightSiblingState[4:8], sibling[0:4]) copy(rightSiblingState[4:8], sibling[0:4])
copy(rightSiblingState[8:12], fourZeros[0:4]) copy(rightSiblingState[8:12], fourZeros[0:4])
rightHash := f.poseidonChip.Poseidon(rightSiblingState)
rightHashCompress := rightHash[0:4]
currentDigest = f.api.Select(bit, leftHashCompress, rightHashCompress).(Hash)
rightHash := f.poseidonChip.Poseidon(rightSiblingState)
var rightHashCompress Hash
rightHashCompress[0] = rightHash[0]
rightHashCompress[1] = rightHash[1]
rightHashCompress[2] = rightHash[2]
rightHashCompress[3] = rightHash[3]
currentDigest = SelectHash(f.field, bit, leftHashCompress, rightHashCompress)
field.PrintHash(f.field, currentDigest)
} }
} }

+ 11
- 0
plonky2_verifier/utils.go

@ -4,6 +4,8 @@ import (
"fmt" "fmt"
. "gnark-ed25519/field" . "gnark-ed25519/field"
"math/bits" "math/bits"
"github.com/consensys/gnark/frontend"
) )
func reduceWithPowers(qe *QuadraticExtensionAPI, terms []QuadraticExtension, scalar QuadraticExtension) QuadraticExtension { func reduceWithPowers(qe *QuadraticExtensionAPI, terms []QuadraticExtension, scalar QuadraticExtension) QuadraticExtension {
@ -30,3 +32,12 @@ func log2Strict(n uint) int {
} }
return res return res
} }
func SelectHash(fieldAPI frontend.API, bit frontend.Variable, leftHash, rightHash Hash) Hash {
var returnHash Hash
for i := 0; i < 4; i++ {
returnHash[i] = fieldAPI.Select(bit, leftHash[i], rightHash[i]).(F)
}
return returnHash
}

Loading…
Cancel
Save