From 05a4ac2b5f20ad5aa118a33b73dbf8a87c31fcbe Mon Sep 17 00:00:00 2001 From: mb Date: Thu, 9 Nov 2023 22:38:25 +0300 Subject: [PATCH] Add TestRecursiveProofFixedSizeMerkleTree for recursive proof generation --- merkle/merkle_test.go | 59 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/merkle/merkle_test.go b/merkle/merkle_test.go index f2dd6094..db47c993 100644 --- a/merkle/merkle_test.go +++ b/merkle/merkle_test.go @@ -11,7 +11,8 @@ import ( // - t: a pointer to the testing.T object // - proofs: a slice of pointers to big.Int objects representing the proofs // Returns: -// none +// +// none func debugProof(t *testing.T, proofs []*big.Int) { t.Log("...proof") for k, v := range proofs { @@ -26,7 +27,8 @@ func debugProof(t *testing.T, proofs []*big.Int) { // Parameters: // - t: A testing.T object used for reporting test failures and logging. // Returns: -// none +// +// none func TestGeneral_FixedSizeMerkleTree_Check1(t *testing.T) { leaves := []*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4), big.NewInt(5), big.NewInt(6), big.NewInt(7)} merkleTree, err := NewFixedSizeMerkleTree(leaves...) @@ -61,3 +63,56 @@ func TestGeneral_FixedSizeMerkleTree_Check1(t *testing.T) { t.Fatal("root should match proof. it does not") } } + +// TestRecursiveProofFixedSizeMerkleTree is a Go function that tests the correctness of the recursive proof generation in the FixedSizeMerkleTree. +// +// It creates a Merkle tree with multiple leaves, selects a specific leaf, and generates a Merkle proof using the recursiveProof method. +// The test then reconstructs the Merkle root using the generated proof and verifies that it matches the original root of the Merkle tree. +// +// Parameters: +// - t: A testing.T object used for reporting test failures and logging. +// Returns: +// +// none +func TestRecursiveProofFixedSizeMerkleTree(t *testing.T) { + // Create a Merkle tree with multiple leaves + leaves := []*big.Int{big.NewInt(1), big.NewInt(2), big.NewInt(3), big.NewInt(4), big.NewInt(5)} + merkleTree, err := NewFixedSizeMerkleTree(leaves...) + if err != nil { + t.Fatalf("Error creating a Merkle tree: %v", err) + } + + // Choose a leaf for which to generate the Merkle proof + targetLeaf := leaves[2] // Replace with the desired leaf + + // Generate the Merkle proof using the recursiveProof method + proof, err := merkleTree.recursiveProof(targetLeaf, 0, []*big.Int{}) + if err != nil { + t.Fatalf("Error generating Merkle proof: %v", err) + } + + // Verify the correctness of the generated proof + reconstructedRoot, err := reconstructRootFromProof(targetLeaf, proof) + if err != nil { + t.Fatalf("Error reconstructing Merkle root from proof: %v", err) + } + + // Verify that the reconstructed root matches the original root + if merkleTree.Root.Cmp(reconstructedRoot) != 0 { + t.Fatalf("Reconstructed Merkle root does not match the original root. Expected: 0x%s, Got: 0x%s", merkleTree.Root.Text(16), reconstructedRoot.Text(16)) + } +} + +// reconstructRootFromProof is a helper function that reconstructs the Merkle +// root from a given root, leaf, and Merkle proof. +func reconstructRootFromProof(leaf *big.Int, proof []*big.Int) (*big.Int, error) { + currentHash := leaf + for _, sibling := range proof { + var err error + currentHash, err = MerkleHash(currentHash, sibling) + if err != nil { + return nil, err + } + } + return currentHash, nil +}