prople_crypto/ecdh/
keypair.rs1use core::fmt;
3
4use rst_common::with_cryptography::hex;
5use rst_common::with_cryptography::rand::{rngs::adapter::ReseedingRng, SeedableRng};
6use rst_common::with_cryptography::rand_chacha::{rand_core::OsRng, ChaCha20Core};
7use rst_common::with_cryptography::x25519_dalek::{PublicKey as ECDHPublicKey, StaticSecret};
8
9use crate::errors::CommonError;
10use crate::types::{ByteHex, BytesValue, Hexer, Value};
11
12use crate::keysecure::builder::Builder;
13use crate::keysecure::types::errors::KeySecureError;
14use crate::keysecure::types::ToKeySecure;
15use crate::keysecure::types::{ContextOptions, Password};
16use crate::keysecure::KeySecure;
17
18use crate::ecdh::pubkey::PublicKey;
19use crate::ecdh::secret::Secret;
20use crate::ecdh::types::errors::*;
21use crate::ecdh::types::PrivateKeyBytes;
22
23#[derive(Clone)]
28pub struct KeyPair {
29 secret: StaticSecret,
30}
31
32impl fmt::Debug for KeyPair {
33 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
34 f.debug_struct("KeyPairs")
35 .field("secret_in_hex", &self.to_hex().hex())
36 .finish()
37 }
38}
39
40impl KeyPair {
41 pub fn generate() -> Self {
42 let prng = ChaCha20Core::from_entropy();
43 let mut reseeding_rng = ReseedingRng::new(prng, 0, OsRng);
44 let secret = StaticSecret::random_from_rng(&mut reseeding_rng);
45 Self { secret }
46 }
47
48 pub fn pub_key(&self) -> PublicKey {
49 PublicKey::new(ECDHPublicKey::from(&self.secret))
50 }
51
52 pub fn secret(self, peer_hex: ByteHex) -> Secret {
53 Secret::new(self.secret, peer_hex)
54 }
55
56 pub fn to_hex(&self) -> ByteHex {
57 ByteHex::from(hex::encode(self.to_bytes().bytes()))
58 }
59
60 pub fn from_hex(val: String) -> Result<Self, EcdhError> {
61 let decoded = hex::decode(val)
62 .map_err(|err| EcdhError::Common(CommonError::ParseHexError(err.to_string())))?;
63
64 let valid_bytes: Result<[u8; 32], _> = decoded.try_into();
65 valid_bytes
66 .map(|val| Self {
67 secret: StaticSecret::from(val),
68 })
69 .map_err(|_| EcdhError::ParseBytesError("unable to parse decode bytes".to_string()))
70 }
71
72 pub fn to_bytes(&self) -> PrivateKeyBytes {
73 PrivateKeyBytes::from(self.secret.to_bytes())
74 }
75
76 pub fn from_bytes(val: PrivateKeyBytes) -> Result<Self, CommonError> {
77 let private_key_bytes = val.get()?;
78 Ok(Self {
79 secret: StaticSecret::from(private_key_bytes),
80 })
81 }
82}
83
84impl ToKeySecure for KeyPair {
85 fn to_keysecure(&self, password: Password) -> Result<KeySecure, KeySecureError> {
86 let priv_key_hex = self.to_hex();
87
88 let keysecure_builder = Builder::new(ContextOptions::X25519, password);
89 let keysecure = keysecure_builder.secure(priv_key_hex.hex())?;
90
91 Ok(keysecure)
92 }
93}
94
95#[cfg(test)]
96mod tests {
97 use super::*;
98
99 #[test]
100 fn test_gen_pub_key_from_hex() {
101 let keypair = KeyPair::generate();
102 let pubkey = keypair.pub_key();
103
104 let pubkeyhex = pubkey.to_hex();
105 let pubkey_decode = PublicKey::from_hex(pubkeyhex);
106 assert!(!pubkey_decode.is_err());
107 assert_eq!(pubkey_decode.unwrap(), pubkey)
108 }
109
110 #[test]
111 fn test_gen_pub_key_from_hex_error() {
112 let given = b"test";
113 let given_hex = hex::encode(given);
114
115 let pubkey_decode = PublicKey::from_hex(ByteHex::from(given_hex));
116 assert!(pubkey_decode.is_err());
117 assert!(matches!(
118 pubkey_decode,
119 Err(EcdhError::ParsePublicKeyError(_))
120 ))
121 }
122
123 #[test]
124 fn test_gen_shared_secret() {
125 let keypair_alice = KeyPair::generate();
126 let keypair_bob = KeyPair::generate();
127 let pubkey_alice = keypair_alice.pub_key();
128 let pubkey_bob = keypair_bob.pub_key();
129
130 let public_alice_hex = pubkey_alice.to_hex();
131 let public_bob_hex = pubkey_bob.to_hex();
132
133 let secret_alice = keypair_alice.secret(public_bob_hex);
134 let secret_bob = keypair_bob.secret(public_alice_hex);
135
136 let shared_secret_alice_blake3 = secret_alice.to_blake3();
137 let shared_secret_bob_blake3 = secret_bob.to_blake3();
138
139 assert!(!&shared_secret_alice_blake3.is_err());
140 assert!(!&shared_secret_bob_blake3.is_err());
141
142 assert_eq!(
143 shared_secret_alice_blake3.unwrap(),
144 shared_secret_bob_blake3.unwrap()
145 )
146 }
147
148 #[test]
149 fn test_serialize_deserialize() {
150 let keypair = KeyPair::generate();
151 let pubkey = keypair.pub_key();
152 let pubkey_hex = pubkey.to_hex();
153
154 let bytes_serialized = keypair.to_bytes();
155 let keypair_from_bytes = KeyPair::from_bytes(bytes_serialized);
156 let pubkey_from_bytes = keypair_from_bytes.unwrap().pub_key();
157 let pubkey_from_bytes_hex = pubkey_from_bytes.to_hex();
158
159 assert_eq!(pubkey_hex, pubkey_from_bytes_hex)
160 }
161
162 #[test]
163 fn test_to_keyseucre() {
164 let keypair = KeyPair::generate();
165 let try_keysecure = keypair.to_keysecure(Password::from("test".to_string()));
166 assert!(!try_keysecure.is_err());
167
168 let keysecure = try_keysecure.unwrap();
169 let keysecure_json = keysecure.to_json();
170 assert!(!keysecure_json.is_err());
171 }
172
173 #[test]
174 fn test_secret_from_hex() {
175 let keypair = KeyPair::generate();
176 let pubkey = keypair.pub_key();
177 let pubkey_hex = pubkey.to_hex();
178
179 let keypair_hex = keypair.to_hex();
180 let keypair_from_hex = KeyPair::from_hex(keypair_hex.hex());
181 assert!(!keypair_from_hex.is_err());
182
183 let keypair_generated = keypair_from_hex.unwrap();
184 let pubkey_generated = keypair_generated.pub_key();
185 let pubkey_generated_hex = pubkey_generated.to_hex();
186 assert_eq!(pubkey_hex, pubkey_generated_hex)
187 }
188}