Skip to content

Commit 0f83447

Browse files
committed
better isSubtreeValid
1 parent 4098e0c commit 0f83447

2 files changed

Lines changed: 15 additions & 16 deletions

File tree

proof/proof.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,12 @@ func Inclusion(index, size uint64) (Nodes, error) {
5959
// - start to be a multiple of the smallest power of two greater than or equal to
6060
// (end - start)
6161
func SubtreeInclusion(index, start, end uint64) (Nodes, error) {
62-
if start >= end {
63-
return Nodes{}, fmt.Errorf("start %d greater than or equal to end %d", start, end)
62+
if err := isSubtreeValid(start, end); err != nil {
63+
return Nodes{}, fmt.Errorf("subtree invalid: %v", err)
6464
}
6565
if index < start || index >= end {
6666
return Nodes{}, fmt.Errorf("index %d out of bounds for subtree [%d, %d)", index, start, end)
6767
}
68-
if err := isSubtreeValid(start, end); err != nil {
69-
return Nodes{}, fmt.Errorf("subtree invalid: %v", err)
70-
}
7168

7269
// Shift the subtree to the left, such that it starts at 0.
7370
p := nodes(index-start, 0, end-start).skipFirst()
@@ -229,20 +226,27 @@ func reverse(ids []compact.NodeID) {
229226
// - no extra node to the left of the subtree
230227
// - potentially extra nodes to the right of the subtree
231228
func isSubtreeValid(start, end uint64) error {
232-
l := end - start
229+
if start >= end {
230+
return fmt.Errorf("start %d must be strictly less than end %d", start, end)
231+
}
233232
if start == 0 {
234233
return nil
235-
} else if l > uint64(1)<<63 {
236-
// special-case large subtree to avoid panic
234+
}
235+
236+
l := end - start
237+
238+
// special-case large subtree to avoid panic
239+
if l > uint64(1)<<63 {
237240
return fmt.Errorf("start %d must be 0 when subtree length %d > 1<<63. ", start, l)
238241
}
239-
if bc := bitCeil(l); start%bc != 0 {
242+
if bc := bitCeil(l); start&(bc-1) != 0 {
240243
return fmt.Errorf("start %d not a multiple of bit_ceil(end - start) = %d", start, bc)
241244
}
245+
242246
return nil
243247
}
244248

245-
// bitCeil returns the smallest power of 2 larger than n.
249+
// bitCeil returns the smallest power of 2 larger or equal than n.
246250
// MUST NOT be used with n larger than uint64(1)<<63.
247251
func bitCeil(n uint64) uint64 {
248252
if n <= 1 {

testonly/tree_fuzz_test.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package testonly
33
import (
44
"bytes"
55
"math"
6-
"math/bits"
76
"testing"
87

98
"github.com/google/go-cmp/cmp"
@@ -86,8 +85,7 @@ func FuzzSubtreeInclusionProofAndVerify(f *testing.F) {
8685
if end >= math.MaxUint16 {
8786
return
8887
}
89-
t.Logf("index=%d, start=%d, end=%d", index, start, end)
90-
if start >= end {
88+
if err := proof.IsSubtreeValid(start, end); err != nil {
9189
return
9290
}
9391
if index < start {
@@ -96,9 +94,6 @@ func FuzzSubtreeInclusionProofAndVerify(f *testing.F) {
9694
if index >= end {
9795
return
9896
}
99-
if bc := uint64(1) << bits.Len64(end-start-1); start%bc != 0 {
100-
return
101-
}
10297
tree := newTree(genEntries(end))
10398
p, err := tree.SubtreeInclusionProof(index, start, end)
10499
t.Logf("proof=%v", p)

0 commit comments

Comments
 (0)