Skip to content

Commit

Permalink
Add wrap protocol signer and clerk
Browse files Browse the repository at this point in the history
  • Loading branch information
iquerejeta authored and jpraynaud committed Sep 23, 2022
1 parent 5142219 commit 6bb80a5
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 11 deletions.
87 changes: 77 additions & 10 deletions mithril-common/src/crypto_helper/types.rs
Expand Up @@ -29,15 +29,11 @@ pub type ProtocolPartyId = String;
/// Alias of [MithrilCore:Stake](https://mithril.network/mithril-core/doc/mithril/stm/type.Stake.html).
pub type ProtocolStake = Stake;
/// A list of [Party Id][ProtocolPartyId] associated with its [Stake][ProtocolStake].
pub type ProtocolStakeDistribution = Vec<(ProtocolPartyId, ProtocolStake)>;
pub type ProtocolStakeDistribution = Vec<(ProtocolPartyId, ProtocolStake)>; // todo: should eventually be Vec<(PoolId, ProtocolStake)>
/// Alias of [MithrilCore::StmParameters](https://mithril.network/mithril-core/doc/mithril/stm/struct.StmParameters.html).
pub type ProtocolParameters = StmParameters;
/// Alias of [MithrilCore::Index](https://mithril.network/mithril-core/doc/mithril/stm/type.Index.html).
pub type ProtocolLotteryIndex = Index;
/// Alias of [MithrilCore:StmSigner](https://mithril.network/mithril-core/doc/mithril/stm/struct.StmSigner.html).
pub type ProtocolSigner = StmSigner<D>;
/// Alias of [MithrilCore:StmClerk](https://mithril.network/mithril-core/doc/mithril/stm/struct.StmClerk.html).
pub type ProtocolClerk = StmClerk<D>;
/// Alias of [MithrilCore:KeyReg](https://mithril.network/mithril-core/doc/mithril/key_reg/struct.KeyReg.html).
pub type ProtocolKeyRegistration = KeyReg;
/// Alias of [MithrilCore:StmSig](https://mithril.network/mithril-core/doc/mithril/stm/struct.StmSig.html).
Expand Down Expand Up @@ -76,6 +72,40 @@ pub struct NewProtocolKeyRegistration {
stake_distribution: HashMap<PoolId, Stake>,
}

/// Wrapper structure for [MithrilCore:StmSigner](https://mithril.network/mithril-core/doc/mithril/stm/struct.StmSigner.html).
#[derive(Debug, Clone)]
pub struct ProtocolSigner(StmSigner<D>);

/// Wrapper structure fo [MithrilCore:StmClerk](https://mithril.network/mithril-core/doc/mithril/stm/struct.StmClerk.html).
#[derive(Debug, Clone)]
pub struct ProtocolClerk(StmClerk<D>);

impl ProtocolClerk {
/// Create a new `Clerk` from a closed registration instance.
pub fn from_registration(params: &StmParameters, closed_reg: &ClosedKeyReg<D>) -> Self {
Self(StmClerk::from_registration(params, closed_reg))
}

/// Create a Clerk from a signer.
pub fn from_signer(signer: &ProtocolSigner) -> Self {
Self(StmClerk::from_signer(&signer.0))
}

/// Aggregate a set of signatures for their corresponding indices.
pub fn aggregate(
&self,
sigs: &[StmSig<D>],
msg: &[u8],
) -> Result<StmAggrSig<D>, AggregationError> {
self.0.aggregate(sigs, msg)
}

/// Compute the `StmAggrVerificationKey` related to the used registration.
pub fn compute_avk(&self) -> StmAggrVerificationKey<D> {
self.0.compute_avk()
}
}

impl ProtocolInitializer {
/// Old setup. todo: remove
pub fn setup<R: RngCore + CryptoRng>(params: StmParameters, stake: Stake, rng: &mut R) -> Self {
Expand Down Expand Up @@ -126,11 +156,8 @@ impl ProtocolInitializer {
/// * the current total stake (according to the registration service)
/// # Error
/// This function fails if the initializer is not registered.
pub fn new_signer<D: Digest + Clone>(
self,
closed_reg: ClosedKeyReg<D>,
) -> Result<StmSigner<D>, RegisterError> {
self.stm_initializer.new_signer(closed_reg)
pub fn new_signer(self, closed_reg: ClosedKeyReg<D>) -> Result<ProtocolSigner, RegisterError> {
Ok(ProtocolSigner(self.stm_initializer.new_signer(closed_reg)?))
}

/// Convert to bytes
Expand Down Expand Up @@ -199,6 +226,46 @@ impl NewProtocolKeyRegistration {
}
}

impl ProtocolSigner {
/// This function produces an STM signature
pub fn sign(&self, msg: &[u8]) -> Option<StmSig<D>> {
self.0.sign(msg)
}

/// This function should be called when a signing epoch is finished (or when a new one starts).
/// It consumes `self` and turns it back to an `StmInitializer`, which allows for an update in
/// the dynamic parameters (such as stake distribution, participants or KES signature). To ensure
/// that the `StmInitializer` will not be used for the previous registration, this function also
/// consumes the `ClosedKeyReg` instance. In case the stake of the current party has changed, it
/// includes it as input.
pub fn new_epoch(
self,
new_kes_key: &[u8],
new_kes_period: usize,
new_stake: Option<Stake>,
) -> ProtocolInitializer {
let stm_initializer = self.0.new_epoch(new_stake);

let kes_sk: Sum6Kes =
serde_cbor::from_slice(new_kes_key).expect("Invalid KES key provided"); // todo: handle this
let kes_signature = kes_sk.sign(
new_kes_period,
&stm_initializer.verification_key().to_bytes(),
);

ProtocolInitializer {
stm_initializer,
kes_signature: Some(kes_signature),
}
}

/// Compute the `StmAggrVerificationKey` related to the used registration, which consists of
/// the merkle tree root and the total stake.
pub fn compute_avk(&self) -> ProtocolAggregateVerificationKey {
ProtocolAggregateVerificationKey::from(&self.0.get_closed_reg())
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down
5 changes: 5 additions & 0 deletions mithril-core/src/stm.rs
Expand Up @@ -549,6 +549,11 @@ impl<D: Clone + Digest> StmSigner<D> {
pub fn compute_avk(&self) -> StmAggrVerificationKey<D> {
StmAggrVerificationKey::from(&self.closed_reg)
}

/// Return the closed registration instance
pub fn get_closed_reg(&self) -> ClosedKeyReg<D> {
self.closed_reg.clone()
}
}

impl<D: Digest + Clone> StmClerk<D> {
Expand Down
5 changes: 4 additions & 1 deletion mithril-signer/src/protocol_initializer_store.rs
Expand Up @@ -164,7 +164,10 @@ mod tests {
.unwrap();

assert!(res.is_some());
assert_eq!(protocol_initializers[0].1.get_stake(), res.unwrap().get_stake());
assert_eq!(
protocol_initializers[0].1.get_stake(),
res.unwrap().get_stake()
);
}

#[tokio::test]
Expand Down

0 comments on commit 6bb80a5

Please sign in to comment.