Chapter 5: The Invalid Proof – The Merkle Proof Verifier

The Verification Lab was unusually quiet the morning after the expanded audit began. The only sounds were the soft hum of cooling fans, the occasional click of keys, and the rhythmic tapping of Liam’s pen against his notebook. Jenna sat at her central workstation, her eyes fixed on the screen where the invalid proof from the Corrupt Node was displayed in all its cryptographic glory.

She’d been staring at it for an hour, turning it over in her mind like a puzzle piece that didn’t quite fit. The numbers were wrong—she knew that—but she wanted to understand exactly why they were wrong. Not just that the verification failed, but what the failure revealed about the person who’d created it.

“Liam, come look at this,” she said, gesturing to the screen.

Liam set down his pen and wheeled his chair over. “What is it?”

“The invalid proof the Corrupt Node sent us,” Jenna said. “I’ve been analyzing it in detail, and I think I’ve figured out how they tried to fake it.”

She pulled up the proof data on her main monitor:

VALIDATOR'S PROOF DATA:
Block Height: 843291
Validator ID: 0x3f8a...
Merkle Root (claimed): 0x8d3a78f9b2c4e5d6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a
Transaction Hash: 0x7f83b1657ff1fc53b92dc18148a1d65dfc2d4b1fa3d677284addd200126d9069
Proof Path:
  Level 1 Sibling: 0x9f7b3a1c2d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9
  Level 2 Sibling: 0x3d8c4e2f1a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a2b1c
  Level 3 Sibling: 0x7e5f1a3b2c4d5e6f7a8b9c0d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9
  Level 4 Sibling: 0x2c9d6b5a4e3f2a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8

“Now watch what happens when we run the verification,” Jenna said, typing a command:

> VERIFY_PROOF_VERBOSE(tx_hash: 0x7f83..., proof_path: [0x9f7b..., 0x3d8c..., 0x7e5f..., 0x2c9d...], merkle_root: 0x8d3a...)
> COMPUTING...
> Step 1: H(0x7f83... || 0x9f7b...) = 0x3d8c...
> Step 2: H(0x3d8c... || 0x3d8c...) = 0x7e5f...
> Step 3: H(0x7e5f... || 0x7e5f...) = 0x2c9d...
> Step 4: H(0x2c9d... || 0x2c9d...) = 0x3f7a...
> Step 5: Compare 0x3f7a... to 0x8d3a...
> RESULT: MISMATCH

“See that?” Jenna said, pointing to the screen. “The final hash is 0x3f7a…, but the validator’s root is 0x8d3a… They don’t match. The proof doesn’t even verify against their own fake root.”

Liam studied the numbers. “Wait, so they didn’t even make the proof consistent with their fake root? They just… made stuff up?”

“That’s exactly what it looks like,” Jenna said. “And that’s the most interesting part of this whole thing.”

She pulled up a new document and began writing out the steps in more detail, breaking down each component:

ANALYSIS: INVALID PROOF

Step 1: Transaction hash + Sibling 1 → Intermediate 1
0x7f83... + 0x9f7b... = 0x3d8c... ✓

Step 2: Intermediate 1 + Sibling 2 → Intermediate 2
0x3d8c... + 0x3d8c... = 0x7e5f... ✓

Step 3: Intermediate 2 + Sibling 3 → Intermediate 3
0x7e5f... + 0x7e5f... = 0x2c9d... ✓

Step 4: Intermediate 3 + Sibling 4 → Intermediate 4
0x2c9d... + 0x2c9d... = 0x3f7a... ✓

Step 5: Compare Intermediate 4 to claimed Merkle Root
0x3f7a... ≠ 0x8d3a... ❌

CONCLUSION: The proof path, when recomputed, produces a different root than the one the validator claimed. The proof is invalid.

“Notice something interesting?” Jenna asked, turning to Liam.

Liam squinted at the steps. “All the intermediate hashes are right… except the final one?”

“Exactly,” Jenna said. “The first four steps work. The hashing is correct. But the final hash doesn’t match the root. That means the validator’s claimed root and the proof path they provided are from different trees.”

She pulled up a new diagram—two Merkle trees side by side. The left tree was labeled “Validator’s Fake Tree” and the right tree “Proof Path Tree.”

“The validator created a fake Merkle Root by removing seven transactions from the tree,” Jenna explained. “Then they tried to create a proof that would verify against that fake root. But they failed to maintain the cryptographic relationships between the hashes.”

Liam looked at the diagram, confused. “I don’t understand. Why would they create a proof that doesn’t match their own root?”

“Because they didn’t understand how Merkle proofs work,” Jenna said simply. “They thought they could just generate random sibling hashes and the proof would verify against their root. But hashing doesn’t work that way. You can’t work backward from a root to find the right sibling hashes without knowing the actual data.”

She pulled up a new window and typed a quick demonstration:

DEMONSTRATION: WHY FAKING A PROOF IS IMPOSSIBLE

Given: Transaction hash = 0x7f83...
Given: Target root = 0x8d3a... (the validator's claimed root)

Question: Can we find a sibling hash S such that H(0x7f83... || S) = 0x8d3a... ?

Answer: No. Hashing is a one-way function. There is no way to compute S from the root and the transaction hash. The only way to find S is to know the original data that was hashed.

This is the avalanche effect: changing even one bit of the input changes the output completely. You cannot predict the output from the input, and you cannot reverse the process.

“Look at this,” Jenna said, pointing to the demonstration. “To create a proof that verifies against their fake root, the Corrupt Node would need to find sibling hashes that—when hashed with the transaction hash—produce exactly the right intermediate hashes. But that’s mathematically impossible without knowing the actual data. Hashes are one-way functions. You can go from data to hash, but you can’t go from hash to data.”

Liam stared at the demonstration, his mind slowly piecing things together. “So they couldn’t fake the proof even if they wanted to?”

“They could have—if they had recomputed the entire Merkle tree from scratch,” Jenna said. “If they had taken the transactions they did include, built a valid tree, and generated a proof from that tree, it would have worked. But they were lazy. They generated a fake root first, then tried to create a proof that would match it. And they failed because they didn’t understand the mathematics.”

She leaned back in her chair, a hint of dark amusement in her eyes. “The Corrupt Node is both evil and bad at math.”

Liam let out a surprised laugh. “So their incompetence is what gave them away?”

“Partly,” Jenna said. “If they had built a proper fake tree, the proof would have verified against their root. It would have taken us much longer to discover the fraud. But they didn’t. They created an inconsistent proof that immediately raised red flags.”

She pulled up the Archival Node’s correct tree, overlaying it with the validator’s fake tree. The differences were stark—the fake tree was missing leaves, with mismatched sibling hashes at multiple levels.

“This is what the validator’s fake tree looks like compared to the real one,” Jenna explained. “They removed seven leaves from the bottom. Then they recomputed the root without those leaves. They published that root as the block’s Merkle Root. And then—this is the crucial part—they tried to create a proof for your transaction that would verify against that root.”

She traced the path through the fake tree. “But to create that proof, they needed sibling hashes that would combine with your transaction hash to produce the fake root. They didn’t have those sibling hashes because they hadn’t recomputed the tree correctly. So they just… made up hashes and hoped no one would check.”

“Which we did,” Liam said.

“Which we did,” Jenna confirmed. “And the math caught them.”

She typed a new command, showing a side-by-side comparison of the expected proof path versus the actual proof path:

EXPECTED PATH (based on fake tree):
Step 1: H(0x7f83... || 0x9f7b...) = 0x8d3a...
Step 2: H(0x8d3a... || 0x3d8c...) = 0x8d3a...
Step 3: H(0x8d3a... || 0x7e5f...) = 0x8d3a...
Step 4: H(0x8d3a... || 0x2c9d...) = 0x8d3a...
FINAL: 0x8d3a... ✓

ACTUAL PATH (provided by validator):
Step 1: H(0x7f83... || 0x9f7b...) = 0x3d8c... ❌
Step 2: H(0x3d8c... || 0x3d8c...) = 0x7e5f... ❌
Step 3: H(0x7e5f... || 0x7e5f...) = 0x2c9d... ❌
Step 4: H(0x2c9d... || 0x2c9d...) = 0x3f7a... ❌
FINAL: 0x3f7a... ≠ 0x8d3a...

“Look at the expected path,” Jenna said. “In a valid proof, every intermediate hash should match the root. That’s the nature of Merkle trees—the path converges to the root. But in the actual proof, the intermediate hashes keep changing. They’re not converging anywhere.”

Liam studied the two paths. “So the validator’s proof doesn’t even pretend to be consistent.”

“Exactly,” Jenna said. “It’s not just wrong—it’s nonsensical. It’s like someone trying to prove 2+2=5 by showing you a series of arithmetic steps that don’t add up.”

She saved the analysis to the evidence log. “I’m documenting all of this for the committee. The invalid proof is one of our strongest pieces of evidence. It shows that the validator not only published a false root but also attempted to deceive us with a fabricated proof.”

She pulled up her growing complaint document and added a new section:

SECTION 4: THE INVALID PROOF

On [DATE], we requested a Merkle Proof for Transaction 0x7f83... from Validator 0x3f8a...
The validator provided a proof path that, when recomputed, did not match their own claimed Merkle Root.

ANALYSIS:
The proof path contained mismatched sibling hashes that failed to converge to the claimed root.
This demonstrates that:
1. The validator published a false Merkle Root.
2. The validator attempted to deceive investigators with a fabricated proof.
3. The validator does not understand the cryptographic principles underlying Merkle proofs.

CONCLUSION:
The invalid proof is evidence of both incompetence and intentional fraud. The validator's actions were deliberate, not accidental.

Liam read over her shoulder. “You’re really building a case here.”

“I’m building a mountain of evidence,” Jenna said. “By the time I’m done, the committee won’t be able to deny anything.”

She paused, her expression growing thoughtful. “But I also need to understand why the validator thought this would work. Was it just incompetence, or was there a method to the madness?”

She pulled up the Corrupt Node’s block history again, looking for patterns. “Let’s see if they did this with other blocks. Did they always provide invalid proofs, or did they sometimes provide valid ones?”

She ran a new script, checking all the proofs the validator had ever provided for the 47 fraudulent blocks:

> ANALYZE_PROOF_HISTORY(validator_id: 0x3f8a...)
> ANALYZING PROOFS FOR 47 FRAUDULENT BLOCKS...
> 47/47 PROOFS ARE INVALID
> PATTERN: All invalid proofs show the same mismatch pattern.
> CONCLUSION: Validator consistently failed to provide valid proofs for hidden transactions.

“Forty-seven for forty-seven,” Jenna murmured. “They didn’t get a single proof right.”

She sat back in her chair, her mind racing. “That’s not just incompetence. That’s systematic incompetence. They didn’t know how to create Merkle proofs at all. They were just winging it.”

Liam frowned. “But they knew enough to publish fake roots. How could they know how to fake a root but not know how to fake a proof?”

“Because faking a root is easy,” Jenna explained. “You remove a few transactions from the tree, recompute the root, and publish it. That’s basic arithmetic. But faking a proof? That requires understanding the structure of the tree and the relationships between hashes. It’s more complex.”

She pulled up a new diagram, showing the difference between the two tasks:

FAKING A ROOT (Easy):
1. Remove 7 leaves from the tree.
2. Recompute the root with the remaining leaves.
3. Publish the new root.
Result: A fake root that passes a simple root check.

FAKING A PROOF (Hard):
1. Start with a transaction hash.
2. Find sibling hashes that will combine with it to produce the desired root.
3. This requires knowledge of the exact structure of the tree.
4. If you don't know the tree structure, you can't create a valid proof.
Result: An invalid proof that fails verification.

THE CORRUPT NODE'S MISTAKE:
They knew how to fake a root (Easy Task).
They didn't know how to fake a proof (Hard Task).
So they made up a proof and hoped no one would check.

“It’s like they learned only half the lesson,” Liam said. “They knew how to hide transactions but not how to cover their tracks.”

“Exactly,” Jenna said. “And that’s why we caught them.”

She stood up and began pacing the lab, her mind still churning. “This case keeps getting stranger. The validator is competent enough to exploit a software vulnerability and run a sophisticated fraud operation, but incompetent enough to provide invalid proofs that immediately raise suspicion. It’s like two different people were running the operation.”

Liam considered this. “Maybe they are. Maybe one person handles the technical side—the block manipulation, the root faking—and another person handles the day-to-day stuff, like responding to proof requests.”

“That’s… actually a good theory,” Jenna said, stopping her pacing. “It would explain the inconsistency. The technical person knows how to manipulate blocks but doesn’t handle proof requests. The operational person handles proof requests but doesn’t understand the cryptography.”

She pulled up a new document and began typing:

THEORY: TWO-PERSON OPERATION

Hypothesis: Validator 0x3f8a... is run by at least two people:
- Person A: Technical expert who manipulates blocks and publishes fake roots.
- Person B: Operational person who handles day-to-day communications, including proof requests.

Evidence:
- The block manipulation is sophisticated (exploits CVE-2026-0384).
- The proof responses are incompetent (invalid proofs, mismatched hashes).
- Inconsistent technical ability suggests two different individuals with different skill sets.

Implications:
- If Person A and Person B are different, we may need to identify both.
- Person B may not even know they're part of a fraud operation.
- Person A is the primary target of the investigation.

Liam read the theory over her shoulder. “You think the person who sent us the proof didn’t know what they were doing?”

“Or didn’t care,” Jenna said. “Either way, it’s a weakness we can exploit. If the operational person is incompetent, they might make mistakes that lead us to the technical person.”

She turned to him, a glint in her eye. “This is what forensic auditing is really about. It’s not just checking numbers—it’s understanding the people behind the numbers. Their motivations, their skills, their mistakes. Every invalid proof tells a story.”

She pulled up the invalid proof again. “And this proof tells a story of someone who was in over their head. Someone who didn’t understand the math but had to fake it anyway.”

She began typing a new section in the evidence log:

PSYCHOLOGICAL PROFILE OF THE CORRUPT NODE

The invalid proof suggests that the person creating it was:
1. Not an expert in cryptographic verification.
2. Working under time pressure (they didn't have time to learn how to create a valid proof).
3. Possibly acting on instructions from someone else (the technical expert).
4. Likely to make other mistakes that can be exploited.

Recommendation: Continue to request proofs for every hidden transaction. The more proofs we request, the more evidence we gather. And the more mistakes they make, the stronger our case becomes.

She saved the document and turned to Liam. “We’re going to request proofs for every hidden transaction. Every single one. We’ll make them work for it. And every time they send an invalid proof, we document it.”

Liam nodded, a sense of purpose filling him. “How many proofs do we need to request?”

“Over 300,” Jenna said. “But we’ll start with the 47 blocks we’ve already identified. One proof per hidden transaction.”

She pulled up a new script—a batch request system that would automatically request proofs for all hidden transactions across all fraudulent blocks.

> BATCH_REQUEST_PROOFS(validator_id: 0x3f8a..., transaction_list: all_hidden)
> SENDING 312 PROOF REQUESTS...
> PROCESSING...

“This will take a while,” she said. “But the result will be worth it. A complete record of every invalid proof the validator has ever provided.”

She watched the terminal with satisfaction as the requests went out. Each one was a tiny hammer blow against the Corrupt Node’s credibility. Each one was another piece of evidence in their growing mountain of proof.

Liam pulled up his notebook, flipping to a fresh page. “I’ll document each response as it comes in. The time, the proof data, the verification result, and any anomalies.”

“Perfect,” Jenna said. “This is exactly the kind of meticulous documentation we need.”

The first response came within minutes:

> PROOF RESPONSE RECEIVED
> Block: 843288
> Transaction: 0x9f7b3a...
> Proof Path: [0x1a2b..., 0x3c4d..., 0x5e6f..., 0x7a8b...]
> VERIFICATION RESULT: INVALID
> Reason: Mismatch at Step 3
> Expected: 0x9f7b... | Actual: 0x2c9d...

Liam documented it carefully, noting the mismatch. “One down, 311 to go.”

They worked through the responses methodically, each invalid proof adding to their growing evidence log. Some proofs were close—failing at the last step—while others were wildly off, failing at the first hash.

By the end of the day, they had documented 47 invalid proofs from the Corrupt Node, with more still coming in.

Jenna saved the final document and leaned back in her chair. “We have the invalid proofs. We have the evidence. Now we wait for the committee to do the right thing—or we take this to the community.”

Liam looked at the mountain of evidence they’d gathered—pages of proof comparisons, hash mismatches, and tracing data—and felt a surge of pride. They had built an airtight case. Nothing could refute the numbers.

“What happens next?” he asked.

Jenna met his eyes, her expression grim but determined. “We wait for the committee. But we also prepare for the worst. If the committee is slow to act—or if they try to cover this up—we go public. We post everything we’ve found on the forums. We let the community decide.”

She paused, her voice dropping. “Because the truth is on our side. The math doesn’t lie. And the math says that Validator 0x3f8a… is guilty of fraud.”

She looked at the screen, where the invalid proof was still displayed, and smiled grimly. “They tried to fool the math. And the math won.”

Table of contents:
Introduction
Chapter 1: The Immutable Ledger
Chapter 2: A Proof of Inclusion
Chapter 3: The Merkle Root
Chapter 4: The Missing Leaf
Chapter 5: The Invalid Proof
Chapter 6: The Tampered Branch <<<<<< NEXT
Chapter 7: The Forensic Audit
Chapter 8: The Historical Root
Chapter 9: The Dual Verification
Chapter 10: Trust, But Always Verify

Loading



Dear reader, love our creation? Support us moving forward