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;
|
mod decode;
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use crate::crypto::*;
|
use crate::crypto;
|
||||||
pub use decode::*;
|
pub use decode::*;
|
||||||
|
|
||||||
/// A parsed nettext term, with many helpers for destructuring
|
/// 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();
|
/// let [msg, hash] = term.dict_of(["message", "hash"], false).unwrap();
|
||||||
/// assert!(hash.b2sum().unwrap().check(msg.raw()).is_ok());
|
/// assert!(hash.b2sum().unwrap().check(msg.raw()).is_ok());
|
||||||
/// ```
|
/// ```
|
||||||
pub fn b2sum(&self) -> Result<Blake2Sum, TypeError> {
|
pub fn b2sum(&self) -> Result<crypto::Blake2Sum, TypeError> {
|
||||||
Ok(Blake2Sum::from_bytes(self.bytes_exact()?))
|
Ok(crypto::Blake2Sum::from_bytes(self.bytes_exact()?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "ed25519-dalek")]
|
#[cfg(feature = "ed25519-dalek")]
|
||||||
impl<'a, 'b> Term<'a, 'b> {
|
impl<'a, 'b> Term<'a, 'b> {
|
||||||
/// Try to interpret this string as an ed25519 keypair (64 bytes base64 encoded)
|
/// 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>()?;
|
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)
|
/// 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>()?;
|
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)
|
/// 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>()?;
|
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)
|
/// 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>()?;
|
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 std::collections::HashMap;
|
||||||
|
|
||||||
use crate::dec::decode;
|
use crate::dec::decode;
|
||||||
|
|
Loading…
Reference in a new issue