libchat/core/crypto/src/signatures.rs
kaichao f41fb40c2f
feat: extend the http registry to store account's installations (#129)
* feat: account to device store

* feat: accout traits and codec

* feat: integrate accounts abstraction

* chore: clean docs and naming

* remove account public key from payload

* chore: fix clippy

* feat: lamport check before update account store

* chore: rebase to core

* chore: register account in new core

* chore: rebase changes and use account pub for index account store

* chore: move chat store outside of libchat

* chore: use account pub for registry
2026-06-11 21:07:11 +08:00

90 lines
2.2 KiB
Rust

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, PartialEq, Eq, Hash)]
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()
}
}