You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In NMTs, an empty proof is defined as a proof that satisfies two conditions: (1) it contains an empty range i.e., proof.start == proof.end, and (2) its nodes field is empty. However, currently, we do not check whether proof.leafHash == 0. This can lead to situations where a proof can be treated as both an absence proof and an empty proof, depending on the order of operations (depends on which type is checked first). Specifically, a proof that satisfies conditions (1) and (2) but has a non-empty leafHash will pass both IsEmptyProof() and IsOfAbsence() checks.
The following test demonstrates this inconsistency:
// create an NMT with 8 sequentially namespaced leaves, numbered from 1 to 8.tree:=exampleNMT(1, 1, 2, 3, 4, 5, 6, 7, 8)
root, err:=tree.Root()
assert.NoError(t, err)
dummyValue:=createByteSlice(tree.treeHasher.Size(), 0x01)
// this proof is neither a well-formed absence proof nor a well-formed empty proofproof:=Proof{start: 1, end: 1, leafHash: dummyValue, nodes: [][]byte{}}
assert.True(t, proof.IsOfAbsence()) // this check passes while proof is not a well-formed absence proof, this result is misleadingassert.True(t, proof.IsEmptyProof()) // this check passes while proof is not a well-formed empty proof, this result is misleading// the proof is not a proper empty proof, yet it can be used as a valid empty proofisVerified:=proof.VerifyNamespace(tree.treeHasher.baseHasher, []byte{10}, [][]byte{}, root)
assert.True(t, isVerified)
The text was updated successfully, but these errors were encountered:
…pty proof definition (#192)
## Overview
Closes#181
The updates made by this PR will result in a breaking change, as empty
proofs with a non-empty `leafHash` field will no longer be considered
valid. This means that their verification through `VerifyNamespace` will
fail.
Example:
```go
nIDSize := 1
tree := exampleNMT(nIDSize, 1, 2, 3, 4)
root, err := tree.Root()
require.NoError(t, err)
hasher :=
proof := Proof{
start: 0,
end: 0,
nodes: nil,
leafHash: tree.leafHashes[0],
}
res := proof.VerifyNamespace(tree.treeHasher.baseHasher, []byte{0}, [][]byte{}, root)
require.True(res) // this is false with the changes in this PR, however, previously, it was true
```
## Checklist
- [x] New and updated code has appropriate documentation
- [x] New and updated code has new and/or updated testing
- [x] Required CI checks are passing
- [x] Visual proof for any user facing features like CLI or
documentation updates
- [x] Linked issues closed with keywords
Problem
In NMTs, an empty
proof
is defined as a proof that satisfies two conditions: (1) it contains an empty range i.e.,proof.start == proof.end
, and (2) itsnodes
field is empty. However, currently, we do not check whetherproof.leafHash == 0
. This can lead to situations where a proof can be treated as both an absence proof and an empty proof, depending on the order of operations (depends on which type is checked first). Specifically, a proof that satisfies conditions (1) and (2) but has a non-emptyleafHash
will pass bothIsEmptyProof()
andIsOfAbsence()
checks.The following test demonstrates this inconsistency:
The text was updated successfully, but these errors were encountered: