diff --git a/field/field.go b/field/field.go index 799ee51..89250df 100644 --- a/field/field.go +++ b/field/field.go @@ -1,6 +1,7 @@ package field import ( + "fmt" "math/big" "github.com/consensys/gnark-crypto/ecc" @@ -36,3 +37,10 @@ var r EmulatedField func EmulatedFieldModulus() *big.Int { 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]) + } +} diff --git a/go.mod b/go.mod index 5692205..38a6172 100644 --- a/go.mod +++ b/go.mod @@ -30,4 +30,4 @@ require ( // 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 -replace github.com/consensys/gnark v0.7.2-0.20220921094618-a121a3074ee8 => github.com/kevjue/gnark v0.7.2-0.20221031212238-0b216679a380 \ No newline at end of file +replace github.com/consensys/gnark v0.7.2-0.20220921094618-a121a3074ee8 => github.com/kevjue/gnark v0.7.2-0.20221109003544-edd49e7202a7 diff --git a/go.sum b/go.sum index 506e36b..9f05fe7 100644 --- a/go.sum +++ b/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/go.mod h1:gSuNB+gJaOiQKLEZ+q+PK9Mq3SOzhRcw2GsGS/FhYDk= 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/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= diff --git a/plonky2_verifier/deserialize.go b/plonky2_verifier/deserialize.go index 2a73141..f987b18 100644 --- a/plonky2_verifier/deserialize.go +++ b/plonky2_verifier/deserialize.go @@ -59,19 +59,18 @@ type MerkleProofRaw struct { } 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) } - 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 diff --git a/plonky2_verifier/fri.go b/plonky2_verifier/fri.go index b447440..8b2c269 100644 --- a/plonky2_verifier/fri.go +++ b/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) { 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} - 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 copy(leftSiblingState[0:4], sibling[0:4]) copy(leftSiblingState[4:8], currentDigest[0:4]) copy(leftSiblingState[8:12], fourZeros[0:4]) + 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 copy(rightSiblingState[0:4], currentDigest[0:4]) copy(rightSiblingState[4:8], sibling[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) } } diff --git a/plonky2_verifier/utils.go b/plonky2_verifier/utils.go index 26d920b..606b8ac 100644 --- a/plonky2_verifier/utils.go +++ b/plonky2_verifier/utils.go @@ -4,6 +4,8 @@ import ( "fmt" . "gnark-ed25519/field" "math/bits" + + "github.com/consensys/gnark/frontend" ) func reduceWithPowers(qe *QuadraticExtensionAPI, terms []QuadraticExtension, scalar QuadraticExtension) QuadraticExtension { @@ -30,3 +32,12 @@ func log2Strict(n uint) int { } 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 +}