From 6d64ce0c8722d8376e478a6044da14457ffe3f68 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 4 Mar 2020 09:12:53 +1300 Subject: [PATCH] Fix vulnerability in get_peaks() pseudocode This addresses finding NCC-1908_Zcash-002. --- zip-0221.rst | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/zip-0221.rst b/zip-0221.rst index 1c921be1..72f53f7d 100644 --- a/zip-0221.rst +++ b/zip-0221.rst @@ -451,21 +451,18 @@ With each new block ``B_n``, we append a new MMR leaf node corresponding to bloc def get_peaks(node: ZcashMMRNode) -> List[ZcashMMRNode]: peaks: List[ZcashMMRNode] = [] - left_child = node.left_child - right_child = node.right_child + # Get number of leaves. + leaves = latest_height - earliest_height + 1 - # find the number of leaves in the subtree - left_leaves = left_child.latest_height - left_child.earliest_height + 1 - right_leaves = right_child.latest_height - right_child.earliest_height + 1 - - if (left_leaves & (left_leaves - 1)) == 0: - peaks.append(left_child) + # Check if the number of leaves is a power of two. + if (leaves & (leaves - 1)) == 0: + # Tree is full, hence a single peak. This also covers the + # case of a single isolated leaf. + peaks.append(node) else: + # If the number of leaves is not a power of two, then this + # node must be internal, and cannot be a peak. peaks.extend(get_peaks(left_child)) - - if (right_leaves & (right_leaves - 1)) == 0: - peaks.append(right_child) - else: peaks.extend(get_peaks(right_child)) return peaks