From 0e6ae14dee09ee540c8d8231650ac39e833e60ec Mon Sep 17 00:00:00 2001 From: Gui Iribarren Date: Mon, 4 Nov 2024 14:34:41 +0100 Subject: [PATCH] arbo: CheckProof now returns nil or error instead of (bool, error) --- api/censuses.go | 9 +++------ censustree/censustree.go | 9 ++++++--- censustree/censustree_test.go | 3 +-- tree/arbo/addbatch_test.go | 14 +++++--------- tree/arbo/proof.go | 10 +++++++--- tree/arbo/tree_test.go | 11 ++++------- tree/tree.go | 4 ++-- tree/tree_test.go | 3 +-- vochain/transaction/proofs/arboproof/arboproof.go | 4 ++-- vochain/vote_test.go | 3 +-- 10 files changed, 32 insertions(+), 38 deletions(-) diff --git a/api/censuses.go b/api/censuses.go index 9447d1654..19b1c3755 100644 --- a/api/censuses.go +++ b/api/censuses.go @@ -945,15 +945,12 @@ func (a *API) censusVerifyHandler(msg *apirest.APIdata, ctx *httprouter.HTTPCont } } - valid, err := ref.Tree().VerifyProof(leafKey, cdata.Value, cdata.CensusProof, cdata.CensusRoot) - if err != nil { + if err := ref.Tree().VerifyProof(leafKey, cdata.Value, cdata.CensusProof, cdata.CensusRoot); err != nil { return ErrCensusProofVerificationFailed.WithErr(err) } - if !valid { - return ctx.Send(nil, apirest.HTTPstatusBadRequest) - } + response := Census{ - Valid: valid, + Valid: true, } var data []byte if data, err = json.Marshal(&response); err != nil { diff --git a/censustree/censustree.go b/censustree/censustree.go index 7a5ce433f..78fb09b7a 100644 --- a/censustree/censustree.go +++ b/censustree/censustree.go @@ -162,12 +162,12 @@ func (t *Tree) Get(key []byte) ([]byte, error) { // VerifyProof verifies a census proof. // If the census is indexed key can be nil (value provides the key already). // If root is nil the last merkle root is used for verify. -func (t *Tree) VerifyProof(key, value, proof, root []byte) (bool, error) { +func (t *Tree) VerifyProof(key, value, proof, root []byte) error { var err error if root == nil { root, err = t.Root() if err != nil { - return false, fmt.Errorf("cannot get tree root: %w", err) + return fmt.Errorf("cannot get tree root: %w", err) } } // If the provided key is longer than the defined maximum length truncate it @@ -176,7 +176,10 @@ func (t *Tree) VerifyProof(key, value, proof, root []byte) (bool, error) { if len(leafKey) > DefaultMaxKeyLen { leafKey = leafKey[:DefaultMaxKeyLen] } - return t.tree.VerifyProof(leafKey, value, proof, root) + if err := t.tree.VerifyProof(leafKey, value, proof, root); err != nil { + return err + } + return nil } // GenProof generates a census proof for the provided key. diff --git a/censustree/censustree_test.go b/censustree/censustree_test.go index 7064e5965..224b5b95c 100644 --- a/censustree/censustree_test.go +++ b/censustree/censustree_test.go @@ -110,9 +110,8 @@ func TestWeightedProof(t *testing.T) { root, err := censusTree.Root() qt.Assert(t, err, qt.IsNil) - verified, err := censusTree.VerifyProof(userKey, value, siblings, root) + err = censusTree.VerifyProof(userKey, value, siblings, root) qt.Assert(t, err, qt.IsNil) - qt.Assert(t, verified, qt.IsTrue) } func TestGetCensusWeight(t *testing.T) { diff --git a/tree/arbo/addbatch_test.go b/tree/arbo/addbatch_test.go index 33ba97dae..7950b2f8c 100644 --- a/tree/arbo/addbatch_test.go +++ b/tree/arbo/addbatch_test.go @@ -998,14 +998,12 @@ func TestAddKeysWithEmptyValues(t *testing.T) { // check with empty array root, err := tree.Root() c.Assert(err, qt.IsNil) - verif, err := CheckProof(tree.hashFunction, keys[9], []byte{}, root, siblings) + err = CheckProof(tree.hashFunction, keys[9], []byte{}, root, siblings) c.Assert(err, qt.IsNil) - c.Check(verif, qt.IsTrue) // check with array with only 1 zero - verif, err = CheckProof(tree.hashFunction, keys[9], []byte{0}, root, siblings) + err = CheckProof(tree.hashFunction, keys[9], []byte{0}, root, siblings) c.Assert(err, qt.IsNil) - c.Check(verif, qt.IsTrue) // check with array with 32 zeroes e32 := []byte{ @@ -1013,12 +1011,10 @@ func TestAddKeysWithEmptyValues(t *testing.T) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, } c.Assert(len(e32), qt.Equals, 32) - verif, err = CheckProof(tree.hashFunction, keys[9], e32, root, siblings) + err = CheckProof(tree.hashFunction, keys[9], e32, root, siblings) c.Assert(err, qt.IsNil) - c.Check(verif, qt.IsTrue) // check with array with value!=0 returns false at verification - verif, err = CheckProof(tree.hashFunction, keys[9], []byte{0, 1}, root, siblings) - c.Assert(err, qt.IsNil) - c.Check(verif, qt.IsFalse) + err = CheckProof(tree.hashFunction, keys[9], []byte{0, 1}, root, siblings) + c.Assert(err, qt.ErrorMatches, "calculated root doesn't match expected root") } diff --git a/tree/arbo/proof.go b/tree/arbo/proof.go index e9ca34ae5..35a9fbe99 100644 --- a/tree/arbo/proof.go +++ b/tree/arbo/proof.go @@ -160,12 +160,16 @@ func bytesToBitmap(b []byte) []bool { // CheckProof verifies the given proof. The proof verification depends on the // HashFunction passed as parameter. -func CheckProof(hashFunc HashFunction, k, v, root, packedSiblings []byte) (bool, error) { +// Returns nil if the proof is valid, or an error otherwise. +func CheckProof(hashFunc HashFunction, k, v, root, packedSiblings []byte) error { hashes, err := CalculateProofNodes(hashFunc, k, v, packedSiblings) if err != nil { - return false, err + return err } - return bytes.Equal(hashes[0], root), nil + if !bytes.Equal(hashes[0], root) { + return fmt.Errorf("calculated root doesn't match expected root") + } + return nil } // CalculateProofNodes calculates the chain of hashes in the path of the given proof. diff --git a/tree/arbo/tree_test.go b/tree/arbo/tree_test.go index 7980e1a93..351d30311 100644 --- a/tree/arbo/tree_test.go +++ b/tree/arbo/tree_test.go @@ -539,9 +539,8 @@ func TestGenProofAndVerify(t *testing.T) { root, err := tree.Root() c.Assert(err, qt.IsNil) - verif, err := CheckProof(tree.hashFunction, k, v, root, siblings) + err = CheckProof(tree.hashFunction, k, v, root, siblings) c.Assert(err, qt.IsNil) - c.Check(verif, qt.IsTrue) } func TestDumpAndImportDump(t *testing.T) { @@ -933,16 +932,14 @@ func TestKeyLen(t *testing.T) { root, err := tree.Root() c.Assert(err, qt.IsNil) - verif, err := CheckProof(tree.HashFunction(), kAux, vAux, root, packedSiblings) + err = CheckProof(tree.HashFunction(), kAux, vAux, root, packedSiblings) c.Assert(err, qt.IsNil) - c.Assert(verif, qt.IsTrue) // use a similar key but with one zero, expect that CheckProof fails on // the verification kAux = append(kAux, 0) - verif, err = CheckProof(tree.HashFunction(), kAux, vAux, root, packedSiblings) - c.Assert(err, qt.IsNil) - c.Assert(verif, qt.IsFalse) + err = CheckProof(tree.HashFunction(), kAux, vAux, root, packedSiblings) + c.Assert(err, qt.ErrorMatches, "calculated root doesn't match expected root") } func TestKeyLenBiggerThan32(t *testing.T) { diff --git a/tree/tree.go b/tree/tree.go index 8a5fc217e..dc491be7a 100644 --- a/tree/tree.go +++ b/tree/tree.go @@ -229,13 +229,13 @@ func (t *Tree) GenProof(rTx db.Reader, key []byte) ([]byte, []byte, error) { // VerifyProof checks the proof for the given key, value and root, using the // passed hash function -func VerifyProof(hashFunc arbo.HashFunction, key, value, proof, root []byte) (bool, error) { +func VerifyProof(hashFunc arbo.HashFunction, key, value, proof, root []byte) error { return arbo.CheckProof(hashFunc, key, value, root, proof) } // VerifyProof checks the proof for the given key, value and root, using the // hash function of the Tree -func (t *Tree) VerifyProof(key, value, proof, root []byte) (bool, error) { +func (t *Tree) VerifyProof(key, value, proof, root []byte) error { return VerifyProof(t.tree.HashFunction(), key, value, proof, root) } diff --git a/tree/tree_test.go b/tree/tree_test.go index 2e9d7a242..8be16b5bb 100644 --- a/tree/tree_test.go +++ b/tree/tree_test.go @@ -84,9 +84,8 @@ func TestGenProof(t *testing.T) { root, err := tree.Root(wTx) qt.Assert(t, err, qt.IsNil) - verif, err := tree.VerifyProof(k, v, proof, root) + err = tree.VerifyProof(k, v, proof, root) qt.Assert(t, err, qt.IsNil) - qt.Assert(t, verif, qt.IsTrue) err = wTx.Commit() qt.Assert(t, err, qt.IsNil) diff --git a/vochain/transaction/proofs/arboproof/arboproof.go b/vochain/transaction/proofs/arboproof/arboproof.go index f9e933d4a..689b73bd8 100644 --- a/vochain/transaction/proofs/arboproof/arboproof.go +++ b/vochain/transaction/proofs/arboproof/arboproof.go @@ -52,8 +52,8 @@ func (*ProofVerifierArbo) Verify(process *models.Process, envelope *models.VoteE key = key[:censustree.DefaultMaxKeyLen] } } - valid, err := tree.VerifyProof(hashFunc, key, p.AvailableWeight, p.Siblings, process.CensusRoot) - if !valid || err != nil { + + if err := tree.VerifyProof(hashFunc, key, p.AvailableWeight, p.Siblings, process.CensusRoot); err != nil { return false, nil, err } // Legacy: support p.LeafWeight == nil, assume then value=1 diff --git a/vochain/vote_test.go b/vochain/vote_test.go index cf04fcec9..cbee6cfde 100644 --- a/vochain/vote_test.go +++ b/vochain/vote_test.go @@ -46,9 +46,8 @@ func testCreateKeysAndBuildWeightedZkCensus(t *testing.T, size int, weight *big. _, proof, err := tr.GenProof(k.Address().Bytes()) qt.Check(t, err, qt.IsNil) proofs = append(proofs, proof) - valid, err := tr.VerifyProof(k.Address().Bytes(), encWeight, proof, root) + err = tr.VerifyProof(k.Address().Bytes(), encWeight, proof, root) qt.Check(t, err, qt.IsNil) - qt.Check(t, valid, qt.IsTrue) } return keys, root, proofs }