From 79a6109403b7f4144fb707a912c0b3b449d29448 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Thu, 17 Nov 2022 22:53:36 +0100 Subject: [PATCH] Refactor and document crypto functions --- src/crypto.rs | 36 ------------------------------------ src/crypto/b2.rs | 30 ++++++++++++++++++++++++++++++ src/crypto/ed25519.rs | 1 + src/crypto/mod.rs | 22 ++++++++++++++++++++++ src/dec/mod.rs | 24 +++++++++++++----------- src/enc/mod.rs | 2 ++ 6 files changed, 68 insertions(+), 47 deletions(-) delete mode 100644 src/crypto.rs create mode 100644 src/crypto/b2.rs create mode 100644 src/crypto/ed25519.rs create mode 100644 src/crypto/mod.rs diff --git a/src/crypto.rs b/src/crypto.rs deleted file mode 100644 index c9847ec..0000000 --- a/src/crypto.rs +++ /dev/null @@ -1,36 +0,0 @@ -pub enum CryptoError { - InvalidHash, - InvalidSignature, -} - -#[cfg(feature = "blake2")] -mod b2 { - use super::CryptoError; - use blake2::{Blake2b512, Digest}; - - #[derive(Clone, Copy, Eq, PartialEq)] - pub struct Blake2Sum([u8; 64]); - - impl Blake2Sum { - pub fn from_bytes(bytes: [u8; 64]) -> Self { - Self(bytes) - } - - pub fn compute(buf: &[u8]) -> Self { - let mut hasher = Blake2b512::new(); - hasher.update(buf); - Self(hasher.finalize()[..].try_into().unwrap()) - } - - pub fn check(&self, buf: &[u8]) -> Result<(), CryptoError> { - if Self::compute(buf) == *self { - Ok(()) - } else { - Err(CryptoError::InvalidHash) - } - } - } -} - -#[cfg(feature = "blake2")] -pub use b2::*; diff --git a/src/crypto/b2.rs b/src/crypto/b2.rs new file mode 100644 index 0000000..3026d12 --- /dev/null +++ b/src/crypto/b2.rs @@ -0,0 +1,30 @@ +use blake2::{Blake2b512, Digest}; + +use crate::crypto::CryptoError; + +/// A Blake2b512 digest +#[derive(Clone, Copy, Eq, PartialEq)] +pub struct Blake2Sum([u8; 64]); + +impl Blake2Sum { + /// Create a Blake2Sum object by passing the digest as bytes directly + pub fn from_bytes(bytes: [u8; 64]) -> Self { + Self(bytes) + } + + /// Compute the Blake2b512 digest of a byte slice + pub fn compute(buf: &[u8]) -> Self { + let mut hasher = Blake2b512::new(); + hasher.update(buf); + Self(hasher.finalize()[..].try_into().unwrap()) + } + + /// Check that this digest corresponds to a given slice + pub fn check(&self, buf: &[u8]) -> Result<(), CryptoError> { + if Self::compute(buf) == *self { + Ok(()) + } else { + Err(CryptoError::InvalidHash) + } + } +} diff --git a/src/crypto/ed25519.rs b/src/crypto/ed25519.rs new file mode 100644 index 0000000..cfc4580 --- /dev/null +++ b/src/crypto/ed25519.rs @@ -0,0 +1 @@ +pub use ed25519_dalek::{Keypair, PublicKey, SecretKey, Signature, Signer}; diff --git a/src/crypto/mod.rs b/src/crypto/mod.rs new file mode 100644 index 0000000..0f099e4 --- /dev/null +++ b/src/crypto/mod.rs @@ -0,0 +1,22 @@ +//! Helpers to use cryptographic data types in nettext + +#[cfg(feature = "blake2")] +mod b2; + +#[cfg(feature = "blake2")] +pub use b2::*; + +#[cfg(feature = "ed25519-dalek")] +mod ed25519; + +#[cfg(feature = "ed25519-dalek")] +pub use ed25519::*; + +/// An error corresponding to a cryptographic check that failed +pub enum CryptoError { + /// A hash verification failed + InvalidHash, + /// A signature verification failed + InvalidSignature, +} + diff --git a/src/dec/mod.rs b/src/dec/mod.rs index 2fc5288..bbede71 100644 --- a/src/dec/mod.rs +++ b/src/dec/mod.rs @@ -1,8 +1,10 @@ +//! Functions to decode nettext and helpers to map it to data structures + mod decode; use std::collections::HashMap; -use crate::crypto::*; +use crate::crypto; pub use decode::*; /// A parsed nettext term, with many helpers for destructuring @@ -430,35 +432,35 @@ impl<'a, 'b> Term<'a, 'b> { /// let [msg, hash] = term.dict_of(["message", "hash"], false).unwrap(); /// assert!(hash.b2sum().unwrap().check(msg.raw()).is_ok()); /// ``` - pub fn b2sum(&self) -> Result { - Ok(Blake2Sum::from_bytes(self.bytes_exact()?)) + pub fn b2sum(&self) -> Result { + Ok(crypto::Blake2Sum::from_bytes(self.bytes_exact()?)) } } #[cfg(feature = "ed25519-dalek")] impl<'a, 'b> Term<'a, 'b> { /// Try to interpret this string as an ed25519 keypair (64 bytes base64 encoded) - pub fn keypair(&self) -> Result { + pub fn keypair(&self) -> Result { let bytes = self.bytes_exact::<64>()?; - ed25519_dalek::Keypair::from_bytes(&bytes).map_err(|_| TypeError::WrongType("KEYPAIR")) + crypto::Keypair::from_bytes(&bytes).map_err(|_| TypeError::WrongType("KEYPAIR")) } /// Try to interpret this string as an ed25519 public key (32 bytes base64 encoded) - pub fn public_key(&self) -> Result { + pub fn public_key(&self) -> Result { let bytes = self.bytes_exact::<32>()?; - ed25519_dalek::PublicKey::from_bytes(&bytes).map_err(|_| TypeError::WrongType("PUBLICKEY")) + crypto::PublicKey::from_bytes(&bytes).map_err(|_| TypeError::WrongType("PUBLICKEY")) } /// Try to interpret this string as an ed25519 secret key (32 bytes base64 encoded) - pub fn secret_key(&self) -> Result { + pub fn secret_key(&self) -> Result { let bytes = self.bytes_exact::<32>()?; - ed25519_dalek::SecretKey::from_bytes(&bytes).map_err(|_| TypeError::WrongType("SECRETKEY")) + crypto::SecretKey::from_bytes(&bytes).map_err(|_| TypeError::WrongType("SECRETKEY")) } /// Try to interpret this string as an ed25519 signature (64 bytes base64 encoded) - pub fn signature(&self) -> Result { + pub fn signature(&self) -> Result { let bytes = self.bytes_exact::<64>()?; - ed25519_dalek::Signature::from_bytes(&bytes).map_err(|_| TypeError::WrongType("SIGNATURE")) + crypto::Signature::from_bytes(&bytes).map_err(|_| TypeError::WrongType("SIGNATURE")) } } diff --git a/src/enc/mod.rs b/src/enc/mod.rs index 2dc2f4c..376ed0e 100644 --- a/src/enc/mod.rs +++ b/src/enc/mod.rs @@ -1,3 +1,5 @@ +//! Functions to generate nettext representations of data structures + use std::collections::HashMap; use crate::dec::decode;