From 848d5793a1c6d18e5ac488e199fe2f0f4fd779c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Friedger=20M=C3=BCffke?= Date: Thu, 22 Jul 2021 13:21:00 +0200 Subject: [PATCH 1/2] add tests for all bitcoin tree leaves --- test/merkletree.test.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/merkletree.test.js b/test/merkletree.test.js index c5de669..d6ba675 100644 --- a/test/merkletree.test.js +++ b/test/merkletree.test.js @@ -351,7 +351,7 @@ test('solidity keccak256 with duplicate leaves', t => { }) test('sha-256 with option.isBitcoinTree', t => { - t.plan(2) + t.plan(100) /* Derived from: * http://www.righto.com/2014/02/bitcoin-mining-hard-way-algorithms.html @@ -464,9 +464,10 @@ test('sha-256 with option.isBitcoinTree', t => { const root = Buffer.from('871714dcbae6c8193a2bb9b2a69fe1c0440399f38d94b3a0f1b447275a29978a', 'hex') t.equal(tree.getRoot().toString('hex'), root.toString('hex')) - const proof_0 = tree.getProof(leaves[0]) - - t.true(tree.verify(proof_0, leaves[0], root)) + for (let i = 0; i < leaves.length; i++) { + const proof_0 = tree.getProof(leaves[i]) + t.true(tree.verify(proof_0, leaves[i], root), 'proof verification for ' + i) + } }) test('keccak256 - hex strings', t => { From 95624eeb5bb916948b656ded0ba130bd4957d913 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Friedger=20M=C3=BCffke?= Date: Thu, 22 Jul 2021 14:46:37 +0200 Subject: [PATCH 2/2] fix bitcoinTree edge case (#38) --- src/MerkleTree.ts | 54 ++++++++++++++++------------------------------- 1 file changed, 18 insertions(+), 36 deletions(-) diff --git a/src/MerkleTree.ts b/src/MerkleTree.ts index 30c2079..6daa5d5 100644 --- a/src/MerkleTree.ts +++ b/src/MerkleTree.ts @@ -396,46 +396,28 @@ export class MerkleTree extends Base { return [] } - if (this.isBitcoinTree && index === (this.leaves.length - 1)) { - // Proof Generation for Bitcoin Trees + for (let i = 0; i < this.layers.length; i++) { + const layer = this.layers[i] + const isRightNode = index % 2 + const pairIndex = (isRightNode ? index - 1 + : this.isBitcoinTree && index === layer.length - 1 && i < this.layers.length - 1 + // Proof Generation for Bitcoin Trees + ? index + // Proof Generation for Non-Bitcoin Trees + : index + 1) - for (let i = 0; i < this.layers.length - 1; i++) { - const layer = this.layers[i] - const isRightNode = index % 2 - const pairIndex = (isRightNode ? index - 1 : index) - - if (pairIndex < layer.length) { - proof.push({ - data: layer[pairIndex] - }) - } - - // set index to parent index - index = (index / 2) | 0 + if (pairIndex < layer.length) { + proof.push({ + position: isRightNode ? 'left' : 'right', + data: layer[pairIndex] + }) } - return proof - } else { - // Proof Generation for Non-Bitcoin Trees - - for (let i = 0; i < this.layers.length; i++) { - const layer = this.layers[i] - const isRightNode = index % 2 - const pairIndex = (isRightNode ? index - 1 : index + 1) - - if (pairIndex < layer.length) { - proof.push({ - position: isRightNode ? 'left' : 'right', - data: layer[pairIndex] - }) - } - - // set index to parent index - index = (index / 2) | 0 - } - - return proof + // set index to parent index + index = (index / 2) | 0 } + + return proof } /**