Skip to content

Commit

Permalink
keymanager/src/churp: Hash using domain separation tag
Browse files Browse the repository at this point in the history
  • Loading branch information
peternose committed Jun 5, 2024
1 parent 43cf675 commit 7bad711
Show file tree
Hide file tree
Showing 9 changed files with 310 additions and 333 deletions.
96 changes: 55 additions & 41 deletions keymanager/src/churp/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use oasis_core_runtime::{
hash::Hash,
signature::{PublicKey, Signer},
},
namespace::Namespace,
namespace::{Namespace, NAMESPACE_SIZE},
},
consensus::{
beacon::EpochTime,
Expand All @@ -38,7 +38,7 @@ use oasis_core_runtime::{
};

use secret_sharing::{
churp::{Dealer, Handoff, HandoffKind, Shareholder, ShareholderId, VerifiableSecretShare},
churp::{encode_shareholder, Dealer, Handoff, HandoffKind, Shareholder, VerifiableSecretShare},
kdc::KeySharer,
suites::{p384, Suite},
vss::{
Expand Down Expand Up @@ -241,7 +241,8 @@ impl Churp {
where
S: Suite,
{
let x = ShareholderId(node_id.0).encode::<S>()?;
let dst = self.domain_separation_tag(status.id);
let x = encode_shareholder::<S>(&node_id.0, &dst)?;
let shareholder = self.get_shareholder::<S>(status.id, status.handoff)?;
let point = shareholder.switch_point(&x);
let point = scalar_to_bytes(&point);
Expand Down Expand Up @@ -306,7 +307,8 @@ impl Churp {
where
S: Suite + 'static,
{
let x = ShareholderId(node_id.0).encode::<S>()?;
let dst = self.domain_separation_tag(status.id);
let x = encode_shareholder::<S>(&node_id.0, &dst)?;
let handoff = self.get_handoff::<S>(status.id, status.next_handoff)?;
let shareholder = handoff.get_reduced_shareholder()?;
let point = shareholder.switch_point(&x);
Expand Down Expand Up @@ -369,7 +371,8 @@ impl Churp {
where
S: Suite,
{
let x = ShareholderId(node_id.0).encode::<S>()?;
let dst = self.domain_separation_tag(status.id);
let x = encode_shareholder::<S>(&node_id.0, &dst)?;
let kind = Self::handoff_kind(status);
let dealer = self.get_dealer::<S::Group>(status.id, status.next_handoff)?;
let share = dealer.make_share(x, kind);
Expand Down Expand Up @@ -412,8 +415,9 @@ impl Churp {
where
S: Suite,
{
let dst = self.domain_separation_tag(status.id);
let shareholder = self.get_shareholder::<S>(status.id, status.handoff)?;
let point = shareholder.make_key_share::<S>(key_id, &[])?; // TODO: Add domain separation.
let point = shareholder.make_key_share::<S>(key_id, &dst)?;
Ok((&point).into())
}

Expand Down Expand Up @@ -559,31 +563,31 @@ impl Churp {
&self,
node_id: PublicKey,
status: &Status,
handoff: &Handoff<S>,
handoff: &Handoff<S::Group>,
client: &RemoteClient,
) -> Result<bool>
where
S: Suite,
{
let id = ShareholderId(node_id.0);
let dst = self.domain_separation_tag(status.id);
let x = encode_shareholder::<S>(&node_id.0, &dst)?;

if !handoff.needs_share_reduction_switch_point(&id)? {
if !handoff.needs_share_reduction_switch_point(&x)? {
return Err(Error::InvalidShareholder.into());
}

// Fetch from the host node.
if node_id == self.node_id {
let me = id.encode::<S>()?;
let shareholder = self.get_shareholder::<S>(status.id, status.handoff)?;
let point = shareholder.switch_point(&me);
let point = shareholder.switch_point(&x);

if handoff.needs_verification_matrix()? {
// Local verification matrix is trusted.
let vm = shareholder.verifiable_share().verification_matrix().clone();
handoff.set_verification_matrix(vm)?;
}

return handoff.add_share_reduction_switch_point(id, point);
return handoff.add_share_reduction_switch_point(x, point);
}

// Fetch from the remote node.
Expand Down Expand Up @@ -612,7 +616,7 @@ impl Churp {
block_on(client.share_reduction_point(status.id, status.next_handoff, self.node_id))?;
let point = scalar_from_bytes(&point).ok_or(Error::PointDecodingFailed)?;

handoff.add_share_reduction_switch_point(id, point)
handoff.add_share_reduction_switch_point(x, point)
}

/// Tries to fetch switch data points for full share distribution from
Expand Down Expand Up @@ -663,25 +667,25 @@ impl Churp {
&self,
node_id: PublicKey,
status: &Status,
handoff: &Handoff<S>,
handoff: &Handoff<S::Group>,
client: &RemoteClient,
) -> Result<bool>
where
S: Suite,
{
let id = ShareholderId(node_id.0);
let dst = self.domain_separation_tag(status.id);
let x = encode_shareholder::<S>(&node_id.0, &dst)?;

if !handoff.needs_full_share_distribution_switch_point(&id)? {
if !handoff.needs_full_share_distribution_switch_point(&x)? {
return Err(Error::InvalidShareholder.into());
}

// Fetch from the host node.
if node_id == self.node_id {
let me = id.encode::<S>()?;
let shareholder = handoff.get_reduced_shareholder()?;
let point = shareholder.switch_point(&me);
let point = shareholder.switch_point(&x);

return handoff.add_full_share_distribution_switch_point(id, point);
return handoff.add_full_share_distribution_switch_point(x, point);
}

// Fetch from the remote node.
Expand All @@ -693,7 +697,7 @@ impl Churp {
))?;
let point = scalar_from_bytes(&point).ok_or(Error::PointDecodingFailed)?;

handoff.add_full_share_distribution_switch_point(id, point)
handoff.add_full_share_distribution_switch_point(x, point)
}

/// Tries to fetch proactive bivariate shares from the given nodes.
Expand Down Expand Up @@ -738,28 +742,28 @@ impl Churp {
&self,
node_id: PublicKey,
status: &Status,
handoff: &Handoff<S>,
handoff: &Handoff<S::Group>,
client: &RemoteClient,
) -> Result<bool>
where
S: Suite,
{
let id = ShareholderId(node_id.0);
let dst = self.domain_separation_tag(status.id);
let x = encode_shareholder::<S>(&node_id.0, &dst)?;

if !handoff.needs_bivariate_share(&id)? {
if !handoff.needs_bivariate_share(&x)? {
return Err(Error::InvalidShareholder.into());
}

// Fetch from the host node.
if node_id == self.node_id {
let x = id.encode::<S>()?;
let kind = Self::handoff_kind(status);
let dealer = self.get_dealer::<S::Group>(status.id, status.next_handoff)?;
let share = dealer.make_share(x, kind);
let vm = dealer.verification_matrix().clone();
let verifiable_share = VerifiableSecretShare::new(share, vm);

return handoff.add_bivariate_share(id, verifiable_share);
return handoff.add_bivariate_share(&x, verifiable_share);
}

// Fetch from the remote node.
Expand All @@ -784,7 +788,7 @@ impl Churp {

let verifiable_share: VerifiableSecretShare<S::Group> = share.try_into()?;

handoff.add_bivariate_share(id, verifiable_share)
handoff.add_bivariate_share(&x, verifiable_share)
}

/// Returns a signed confirmation request containing the checksum
Expand Down Expand Up @@ -945,8 +949,9 @@ impl Churp {
let share = share.ok_or(Error::ShareholderNotFound)?;

// Verify that the host hasn't changed.
let me = ShareholderId(self.node_id.0).encode::<S>()?;
if share.secret_share().coordinate_x() != &me {
let dst = self.domain_separation_tag(churp_id);
let x = encode_shareholder::<S>(&self.node_id.0, &dst)?;
if share.secret_share().coordinate_x() != &x {
return Err(Error::InvalidHost.into());
}

Expand Down Expand Up @@ -1119,28 +1124,28 @@ impl Churp {
}

/// Returns the handoff for the specified scheme and handoff epoch.
fn get_handoff<S>(&self, churp_id: u8, epoch: EpochTime) -> Result<Arc<Handoff<S>>>
fn get_handoff<S>(&self, churp_id: u8, epoch: EpochTime) -> Result<Arc<Handoff<S::Group>>>
where
S: Suite + 'static,
{
self._get_or_create_handoff(churp_id, epoch, None)
self._get_or_create_handoff::<S>(churp_id, epoch, None)
}

/// Returns the handoff for the specified scheme and the next handoff epoch.
/// If the handoff doesn't exist, a new one is created.
fn get_or_create_handoff<S>(&self, status: &Status) -> Result<Arc<Handoff<S>>>
fn get_or_create_handoff<S>(&self, status: &Status) -> Result<Arc<Handoff<S::Group>>>
where
S: Suite + 'static,
{
self._get_or_create_handoff(status.id, status.next_handoff, Some(status))
self._get_or_create_handoff::<S>(status.id, status.next_handoff, Some(status))
}

fn _get_or_create_handoff<S>(
&self,
churp_id: u8,
epoch: EpochTime,
status: Option<&Status>,
) -> Result<Arc<Handoff<S>>>
) -> Result<Arc<Handoff<S::Group>>>
where
S: Suite + 'static,
{
Expand All @@ -1157,7 +1162,7 @@ impl Churp {
let handoff = data
.object
.clone()
.downcast::<Handoff<S>>()
.downcast::<Handoff<S::Group>>()
.or(Err(Error::HandoffDowncastFailed))?;

return Ok(handoff);
Expand All @@ -1171,13 +1176,13 @@ impl Churp {

// Create a new handoff.
let threshold = status.threshold;
let me = ShareholderId(self.node_id.0);
let shareholders = status
.applications
.keys()
.cloned()
.map(|id| ShareholderId(id.0))
.collect();
let dst = self.domain_separation_tag(status.id);
let me = encode_shareholder::<S>(&self.node_id.0, &dst)?;
let mut shareholders = Vec::with_capacity(status.applications.len());
for id in status.applications.keys() {
let x = encode_shareholder::<S>(&id.0, &dst)?;
shareholders.push(x);
}
let kind = Self::handoff_kind(status);
let handoff = Handoff::new(threshold, me, shareholders, kind)?;

Expand Down Expand Up @@ -1397,6 +1402,15 @@ impl Churp {
HandoffKind::CommitteeChanged
}

/// Returns domain separation tag for encoding shareholder IDs.
fn domain_separation_tag(&self, churp_id: u8) -> [u8; NAMESPACE_SIZE + 1] {
let mut dst = [0; NAMESPACE_SIZE + 1];
dst[..NAMESPACE_SIZE].copy_from_slice(&self.runtime_id.0);
dst[NAMESPACE_SIZE] = churp_id;
dst
}

/// Returns consensus state.
fn consensus_state(&self) -> Result<ConsensusState> {
let consensus_state = block_on(self.consensus_verifier.latest_state())?;
Ok(consensus_state)
Expand Down
Loading

0 comments on commit 7bad711

Please sign in to comment.