use std::error::Error;
use rand::{thread_rng, Rng};
use sha2::{Digest, Sha256};
pub mod merkle;
#[derive(Debug, Clone, Copy)]
pub enum SigningError {
KeyRejected,
Unspecified,
SerializationError,
}
impl std::fmt::Display for SigningError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(self, f)
}
}
impl Error for SigningError {}
impl From<ring::error::KeyRejected> for SigningError {
fn from(_: ring::error::KeyRejected) -> Self {
SigningError::KeyRejected
}
}
impl From<ring::error::Unspecified> for SigningError {
fn from(_: ring::error::Unspecified) -> Self {
SigningError::Unspecified
}
}
#[derive(Debug, Clone, Copy)]
pub enum VerificationError {
InvalidSignature,
NoMatch,
BadKey,
Unspecified,
SerdeError,
}
impl Error for VerificationError {}
impl std::fmt::Display for VerificationError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(self, f)
}
}
impl From<ring::error::Unspecified> for VerificationError {
fn from(_: ring::error::Unspecified) -> Self {
VerificationError::Unspecified
}
}
pub fn hash<T: Sized + serde::Serialize>(data: &T) -> Hash {
let bytes = bincode::serialize(data).unwrap();
let buffer = hash_bytes(&bytes);
buffer.into()
}
pub fn hash_bytes(bytes: &[u8]) -> Vec<u8> {
let mut hasher = Sha256::new();
hasher.update(bytes);
let data = hasher.finalize();
data.to_vec()
}
use crate::{
block::UnchainedInstance,
data::{Position, Timestamp},
record::Record,
};
use serde::{Deserialize, Serialize};
pub fn hash_block<R: Record + Serialize>(
block: &UnchainedInstance<R>,
prev_hash: &Hash,
timestamp: &Timestamp,
position: &Position,
) -> Hash {
let records = bincode::serialize(block.records()).unwrap().into();
let timestamp = bincode::serialize(timestamp).unwrap().into();
let position = bincode::serialize(position).unwrap().into();
let buffer = sha_from_x([
prev_hash,
&records,
block.merkle_root(),
×tamp,
&position,
]);
buffer.into()
}
pub fn random_sha256() -> Hash {
let mut bytes = vec![0; 32];
thread_rng().fill(&mut bytes[..]);
bytes.into()
}
pub fn random_bytes<const N: usize>() -> [u8; N] {
let mut bytes = [0; N];
thread_rng().fill(&mut bytes[..]);
bytes
}
pub fn random_bytes_vec(len: usize) -> Vec<u8> {
let mut bytes = vec![0; len];
thread_rng().fill(&mut bytes[..]);
bytes
}
pub fn sha<H: AsRef<[u8]>>(value: &H) -> Hash {
let mut hasher = Sha256::new();
hasher.update(value);
hasher.finalize().to_vec().into()
}
pub fn sha_from_x<H: AsRef<[u8]>, const N: usize>(values: [&H; N]) -> Hash {
let mut hasher = Sha256::new();
for value in values {
hasher.update(value);
}
hasher.finalize().to_vec().into()
}
pub fn verify_hash<T: Sized + serde::Serialize>(obj: &T, value: &Hash) -> bool {
value == &hash(obj)
}
pub fn generate_ed25519_key_pair() -> AuthKeyPair {
let mut rng = rand::thread_rng();
let keypair = ed25519_dalek::Keypair::generate(&mut rng);
let public_key = keypair.public.as_ref().to_vec();
let private_key = keypair.secret.as_ref().to_vec();
AuthKeyPair::new(
private_key.into_boxed_slice(),
public_key.into_boxed_slice(),
KeyPairAlgorithm::Ed25519,
)
}
pub fn verify_signature_ed25519(
msg: &[u8],
signature: DigitalSignature,
signer: PublicKey,
) -> Result<(), VerificationError> {
let dalek = ed25519_dalek::Signature::from_bytes(signature.buffer())
.map_err(|_| VerificationError::InvalidSignature)?;
match ed25519_dalek::PublicKey::from_bytes(signer.buffer()) {
Ok(key) => match ed25519_dalek::Verifier::verify(&key, msg, &dalek) {
Ok(_) => Ok(()),
Err(_) => Err(VerificationError::NoMatch),
},
Err(_) => Err(VerificationError::BadKey),
}
}
pub fn sign_msg(msg: &[u8], key: &AuthKeyPair) -> Result<DigitalSignature, SigningError> {
key.sign(msg)
}
pub fn verify_signature(
msg: &[u8],
signature: &DigitalSignature,
signer: &PublicKey,
) -> Result<(), VerificationError> {
signer.verify(msg, signature)
}
pub fn serialize<T: Serialize>(value: &T) -> Result<Vec<u8>, SigningError> {
bincode::serialize(value).map_err(|_| SigningError::SerializationError)
}
#[derive(Debug, PartialEq, Eq, Clone)]
pub struct PrivateKey {
buffer: Box<[u8]>,
}
impl PrivateKey {
pub fn new(buffer: Box<[u8]>) -> PrivateKey {
Self { buffer }
}
pub fn buffer(&self) -> &[u8] {
&self.buffer
}
}
impl From<Vec<u8>> for PrivateKey {
fn from(buffer: Vec<u8>) -> Self {
PrivateKey {
buffer: buffer.into_boxed_slice(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct PublicKey {
buffer: Box<[u8]>,
algorithm: KeyPairAlgorithm,
}
impl PublicKey {
pub fn new(buffer: Box<[u8]>, algorithm: KeyPairAlgorithm) -> PublicKey {
Self { buffer, algorithm }
}
pub fn buffer(&self) -> &[u8] {
&self.buffer
}
pub fn algorithm(&self) -> KeyPairAlgorithm {
self.algorithm
}
pub fn verify(
&self,
msg: &[u8],
signature: &DigitalSignature,
) -> Result<(), VerificationError> {
self.algorithm.verify(msg, signature, self.buffer())
}
pub fn to_hex(&self) -> String {
hex::encode(&self.buffer)
}
}
impl AsRef<[u8]> for PublicKey {
fn as_ref(&self) -> &[u8] {
self.buffer()
}
}
impl From<PublicKey> for String {
fn from(value: PublicKey) -> Self {
value.to_hex()
}
}
impl std::fmt::Display for PublicKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.to_hex())
}
}
impl From<AuthKeyPair> for PublicKey {
fn from(value: AuthKeyPair) -> Self {
let AuthKeyPair {
private_key: _,
public_key,
algorithm,
} = value;
Self {
buffer: public_key,
algorithm,
}
}
}
#[derive(Debug, Clone)]
pub struct AuthKeyPair {
private_key: Box<[u8]>,
public_key: Box<[u8]>,
algorithm: KeyPairAlgorithm,
}
impl AuthKeyPair {
pub fn new(
private_key: Box<[u8]>,
public_key: Box<[u8]>,
algorithm: KeyPairAlgorithm,
) -> AuthKeyPair {
AuthKeyPair {
private_key,
public_key,
algorithm,
}
}
pub fn public_key_bytes(&self) -> &[u8] {
&self.public_key
}
pub fn private_key_bytes(&self) -> &[u8] {
&self.private_key
}
pub fn into_public_key(self) -> PublicKey {
self.into()
}
pub fn algorithm(&self) -> KeyPairAlgorithm {
self.algorithm
}
pub fn sign(&self, msg: &[u8]) -> Result<DigitalSignature, SigningError> {
self.algorithm.sign(msg, self)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Hash {
buffer: Box<[u8]>,
}
impl Hash {
pub fn new(buffer: Box<[u8]>) -> Hash {
Hash { buffer }
}
pub fn buffer(&self) -> &[u8] {
&self.buffer
}
pub fn to_hex(&self) -> String {
hex::encode(&self.buffer)
}
}
impl Default for Hash {
fn default() -> Self {
let buffer = vec![0; 32];
Hash::new(buffer.into_boxed_slice())
}
}
impl Into<[u8; 32]> for Hash {
fn into(self) -> [u8; 32] {
let mut buffer = [0; 32];
for i in 0..usize::min(32, self.buffer.len()) {
buffer[i] = self.buffer[i];
}
buffer
}
}
impl From<Hash> for String {
fn from(data: Hash) -> Self {
hex::encode(data)
}
}
impl std::fmt::Display for Hash {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.to_hex())
}
}
impl std::ops::Deref for Hash {
type Target = [u8];
fn deref(&self) -> &Self::Target {
self.buffer()
}
}
impl AsRef<[u8]> for Hash {
fn as_ref(&self) -> &[u8] {
self.buffer()
}
}
impl From<Vec<u8>> for Hash {
fn from(value: Vec<u8>) -> Hash {
Hash::new(value.into_boxed_slice())
}
}
impl From<[u8; 32]> for Hash {
fn from(value: [u8; 32]) -> Self {
Hash {
buffer: value.into(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DigitalSignature {
pub(crate) buffer: Box<[u8]>,
}
impl DigitalSignature {
pub fn new(buffer: Box<[u8]>) -> DigitalSignature {
Self { buffer }
}
pub fn buffer(&self) -> &[u8] {
&self.buffer
}
pub fn to_hex(&self) -> String {
hex::encode(&self.buffer)
}
}
impl From<Vec<u8>> for DigitalSignature {
fn from(value: Vec<u8>) -> DigitalSignature {
DigitalSignature::new(value.into_boxed_slice())
}
}
impl From<DigitalSignature> for String {
fn from(value: DigitalSignature) -> Self {
value.to_hex()
}
}
impl std::fmt::Display for DigitalSignature {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.to_hex())
}
}
impl AsRef<[u8]> for DigitalSignature {
fn as_ref(&self) -> &[u8] {
self.buffer()
}
}
use ring::signature::{
EcdsaKeyPair, EcdsaSigningAlgorithm, Ed25519KeyPair, RsaEncoding, RsaKeyPair,
UnparsedPublicKey, VerificationAlgorithm,
};
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum KeyPairAlgorithm {
Ed25519,
Ecdsa256256Fixed,
RsaPKCS1256,
}
impl std::fmt::Display for KeyPairAlgorithm {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Debug::fmt(self, f)
}
}
impl KeyPairAlgorithm {
fn sign(self, msg: &[u8], key: &AuthKeyPair) -> Result<DigitalSignature, SigningError> {
match self {
KeyPairAlgorithm::Ed25519 => sign_ed25519(msg, key),
KeyPairAlgorithm::RsaPKCS1256 => {
sign_rsa(msg, &key, &ring::signature::RSA_PKCS1_SHA256)
}
KeyPairAlgorithm::Ecdsa256256Fixed => {
sign_ecdsa(msg, key, &ring::signature::ECDSA_P256_SHA256_FIXED_SIGNING)
}
}
}
pub fn verify(
self,
msg: &[u8],
signature: &DigitalSignature,
signer: &[u8],
) -> Result<(), VerificationError> {
let algo: &dyn VerificationAlgorithm = match self {
KeyPairAlgorithm::Ed25519 => &ring::signature::ED25519,
KeyPairAlgorithm::RsaPKCS1256 => &ring::signature::RSA_PKCS1_2048_8192_SHA256,
KeyPairAlgorithm::Ecdsa256256Fixed => &ring::signature::ECDSA_P256_SHA256_FIXED,
};
let key = UnparsedPublicKey::new(algo, signer);
key.verify(msg, signature.buffer())?;
Ok(())
}
}
fn sign_ecdsa(
msg: &[u8],
key: &AuthKeyPair,
algo: &'static EcdsaSigningAlgorithm,
) -> Result<DigitalSignature, SigningError> {
let rng = ring::rand::SystemRandom::new();
let key = EcdsaKeyPair::from_private_key_and_public_key(
algo,
key.private_key_bytes(),
key.public_key_bytes(),
)?;
let signature = key.sign(&rng, msg)?;
let buffer = signature.as_ref().to_vec();
Ok(buffer.into())
}
fn sign_ed25519(msg: &[u8], key: &AuthKeyPair) -> Result<DigitalSignature, SigningError> {
let key =
Ed25519KeyPair::from_seed_and_public_key(key.private_key_bytes(), key.public_key_bytes())?;
let signature = key.sign(msg).as_ref().to_vec();
Ok(signature.into())
}
fn sign_rsa(
msg: &[u8],
key: &AuthKeyPair,
padding: &'static dyn RsaEncoding,
) -> Result<DigitalSignature, SigningError> {
let rng = ring::rand::SystemRandom::new();
let private_key = RsaKeyPair::from_der(key.private_key_bytes())?;
let mut signature_vec = vec![0u8; private_key.public_modulus_len()];
private_key.sign(padding, &rng, &msg, &mut signature_vec)?;
Ok(signature_vec.into())
}
#[cfg(test)]
mod tests {
use serde::Serialize;
#[test]
fn hash_test() {
#[derive(Serialize)]
struct DMS {
audio: Option<String>,
moving_pictures: Option<String>,
metadata: String,
}
impl DMS {
fn new(audio: Option<String>, mp: Option<String>, d: String) -> DMS {
DMS {
audio,
moving_pictures: mp,
metadata: d,
}
}
}
impl Default for DMS {
fn default() -> Self {
DMS::new(None, None, String::new())
}
}
let dms = DMS::default();
let my_dms = DMS::new(None, Some("Harry Potter".into()), "".into());
let dms_hash = crate::hash(&dms);
let my_dms_hash = crate::hash(&my_dms);
println!("{}", dms_hash.to_hex());
println!("{}", my_dms_hash.to_hex());
}
}