Skip to content

Commit

Permalink
secret-sharing/src/churp: Implement key derivation center
Browse files Browse the repository at this point in the history
  • Loading branch information
peternose committed May 21, 2024
1 parent c29d602 commit a20ff50
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 3 deletions.
1 change: 1 addition & 0 deletions .changelog/5698.feature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
secret-sharing/src/churp: Implement key derivation center
103 changes: 100 additions & 3 deletions secret-sharing/src/churp/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::iter::zip;
use anyhow::{bail, Result};
use group::ff::PrimeField;

use crate::vss::lagrange;
use crate::{kdc::KeyRecoverer, vss::lagrange};

use super::{HandoffKind, SecretShare};

Expand Down Expand Up @@ -62,13 +62,20 @@ impl Player {
}
}

impl KeyRecoverer for Player {
fn min_shares(&self) -> usize {
self.min_shares()
}
}

#[cfg(test)]
mod tests {
use rand_core::OsRng;

use crate::{
churp::{self, HandoffKind},
suites::{self, p384},
churp::{self, HandoffKind, Shareholder},
kdc::{KeyRecoverer, KeySharer},
suites::{self, p384, GroupDigest},
};

use super::Player;
Expand Down Expand Up @@ -128,4 +135,94 @@ mod tests {
assert_eq!(secret, recovered);
}
}

#[test]
fn test_kdc() {
let test_cases = vec![
HandoffKind::DealingPhase,
HandoffKind::CommitteeUnchanged,
HandoffKind::CommitteeChanged,
];

for kind in test_cases.into_iter() {
// Prepare scheme.
let threshold = 2;
let key_id = b"key identifier";
let dst = b"shamir secret sharing scheme";
let secret = PrimeField::from_u64(100);
let hash = Suite::hash_to_group(key_id, dst).unwrap();
let key = hash * secret;
let dealer = Dealer::new(threshold, secret, &mut OsRng).unwrap();
let player = Player::new(threshold, kind);
let min_shares = player.min_shares() as u64;

// Not enough shares.
let n = min_shares - 1;
let xs = (1..=n).map(PrimeField::from_u64).collect();
let shares = dealer.make_shares(xs, kind);
let vm = dealer.verification_matrix();
let shareholders: Vec<_> = shares
.into_iter()
.map(|share| Shareholder::new(share, vm.clone()))
.collect();
let key_shares: Vec<_> = shareholders
.iter()
.map(|sh| sh.make_key_share::<Suite>(key_id, dst).unwrap())
.collect();
let result = player.recover_key(&key_shares);
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "not enough shares");

// Duplicate shares.
let xs = (1..=n)
.flat_map(|x| std::iter::repeat(x).take(2))
.map(PrimeField::from_u64)
.collect();
let shares = dealer.make_shares(xs, kind);
let vm = dealer.verification_matrix();
let shareholders: Vec<_> = shares
.into_iter()
.map(|share| Shareholder::new(share, vm.clone()))
.collect();
let key_shares: Vec<_> = shareholders
.iter()
.map(|sh| sh.make_key_share::<Suite>(key_id, dst).unwrap())
.collect();
let result = player.recover_key(&key_shares);
assert!(result.is_err());
assert_eq!(result.unwrap_err().to_string(), "not distinct shares");

// Exact number of shares.
let n = min_shares;
let xs = (1..=n).map(PrimeField::from_u64).collect();
let shares = dealer.make_shares(xs, kind);
let vm = dealer.verification_matrix();
let shareholders: Vec<_> = shares
.into_iter()
.map(|share| Shareholder::new(share, vm.clone()))
.collect();
let key_shares: Vec<_> = shareholders
.iter()
.map(|sh| sh.make_key_share::<Suite>(key_id, dst).unwrap())
.collect();
let recovered = player.recover_key(&key_shares).unwrap();
assert_eq!(key, recovered);

// Too many shares.
let n = min_shares + 10;
let xs = (1..=n).map(PrimeField::from_u64).collect();
let shares = dealer.make_shares(xs, kind);
let vm = dealer.verification_matrix();
let shareholders: Vec<_> = shares
.into_iter()
.map(|share| Shareholder::new(share, vm.clone()))
.collect();
let key_shares: Vec<_> = shareholders
.iter()
.map(|sh| sh.make_key_share::<Suite>(key_id, dst).unwrap())
.collect();
let recovered = player.recover_key(&key_shares).unwrap();
assert_eq!(key, recovered);
}
}
}
14 changes: 14 additions & 0 deletions secret-sharing/src/churp/shareholder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use group::{
};

use crate::{
kdc::PointShareholder,
suites::FieldDigest,
vss::{matrix::VerificationMatrix, polynomial::Polynomial},
};
Expand Down Expand Up @@ -96,6 +97,19 @@ where
}
}

impl<G> PointShareholder<G::Scalar> for Shareholder<G>
where
G: Group + GroupEncoding,
{
fn coordinate_x(&self) -> &G::Scalar {
self.verifiable_share.share.coordinate_x()
}

fn coordinate_y(&self) -> &G::Scalar {
self.verifiable_share.share.coordinate_y()
}
}

/// Secret share of the shared secret.
pub struct SecretShare<F: PrimeField> {
/// The encoded identity of the shareholder.
Expand Down

0 comments on commit a20ff50

Please sign in to comment.