Refactor and document crypto functions

This commit is contained in:
Alex 2022-11-17 22:53:36 +01:00
parent ab8c3e70c3
commit 79a6109403
Signed by: lx
GPG key ID: 0E496D15096376BE
6 changed files with 68 additions and 47 deletions

View file

@ -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::*;

30
src/crypto/b2.rs Normal file
View file

@ -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)
}
}
}

1
src/crypto/ed25519.rs Normal file
View file

@ -0,0 +1 @@
pub use ed25519_dalek::{Keypair, PublicKey, SecretKey, Signature, Signer};

22
src/crypto/mod.rs Normal file
View file

@ -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,
}

View file

@ -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<Blake2Sum, TypeError> {
Ok(Blake2Sum::from_bytes(self.bytes_exact()?))
pub fn b2sum(&self) -> Result<crypto::Blake2Sum, TypeError> {
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<ed25519_dalek::Keypair, TypeError> {
pub fn keypair(&self) -> Result<crypto::Keypair, TypeError> {
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<ed25519_dalek::PublicKey, TypeError> {
pub fn public_key(&self) -> Result<crypto::PublicKey, TypeError> {
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<ed25519_dalek::SecretKey, TypeError> {
pub fn secret_key(&self) -> Result<crypto::SecretKey, TypeError> {
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<ed25519_dalek::Signature, TypeError> {
pub fn signature(&self) -> Result<crypto::Signature, TypeError> {
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"))
}
}

View file

@ -1,3 +1,5 @@
//! Functions to generate nettext representations of data structures
use std::collections::HashMap;
use crate::dec::decode;