revm_precompile/secp256k1/
bitcoin_secp256k1.rs

1//! bitcoin_secp256k1 implementation of `ecrecover`. More about it in [`crate::secp256k1`].
2use primitives::{alloy_primitives::B512, keccak256, B256};
3use secp256k1::{
4    ecdsa::{RecoverableSignature, RecoveryId},
5    Message, SECP256K1,
6};
7
8// Silence the unused crate dependency warning.
9use k256 as _;
10
11/// Recover the public key from a signature and a message.
12///
13/// This function is using the `secp256k1` crate, it is enabled by `libsecp256k1` feature and it is in default.
14pub fn ecrecover(sig: &B512, recid: u8, msg: &B256) -> Result<B256, secp256k1::Error> {
15    let recid = RecoveryId::try_from(recid as i32).expect("recovery ID is valid");
16    let sig = RecoverableSignature::from_compact(sig.as_slice(), recid)?;
17
18    let msg = Message::from_digest(msg.0);
19    let public = SECP256K1.recover_ecdsa(&msg, &sig)?;
20
21    let mut hash = keccak256(&public.serialize_uncompressed()[1..]);
22    hash[..12].fill(0);
23    Ok(hash)
24}