Skip to content

feat: Add support for verification of aggregated BLS signatures#2

Draft
MalteHerrmann wants to merge 3 commits intonoble-assets:mainfrom
MalteHerrmann:malte/noble-bls-ism
Draft

feat: Add support for verification of aggregated BLS signatures#2
MalteHerrmann wants to merge 3 commits intonoble-assets:mainfrom
MalteHerrmann:malte/noble-bls-ism

Conversation

@MalteHerrmann
Copy link
Copy Markdown

This PR adds the implementation to verify aggregated BLS signatures from the validator set on the Noble EVM, based on @keyleu's original approach and @johnletey's PoC for signature verification.

It's still work-in-progress and the PR is only opened to gather early feedback while I'm out of office 🙏

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Feb 17, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

Issue Planner is now in beta. Read the docs and try it out! Share your feedback on Discord.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@keyleu keyleu left a comment

Choose a reason for hiding this comment

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

preliminary input! Looks promising!

/// @notice The canonical interface for a Hyperlane Interchain Security Module, which verifies
/// incoming messages based on a provided BLS12-381 signature from Noble's validator set, and
/// a provided SP1 proof for the inclusion of a given message in the Hyperlane Merkle Tree.
interface INobleISM is IInterchainSecurityModule, IVersioned, IVkUpdatable {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I recently added a new interface to unify some of the core logic that doesn't require duplicating some of the things. We can make it inherit IEvmISM and then this interface is much smaller

import { IVersioned } from "./IVersioned.sol";
import { IVkUpdatable } from "./IVkUpdatable.sol";

interface INobleLightClient is IVersioned, IVkUpdatable {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Same as above, we can make this one inherit IEvmLightClient

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This contract is not needed. We can reuse EvmISM, which is the one that will store the hyperlane merkle roots validating against the state roots that we have in the noble light client

Comment on lines +9 to +10
// TODO: make pausable?
contract NobleLightClient is INobleLightClient, OwnableUpgradeable, UUPSUpgradeable {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Yeah, let's make it pausable like the other one. The idea of being able to pause is if there is an exploit in the zkVM and we need to pause all proof verifications / updates until we can update the VK


/// @notice The latest block number that was verified.
uint64 latestBlockNumber = 0;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
uint256 public latestBlockNumber;

sketch = sketch.with_genesis(Genesis::Sepolia);
SEPOLIA_MERKLE_HOOK_CONTRACT
}
NOBLE_DEVNET_CHAIN_ID => NOBLE_DEVNET_MERKLE_HOOK_CONTRACT,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

here we'd also need to use the chain config for Noble


// Generate proof
println!("Generating proof...");
debug!("Generating proof...");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
debug!("Generating proof...");
info!("Generating proof...");


// Verify proof
println!("Verifying proof...");
debug!("verifying proof...");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
debug!("verifying proof...");
info!("Verifying proof...");

Comment on lines +25 to +27
message NobleHyperlaneRootResponse {
// The Hyperlane Merkle Tree root.
bytes hyperlane_root = 1;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

we'd need to return the same as for the EthereumHyperlaneRootResponse, the 2 proofs and the 2 public inputs

tracing-subscriber = { workspace = true, features = ["env-filter", "json"] }
dotenvy = { workspace = true }
sp1-sdk = { workspace = true }
sp1-cc-client-executor = { workspace = true }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: ident

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.

2 participants