use std::time::Duration;
use derivation_path::DerivationPath;
use signature::{SignatureEncoding, Signer, Verifier};
use crate::message::{InstanceId, MessageTag, MsgId};
pub struct AllOtherParties {
total: usize,
me: usize,
curr: usize,
}
impl Iterator for AllOtherParties {
type Item = usize;
fn next(&mut self) -> Option<Self::Item> {
loop {
let val = self.curr;
if val >= self.total {
return None;
}
self.curr += 1;
if val != self.me {
return Some(val);
}
}
}
}
impl ExactSizeIterator for AllOtherParties {
fn len(&self) -> usize {
self.total - 1
}
}
pub trait ProtocolParticipant {
type MessageSignature: SignatureEncoding;
type MessageSigner: Signer<Self::MessageSignature>;
type MessageVerifier: Verifier<Self::MessageSignature> + AsRef<[u8]>;
fn total_participants(&self) -> usize;
fn verifier(&self, index: usize) -> &Self::MessageVerifier;
fn signer(&self) -> &Self::MessageSigner;
fn participant_index(&self) -> usize;
fn instance_id(&self) -> &InstanceId;
fn message_ttl(&self) -> Duration;
fn participant_verifier(&self) -> &Self::MessageVerifier {
self.verifier(self.participant_index())
}
fn all_other_parties(&self) -> AllOtherParties {
AllOtherParties {
curr: 0,
total: self.total_participants(),
me: self.participant_index(),
}
}
fn msg_id(&self, receiver: Option<usize>, tag: MessageTag) -> MsgId {
self.msg_id_from(self.participant_index(), receiver, tag)
}
fn msg_id_from(
&self,
sender: usize,
receiver: Option<usize>,
tag: MessageTag,
) -> MsgId {
let receiver = receiver
.map(|p| self.verifier(p))
.map(AsRef::<[u8]>::as_ref);
MsgId::new(
self.instance_id(),
self.verifier(sender).as_ref(),
receiver.as_ref().map(AsRef::as_ref),
tag,
)
}
fn setup_hash(&self) -> &[u8] {
&[]
}
}
impl<M: ProtocolParticipant> ProtocolParticipant for &M {
type MessageSignature = M::MessageSignature;
type MessageSigner = M::MessageSigner;
type MessageVerifier = M::MessageVerifier;
fn total_participants(&self) -> usize {
(**self).total_participants()
}
fn verifier(&self, index: usize) -> &Self::MessageVerifier {
(**self).verifier(index)
}
fn signer(&self) -> &Self::MessageSigner {
(**self).signer()
}
fn participant_index(&self) -> usize {
(**self).participant_index()
}
fn participant_verifier(&self) -> &Self::MessageVerifier {
(**self).participant_verifier()
}
fn instance_id(&self) -> &InstanceId {
(**self).instance_id()
}
fn message_ttl(&self) -> Duration {
(**self).message_ttl()
}
fn setup_hash(&self) -> &[u8] {
(**self).setup_hash()
}
}
pub trait KeygenSetupMessage: ProtocolParticipant {
fn threshold(&self) -> u8;
fn participant_rank(&self, _party_index: usize) -> u8 {
0
}
fn derive_key_id(&self, public_key: &[u8]) -> [u8; 32];
fn keyshare_extra(&self) -> &[u8] {
&[]
}
}
impl<M: KeygenSetupMessage> KeygenSetupMessage for &M {
fn threshold(&self) -> u8 {
(**self).threshold()
}
fn participant_rank(&self, party_index: usize) -> u8 {
(**self).participant_rank(party_index)
}
fn derive_key_id(&self, public_key: &[u8]) -> [u8; 32] {
(**self).derive_key_id(public_key)
}
fn keyshare_extra(&self) -> &[u8] {
(**self).keyshare_extra()
}
}
pub trait PreSignSetupMessage<KS>: ProtocolParticipant {
fn keyshare(&self) -> &KS;
fn chain_path(&self) -> &DerivationPath;
fn presignature_extra(&self) -> &[u8] {
&[]
}
fn banned_parties(&self) -> &[u8] {
&[]
}
}
pub trait FinalSignSetupMessage<PS>: ProtocolParticipant {
fn pre_signature(&self) -> &PS;
fn message_hash(&self) -> [u8; 32];
}
pub trait SignSetupMessage<KS>: PreSignSetupMessage<KS> {
fn message_hash(&self) -> [u8; 32];
}
pub trait KeyExporterSetupMessage<PK, KS>: ProtocolParticipant {
fn receiver_public_key(&self) -> &PK;
fn keyshare(&self) -> &KS;
}
pub trait KeyExportReceiverSetupMessage<KS, SK>: ProtocolParticipant {
fn receiver_private_key(&self) -> &SK;
fn keyshare(&self) -> &KS;
}
pub trait QuorumChangeSetupMessage<KS, PK>: ProtocolParticipant {
fn old_keyshare(&self) -> Option<&KS>;
fn new_threshold(&self) -> u8;
fn new_participant_rank(&self, _party_id: u8) -> u8 {
0
}
fn expected_public_key(&self) -> &PK;
fn new_party_id(&self, index: usize) -> Option<u8> {
self.new_party_indices()
.iter()
.position(|p| p == &index)
.map(|p| p as u8)
}
fn old_party_indices(&self) -> &[usize];
fn new_party_indices(&self) -> &[usize];
fn keyshare_extra(&self) -> &[u8] {
&[]
}
fn derive_key_id(&self, public_key: &[u8]) -> [u8; 32];
}
impl<KS, PK, M: QuorumChangeSetupMessage<KS, PK>>
QuorumChangeSetupMessage<KS, PK> for &M
{
fn old_keyshare(&self) -> Option<&KS> {
(**self).old_keyshare()
}
fn new_threshold(&self) -> u8 {
(**self).new_threshold()
}
fn expected_public_key(&self) -> &PK {
(**self).expected_public_key()
}
fn old_party_indices(&self) -> &[usize] {
(**self).old_party_indices()
}
fn new_party_indices(&self) -> &[usize] {
(**self).new_party_indices()
}
fn derive_key_id(&self, public_key: &[u8]) -> [u8; 32] {
(**self).derive_key_id(public_key)
}
}
pub trait WeightedKeygenSetupMessage: ProtocolParticipant {
fn participant_weight(&self, _party_index: usize) -> u16 {
1
}
fn weighted_threshold(&self) -> u16;
fn derive_key_id(&self, public_key: &[u8]) -> [u8; 32];
fn keyshare_extra(&self) -> &[u8] {
&[]
}
}
pub trait WeightedQuorumChangeSetupMessage<KS, PK>:
QuorumChangeSetupMessage<KS, PK>
{
fn new_participant_weight(&self, party_id: usize) -> u16;
}