inkpad_sandbox/
crypto.rs

1//! Crypto fns
2use crate::Sandbox;
3
4impl Sandbox {
5    /// Verify and recover a SECP256k1 ECDSA signature.
6    ///
7    /// - `sig` is passed in RSV format. V should be either `0/1` or `27/28`.
8    /// - `msg` is the blake2-256 hash of the message.
9    ///
10    /// Returns `Err` if the signature is bad, otherwise the 33-byte compressed pubkey.
11    #[allow(clippy::result_unit_err)]
12    pub fn ecdsa_recover(&self, sig: &[u8; 65], msg: &[u8; 32]) -> Result<[u8; 33], ()> {
13        let rs = libsecp256k1::Signature::parse_overflowing_slice(&sig[0..64]).map_err(|_| ())?;
14        let v = libsecp256k1::RecoveryId::parse(
15            if sig[64] > 26 { sig[64] - 27 } else { sig[64] } as u8
16        )
17        .map_err(|_| ())?;
18        let pubkey =
19            libsecp256k1::recover(&libsecp256k1::Message::parse(msg), &rs, &v).map_err(|_| ())?;
20        Ok(pubkey.serialize_compressed())
21    }
22}