@@ -234,27 +234,38 @@ func rootFromSubtreeConsistencyProof(hasher merkle.LogHasher, start, end, size u
234234
235235 // Verify the second root.
236236 hash2 := chainInner (hasher , seed , proof [:inner ], mask )
237- // Then, chain the upper part of the proof.
238237 hash2 = chainBorderRight (hasher , hash2 , proof [inner :])
239238 return hash2 , nil
240239}
241240
242241// decompInclProof breaks down inclusion proof for a leaf at the specified
243242// |index| in a tree of the specified |size| into 2 components. The splitting
244243// point between them is where paths to leaves |index| and |size-1| diverge.
245- // Returns lengths of the bottom and upper proof parts correspondingly. The sum
244+ // Returns lengths of the inner and border proof parts correspondingly. The sum
246245// of the two determines the correct length of the inclusion proof.
246+ //
247+ // Inner nodes are left or right siblings depending on the level they are used
248+ // in the proof. There can be multiple nodes per level.
249+ // Border nodes are left siblings only. There's always only one node per level.
247250func decompInclProof (index , size uint64 ) (int , int ) {
248251 inner := innerProofSize (index , size )
249252 border := bits .OnesCount64 (index >> uint (inner ))
250253 return inner , border
251254}
252255
253- // decompSubtreeProof computes the exact proof slice indices needed to reconstruct
254- // the [start, end) subtree root (hash1):
255- // - subInner: end index of inner proof hashes inside the subtree (proof[:subInner])
256- // - inner: start index of border proof hashes (proof[inner:])
257- // - inner+subBorder: end index of border proof hashes inside the subtree
256+ // decompSubtreeProof computes the exact proof slice indices needed to
257+ // reconstruct the [start, end) subtree root
258+ // - subInner: end index of inner proof hashes inside the subtree
259+ // (proof[:subInner]), regardless of the size of the parent tree.
260+ // These nodes can be left or right siblings depending on the level at
261+ // which they are used in the proof. Only left siblings are required to
262+ // reconstruct the subtree root.
263+ // - inner: end index of inner proof hashes inside the tree, and potentially
264+ // outside of the subtree. It is also the start index of border proof
265+ // hashes (proof[inner:]). Border proof hashes are left siblings only.
266+ // There's one per level and they can be inside or outside of the subtree.
267+ // - inner+subBorder: end index of border proof hashes inside the subtree.
268+ // (proof[inner:inner+subBorder]). These nodes are left siblings only.
258269func decompSubtreeProof (start , end , size uint64 , border int ) (int , int , int ) {
259270 // xor trims the common prefix between the first and last entry. The bit len
260271 // of the result is the height of the subtree.
@@ -268,14 +279,18 @@ func decompSubtreeProof(start, end, size uint64, border int) (int, int, int) {
268279
269280 // Number of inner proof nodes from level |shift| up to subtree height |h|
270281 // (clamped at |forkLevel|) that belong inside the [start, end) subtree.
282+ // We take the minimum between h and forkLevel to make sure that subInner
283+ // isn't higher than the subtree root. Substract shift since the proof
284+ // starts at this level.
271285 subInner := min (h , forkLevel ) - shift
272286 // Total number of inner proof nodes between level |shift| and |forkLevel|.
273287 inner := forkLevel - shift
274288 // Number of border proof nodes above |forkLevel| and below subtree height |h|
275- // that belong inside the [start, end) subtree.
289+ // that belong inside the [start, end) subtree. Use max as the border proof
290+ // might not include any node that belong to the subtree.
276291 subBorder := max (0 , border - bits .OnesCount64 ((end - 1 )>> uint (h )))
277- // The proof slice indices needed to reconstruct hash1 are [0:subInner] for inner
278- // chaining and [inner:inner+subBorder] for border chaining.
292+ // The proof slice indices needed to reconstruct hash1 are [0:subInner] for
293+ // inner-right chaining and [inner:inner+subBorder] for border chaining.
279294 return subInner , inner , inner + subBorder
280295}
281296
0 commit comments