saa_auth/cosmos/
arbitrary.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

#[cfg(any(feature = "wasm", feature = "native"))]
use {
    saa_common::{hashes::sha256, utils::pubkey_to_address, ensure},
    super::utils::preamble_msg_arb_036
};
use saa_common::{AuthError, Binary, CredentialId, String, ToString, Verifiable};
use saa_schema::wasm_serde;


#[wasm_serde]
pub struct CosmosArbitrary {
    pub pubkey:    Binary,
    pub signature: Binary,
    pub message:   Binary,
    pub hrp:       Option<String>
}

#[cfg(any(feature = "wasm", feature = "native"))]
impl CosmosArbitrary {
    fn message_digest(&self) -> Result<Vec<u8>, AuthError> {
        ensure!(self.hrp.is_some(), AuthError::Generic("Must provide prefix for the public key".to_string()));
        Ok(sha256(&preamble_msg_arb_036(
            pubkey_to_address(&self.pubkey, self.hrp.as_ref().unwrap())?.as_str(),
            &self.message.to_string()
        ).as_bytes()))
    }
}


impl Verifiable for CosmosArbitrary {

    fn id(&self) -> CredentialId {
        self.pubkey.to_vec()
    }

    fn hrp(&self) -> Option<String> {
        self.hrp.clone()
    }

    fn validate(&self) -> Result<(), AuthError> {
        if !(self.signature.len() > 0 &&
            self.message.to_string().len() > 0 && 
            self.pubkey.len() > 0) {
            return Err(AuthError::MissingData("Empty credential data".to_string()));
        }
        Ok(())
    }

    #[cfg(feature = "native")]
    fn verify(&self) -> Result<(), AuthError> {
        let success = saa_common::crypto::secp256k1_verify(
            &self.message_digest()?,
            &self.signature,
            &self.pubkey
        )?;
        ensure!(success, AuthError::Signature("Signature verification failed".to_string()));
        Ok(())
    }


    #[cfg(feature = "wasm")]
    fn verify_cosmwasm(
        &self, 
        api:  &dyn saa_common::cosmwasm::Api
    ) -> Result<(), AuthError> {
        let success = api.secp256k1_verify(
            &self.message_digest()?,
            &self.signature,
            &self.pubkey
        )?;
        ensure!(success, AuthError::Signature("Signature verification failed".to_string()));
        Ok(())
    }

}