@@ -94,6 +94,21 @@ func (t *Tree) HashAt(size uint64) []byte {
9494 return hash
9595}
9696
97+ // HashSubtreeAt 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 {
101+ return t .hasher .EmptyRoot ()
102+ }
103+ hashes := t .getNodes (compact .RangeNodes (start , end , nil ))
104+
105+ hash := hashes [len (hashes )- 1 ]
106+ for i := len (hashes ) - 2 ; i >= 0 ; i -- {
107+ hash = t .hasher .HashChildren (hashes [i ], hash )
108+ }
109+ return hash
110+ }
111+
97112// InclusionProof returns the inclusion proof for the given leaf index in the
98113// tree of the given size. Requires 0 <= index < size <= Size(), otherwise may
99114// panic.
@@ -105,6 +120,20 @@ func (t *Tree) InclusionProof(index, size uint64) ([][]byte, error) {
105120 return nodes .Rehash (t .getNodes (nodes .IDs ), t .hasher .HashChildren )
106121}
107122
123+ // SubtreeInclusionProof returns the inclusion proof for the given leaf index in the
124+ // [start, end) subtree.
125+ // It requires end <= Size(), and may panic otherwise.
126+ // It returns an error if:
127+ // - index is outside of [start, end)
128+ // - the subtree boundaries are not MTC compliant
129+ func (t * Tree ) SubtreeInclusionProof (index , start , end uint64 ) ([][]byte , error ) {
130+ nodes , err := proof .SubtreeInclusion (index , start , end )
131+ if err != nil {
132+ return nil , err
133+ }
134+ return nodes .Rehash (t .getNodes (nodes .IDs ), t .hasher .HashChildren )
135+ }
136+
108137// ConsistencyProof returns the consistency proof between the two given tree
109138// sizes. Requires 0 <= size1 <= size2 <= Size(), otherwise may panic.
110139func (t * Tree ) ConsistencyProof (size1 , size2 uint64 ) ([][]byte , error ) {
0 commit comments