Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move DeserializeAndVerifyVerkleProof to go-verkle #444

Merged
merged 4 commits into from
Jul 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 58 additions & 4 deletions proof_ipa.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,21 +202,21 @@
return proof, pe.Cis, pe.Zis, pe.Yis, nil
}

// VerifyVerkleProofWithPreState takes a proof and a trusted tree root and verifies that the proof is valid.
func VerifyVerkleProofWithPreState(proof *Proof, preroot VerkleNode) error {
// verifyVerkleProofWithPreState takes a proof and a trusted tree root and verifies that the proof is valid.
func verifyVerkleProofWithPreState(proof *Proof, preroot VerkleNode) error {
pe, _, _, _, err := getProofElementsFromTree(preroot, nil, proof.Keys, nil)
if err != nil {
return fmt.Errorf("error getting proof elements: %w", err)
}

if ok, err := VerifyVerkleProof(proof, pe.Cis, pe.Zis, pe.Yis, GetConfig()); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, pe.Cis, pe.Zis, pe.Yis, GetConfig()); !ok || err != nil {
return fmt.Errorf("error verifying proof: verifies=%v, error=%w", ok, err)
}

return nil
}

func VerifyVerkleProof(proof *Proof, Cs []*Point, indices []uint8, ys []*Fr, tc *Config) (bool, error) {
func verifyVerkleProof(proof *Proof, Cs []*Point, indices []uint8, ys []*Fr, tc *Config) (bool, error) {
tr := common.NewTranscript("vt")
return ipa.CheckMultiProof(tr, tc.conf, proof.Multipoint, Cs, ys, indices)
}
Expand Down Expand Up @@ -555,3 +555,57 @@
func (x bytesSlice) Len() int { return len(x) }
func (x bytesSlice) Less(i, j int) bool { return bytes.Compare(x[i], x[j]) < 0 }
func (x bytesSlice) Swap(i, j int) { x[i], x[j] = x[j], x[i] }

// Verify is the API function that verifies a verkle proofs as found in a block/execution payload.
func Verify(vp *VerkleProof, preStateRoot []byte, postStateRoot []byte, statediff StateDiff) error {

proof, err := DeserializeProof(vp, statediff)
if err != nil {
return fmt.Errorf("verkle proof deserialization error: %w", err)
}

rootC := new(Point)
rootC.SetBytes(preStateRoot)

Check failure on line 568 in proof_ipa.go

View workflow job for this annotation

GitHub Actions / lint

Error return value of `rootC.SetBytes` is not checked (errcheck)
pretree, err := PreStateTreeFromProof(proof, rootC)
if err != nil {
return fmt.Errorf("error rebuilding the pre-tree from proof: %w", err)
}
// TODO this should not be necessary, remove it
// after the new proof generation code has stabilized.
for _, stemdiff := range statediff {
for _, suffixdiff := range stemdiff.SuffixDiffs {
var key [32]byte
copy(key[:31], stemdiff.Stem[:])
key[31] = suffixdiff.Suffix

val, err := pretree.Get(key[:], nil)
if err != nil {
return fmt.Errorf("could not find key %x in tree rebuilt from proof: %w", key, err)
}
if len(val) > 0 {
if !bytes.Equal(val, suffixdiff.CurrentValue[:]) {
return fmt.Errorf("could not find correct value at %x in tree rebuilt from proof: %x != %x", key, val, *suffixdiff.CurrentValue)
}
} else {
if suffixdiff.CurrentValue != nil && len(suffixdiff.CurrentValue) != 0 {
return fmt.Errorf("could not find correct value at %x in tree rebuilt from proof: %x != %x", key, val, *suffixdiff.CurrentValue)
}
}
}
}

// TODO: this is necessary to verify that the post-values are the correct ones.
// But all this can be avoided with a even faster way. The EVM block execution can
// keep track of the written keys, and compare that list with this post-values list.
// This can avoid regenerating the post-tree which is somewhat expensive.
posttree, err := PostStateTreeFromStateDiff(pretree, statediff)
if err != nil {
return fmt.Errorf("error rebuilding the post-tree from proof: %w", err)
}
regeneratedPostTreeRoot := posttree.Commitment().Bytes()
if !bytes.Equal(regeneratedPostTreeRoot[:], postStateRoot) {
return fmt.Errorf("post tree root mismatch: %x != %x", regeneratedPostTreeRoot, postStateRoot)
}

return verifyVerkleProofWithPreState(proof, pretree)
}
38 changes: 19 additions & 19 deletions proof_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestProofEmptyTree(t *testing.T) {

proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ffx32KeyTest}, nil)
cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
t.Fatalf("could not verify verkle proof: %s", ToDot(root))
}
}
Expand All @@ -67,7 +67,7 @@ func TestProofVerifyTwoLeaves(t *testing.T) {
proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ffx32KeyTest}, nil)

cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
t.Fatalf("could not verify verkle proof: %s", ToDot(root))
}
}
Expand All @@ -94,7 +94,7 @@ func TestProofVerifyMultipleLeaves(t *testing.T) {
proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{keys[0]}, nil)

cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
t.Fatal("could not verify verkle proof")
}
}
Expand Down Expand Up @@ -125,7 +125,7 @@ func TestMultiProofVerifyMultipleLeaves(t *testing.T) {
t.Fatal(err)
}
cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, pe.Cis, pe.Zis, pe.Yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, pe.Cis, pe.Zis, pe.Yis, cfg); !ok || err != nil {
t.Fatal("could not verify verkle proof")
}
}
Expand Down Expand Up @@ -172,7 +172,7 @@ func TestMultiProofVerifyMultipleLeavesWithAbsentStem(t *testing.T) {
}

cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, pe.Cis, pe.Zis, pe.Yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, pe.Cis, pe.Zis, pe.Yis, cfg); !ok || err != nil {
t.Fatal("could not verify verkle proof")
}
}
Expand All @@ -199,7 +199,7 @@ func TestMultiProofVerifyMultipleLeavesCommitmentRedundancy(t *testing.T) {
t.Fatal(err)
}
cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, pe.Cis, pe.Zis, pe.Yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, pe.Cis, pe.Zis, pe.Yis, cfg); !ok || err != nil {
t.Fatal("could not verify verkle proof")
}
}
Expand All @@ -219,7 +219,7 @@ func TestProofOfAbsenceInternalVerify(t *testing.T) {
proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ffx32KeyTest}, nil)

cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
t.Fatal("could not verify verkle proof")
}
}
Expand All @@ -239,7 +239,7 @@ func TestProofOfAbsenceLeafVerify(t *testing.T) {
proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{oneKeyTest}, nil)

cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
t.Fatal("could not verify verkle proof")
}
}
Expand All @@ -263,7 +263,7 @@ func TestProofOfAbsenceLeafVerifyOtherSuffix(t *testing.T) {
proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{key}, nil)

cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
t.Fatal("could not verify verkle proof")
}
}
Expand All @@ -285,7 +285,7 @@ func TestProofOfAbsenceStemVerify(t *testing.T) {
proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{key}, nil)

cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
t.Fatal("could not verify verkle proof")
}
}
Expand Down Expand Up @@ -336,7 +336,7 @@ func BenchmarkProofVerification(b *testing.B) {

cfg := GetConfig()
for i := 0; i < b.N; i++ {
if ok, err := VerifyVerkleProof(proof, cis, zis, yis, cfg); err != nil || !ok {
if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); err != nil || !ok {
b.Fatal(err)
}
}
Expand Down Expand Up @@ -458,7 +458,7 @@ func TestProofDeserialize(t *testing.T) {
t.Fatal(err)
}
cfg := GetConfig()
if ok, err := VerifyVerkleProof(deserialized, pe.Cis, pe.Zis, pe.Yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(deserialized, pe.Cis, pe.Zis, pe.Yis, cfg); !ok || err != nil {
t.Fatal("could not verify verkle proof")
}
}
Expand All @@ -472,7 +472,7 @@ func TestProofOfAbsenceEdgeCase(t *testing.T) {
ret, _ := hex.DecodeString("0303030303030303030303030303030303030303030303030303030303030303")
proof, cs, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ret}, nil)
cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, cs, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cs, zis, yis, cfg); !ok || err != nil {
t.Fatal("could not verify proof")
}
}
Expand All @@ -493,7 +493,7 @@ func TestProofOfAbsenceOtherMultipleLeaves(t *testing.T) {
ret2, _ := hex.DecodeString("0303030303030303030303030303030303030303030303030303030303030301")
proof, cs, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ret1, ret2}, nil)
cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, cs, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cs, zis, yis, cfg); !ok || err != nil {
t.Fatal("could not verify proof")
}

Expand Down Expand Up @@ -555,7 +555,7 @@ func TestProofOfAbsenceNoneMultipleStems(t *testing.T) {
ret2, _ := hex.DecodeString("0303030303030303030303030303030303030303030303030303030303030200")
proof, cs, zis, yis, _ := MakeVerkleMultiProof(root, nil, [][]byte{ret1, ret2}, nil)
cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, cs, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cs, zis, yis, cfg); !ok || err != nil {
t.Fatal("could not verify proof")
}

Expand Down Expand Up @@ -1050,7 +1050,7 @@ func TestProofVerificationWithPostState(t *testing.T) { // skipcq: GO-R1005
t.Fatalf("error deserializing proof: %v", err)
}

if err = VerifyVerkleProofWithPreState(dproof, root); err != nil {
if err = verifyVerkleProofWithPreState(dproof, root); err != nil {
t.Fatalf("could not verify verkle proof: %v, original: %s reconstructed: %s", err, ToDot(root), ToDot(postroot))
}

Expand All @@ -1068,7 +1068,7 @@ func TestProofVerificationWithPostState(t *testing.T) { // skipcq: GO-R1005
t.Fatalf("differing root commitments %x != %x", dpostroot.Commitment().Bytes(), postroot.Commitment().Bytes())
}

if err = VerifyVerkleProofWithPreState(dproof, dpreroot); err != nil {
if err = verifyVerkleProofWithPreState(dproof, dpreroot); err != nil {
t.Fatalf("could not verify verkle proof: %v, original: %s reconstructed: %s", err, ToDot(dpreroot), ToDot(dpostroot))
}
})
Expand All @@ -1094,7 +1094,7 @@ func TestGenerateProofWithOnlyAbsentKeys(t *testing.T) {
}

// It must pass.
if ok, err := VerifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
t.Fatalf("original proof didn't verify: %v", err)
}

Expand All @@ -1119,7 +1119,7 @@ func TestGenerateProofWithOnlyAbsentKeys(t *testing.T) {
}

// It must pass.
if ok, err := VerifyVerkleProof(dproof, pe.Cis, pe.Zis, pe.Yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(dproof, pe.Cis, pe.Zis, pe.Yis, cfg); !ok || err != nil {
t.Fatalf("reconstructed proof didn't verify: %v", err)
}

Expand Down
6 changes: 3 additions & 3 deletions tree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1310,7 +1310,7 @@ func TestRustBanderwagonBlock48(t *testing.T) {
t.Logf("serialized proof=%v", vp)

cfg := GetConfig()
if ok, err := VerifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
t.Fatal("proof didn't verify")
}

Expand All @@ -1328,7 +1328,7 @@ func TestRustBanderwagonBlock48(t *testing.T) {
t.Fatal(err)
}

if ok, err := VerifyVerkleProof(dproof, pe.Cis, pe.Zis, pe.Yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(dproof, pe.Cis, pe.Zis, pe.Yis, cfg); !ok || err != nil {
t.Fatal("deserialized proof didn't verify")
}
}
Expand Down Expand Up @@ -1775,7 +1775,7 @@ func runRandTest(rt randTest) error {
}
root.Commit()
proof, cis, zis, yis, _ := MakeVerkleMultiProof(root, nil, keys, nil)
if ok, err := VerifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
if ok, err := verifyVerkleProof(proof, cis, zis, yis, cfg); !ok || err != nil {
rt[i].err = fmt.Errorf("could not verify verkle proof: %s, err %v", ToDot(root), err)
}
// TODO: reconsider if we should avoid returning pointers in Hash() and Commit()
Expand Down
Loading