From 8787a6fc1636f59a6a3104f89e4e0b4c1d60f609 Mon Sep 17 00:00:00 2001 From: Mark Friedenbach Date: Fri, 22 Jan 2016 08:50:33 -0800 Subject: [PATCH] f 'Add fast Merkle branch functions.' Turns out the path calculation code, as written, did not work. Additionally, doing the position -> path calculation at validation time is both wasteful and introduces a source of malleability. Thankfully none of this code is used anywhere yet. --- src/consensus/merkle.cpp | 27 +++++++++++---------- src/consensus/merkle.h | 51 +++++++++++++++++++++++++++++++++++++--- 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/src/consensus/merkle.cpp b/src/consensus/merkle.cpp index 3b2f6cd587..c5801b361f 100644 --- a/src/consensus/merkle.cpp +++ b/src/consensus/merkle.cpp @@ -181,36 +181,37 @@ uint256 ComputeFastMerkleRoot(const std::vector& leaves) { return hash; } -std::vector ComputeFastMerkleBranch(const std::vector& leaves, uint32_t position) { +std::pair, uint32_t> ComputeFastMerkleBranch(const std::vector& leaves, uint32_t position) { std::vector ret; MerkleComputation(leaves, NULL, NULL, position, &ret, MERKLE_COMPUTATION_FAST); - return ret; -} - -uint256 ComputeFastMerkleRootFromBranch(const uint256& leaf, const std::vector& vMerkleBranch, uint32_t nIndex) { size_t max = 0; for (int i = 0; i < 32; ++i) - if (nIndex & ((uint32_t)1)< vMerkleBranch.size()) { + uint32_t path = position; + while (max > ret.size()) { int i; for (i = max-1; i >= 0; --i) - if (!(nIndex & ((uint32_t)1)<>1) | - ((((uint32_t)1)<< i )-1); + return std::pair, uint32_t>(); + path = ((path & ~((((uint32_t)1)<<(i+1))-1))>>1) + | (path & ((((uint32_t)1)<< i )-1)); --max; } + return std::pair, uint32_t>(ret, path); +} + +uint256 ComputeFastMerkleRootFromBranch(const uint256& leaf, const std::vector& vMerkleBranch, uint32_t nPath) { uint256 hash = leaf; for (std::vector::const_iterator it = vMerkleBranch.begin(); it != vMerkleBranch.end(); ++it) { - if (nIndex & 1) { + if (nPath & 1) { MerkleHash_Sha256Midstate(hash, *it, hash); } else { MerkleHash_Sha256Midstate(hash, hash, *it); } - nIndex >>= 1; + nPath >>= 1; } return hash; } diff --git a/src/consensus/merkle.h b/src/consensus/merkle.h index 71eb27ad19..81b31fda37 100644 --- a/src/consensus/merkle.h +++ b/src/consensus/merkle.h @@ -20,11 +20,56 @@ uint256 ComputeMerkleRootFromBranch(const uint256& leaf, const std::vector& leaves); -std::vector ComputeFastMerkleBranch(const std::vector& leaves, uint32_t position); -uint256 ComputeFastMerkleRootFromBranch(const uint256& leaf, const std::vector& branch, uint32_t position); +std::pair, uint32_t> ComputeFastMerkleBranch(const std::vector& leaves, uint32_t position); +uint256 ComputeFastMerkleRootFromBranch(const uint256& leaf, const std::vector& branch, uint32_t path); /* * Compute the Merkle root of the transactions in a block.