embedded_td/crypto/
keypair.rs

1use rand_core::{CryptoRng, RngCore};
2use ripemd::Ripemd160;
3use sha2::{Digest, Sha256};
4
5use crate::model;
6
7use super::{ed25519, secp256k1, sr25519};
8
9/// Secret key for tendermint
10#[derive(Debug, Clone)]
11pub enum SecretKey {
12    Ed25519(ed25519::SecretKey),
13    Secp256k1(secp256k1::SecretKey),
14    Sr25519(sr25519::SecretKey),
15}
16
17impl SecretKey {
18    pub(crate) fn into_model(self) -> model::Key {
19        let (ty, value) = match self {
20            Self::Ed25519(k) => ("tendermint/PrivKeyEd25519", base64::encode(k)),
21            Self::Secp256k1(k) => ("tendermint/PrivKeySecp256k1", base64::encode(k)),
22            Self::Sr25519(k) => ("tendermint/PrivKeySr25519", base64::encode(k)),
23        };
24
25        model::Key {
26            ty: String::from(ty),
27            value,
28        }
29    }
30
31    pub fn generate(ty: AlgorithmType, rng: impl RngCore + CryptoRng) -> Self {
32        match ty {
33            AlgorithmType::Ed25519 => Self::Ed25519(ed25519::SecretKey::generate(rng)),
34            AlgorithmType::Secp256k1 => Self::Secp256k1(secp256k1::SecretKey::generate(rng)),
35            AlgorithmType::Sr25519 => Self::Sr25519(sr25519::SecretKey::generate(rng)),
36        }
37    }
38
39    pub fn public_key(&self) -> PublicKey {
40        match self {
41            Self::Ed25519(k) => PublicKey::Ed25519(k.public_key()),
42            Self::Secp256k1(k) => PublicKey::Secp256k1(k.public_key()),
43            Self::Sr25519(k) => PublicKey::Sr25519(k.public_key()),
44        }
45    }
46}
47
48/// Public key for tendermint
49#[derive(Debug, Clone)]
50pub enum PublicKey {
51    Ed25519(ed25519::PublicKey),
52    Secp256k1(secp256k1::PublicKey),
53    Sr25519(sr25519::PublicKey),
54}
55
56impl PublicKey {
57    pub(crate) fn into_model(self) -> model::Key {
58        let (ty, value) = match self {
59            Self::Ed25519(k) => ("tendermint/PubKeyEd25519", base64::encode(k)),
60            Self::Secp256k1(k) => ("tendermint/PubKeySecp256k1", base64::encode(k)),
61            Self::Sr25519(k) => ("tendermint/PubKeySr25519", base64::encode(k)),
62        };
63
64        model::Key {
65            ty: String::from(ty),
66            value,
67        }
68    }
69
70    pub fn address(&self) -> [u8; 20] {
71        let mut addr = [0u8; 20];
72
73        match self {
74            Self::Secp256k1(k) => {
75                let step1_sha = Sha256::digest(k);
76
77                let res = Ripemd160::digest(step1_sha);
78
79                addr.copy_from_slice(&res);
80            }
81            Self::Ed25519(k) => {
82                let res = Sha256::digest(k);
83
84                addr.copy_from_slice(&res[..20]);
85            }
86            Self::Sr25519(k) => {
87                let res = Sha256::digest(k);
88
89                addr.copy_from_slice(&res[..20]);
90            }
91        }
92
93        addr
94    }
95}
96
97/// Keypair of tendermint
98#[derive(Debug, Clone)]
99pub struct Keypair {
100    pub secret_key: SecretKey,
101    pub public_key: PublicKey,
102}
103
104pub enum AlgorithmType {
105    Secp256k1,
106    Ed25519,
107    Sr25519,
108}
109
110impl Keypair {
111    pub(crate) fn into_model(self) -> model::Keypair {
112        let address = self.public_key.address();
113        let pub_key = self.public_key.into_model();
114
115        let priv_key = self.secret_key.into_model();
116
117        model::Keypair {
118            address: hex::encode(address),
119            priv_key,
120            pub_key,
121        }
122    }
123    pub fn generate(ty: AlgorithmType, rng: impl RngCore + CryptoRng) -> Self {
124        let secret_key = SecretKey::generate(ty, rng);
125        let public_key = secret_key.public_key();
126
127        Self {
128            secret_key,
129            public_key,
130        }
131    }
132}