terra_rust_api/keys/
signature.rs

1use crate::errors::TerraRustAPIError;
2use crypto::sha2::Sha256;
3use secp256k1::Message;
4use secp256k1::Secp256k1;
5
6use crypto::digest::Digest;
7
8pub struct Signature {}
9impl Signature {
10    pub fn verify<C: secp256k1::Verification + secp256k1::Context>(
11        secp: &Secp256k1<C>,
12        pub_key: &str,
13        signature: &str,
14        blob: &str,
15    ) -> Result<(), TerraRustAPIError> {
16        let public = base64::decode(pub_key)?;
17        let sig = base64::decode(signature)?;
18        let pk = secp256k1::PublicKey::from_slice(public.as_slice())?;
19        let mut sha = Sha256::new();
20        let mut sha_result: [u8; 32] = [0; 32];
21        sha.input_str(blob);
22        sha.result(&mut sha_result);
23
24        let message: Message = Message::from_slice(&sha_result)?;
25        let secp_sig = secp256k1::Signature::from_compact(sig.as_slice())?;
26        secp.verify(&message, &secp_sig, &pk)?;
27        Ok(())
28    }
29}
30#[cfg(test)]
31mod tst {
32    use super::*;
33    #[allow(unused_imports)]
34    use dotenv::dotenv;
35    #[allow(unused_imports)]
36    use env_logger;
37    #[test]
38    pub fn test_verify() -> anyhow::Result<()> {
39        let secp = Secp256k1::new();
40
41        let message = r#"{"account_number":"45","chain_id":"columbus-3-testnet","fee":{"amount":[{"amount":"698","denom":"uluna"}],"gas":"46467"},"memo":"","msgs":[{"type":"bank/MsgSend","value":{"amount":[{"amount":"100000000","denom":"uluna"}],"from_address":"terra1n3g37dsdlv7ryqftlkef8mhgqj4ny7p8v78lg7","to_address":"terra1wg2mlrxdmnnkkykgqg4znky86nyrtc45q336yv"}}],"sequence":"0"}"#;
42        let signature = "FJKAXRxNB5ruqukhVqZf3S/muZEUmZD10fVmWycdVIxVWiCXXFsUy2VY2jINEOUGNwfrqEZsT2dUfAvWj8obLg==";
43        let pub_key = "AiMzHaA2bvnDXfHzkjMM+vkSE/p0ymBtAFKUnUtQAeXe";
44        Signature::verify(&secp, pub_key, signature, message)?;
45        Ok(())
46    }
47}