mirror of https://github.com/Revertron/Alfis
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
88 lines
2.6 KiB
Rust
88 lines
2.6 KiB
Rust
use std::fmt;
|
|
use std::fmt::{Debug, Formatter};
|
|
|
|
use ecies_ed25519_ng::{decrypt, encrypt, Error, PublicKey, SecretKey};
|
|
use rand::{CryptoRng, RngCore};
|
|
|
|
use crate::{from_hex, to_hex};
|
|
|
|
pub struct CryptoBox {
|
|
pub(crate) secret: SecretKey,
|
|
pub(crate) public: PublicKey
|
|
}
|
|
|
|
impl CryptoBox {
|
|
pub fn new(seed: &[u8]) -> Self {
|
|
let secret = SecretKey::from_bytes(seed).expect("Unable to parse secret key");
|
|
let public = PublicKey::from_secret(&secret);
|
|
Self { secret, public }
|
|
}
|
|
|
|
pub fn generate<R>(csprng: &mut R) -> Self where R: CryptoRng + RngCore {
|
|
let (secret, public) = ecies_ed25519_ng::generate_keypair(csprng);
|
|
Self { secret, public }
|
|
}
|
|
|
|
pub fn from_strings(secret: &str, public: &str) -> Self {
|
|
let secret = SecretKey::from_bytes(&from_hex(secret).unwrap()).unwrap();
|
|
let public = PublicKey::from_bytes(&from_hex(public).unwrap()).unwrap();
|
|
Self { secret, public }
|
|
}
|
|
|
|
pub fn hide(&self, msg: &[u8]) -> Result<Vec<u8>, Error> {
|
|
let mut random = rand::thread_rng();
|
|
encrypt(&self.public, msg, &mut random)
|
|
}
|
|
|
|
pub fn reveal(&self, msg: &[u8]) -> Result<Vec<u8>, Error> {
|
|
decrypt(&self.secret, msg)
|
|
}
|
|
|
|
pub fn encrypt(public: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
|
|
let public = PublicKey::from_bytes(public).unwrap();
|
|
let mut random = rand::thread_rng();
|
|
encrypt(&public, message, &mut random)
|
|
}
|
|
|
|
pub fn decrypt(secret: &[u8], message: &[u8]) -> Result<Vec<u8>, Error> {
|
|
let secret = SecretKey::from_bytes(secret).unwrap();
|
|
decrypt(&secret, message)
|
|
}
|
|
}
|
|
|
|
impl Debug for CryptoBox {
|
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
|
f.debug_struct("CryptoBox")
|
|
.field("public", &to_hex(&self.public.to_bytes()))
|
|
.finish()
|
|
}
|
|
}
|
|
|
|
impl Clone for CryptoBox {
|
|
fn clone(&self) -> Self {
|
|
let secret = SecretKey::from_bytes(&self.secret.as_bytes()[..]).expect("Unable clone secret key");
|
|
let public = PublicKey::from_secret(&secret);
|
|
Self { secret, public }
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use rand::RngCore;
|
|
|
|
use crate::crypto::CryptoBox;
|
|
|
|
const TEXT: &str = "Some very secret message";
|
|
|
|
#[test]
|
|
pub fn hide_reveal() {
|
|
let mut rng = rand::thread_rng();
|
|
let mut buf = [0u8; 32];
|
|
rng.fill_bytes(&mut buf);
|
|
let coder = CryptoBox::new(&buf);
|
|
let encrypted = coder.hide(TEXT.as_bytes()).unwrap();
|
|
let decrypted = coder.reveal(&encrypted.as_slice()).unwrap();
|
|
|
|
assert_eq!(TEXT, &String::from_utf8(decrypted).unwrap());
|
|
}
|
|
} |