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

Run the aux gen protocol when resharing to a new signing committee #977

Merged
merged 12 commits into from
Aug 7, 2024
8 changes: 4 additions & 4 deletions crates/protocol/src/execute_protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ use crate::{
errors::{GenericProtocolError, ProtocolExecutionErr},
protocol_message::{ProtocolMessage, ProtocolMessagePayload},
protocol_transport::Broadcaster,
DkgSubsession, KeyParams, KeyShareWithAuxInfo, PartyId, SessionId,
KeyParams, KeyShareWithAuxInfo, PartyId, SessionId, Subsession,
};

use std::collections::BTreeSet;
Expand Down Expand Up @@ -217,7 +217,7 @@ pub async fn execute_dkg(

let my_party_id = PartyId::new(AccountId32(threshold_pair.public().0));

let session_id_hash = session_id.blake2(Some(DkgSubsession::KeyInit))?;
let session_id_hash = session_id.blake2(Some(Subsession::KeyInit))?;
let (key_init_parties, includes_me) =
get_key_init_parties(&my_party_id, threshold, &party_ids, &session_id_hash)?;

Expand Down Expand Up @@ -293,7 +293,7 @@ pub async fn execute_dkg(
new_threshold: threshold,
};

let session_id_hash = session_id.blake2(Some(DkgSubsession::Reshare))?;
let session_id_hash = session_id.blake2(Some(Subsession::Reshare))?;
let session = make_key_resharing_session(
&mut OsRng,
SynedrionSessionId::from_seed(session_id_hash.as_slice()),
Expand All @@ -312,7 +312,7 @@ pub async fn execute_dkg(
let chans = Channels(broadcaster.clone(), rx);

// Now run the aux gen protocol to get AuxInfo
let session_id_hash = session_id.blake2(Some(DkgSubsession::AuxGen))?;
let session_id_hash = session_id.blake2(Some(Subsession::AuxGen))?;
let session = make_aux_gen_session(
&mut OsRng,
SynedrionSessionId::from_seed(session_id_hash.as_slice()),
Expand Down
6 changes: 3 additions & 3 deletions crates/protocol/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ impl SessionId {
/// Optionally with some extra data used to identify a sub-session
pub fn blake2(
&self,
sub_session: Option<DkgSubsession>,
sub_session: Option<Subsession>,
) -> Result<[u8; 32], ProtocolExecutionErr> {
let mut hasher = Blake2s256::new();
hasher.update(bincode::serialize(self)?);
Expand All @@ -214,9 +214,9 @@ impl SessionId {
}
}

/// A sub-protocol of the DKG protocol
/// A sub-protocol of the DKG or reshare protocols
#[derive(Debug)]
pub enum DkgSubsession {
pub enum Subsession {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I renamed this enum because it is no longer only used for DKG

/// The synedrion key init protocol
KeyInit,
/// The synedrion reshare protocol
Expand Down
2 changes: 1 addition & 1 deletion crates/testing-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ tokio ={ version="1.39", features=["macros", "fs", "rt-multi-thread"
axum ={ version="0.7.5" }
entropy-shared ={ version="0.2.0", path="../shared" }
entropy-kvdb ={ version="0.2.0", path="../kvdb", default-features=false }
entropy-tss ={ version="0.2.0", path="../threshold-signature-server" }
entropy-tss ={ version="0.2.0", path="../threshold-signature-server", features=["test_helpers"] }
entropy-protocol ={ version="0.2.0", path="../protocol" }
synedrion ={ git="https://github.com/entropyxyz/synedrion", rev="3be1339c21384a8e60a1534f1d3bfdd022662e63" }
hex ="0.4.3"
Expand Down
16 changes: 14 additions & 2 deletions crates/threshold-signature-server/src/signing_client/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use axum::{
use blake2::{Blake2s256, Digest};
use entropy_protocol::{
execute_protocol::{execute_proactive_refresh, Channels},
KeyParams, Listener, PartyId, SessionId, ValidatorInfo,
KeyParams, KeyShareWithAuxInfo, Listener, PartyId, SessionId, ValidatorInfo,
};
use parity_scale_codec::Encode;

Expand Down Expand Up @@ -112,7 +112,19 @@ pub async fn proactive_refresh(
ocw_data.block_number,
)
.await?;
let serialized_key_share = key_serialize(&new_key_share)

// Get aux info from existing entry
let aux_info = {
let existing_entry = app_state.kv_store.kv().get(&key).await?;
let (_old_key_share, aux_info): KeyShareWithAuxInfo = deserialize(&existing_entry)
HCastano marked this conversation as resolved.
Show resolved Hide resolved
.ok_or_else(|| {
ProtocolErr::Deserialization("Failed to load KeyShare".into())
})?;
aux_info
};

// Since this is a refresh with the parties not changing, store the old aux_info
let serialized_key_share = key_serialize(&(new_key_share, aux_info))
.map_err(|_| ProtocolErr::KvSerialize("Kv Serialize Error".to_string()))?;

app_state.kv_store.kv().delete(&key).await?;
Expand Down
43 changes: 32 additions & 11 deletions crates/threshold-signature-server/src/validator/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use crate::{
};
use axum::{body::Bytes, extract::State, http::StatusCode};
use entropy_kvdb::kv_manager::{helpers::serialize as key_serialize, KvManager};
use entropy_protocol::Subsession;
pub use entropy_protocol::{
decode_verifying_key,
errors::ProtocolExecutionErr,
Expand All @@ -45,8 +46,8 @@ use subxt::{
OnlineClient,
};
use synedrion::{
make_key_resharing_session, sessions::SessionId as SynedrionSessionId, KeyResharingInputs,
NewHolder, OldHolder,
make_aux_gen_session, make_key_resharing_session, sessions::SessionId as SynedrionSessionId,
AuxInfo, KeyResharingInputs, NewHolder, OldHolder,
};
use tokio::time::timeout;

Expand Down Expand Up @@ -150,7 +151,7 @@ pub async fn new_reshare(

let session_id = SessionId::Reshare { verifying_key, block_number: data.block_number };
let account_id = AccountId32(signer.signer().public().0);
let session_id_hash = session_id.blake2(None)?;
let session_id_hash = session_id.blake2(Some(Subsession::Reshare))?;
let pair = PairWrapper(signer.signer().clone());

let mut converted_validator_info = vec![];
Expand Down Expand Up @@ -183,27 +184,47 @@ pub async fn new_reshare(
)
.await?;

let channels = {
let (channels, broadcaster) = {
let ready = timeout(Duration::from_secs(SETUP_TIMEOUT_SECONDS), rx_ready).await?;
let broadcast_out = ready??;
Channels(broadcast_out, rx_from_others)
(Channels(broadcast_out.clone(), rx_from_others), broadcast_out)
};

let session = make_key_resharing_session(
&mut OsRng,
SynedrionSessionId::from_seed(session_id_hash.as_slice()),
pair,
pair.clone(),
&party_ids,
inputs,
)
.map_err(ProtocolExecutionErr::SessionCreation)?;

let new_key_share = execute_protocol_generic(channels, session, session_id_hash)
let (new_key_share_option, rx) = execute_protocol_generic(channels, session, session_id_hash)
.await
.map_err(|_| ValidatorErr::ProtocolError("Error executing protocol".to_string()))?
.0
.ok_or(ValidatorErr::NoOutputFromReshareProtocol)?;
let serialized_key_share = key_serialize(&new_key_share)
.map_err(|_| ValidatorErr::ProtocolError("Error executing protocol".to_string()))?;

let new_key_share = new_key_share_option.ok_or(ValidatorErr::NoOutputFromReshareProtocol)?;

// Setup channels for the next session
let channels = Channels(broadcaster, rx);

// Now run an aux gen session
let session_id_hash = session_id.blake2(Some(Subsession::AuxGen))?;
let session = make_aux_gen_session(
&mut OsRng,
SynedrionSessionId::from_seed(session_id_hash.as_slice()),
pair,
&party_ids,
)
.map_err(ProtocolExecutionErr::SessionCreation)?;

let aux_info: AuxInfo<KeyParams, PartyId> =
execute_protocol_generic(channels, session, session_id_hash)
.await
.map_err(|_| ValidatorErr::ProtocolError("Error executing protocol".to_string()))?
.0;

let serialized_key_share = key_serialize(&(new_key_share, aux_info))
.map_err(|_| ProtocolErr::KvSerialize("Kv Serialize Error".to_string()))?;
let network_parent_key = hex::encode(NETWORK_PARENT_KEY);
// TODO: should this be a two step process? see # https://github.com/entropyxyz/entropy-core/issues/968
Expand Down
24 changes: 19 additions & 5 deletions crates/threshold-signature-server/src/validator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@ use crate::{
},
validator::{api::validate_new_reshare, errors::ValidatorErr},
};
use entropy_kvdb::clean_tests;
use entropy_kvdb::{
clean_tests,
kv_manager::helpers::{deserialize, serialize},
};
use entropy_protocol::KeyShareWithAuxInfo;
use entropy_shared::{
OcwMessageReshare, EVE_VERIFYING_KEY, MIN_BALANCE, NETWORK_PARENT_KEY,
TEST_RESHARE_BLOCK_NUMBER,
Expand Down Expand Up @@ -92,12 +96,22 @@ async fn test_reshare() {
for response_result in response_results {
assert_eq!(response_result.unwrap().text().await.unwrap(), "");
}

for i in 0..validator_ports.len() {
assert_ne!(
key_shares_before[i],
unsafe_get(&client, hex::encode(NETWORK_PARENT_KEY), validator_ports[i]).await
);
let (key_share_before, aux_info_before): KeyShareWithAuxInfo =
deserialize(&key_shares_before[i]).unwrap();

let key_share_and_aux_data_after =
unsafe_get(&client, hex::encode(NETWORK_PARENT_KEY), validator_ports[i]).await;
let (key_share_after, aux_info_after): KeyShareWithAuxInfo =
deserialize(&key_share_and_aux_data_after).unwrap();

// Check key share has changed
assert_ne!(serialize(&key_share_before).unwrap(), serialize(&key_share_after).unwrap());
// Check aux info has changed
assert_ne!(serialize(&aux_info_before).unwrap(), serialize(&aux_info_after).unwrap());
}
// TODO #981 - test signing a message with the new keyshare set
clean_tests();
}

Expand Down
Loading