@@ -94,6 +94,24 @@ func (t *Tree) HashAt(size uint64) []byte {
9494 return hash
9595}
9696
97+ // SubtreeHashAt returns the root hash of the [start, end) subtree.
98+ // Requires 0 <= start <= end <= Size() otherwise panics.
99+ func (t * Tree ) SubtreeHashAt (start , end uint64 ) []byte {
100+ if start > end || end > t .size {
101+ panic ("invalid subtree range" )
102+ }
103+ if start == end {
104+ return t .hasher .EmptyRoot ()
105+ }
106+ hashes := t .getNodes (compact .RangeNodes (start , end , nil ))
107+
108+ hash := hashes [len (hashes )- 1 ]
109+ for i := len (hashes ) - 2 ; i >= 0 ; i -- {
110+ hash = t .hasher .HashChildren (hashes [i ], hash )
111+ }
112+ return hash
113+ }
114+
97115// InclusionProof returns the inclusion proof for the given leaf index in the
98116// tree of the given size. Requires 0 <= index < size <= Size(), otherwise may
99117// panic.
@@ -105,6 +123,20 @@ func (t *Tree) InclusionProof(index, size uint64) ([][]byte, error) {
105123 return nodes .Rehash (t .getNodes (nodes .IDs ), t .hasher .HashChildren )
106124}
107125
126+ // SubtreeInclusionProof returns the inclusion proof for the given leaf index in the
127+ // [start, end) subtree.
128+ // It requires end <= Size(), and may panic otherwise.
129+ // It returns an error if:
130+ // - index is outside of [start, end)
131+ // - start is not a multiple of the smallest power of two greater than or equal to (end-start)
132+ func (t * Tree ) SubtreeInclusionProof (index , start , end uint64 ) ([][]byte , error ) {
133+ nodes , err := proof .SubtreeInclusion (index , start , end )
134+ if err != nil {
135+ return nil , err
136+ }
137+ return nodes .Rehash (t .getNodes (nodes .IDs ), t .hasher .HashChildren )
138+ }
139+
108140// ConsistencyProof returns the consistency proof between the two given tree
109141// sizes. Requires 0 <= size1 <= size2 <= Size(), otherwise may panic.
110142func (t * Tree ) ConsistencyProof (size1 , size2 uint64 ) ([][]byte , error ) {
0 commit comments