Skip to content

fix(l1): use hash precompiles in eip8025 hash tree root#6549

Open
benbencik wants to merge 2 commits intolambdaclass:mainfrom
benbencik:fix-hash-precompiles
Open

fix(l1): use hash precompiles in eip8025 hash tree root#6549
benbencik wants to merge 2 commits intolambdaclass:mainfrom
benbencik:fix-hash-precompiles

Conversation

@benbencik
Copy link
Copy Markdown

Motivation
Earlier work #6365 added &dyn Crypto, so zkVM can route hashing to precompiles. However, it is not applied everywhere in the eip-8025 execution path.

Description
The execution_program is calling hash_tree_root with libssz_merkle::Sha2Hasher. This fix implements libssz_merkle::Sha256Hasher trait for &dyn Crypto such that hash precompiles can be used in computing the hash of the tree root.

This fix significantly reduces the AIR-costs inside ZisK v0.16.1, and it is the main reason for the previously observed inefficiency in #6524. Profiling on mainnet blocks: 24949787 - 24949836:

  • Average cost (main 1e85b1c36): 57.6B
  • Average cost (this change): 45.2B

Copilot AI review requested due to automatic review settings April 29, 2026 13:46
@benbencik benbencik requested a review from a team as a code owner April 29, 2026 13:46
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 29, 2026

Greptile Summary

This PR wires the Arc<dyn Crypto> precompile into the EIP-8025 hash_tree_root computation by introducing a thin CryptoWrapper newtype that implements libssz_merkle::Sha256Hasher. Previously, hash_tree_root always used the software Sha2Hasher, bypassing zkVM precompile acceleration. The change is correctly gated behind #[cfg(feature = "eip-8025")] and the wrapper is only created for the hash_tree_root call, while the original crypto arc continues to be passed into validate_eip8025_execution unchanged.

Confidence Score: 5/5

Safe to merge — the change is minimal, correctly gated, and the new code path is semantically equivalent to the old one for non-zkVM use.

The diff is a focused 18-line change with no logic alterations: CryptoWrapper is a transparent delegation to Crypto::sha256 which returns [u8; 32], exactly matching the Sha256Hasher::hash contract. Feature gating is consistent with the rest of the file. No tests are broken and the existing unit test still exercises the decode-error path.

No files require special attention.

Important Files Changed

Filename Overview
crates/guest-program/src/l1/program.rs Adds CryptoWrapper(Arc) implementing Sha256Hasher, replacing Sha2Hasher in the hash_tree_root call so zkVM SHA-256 precompiles are used during Merkle tree computation.

Sequence Diagram

sequenceDiagram
    participant EP as execution_program
    participant CW as CryptoWrapper
    participant HTR as hash_tree_root
    participant C as Crypto precompile

    EP->>HTR: hash_tree_root(&CryptoWrapper(crypto.clone()))
    loop For each Merkle node
        HTR->>CW: hash(data)
        CW->>C: self.0.sha256(data)
        C-->>CW: digest
        CW-->>HTR: digest
    end
    HTR-->>EP: request_root
    EP->>EP: validate_eip8025_execution(request, witness, crypto)
Loading

Reviews (1): Last reviewed commit: "style(l1): fmt" | Re-trigger Greptile

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates the EIP-8025 L1 guest execution path so SSZ hash_tree_root uses the injected Crypto implementation (enabling zkVMs to route SHA-256 through precompiles) instead of libssz_merkle::Sha2Hasher.

Changes:

  • Add a small Sha256Hasher adapter that delegates hashing to Crypto::sha256.
  • Use the adapter when computing NewPayloadRequest::hash_tree_root in the EIP-8025 execution_program.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +60 to +61
/// Wrapper to pass Crypto into libssz_merkle::hash_tree_root,
/// so hashing is computed by precompiles
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment on this wrapper implies hashing will be computed by precompiles, but in native builds Crypto::sha256 uses a software SHA-256 implementation. Consider rewording to clarify that this enables precompile-backed hashing when the provided Crypto implementation supports it (e.g., zkVM targets).

Suggested change
/// Wrapper to pass Crypto into libssz_merkle::hash_tree_root,
/// so hashing is computed by precompiles
/// Wrapper to pass `Crypto` into `libssz_merkle::hash_tree_root`,
/// enabling precompile-backed hashing when the provided `Crypto`
/// implementation supports it (for example, on zkVM targets).

Copilot uses AI. Check for mistakes.
Comment on lines +88 to 89
let request_root = new_payload_request.hash_tree_root(&CryptoWrapper(crypto.clone()));
let valid = validate_eip8025_execution(&new_payload_request, execution_witness, crypto).is_ok();
Copy link

Copilot AI Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change makes NewPayloadRequest root computation depend on the provided Crypto implementation. There’s currently no test that would fail if hash_tree_root accidentally reverted to using Sha2Hasher/a native hasher. Consider adding a unit test (under cfg(all(test, feature = "eip-8025"))) with a small custom Crypto impl overriding sha256 (e.g., counting calls or returning a distinctive value) to assert the hasher passed into hash_tree_root is actually used.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants