use base64::prelude::*;
use serde::{Deserialize, Serialize};
use sha3::Digest;
use crate::signer_user::SignerUser;
#[derive(Debug, Serialize, Deserialize)]
pub struct SignerSignature {
pub bytes: String,
pub pub_key: String,
}
impl SignerSignature {
pub fn create(user: &SignerUser, message: &[u8]) -> anyhow::Result<Self> {
let mut hasher = sha3::Sha3_256::new();
hasher.update(message);
let hash = hasher.finalize();
let keypair = user.to_keypair()?;
let sig = keypair.sign_simple(b"", hash.as_slice());
Ok(SignerSignature {
bytes: BASE64_URL_SAFE.encode(sig.to_bytes()),
pub_key: user.public.pub_key.clone(),
})
}
pub fn verify(&self, message: &[u8]) -> anyhow::Result<()> {
let mut hasher = sha3::Sha3_256::new();
hasher.update(message);
let hash = hasher.finalize();
let sig =
schnorrkel::Signature::from_bytes(&BASE64_URL_SAFE.decode(&self.bytes)?)
.map_err(|e| anyhow::anyhow!("decode signature failed: {}", e))?;
let pub_key = schnorrkel::PublicKey::from_bytes(
&BASE64_URL_SAFE.decode(&self.pub_key)?,
)
.map_err(|e| anyhow::anyhow!("decode public key failed: {}", e))?;
pub_key
.verify_simple(b"", hash.as_slice(), &sig)
.map_err(|e| anyhow::anyhow!("verify signature failed: {}", e))
}
}