use crate::network::protocol::BanListMessage;
use secp256k1::{ecdsa::Signature, Message, PublicKey, Secp256k1, SecretKey};
pub fn sign_ban_list(
ban_list: &BanListMessage,
private_key: &SecretKey,
) -> Result<Vec<u8>, secp256k1::Error> {
let secp = Secp256k1::new();
let serialized = bincode::serialize(ban_list).map_err(|_| secp256k1::Error::InvalidMessage)?;
use sha2::{Digest, Sha256};
let hash = Sha256::digest(&serialized);
let hash_array: [u8; 32] = hash.into();
let message = Message::from_digest(hash_array);
let signature = secp.sign_ecdsa(&message, private_key);
Ok(signature.serialize_compact().to_vec())
}
pub fn verify_ban_list_signature(
ban_list: &BanListMessage,
signature: &[u8],
public_key: &PublicKey,
) -> Result<bool, secp256k1::Error> {
if signature.len() != 64 {
return Ok(false);
}
let secp = Secp256k1::new();
let serialized = bincode::serialize(ban_list).map_err(|_| secp256k1::Error::InvalidMessage)?;
use sha2::{Digest, Sha256};
let hash = Sha256::digest(&serialized);
let hash_array: [u8; 32] = hash.into();
let message = Message::from_digest(hash_array);
let sig = Signature::from_compact(signature).map_err(|_| secp256k1::Error::InvalidSignature)?;
Ok(secp.verify_ecdsa(&message, &sig, public_key).is_ok())
}
#[derive(Debug, Clone)]
pub struct SignedBanListMessage {
pub ban_list: BanListMessage,
pub signature: Vec<u8>,
pub public_key: PublicKey,
}
impl SignedBanListMessage {
pub fn new(
ban_list: BanListMessage,
private_key: &SecretKey,
) -> Result<Self, secp256k1::Error> {
let secp = Secp256k1::new();
let public_key = PublicKey::from_secret_key(&secp, private_key);
let signature = sign_ban_list(&ban_list, private_key)?;
Ok(Self {
ban_list,
signature,
public_key,
})
}
pub fn verify(&self) -> Result<bool, secp256k1::Error> {
verify_ban_list_signature(&self.ban_list, &self.signature, &self.public_key)
}
}