note in the broadcast example about the use of keys

This commit is contained in:
Vladimir Komendantskiy 2018-06-13 18:24:35 +01:00
parent 87485c2eb1
commit b82ac64148
6 changed files with 55 additions and 129 deletions

View File

@ -10,16 +10,17 @@ extern crate hbbft;
extern crate log;
extern crate pairing;
extern crate protobuf;
extern crate rand;
mod network;
use docopt::Docopt;
use network::node::Node;
use std::collections::HashSet;
use std::net::SocketAddr;
use std::vec::Vec;
use docopt::Docopt;
use network::node::Node;
const VERSION: &str = "0.1.0";
const USAGE: &str = "
Consensus node example
@ -62,6 +63,11 @@ pub fn main() {
env_logger::init();
let args: Args = parse_args();
println!("{:?}", args);
let node = Node::new(args.bind_address, args.remote_addresses, args.value);
let node = Node::new(
args.bind_address,
args.remote_addresses,
args.value,
);
node.run().expect("Node failed");
}

View File

@ -35,17 +35,15 @@
//! consensus node will be the same `result`.
use crossbeam;
use std::collections::HashSet;
use std::collections::{BTreeSet, HashSet};
use std::fmt::Debug;
use std::marker::{Send, Sync};
use std::net::SocketAddr;
use std::rc::Rc;
use std::{io, iter, process, thread, time};
use pairing::bls12_381::Bls12;
use rand;
use hbbft::broadcast::{Broadcast, BroadcastMessage};
use hbbft::crypto::keygen::Poly;
use hbbft::crypto::SecretKeySet;
use hbbft::messaging::{DistAlgorithm, NetworkInfo, SourcedMessage};
use hbbft::proto::message::BroadcastProto;
@ -101,17 +99,25 @@ impl<T: Clone + Debug + AsRef<[u8]> + PartialEq + Send + Sync + From<Vec<u8>> +
.chain(connections.iter().map(|c| c.node_str.clone()))
.collect();
node_strs.sort();
debug!("Nodes: {:?}", node_strs);
let proposer_id = 0;
let our_id = node_strs.binary_search(&our_str).unwrap();
let num_nodes = connections.len() + 1;
let all_ids: BTreeSet<_> = (0..node_strs.len()).collect();
if value.is_some() != (our_id == proposer_id) {
// FIXME: This example doesn't call algorithms that use cryptography. However the keys are
// required by the interface to all algorithms in Honey Badger. Therefore we set placeholder
// keys here. A fully-featured application would need to take appropriately initialized keys
// from elsewhere.
let secret_key_set = SecretKeySet::from(Poly::zero());
let secret_key = secret_key_set.secret_key_share(our_id as u64);
let public_key_set = secret_key_set.public_keys();
let netinfo = NetworkInfo::new(our_id, all_ids.clone(), secret_key, public_key_set);
if value.is_some() != (our_id == 0) {
panic!("Exactly the first node must propose a value.");
}
// Initialise the message delivery system and obtain TX and RX handles.
let messaging: Messaging<BroadcastMessage> = Messaging::new(num_nodes);
let messaging: Messaging<BroadcastMessage> = Messaging::new(all_ids.len());
let rxs_to_comms = messaging.rxs_to_comms();
let tx_from_comms = messaging.tx_from_comms();
let rx_to_algo = messaging.rx_to_algo();
@ -128,18 +134,8 @@ impl<T: Clone + Debug + AsRef<[u8]> + PartialEq + Send + Sync + From<Vec<u8>> +
// corresponding to this instance, and no dedicated comms task. The
// node index is 0.
let broadcast_handle = scope.spawn(move || {
let all_ids = (0..num_nodes).collect();
let sk_set =
SecretKeySet::<Bls12>::new((num_nodes - 1) / 3, &mut rand::thread_rng());
let pk_set = sk_set.public_keys();
let netinfo = Rc::new(NetworkInfo::new(
our_id,
all_ids,
sk_set.secret_key_share(our_id as u64),
pk_set.clone(),
));
let mut broadcast =
Broadcast::new(netinfo, proposer_id).expect("failed to instantiate broadcast");
Broadcast::new(Rc::new(netinfo), 0).expect("failed to instantiate broadcast");
if let Some(v) = value {
broadcast.input(v.clone().into()).expect("propose value");
@ -210,13 +206,6 @@ impl<T: Clone + Debug + AsRef<[u8]> + PartialEq + Send + Sync + From<Vec<u8>> +
.unwrap();
process::exit(0);
// TODO: Exit cleanly.
// match msg_handle.join() {
// Ok(()) => debug!("Messaging stopped OK"),
// Err(e) => debug!("Messaging error: {:?}", e),
// }
// Err(Error::NotImplemented)
}) // end of thread scope
}
}

View File

@ -1,5 +1,7 @@
pub mod error;
pub mod keygen;
#[cfg(feature = "serialization-protobuf")]
pub mod protobuf_impl;
#[cfg(feature = "serialization-serde")]
mod serde_impl;
@ -237,6 +239,12 @@ pub struct SecretKeySet<E: Engine> {
poly: Poly<E>,
}
impl<E: Engine> From<Poly<E>> for SecretKeySet<E> {
fn from(poly: Poly<E>) -> SecretKeySet<E> {
SecretKeySet { poly }
}
}
impl<E: Engine> SecretKeySet<E> {
/// Creates a set of secret key shares, where any `threshold + 1` of them can collaboratively
/// sign and decrypt.
@ -535,99 +543,3 @@ mod tests {
assert_eq!(sig, deser_sig);
}
}
#[cfg(feature = "serialization-serde")]
mod serde {
use pairing::{CurveAffine, CurveProjective, EncodedPoint, Engine};
use super::{DecryptionShare, PublicKey, Signature};
use serde::de::Error as DeserializeError;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
const ERR_LEN: &str = "wrong length of deserialized group element";
const ERR_CODE: &str = "deserialized bytes don't encode a group element";
impl<E: Engine> Serialize for PublicKey<E> {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
serialize_projective(&self.0, s)
}
}
impl<'de, E: Engine> Deserialize<'de> for PublicKey<E> {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
Ok(PublicKey(deserialize_projective(d)?))
}
}
impl<E: Engine> Serialize for Signature<E> {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
serialize_projective(&self.0, s)
}
}
impl<'de, E: Engine> Deserialize<'de> for Signature<E> {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
Ok(Signature(deserialize_projective(d)?))
}
}
impl<E: Engine> Serialize for DecryptionShare<E> {
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
serialize_projective(&self.0, s)
}
}
impl<'de, E: Engine> Deserialize<'de> for DecryptionShare<E> {
fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
Ok(DecryptionShare(deserialize_projective(d)?))
}
}
/// Serializes the compressed representation of a group element.
fn serialize_projective<S, C>(c: &C, s: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
C: CurveProjective,
{
c.into_affine().into_compressed().as_ref().serialize(s)
}
/// Deserializes the compressed representation of a group element.
fn deserialize_projective<'de, D, C>(d: D) -> Result<C, D::Error>
where
D: Deserializer<'de>,
C: CurveProjective,
{
let bytes = <Vec<u8>>::deserialize(d)?;
if bytes.len() != <C::Affine as CurveAffine>::Compressed::size() {
return Err(D::Error::custom(ERR_LEN));
}
let mut compressed = <C::Affine as CurveAffine>::Compressed::empty();
compressed.as_mut().copy_from_slice(&bytes);
let to_err = |_| D::Error::custom(ERR_CODE);
Ok(compressed.into_affine().map_err(to_err)?.into_projective())
}
}
#[cfg(feature = "serialization-protobuf")]
pub mod proto {
use super::Signature;
use pairing::{CurveAffine, CurveProjective, EncodedPoint, Engine};
impl<E: Engine> Signature<E> {
pub fn to_vec(&self) -> Vec<u8> {
let comp = self.0.into_affine().into_compressed();
comp.as_ref().to_vec()
}
pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
let mut comp = <E::G2Affine as CurveAffine>::Compressed::empty();
comp.as_mut().copy_from_slice(bytes);
if let Ok(affine) = comp.into_affine() {
Some(Signature(affine.into_projective()))
} else {
None
}
}
}
}

View File

@ -0,0 +1,19 @@
use super::Signature;
use pairing::{CurveAffine, CurveProjective, EncodedPoint, Engine};
impl<E: Engine> Signature<E> {
pub fn to_vec(&self) -> Vec<u8> {
let comp = self.0.into_affine().into_compressed();
comp.as_ref().to_vec()
}
pub fn from_bytes(bytes: &[u8]) -> Option<Self> {
let mut comp = <E::G2Affine as CurveAffine>::Compressed::empty();
comp.as_mut().copy_from_slice(bytes);
if let Ok(affine) = comp.into_affine() {
Some(Signature(affine.into_projective()))
} else {
None
}
}
}

View File

@ -72,7 +72,7 @@ impl Adversary<Broadcast<NodeUid>> for ProposeAdversary {
// FIXME: Take the correct, known keys from the network.
let mut rng = rand::thread_rng();
let sk_set = SecretKeySet::<Bls12>::new(self.adv_nodes.len(), &mut rng);
let sk_set = SecretKeySet::<Bls12>::random(self.adv_nodes.len(), &mut rng);
let pk_set = sk_set.public_keys();
let netinfo = Rc::new(NetworkInfo::new(

View File

@ -160,7 +160,7 @@ where
F: Fn(Rc<NetworkInfo<NodeUid>>) -> D,
{
let mut rng = rand::thread_rng();
let sk_set = SecretKeySet::<Bls12>::new(adv_num, &mut rng);
let sk_set = SecretKeySet::<Bls12>::random(adv_num, &mut rng);
let pk_set = sk_set.public_keys();
let node_ids: BTreeSet<NodeUid> = (0..(good_num + adv_num)).map(NodeUid).collect();