Refactor and document crypto functions
This commit is contained in:
parent
ab8c3e70c3
commit
79a6109403
6 changed files with 68 additions and 47 deletions
|
@ -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
30
src/crypto/b2.rs
Normal 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
1
src/crypto/ed25519.rs
Normal file
|
@ -0,0 +1 @@
|
|||
pub use ed25519_dalek::{Keypair, PublicKey, SecretKey, Signature, Signer};
|
22
src/crypto/mod.rs
Normal file
22
src/crypto/mod.rs
Normal 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,
|
||||
}
|
||||
|
|
@ -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"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
//! Functions to generate nettext representations of data structures
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::dec::decode;
|
||||
|
|
Loading…
Reference in a new issue