prople_crypto/eddsa/
keypair.rs

1//! `keypair` module provide primary object to generate [`KeyPair`] which hold the [`SigningKey`]
2//! data structure
3use rst_common::with_cryptography::ed25519_dalek::{pkcs8::DecodePrivateKey, SigningKey};
4
5use rst_common::with_cryptography::rand::{rngs::adapter::ReseedingRng, SeedableRng};
6use rst_common::with_cryptography::rand_chacha::{rand_core::OsRng, ChaCha20Core};
7
8use crate::eddsa::privkey::PrivKey;
9use crate::eddsa::pubkey::PubKey;
10use crate::eddsa::signature::Signature;
11use crate::eddsa::types::errors::EddsaError;
12
13/// `KeyPair` actually is main entrypoint used to generate the [`SigningKey`]
14///
15/// From this signing key we will also able to generate [`PubKey`] and also [`Signature`] objects.
16/// Besides to generate all necessary objects, this object also able to import given `PEM` data format
17/// into its self
18#[derive(Clone, Debug)]
19pub struct KeyPair {
20    keypair: SigningKey,
21}
22
23impl KeyPair {
24    pub fn generate() -> Self {
25        let prng = ChaCha20Core::from_entropy();
26        let mut reseeding_rng = ReseedingRng::new(prng, 0, OsRng);
27        let sign_key = SigningKey::generate(&mut reseeding_rng);
28        Self { keypair: sign_key }
29    }
30
31    pub fn pub_key(&self) -> PubKey {
32        PubKey::new(self.keypair.verifying_key())
33    }
34
35    pub fn priv_key(&self) -> PrivKey {
36        PrivKey::new(self.keypair.clone())
37    }
38
39    pub fn from_pem(pem: String) -> Result<Self, EddsaError> {
40        SigningKey::from_pkcs8_pem(pem.as_str())
41            .map(|val| Self { keypair: val })
42            .map_err(|err| EddsaError::DecodePemError(err.to_string()))
43    }
44
45    pub fn signature(&self, message: &[u8]) -> Signature {
46        Signature::new(self.keypair.clone(), message.to_vec())
47    }
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53    use rst_common::with_cryptography::hex;
54
55    use crate::{
56        keysecure::types::{Password, ToKeySecure},
57        types::{ByteHex, Hexer, Value},
58    };
59
60    #[test]
61    fn test_gen_pub_key_multiple() {
62        let keypair1 = KeyPair::generate();
63        let keypair2 = KeyPair::generate();
64        let keypair3 = KeyPair::generate();
65
66        let pubkey1 = keypair1.pub_key();
67        let pubkey2 = keypair2.pub_key();
68        let pubkey3 = keypair3.pub_key();
69
70        let pubkeyhex1 = pubkey1.to_hex();
71        let pubkeyhex2 = pubkey2.to_hex();
72        let pubkeyhex3 = pubkey3.to_hex();
73
74        assert_ne!(pubkeyhex1, pubkeyhex2);
75        assert_ne!(pubkeyhex1, pubkeyhex3);
76        assert_ne!(pubkeyhex2, pubkeyhex3)
77    }
78
79    #[test]
80    fn test_gen_pub_key() {
81        let keypair = KeyPair::generate();
82        let pubkey = keypair.pub_key();
83        let pubkeybytes = pubkey.serialize();
84        let pubkeyhex = pubkey.to_hex();
85        let pubkeytoorig = hex::decode(pubkeyhex.clone().hex());
86
87        let pubkeybytes_val = pubkeybytes.get();
88        assert!(!pubkeybytes_val.is_err());
89
90        assert!(!pubkeytoorig.is_err());
91        assert_eq!(
92            pubkeybytes_val.unwrap(),
93            pubkeytoorig.clone().unwrap().as_slice()
94        );
95        assert_eq!(
96            pubkeyhex.hex(),
97            hex::encode(pubkeytoorig.unwrap().as_slice())
98        )
99    }
100
101    #[test]
102    fn test_gen_pub_key_from_hex() {
103        let keypair = KeyPair::generate();
104        let pubkey = keypair.pub_key();
105        let pubkeyhex = pubkey.to_hex();
106
107        let pubkey_from_hex = PubKey::from_hex(pubkeyhex);
108        assert!(!pubkey_from_hex.is_err());
109
110        let pubkey2 = pubkey_from_hex.unwrap();
111        assert_eq!(pubkey2.serialize(), pubkey.serialize());
112        assert_eq!(pubkey2.to_hex(), pubkey.to_hex())
113    }
114
115    #[test]
116    fn test_sign_to_hex() {
117        let message = b"hello world";
118        let keypair = KeyPair::generate();
119        let pubkey = keypair.pub_key();
120        let signature = keypair.signature(message);
121        let signature_hex = signature.to_hex();
122
123        let verify_hex_valid = pubkey.verify(message, ByteHex::from(signature_hex.clone()));
124        assert!(!verify_hex_valid.is_err());
125
126        let verify_hex_invalid = pubkey.verify(b"invalid", ByteHex::from(signature_hex));
127        assert!(verify_hex_invalid.is_err());
128        assert!(matches!(
129            verify_hex_invalid,
130            Err(EddsaError::InvalidSignatureError(_))
131        ));
132    }
133
134    #[test]
135    fn test_encode_priv_key_to_pem() {
136        let keypair = KeyPair::generate();
137        let priv_key_pem = keypair.priv_key().to_pem();
138        assert!(!priv_key_pem.is_err());
139        assert!(priv_key_pem.unwrap().contains("BEGIN PRIVATE KEY"))
140    }
141
142    #[test]
143    fn test_priv_key_to_keysecure() {
144        let keypair = KeyPair::generate();
145        let priv_key = keypair.priv_key();
146        let priv_key_pem = priv_key.to_pem();
147        assert!(!priv_key_pem.is_err());
148
149        let priv_key_secure = priv_key.to_keysecure(Password::from("test".to_string()));
150        assert!(!priv_key_secure.is_err());
151
152        let keysecure = priv_key_secure.unwrap();
153        let keysecure_json = keysecure.to_json();
154        assert!(!keysecure_json.is_err())
155    }
156
157    #[test]
158    fn test_decode_pem() {
159        let keypair = KeyPair::generate();
160        let priv_key = keypair.priv_key();
161        let priv_key_pem = priv_key.to_pem();
162        let keypair2 = KeyPair::from_pem(priv_key_pem.unwrap());
163
164        assert!(!keypair2.is_err());
165        assert_eq!(
166            priv_key.serialize(),
167            keypair2.unwrap().clone().priv_key().serialize()
168        );
169    }
170}