use std::sync::Arc;
use base_xx::ByteVec;
use ed25519_dalek::Signer as _;
use rand_core::OsRng;
use slahasher::Hash;
use crate::Signature;
use crate::SignatureError;
use crate::Signer;
use crate::SigningAlgorithm;
pub struct Ed25519Signer {
signing_key: ed25519_dalek::SigningKey,
}
impl Ed25519Signer {
#[must_use]
pub const fn new(signing_key: ed25519_dalek::SigningKey) -> Self {
Self { signing_key }
}
#[must_use]
pub fn new_random() -> Self {
Self {
signing_key: ed25519_dalek::SigningKey::generate(&mut OsRng),
}
}
#[must_use]
pub const fn get_signing_key(&self) -> &ed25519_dalek::SigningKey {
&self.signing_key
}
#[must_use]
pub fn get_verifying_key(&self) -> ed25519_dalek::VerifyingKey {
self.signing_key.verifying_key()
}
}
impl Default for Ed25519Signer {
fn default() -> Self {
Self::new_random()
}
}
impl Signer for Ed25519Signer {
fn sign(self: Arc<Self>, hash: Arc<Hash>) -> Result<Arc<Signature>, SignatureError> {
let signature: ed25519_dalek::Signature =
self.signing_key.sign(hash.get_bytes().get_bytes());
Ok(Arc::new(Signature::new_with_algorithm(
SigningAlgorithm::ED25519,
Arc::new(ByteVec::new(Arc::new(signature.to_bytes().to_vec()))),
)))
}
}
#[cfg(test)]
mod tests {
use super::*;
use base_xx::{ByteVec, EncodedString, Encoding, byte_vec::Encodable};
use slahasher::HashAlgorithm;
use slogger::debug;
#[test]
fn test_ed25519_sign() {
let signer = Ed25519Signer::default();
let data = b"test";
let bytes = ByteVec::new(Arc::new(data.to_vec()));
let hash = Hash::try_hash(Arc::new(bytes), HashAlgorithm::KECCAK512)
.unwrap_or_else(|_| unreachable!());
let signature =
Ed25519Signer::sign(Arc::new(signer), hash).unwrap_or_else(|_| unreachable!());
let serialised = Arc::clone(&signature)
.try_encode(Encoding::Base58)
.unwrap_or_else(|_| EncodedString::new(Encoding::Base58, String::new()));
debug!("signature {serialised}");
assert_eq!(signature.get_algorithm(), SigningAlgorithm::ED25519);
assert_eq!(signature.get_signature().get_bytes().len(), 64);
}
}