use crate::{
ClosedKeyRegistration, MembershipDigest, Parameters, SingleSignature, Stake, is_lottery_won,
proof_system::SingleSignatureForConcatenation,
signature_scheme::{BlsSignature, BlsSigningKey, BlsVerificationKey},
};
pub type VerificationKey = BlsVerificationKey;
#[derive(Debug, Clone)]
pub struct Signer<D: MembershipDigest> {
signer_index: u64,
stake: Stake,
params: Parameters,
sk: BlsSigningKey,
vk: VerificationKey,
closed_reg: Option<ClosedKeyRegistration<D>>,
}
impl<D: MembershipDigest> Signer<D> {
pub(crate) fn set_signer(
signer_index: u64,
stake: Stake,
params: Parameters,
sk: BlsSigningKey,
vk: VerificationKey,
closed_reg: ClosedKeyRegistration<D>,
) -> Signer<D> {
Self {
signer_index,
stake,
params,
sk,
vk,
closed_reg: Some(closed_reg),
}
}
pub fn sign(&self, msg: &[u8]) -> Option<SingleSignature> {
let closed_reg = self
.closed_reg
.as_ref()
.expect("Closed registration not found! Cannot produce SingleSignatures.");
let msgp = closed_reg
.merkle_tree
.to_merkle_tree_batch_commitment()
.concatenate_with_message(msg);
let sigma = self.sk.sign(&msgp);
let indexes = self.check_lottery(&msgp, &sigma, closed_reg.total_stake);
if !indexes.is_empty() {
Some(SingleSignature {
concatenation_signature: SingleSignatureForConcatenation::new(sigma, indexes),
signer_index: self.signer_index,
})
} else {
None
}
}
pub fn get_verification_key(&self) -> VerificationKey {
self.vk
}
pub fn get_stake(&self) -> Stake {
self.stake
}
pub fn check_lottery(&self, msg: &[u8], sigma: &BlsSignature, total_stake: Stake) -> Vec<u64> {
let mut indexes = Vec::new();
for index in 0..self.params.m {
if is_lottery_won(
self.params.phi_f,
sigma.evaluate_dense_mapping(msg, index),
self.stake,
total_stake,
) {
indexes.push(index);
}
}
indexes
}
pub(crate) fn get_parameters(&self) -> Parameters {
self.params
}
pub(crate) fn get_closed_key_registration(&self) -> Option<ClosedKeyRegistration<D>> {
self.closed_reg.clone()
}
}