Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement node bls #16

Open
wants to merge 11 commits into
base: development
Choose a base branch
from
10 changes: 8 additions & 2 deletions crates/dkg-cli/src/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use crate::{
opts::*,
};
use rand::RngCore;
use std::{fs::File, io::Write, sync::Arc};
use std::{
fs::File,
io::{self, Write},
sync::Arc,
};

use dkg_core::{
primitives::{joint_feldman::*, *},
Expand Down Expand Up @@ -182,7 +186,7 @@ where

// Instantiate the DKG with the group info
println!("Calculating and broadcasting our shares...");
let phase0 = DKG::new(private_key, group)?;
let phase0 = DKG::new(private_key, String::from(""), group)?;

// Run Phase 1 and publish to the chain
let phase1 = phase0.run(&mut dkg, rand::thread_rng).await?;
Expand Down Expand Up @@ -256,6 +260,8 @@ async fn wait_for_phase<M: ethers::providers::Middleware>(
break;
}
print!(".");
io::stdout().flush().unwrap();

// 6s for 1 Celo block
tokio::time::delay_for(std::time::Duration::from_millis(6000)).await;
}
Expand Down
4 changes: 3 additions & 1 deletion crates/dkg-core/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,9 @@ mod tests {
// Create the Phase 0 for each participant
let phase0s = keypairs
.iter()
.map(|(private, _)| joint_feldman::DKG::new(private.clone(), group.clone()).unwrap())
.map(|(private, _)| {
joint_feldman::DKG::new(private.clone(), String::from(""), group.clone()).unwrap()
})
.collect::<Vec<_>>();

// Create the board
Expand Down
40 changes: 30 additions & 10 deletions crates/dkg-core/src/primitives/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use threshold_bls::{
poly::{Idx, PrivatePoly, PublicPoly},
};

pub type ShareInfo<C> = HashMap<Idx, <C as Curve>::Scalar>;
pub type ShareInfo<C> = HashMap<Idx, (<C as Curve>::Scalar, String)>;
pub type PublicInfo<C> = HashMap<Idx, PublicPoly<C>>;

pub fn decrypt_and_check_share<C: Curve>(
Expand All @@ -22,7 +22,7 @@ pub fn decrypt_and_check_share<C: Curve>(
dealer_idx: Idx,
public: &PublicPoly<C>,
share: &EncryptedShare<C>,
) -> Result<C::Scalar, DKGError> {
) -> Result<(C::Scalar, String), DKGError> {
let buff = ecies::decrypt::<C>(private_key, &share.secret).map_err(|err| {
println!("ERROR {:?}", err);
ShareError::InvalidCiphertext(dealer_idx, err)
Expand All @@ -35,7 +35,15 @@ pub fn decrypt_and_check_share<C: Curve>(
return Err(ShareError::InvalidShare(dealer_idx).into());
}

Ok(clear_share)
let rpc_endpoint_buff =
ecies::decrypt::<C>(private_key, &share.rpc_endpoint_secret).map_err(|err| {
println!("ERROR {:?}", err);
ShareError::InvalidCiphertext(dealer_idx, err)
})?;

let clear_rpc_endpoint = bincode::deserialize(&rpc_endpoint_buff)?;

Ok((clear_share, clear_rpc_endpoint))
}

/// set_statuses set the status of the given responses on the status matrix.
Expand Down Expand Up @@ -81,6 +89,7 @@ pub fn create_share_bundle<C: Curve, R: RngCore>(
dealer_idx: Idx,
secret: &PrivatePoly<C>,
public: &PublicPoly<C>,
node_rpc_endpoint: &str,
group: &Group<C>,
mut rng: R,
) -> DKGResult<BundledShares<C>> {
Expand All @@ -98,10 +107,15 @@ pub fn create_share_bundle<C: Curve, R: RngCore>(
// encrypt it
let cipher = ecies::encrypt::<C, _>(n.key(), &buff, &mut rng);

let rpc_endpoint_buff = bincode::serialize(node_rpc_endpoint)?;

let rpc_endpoint_secret = ecies::encrypt::<C, _>(n.key(), &rpc_endpoint_buff, &mut rng);

// save the share
Ok(EncryptedShare {
share_idx: n.id(),
secret: cipher,
rpc_endpoint_secret,
})
})
.collect::<Result<Vec<_>, DKGError>>()?;
Expand Down Expand Up @@ -211,12 +225,15 @@ pub fn process_shares_get_all<C: Curve>(
.map(|share| (bundle.dealer_idx, share))
.ok()
})
.fold(ShareInfo::<C>::new(), |mut acc, (didx, share)| {
// println!(" -- got new share from {}", didx);
statuses.set(didx, my_idx, Status::Success);
acc.insert(didx, share);
acc
});
.fold(
ShareInfo::<C>::new(),
|mut acc, (didx, (share, rpc_endpoint))| {
// println!(" -- got new share from {}", didx);
statuses.set(didx, my_idx, Status::Success);
acc.insert(didx, (share, rpc_endpoint));
acc
},
);

Ok((valid_shares, publics, statuses))
}
Expand Down Expand Up @@ -286,7 +303,10 @@ pub fn internal_process_justifications<C: Curve>(
// justification is valid, we mark it off from our matrix
statuses.set(bundle.dealer_idx, justification.share_idx, Status::Success);
if holder_idx == justification.share_idx {
valid_shares.insert(bundle.dealer_idx, justification.share.clone());
valid_shares.insert(
bundle.dealer_idx,
(justification.share.clone(), "".to_string()),
);
}
})
});
Expand Down
12 changes: 10 additions & 2 deletions crates/dkg-core/src/primitives/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ use threshold_bls::{group::Curve, poly::Idx};
/// of the protocol, if sucessful, the index is used to verify the validity of
/// the share this node holds.
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub struct Node<C: Curve>(Idx, C::Point);
pub struct Node<C: Curve>(Idx, C::Point, Option<String>);

impl<C: Curve> Node<C> {
pub fn new(index: Idx, public: C::Point) -> Self {
Self(index, public)
Self(index, public, None)
}
}

Expand All @@ -25,6 +25,14 @@ impl<C: Curve> Node<C> {
pub fn key(&self) -> &C::Point {
&self.1
}

pub fn set_rpc_endpoint(&mut self, rpc_endpoint: String) {
self.2 = Some(rpc_endpoint);
}

pub fn get_rpc_endpoint(&self) -> Option<&String> {
self.2.as_ref()
}
}

/// A Group is a collection of Nodes with an associated threshold. A DKG scheme
Expand Down
37 changes: 28 additions & 9 deletions crates/dkg-core/src/primitives/joint_feldman.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ pub struct DKGInfo<C: Curve> {
group: Group<C>,
secret: Poly<C::Scalar>,
public: Poly<C::Point>,
rpc_endpoint: String,
}

impl<C: Curve> DKGInfo<C> {
Expand Down Expand Up @@ -62,16 +63,21 @@ impl<C: Curve> DKG<C> {
/// Creates a new DKG instance from the provided private key and group.
///
/// The private key must be part of the group, otherwise this will return an error.
pub fn new(private_key: C::Scalar, group: Group<C>) -> Result<DKG<C>, DKGError> {
pub fn new(
private_key: C::Scalar,
rpc_endpoint: String,
group: Group<C>,
) -> Result<DKG<C>, DKGError> {
use rand::prelude::*;
Self::new_rand(private_key, group, &mut thread_rng())
Self::new_rand(private_key, rpc_endpoint, group, &mut thread_rng())
}

/// Creates a new DKG instance from the provided private key, group and RNG.
///
/// The private key must be part of the group, otherwise this will return an error.
pub fn new_rand<R: RngCore>(
private_key: C::Scalar,
rpc_endpoint: String,
group: Group<C>,
rng: &mut R,
) -> Result<DKG<C>, DKGError> {
Expand All @@ -95,6 +101,7 @@ impl<C: Curve> DKG<C> {
group,
secret,
public,
rpc_endpoint,
};

Ok(DKG { info })
Expand All @@ -118,6 +125,7 @@ impl<C: Curve> Phase0<C> for DKG<C> {
self.info.index,
&self.info.secret,
&self.info.public,
&self.info.rpc_endpoint,
&self.info.group,
rng(),
)?;
Expand Down Expand Up @@ -151,7 +159,7 @@ impl<C: Curve> Phase1<C> for DKGWaitingShare<C> {
/// - invalid length of public polynomial
/// - invalid share w.r.t. public polynomial
fn process_shares(
self,
mut self,
bundles: &[BundledShares<C>],
mut publish_all: bool,
) -> DKGResult<(DKGWaitingResponse<C>, Option<BundledResponses>)> {
Expand Down Expand Up @@ -179,10 +187,21 @@ impl<C: Curve> Phase1<C> for DKGWaitingShare<C> {
let mut fshare = self.info.secret.eval(self.info.index).value;
// The public key polynomial is the sum of all shared polynomials
let mut fpub = self.info.public.clone();
shares.iter().for_each(|(&dealer_idx, share)| {
fpub.add(publics.get(&dealer_idx).unwrap());
fshare.add(share);
});
shares
.iter()
.for_each(|(&dealer_idx, (share, rpc_endpoint))| {
let node = self
.info
.group
.nodes
.iter_mut()
.find(|node| node.id() == dealer_idx)
.unwrap();
node.set_rpc_endpoint(rpc_endpoint.to_string());

fpub.add(publics.get(&dealer_idx).unwrap());
fshare.add(share);
});
let bundle = compute_bundle_response(my_idx, &statuses, publish_all);
let new_dkg = DKGWaitingResponse::new(self.info, fshare, fpub, statuses, publics);

Expand Down Expand Up @@ -318,7 +337,7 @@ where
justifs,
);

for (idx, share) in &valid_shares {
for (idx, (share, _)) in &valid_shares {
add_share.add(share);
// unwrap since internal_process_justi. gauarantees each share comes
// from a public polynomial we've seen in the first round.
Expand Down Expand Up @@ -387,7 +406,7 @@ pub mod tests {
let (privs, group) = setup_group::<C>(n, default_threshold(n));
privs
.into_iter()
.map(|p| DKG::new(p, group.clone()).unwrap())
.map(|p| DKG::new(p, String::from(""), group.clone()).unwrap())
.collect::<Vec<_>>()
}

Expand Down
6 changes: 4 additions & 2 deletions crates/dkg-core/src/primitives/resharing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ impl<C: Curve> Phase0<C> for RDKG<C> {
info.prev_index.unwrap(),
&secret,
&public,
"",
&info.new_group,
rng(),
)?;
Expand Down Expand Up @@ -239,7 +240,7 @@ impl<C: Curve> Phase1<C> for RDKGWaitingShare<C> {
let secret = info.secret.take().unwrap();
// we register our own share and publics into the mix
let didx = info.prev_index.unwrap();
shares.insert(didx, secret.eval(didx).value);
shares.insert(didx, (secret.eval(didx).value, "".to_string()));
publics.insert(didx, public.clone());
// we treat our own share as valid!
statuses.set(didx, my_idx, Status::Success);
Expand Down Expand Up @@ -423,7 +424,7 @@ fn compute_resharing_output<C: Curve>(
// to compute the final share, we interpolate all the valid shares received
let mut shares_eval: Vec<Eval<C::Scalar>> = shares
.into_iter()
.map(|(idx, sh)| Eval {
.map(|(idx, (sh, _))| Eval {
value: sh,
index: idx,
})
Expand Down Expand Up @@ -627,6 +628,7 @@ mod tests {
s[target_idx].dealer_idx,
&nsecret,
&npublic,
"",
&group,
&mut thread_rng(),
)
Expand Down
2 changes: 2 additions & 0 deletions crates/dkg-core/src/primitives/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ pub struct EncryptedShare<C: Curve> {
pub share_idx: Idx,
/// The ECIES encrypted share
pub secret: EciesCipher<C>,

pub rpc_endpoint_secret: EciesCipher<C>,
}

/// A `BundledResponses` is sent during the second phase of the protocol by all
Expand Down
6 changes: 5 additions & 1 deletion crates/randcast-mock-demo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ path = "src/contract/server.rs"

[[bin]]
name = "node-client"
path = "src/client.rs"
path = "src/node_client.rs"

[[bin]]
name = "user-client"
path = "src/user_client.rs"

[dependencies]
dkg-core = { path = "../dkg-core" }
Expand Down
6 changes: 5 additions & 1 deletion crates/randcast-mock-demo/build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
let protos = &["proto/controller.proto", "proto/coordinator.proto"];
let protos = &[
"proto/controller.proto",
"proto/coordinator.proto",
"proto/committer.proto",
];

for proto in protos {
println!("cargo:rerun-if-changed={}", proto);
Expand Down
20 changes: 20 additions & 0 deletions crates/randcast-mock-demo/proto/committer.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
syntax = "proto3";

import "google/protobuf/empty.proto";

package committer;

service CommitterService {
rpc CommitPartialSignature(CommitPartialSignatureRequest)
returns (CommitPartialSignatureReply);
}

message CommitPartialSignatureRequest {
string id_address = 1;
uint32 signature_index = 2;
bytes partial_signature = 3;
}

message CommitPartialSignatureReply {
bool result = 1;
}
Loading