mithril_stm/participant/
signer.rs1use blake2::digest::{Digest, FixedOutput};
2
3use crate::bls_multi_signature::{BlsSignature, BlsSigningKey, BlsVerificationKey};
4use crate::eligibility_check::ev_lt_phi;
5use crate::key_registration::ClosedKeyRegistration;
6use crate::{Parameters, SingleSignature, Stake};
7
8pub type VerificationKey = BlsVerificationKey;
10
11#[derive(Debug, Clone)]
19pub struct Signer<D: Digest> {
20 signer_index: u64,
21 stake: Stake,
22 params: Parameters,
23 sk: BlsSigningKey,
24 vk: VerificationKey,
25 closed_reg: Option<ClosedKeyRegistration<D>>,
26}
27
28impl<D: Clone + Digest + FixedOutput> Signer<D> {
29 pub fn set_stm_signer(
31 signer_index: u64,
32 stake: Stake,
33 params: Parameters,
34 sk: BlsSigningKey,
35 vk: VerificationKey,
36 closed_reg: ClosedKeyRegistration<D>,
37 ) -> Signer<D> {
38 Self {
39 signer_index,
40 stake,
41 params,
42 sk,
43 vk,
44 closed_reg: Some(closed_reg),
45 }
46 }
47
48 pub fn set_core_signer(
50 signer_index: u64,
51 stake: Stake,
52 params: Parameters,
53 sk: BlsSigningKey,
54 vk: VerificationKey,
55 ) -> Signer<D> {
56 Self {
57 signer_index,
58 stake,
59 params,
60 sk,
61 vk,
62 closed_reg: None,
63 }
64 }
65
66 pub fn sign(&self, msg: &[u8]) -> Option<SingleSignature> {
73 let closed_reg = self.closed_reg.as_ref().expect("Closed registration not found! Cannot produce SingleSignatures. Use core_sign to produce core signatures (not valid for an StmCertificate).");
74 let msgp = closed_reg
75 .merkle_tree
76 .to_commitment_batch_compat()
77 .concat_with_msg(msg);
78 let signature = self.core_sign(&msgp, closed_reg.total_stake)?;
79
80 Some(SingleSignature {
81 sigma: signature.sigma,
82 signer_index: self.signer_index,
83 indexes: signature.indexes,
84 })
85 }
86
87 pub fn verification_key(&self) -> VerificationKey {
89 self.vk
90 }
91
92 pub fn get_stake(&self) -> Stake {
94 self.stake
95 }
96
97 pub fn core_sign(&self, msg: &[u8], total_stake: Stake) -> Option<SingleSignature> {
103 let sigma = self.sk.sign(msg);
104
105 let indexes = self.check_lottery(msg, &sigma, total_stake);
106 if !indexes.is_empty() {
107 Some(SingleSignature {
108 sigma,
109 indexes,
110 signer_index: self.signer_index,
111 })
112 } else {
113 None
114 }
115 }
116
117 pub fn check_lottery(&self, msg: &[u8], sigma: &BlsSignature, total_stake: Stake) -> Vec<u64> {
119 let mut indexes = Vec::new();
120 for index in 0..self.params.m {
121 if ev_lt_phi(
122 self.params.phi_f,
123 sigma.eval(msg, index),
124 self.stake,
125 total_stake,
126 ) {
127 indexes.push(index);
128 }
129 }
130 indexes
131 }
132
133 pub fn get_params(&self) -> Parameters {
135 self.params
136 }
137
138 pub fn get_closed_reg(&self) -> Option<ClosedKeyRegistration<D>> {
140 self.closed_reg.clone()
141 }
142
143 pub fn get_vk(&self) -> VerificationKey {
145 self.vk
146 }
147}