/// This module has wrappers for cryptography with RSA algorithms. /// Its main structs - `PublicKey` and `Keys` implement all functions for key generation, signatures and asymmetric encryption use alloc::vec::Vec; use serde::{Deserialize, Serialize}; use rsa::{RsaPublicKey, RsaPrivateKey, PaddingScheme, PublicKey as RPK}; use rsa::errors::Result as RsaRes; use rand::rngs::OsRng; static KEY_LENGTH: usize = 2048; /// Public key of a node #[derive(Debug, PartialEq, Serialize, Deserialize, Clone)] pub struct PublicKey { pub key: RsaPublicKey, } impl PublicKey { /// Check if the sign is valid for given data and key pub fn verify_sign(&self, data: &[u8], sign: &[u8]) -> bool { self.key.verify(PaddingScheme::PKCS1v15Sign { hash: None }, data, sign).is_ok() } /// Encrypt some data for a user with this public key pub fn encrypt_data(&self, data: &[u8]) -> RsaRes> { self.key.encrypt(&mut OsRng {}, PaddingScheme::PKCS1v15Encrypt, data) } } /// Key pair (public and secret) for a node, should be stored locally #[derive(Debug, Serialize, Deserialize, Clone)] pub struct Keys { public_key: RsaPublicKey, private_key: RsaPrivateKey, } impl Keys { /// Generate new random key pub fn generate() -> Self { let mut rng = OsRng; let private_key = RsaPrivateKey::new(&mut rng, KEY_LENGTH).expect("failed to generate a key"); let public_key = RsaPublicKey::from(&private_key); Self { private_key, public_key, } } } impl Keys { /// Sign content using these keys pub fn sign(&self, content: &[u8]) -> RsaRes> { self.private_key.sign(PaddingScheme::PKCS1v15Sign { hash: None }, content) } /// Decrypt data pub fn decrypt_data(&self, data_encrypted: &[u8]) -> RsaRes> { self.private_key.decrypt(PaddingScheme::PKCS1v15Encrypt, data_encrypted) } /// Get public key pub fn get_public(&self) -> PublicKey { PublicKey { key: self.public_key.clone() } } } #[test] fn test_encrypt() { let data = vec![0, 5, 8, 135, 67]; let keys = Keys::generate(); assert_eq!( keys.decrypt_data(&keys.get_public().encrypt_data(&data).unwrap()).unwrap(), data ); } #[cfg(test)] use alloc::vec; #[test] fn test_invalid_encrypt() { let data = vec![0, 5, 8, 135, 67]; let keys_1 = Keys::generate(); let keys_2 = Keys::generate(); assert!(keys_2.decrypt_data(&keys_1.get_public().encrypt_data(&data).unwrap()).is_err()); } #[test] fn test_signing() { let data = vec![0, 5, 8, 135, 67]; let keys = Keys::generate(); assert!(keys.get_public().verify_sign(&data, &keys.sign(&data).unwrap())); } #[test] fn test_invalid_signing() { let data = vec![0, 5, 8, 135, 67]; let keys_1 = Keys::generate(); let keys_2 = Keys::generate(); assert!(!keys_2.get_public().verify_sign(&data, &keys_1.sign(&data).unwrap())); }