2018-12-11 05:44:36 -08:00
|
|
|
// `threshold_sign::Message` triggers this Clippy lint, but `Box<T>` doesn't implement `Rand`.
|
|
|
|
#![allow(clippy::large_enum_variant)]
|
|
|
|
|
2018-12-27 01:34:34 -08:00
|
|
|
use rand::distributions::{Distribution, Standard};
|
|
|
|
use rand::{seq::SliceRandom, Rng};
|
2019-04-01 05:37:14 -07:00
|
|
|
use serde::{Deserialize, Serialize};
|
2018-07-31 13:27:22 -07:00
|
|
|
|
2018-12-11 05:44:36 -08:00
|
|
|
use crate::subset;
|
|
|
|
use crate::threshold_decrypt;
|
2018-07-31 13:27:22 -07:00
|
|
|
|
|
|
|
/// The content of a `HoneyBadger` message. It should be further annotated with an epoch.
|
2018-12-27 01:34:34 -08:00
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
|
|
pub enum MessageContent<N> {
|
2018-08-14 06:06:51 -07:00
|
|
|
/// A message belonging to the subset algorithm in the given epoch.
|
|
|
|
Subset(subset::Message<N>),
|
2018-11-26 06:35:24 -08:00
|
|
|
/// A decryption share of the output of `proposer_id`.
|
2018-07-31 13:27:22 -07:00
|
|
|
DecryptionShare {
|
2018-11-26 06:35:24 -08:00
|
|
|
/// The ID of the node that proposed the contribution that is being decrypted.
|
2018-08-02 14:27:55 -07:00
|
|
|
proposer_id: N,
|
2018-11-26 06:35:24 -08:00
|
|
|
/// The decryption share: _f + 1_ of these are required to decrypt the contribution.
|
2018-11-07 08:13:10 -08:00
|
|
|
share: threshold_decrypt::Message,
|
2018-07-31 13:27:22 -07:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2018-12-27 01:34:34 -08:00
|
|
|
impl<N> Distribution<MessageContent<N>> for Standard
|
|
|
|
where
|
|
|
|
Standard: Distribution<N>,
|
|
|
|
{
|
|
|
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> MessageContent<N> {
|
|
|
|
let message_type = *["subset", "dec_share"].choose(rng).unwrap();
|
|
|
|
|
|
|
|
match message_type {
|
|
|
|
"subset" => MessageContent::Subset(rng.gen::<subset::Message<N>>()),
|
|
|
|
"dec_share" => MessageContent::DecryptionShare {
|
|
|
|
proposer_id: rng.gen::<N>(),
|
|
|
|
share: rng.gen::<threshold_decrypt::Message>(),
|
|
|
|
},
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N> MessageContent<N> {
|
2018-11-26 06:35:24 -08:00
|
|
|
/// Wraps this content in a `Message` with the given epoch.
|
2018-08-02 14:27:55 -07:00
|
|
|
pub fn with_epoch(self, epoch: u64) -> Message<N> {
|
2018-10-09 07:07:56 -07:00
|
|
|
Message {
|
2018-07-31 13:27:22 -07:00
|
|
|
epoch,
|
|
|
|
content: self,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// A message sent to or received from another node's Honey Badger instance.
|
2018-12-27 01:34:34 -08:00
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
|
|
pub struct Message<N> {
|
2018-10-09 07:07:56 -07:00
|
|
|
pub(super) epoch: u64,
|
|
|
|
pub(super) content: MessageContent<N>,
|
2018-07-31 13:27:22 -07:00
|
|
|
}
|
|
|
|
|
2018-12-27 01:34:34 -08:00
|
|
|
impl<N> Distribution<Message<N>> for Standard
|
|
|
|
where
|
|
|
|
Standard: Distribution<N>,
|
|
|
|
{
|
|
|
|
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Message<N> {
|
|
|
|
Message {
|
|
|
|
epoch: rng.gen::<u64>(),
|
|
|
|
content: rng.gen::<MessageContent<N>>(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<N> Message<N> {
|
2018-11-07 08:21:24 -08:00
|
|
|
/// Returns this message's Honey Badger epoch.
|
|
|
|
pub fn epoch(&self) -> u64 {
|
2018-10-09 07:07:56 -07:00
|
|
|
self.epoch
|
2018-07-31 13:27:22 -07:00
|
|
|
}
|
|
|
|
}
|