1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
use ring::signature::{ED25519, Ed25519KeyPair, UnparsedPublicKey}; pub struct PrivateKey(Ed25519KeyPair); impl PrivateKey { pub fn from_bytes(buf: &[u8]) -> Option<Self> { Ed25519KeyPair::from_seed_unchecked(buf) .map(Self) .ok() } pub fn sign(&self, msg: &[u8]) -> Vec<u8> { self.0.sign(msg).as_ref().to_vec() } pub fn from_base64_encoded<T: ?Sized + AsRef<[u8]>>(input: &T) -> Option<Self> { base64::decode_config(input, base64::URL_SAFE_NO_PAD) .ok() .and_then(|seed| Self::from_bytes(&seed)) } } pub struct PublicKey(UnparsedPublicKey<Vec<u8>>); impl PublicKey { pub fn from_bytes(buf: &[u8]) -> Self { Self(UnparsedPublicKey::new(&ED25519, buf.to_vec())) } pub fn from_base64_encoded<T: ?Sized + AsRef<[u8]>>(input: &T) -> Option<Self> { base64::decode_config(input, base64::URL_SAFE_NO_PAD) .ok() .map(|buf| Self(UnparsedPublicKey::new(&ED25519, buf))) } pub fn verify(&self, message: &[u8], signature: &[u8]) -> bool { self.0.verify(message, signature).is_ok() } } impl Clone for PublicKey { fn clone(&self) -> Self { PublicKey(self.0.clone()) } } #[cfg(test)] pub mod tests { pub fn get_test_public_key() -> String { String::from("y9OTFvZmHe41kMjCYtDd8574bv46CSDKexUKN9R7mgM") } pub fn get_test_private_key() -> String { String::from("aMWX1G0p36BRx7YqAJaBJ7hnMDxqIbln0toRQcWQfoA") } }