libchat/core/crypto/src/signatures.rs

90 lines
2.2 KiB
Rust
Raw Normal View History

use ed25519_dalek::{self, Signer};
use rand_core::OsRng;
use std::fmt::Debug;
use thiserror::Error;
#[derive(Debug, Error)]
#[error("verification failed of the Ed25519 Signature")]
pub struct SignatureVerificationError {}
/// A 64-byte XEdDSA signature over an Ed25519-compatible curve.
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Ed25519Signature([u8; 64]);
impl Ed25519Signature {
pub fn empty() -> Self {
Self([0u8; 64])
}
}
impl AsRef<[u8; 64]> for Ed25519Signature {
fn as_ref(&self) -> &[u8; 64] {
&self.0
}
}
impl From<[u8; 64]> for Ed25519Signature {
fn from(bytes: [u8; 64]) -> Self {
Self(bytes)
}
}
#[derive(Clone)]
pub struct Ed25519SigningKey(ed25519_dalek::SigningKey);
impl Ed25519SigningKey {
pub fn generate() -> Self {
Self(ed25519_dalek::SigningKey::generate(&mut OsRng))
}
pub fn sign(&self, msg: &[u8]) -> Ed25519Signature {
self.0.sign(msg).to_bytes().into()
}
pub fn verifying_key(&self) -> Ed25519VerifyingKey {
self.0.verifying_key().into()
}
}
impl Debug for Ed25519SigningKey {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("Ed25519SigningKey")
.field(&"[redacted]")
.finish()
}
}
#[derive(Clone, Debug)]
pub struct Ed25519VerifyingKey(ed25519_dalek::VerifyingKey);
impl Ed25519VerifyingKey {
pub fn verify(
&self,
msg: &[u8],
signature: &Ed25519Signature,
) -> Result<(), SignatureVerificationError> {
let inner_signature = signature.0;
self.0
.verify_strict(msg, &ed25519_dalek::Signature::from_bytes(&inner_signature))
.map_err(|_| SignatureVerificationError {})
}
pub fn from_bytes(bytes: &[u8; 32]) -> Result<Self, SignatureVerificationError> {
ed25519_dalek::VerifyingKey::from_bytes(bytes)
.map(Self)
.map_err(|_| SignatureVerificationError {})
}
}
impl From<ed25519_dalek::VerifyingKey> for Ed25519VerifyingKey {
fn from(value: ed25519_dalek::VerifyingKey) -> Self {
Ed25519VerifyingKey(value)
}
}
impl AsRef<[u8]> for Ed25519VerifyingKey {
fn as_ref(&self) -> &[u8] {
self.0.as_bytes()
}
}