Skip to content

Commit

Permalink
Rearrange KeyShares internal structure
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Aug 12, 2023
1 parent 192fa42 commit eccb5ea
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 210 deletions.
81 changes: 41 additions & 40 deletions synedrion/src/centralized_keygen.rs
Original file line number Diff line number Diff line change
@@ -1,49 +1,38 @@
use alloc::boxed::Box;
use alloc::vec::Vec;

use rand_core::CryptoRngCore;

use crate::curve::{Point, Scalar};
use crate::curve::Scalar;
use crate::paillier::uint::Zero;
use crate::paillier::{PaillierParams, SecretKeyPaillier};
use crate::protocols::common::{KeyShare, KeySharePublic, KeyShareSecret, SchemeParams};
use crate::protocols::common::{KeyShare, PublicAuxInfo, SchemeParams, SecretAuxInfo};
use crate::protocols::threshold::ThresholdKeyShare;
use crate::tools::sss::{shamir_evaluation_points, shamir_split};
use crate::PartyIdx;

#[allow(clippy::type_complexity)]
fn make_key_shares_from_secrets<P: SchemeParams>(
fn make_aux_info<P: SchemeParams>(
rng: &mut impl CryptoRngCore,
secrets: &[Scalar],
) -> (Box<[KeyShareSecret<P>]>, Box<[KeySharePublic<P>]>) {
let paillier_sks = secrets
.iter()
.map(|_| SecretKeyPaillier::<P::Paillier>::random(rng))
.collect::<Vec<_>>();
num_parties: usize,
) -> (Box<[SecretAuxInfo<P>]>, Box<[PublicAuxInfo<P>]>) {
let secret_aux = (0..num_parties)
.map(|_| SecretAuxInfo {
paillier_sk: SecretKeyPaillier::<P::Paillier>::random(rng),
el_gamal_sk: Scalar::random(rng),
})
.collect::<Box<_>>();

let public = secrets
let public_aux = secret_aux
.iter()
.zip(paillier_sks.iter())
.map(|(share_sk, sk)| KeySharePublic {
share_pk: share_sk.mul_by_generator(),
el_gamal_pk: Point::GENERATOR, // TODO: currently unused in the protocol
.map(|secret| PublicAuxInfo {
paillier_pk: secret.paillier_sk.public_key(),
el_gamal_pk: secret.el_gamal_sk.mul_by_generator(),
rp_generator: <P::Paillier as PaillierParams>::DoubleUint::ZERO, // TODO: currently unused in the protocol
rp_power: <P::Paillier as PaillierParams>::DoubleUint::ZERO, // TODO: currently unused in the protocol
paillier_pk: sk.public_key(),
})
.collect();

let secret = secrets
.iter()
.zip(paillier_sks.iter())
.map(|(share_sk, paillier_sk)| KeyShareSecret {
share_sk: *share_sk,
paillier_sk: (*paillier_sk).clone(),
el_gamal_sk: Scalar::random(rng), // TODO: currently unused in the protocol
})
.collect();

(secret, public)
(secret_aux, public_aux)
}

/// Returns `num_parties` of random self-consistent key shares
Expand All @@ -58,18 +47,24 @@ pub fn make_key_shares<P: SchemeParams>(
Some(sk) => Scalar::from(sk.as_nonzero_scalar()),
};

let secrets = secret.split(rng, num_parties);
let secret_shares = secret.split(rng, num_parties);
let public_shares = secret_shares
.iter()
.map(|s| s.mul_by_generator())
.collect::<Box<_>>();

let (secret_shares, public_shares) = make_key_shares_from_secrets(rng, &secrets);
let (secret_aux, public_aux) = make_aux_info(rng, num_parties);

secret_shares
secret_aux
.into_vec()
.into_iter()
.enumerate()
.map(|(idx, secret)| KeyShare {
.map(|(idx, secret_aux)| KeyShare {
index: PartyIdx::from_usize(idx),
secret,
public: public_shares.clone(),
secret_share: secret_shares[idx],
public_shares: public_shares.clone(),
secret_aux,
public_aux: public_aux.clone(),
})
.collect()
}
Expand All @@ -87,24 +82,30 @@ pub fn make_threshold_key_shares<P: SchemeParams>(
Some(sk) => Scalar::from(sk.as_nonzero_scalar()),
};

let secrets = shamir_split(
let secret_shares = shamir_split(
rng,
&secret,
threshold,
&shamir_evaluation_points(num_parties),
);
let public_shares = secret_shares
.iter()
.map(|s| s.mul_by_generator())
.collect::<Box<_>>();

let (secret_shares, public_shares) = make_key_shares_from_secrets(rng, &secrets);
let (secret_aux, public_aux) = make_aux_info(rng, num_parties);

secret_shares
secret_aux
.into_vec()
.into_iter()
.enumerate()
.map(|(idx, secret)| ThresholdKeyShare {
.map(|(idx, secret_aux)| ThresholdKeyShare {
index: PartyIdx::from_usize(idx),
threshold: threshold as u32, // TODO: fallible conversion?
secret,
public: public_shares.clone(),
secret_share: secret_shares[idx],
public_shares: public_shares.clone(),
secret_aux,
public_aux: public_aux.clone(),
})
.collect()
}
Expand Down Expand Up @@ -137,7 +138,7 @@ mod tests {
assert_eq!(&nt_share0.verifying_key(), sk.verifying_key());
assert_eq!(&nt_share1.verifying_key(), sk.verifying_key());
assert_eq!(
nt_share0.secret.share_sk + nt_share1.secret.share_sk,
nt_share0.secret_share + nt_share1.secret_share,
Scalar::from(sk.as_nonzero_scalar())
);
}
Expand Down
38 changes: 19 additions & 19 deletions synedrion/src/protocols/auxiliary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ use crypto_bigint::Pow;
use rand_core::CryptoRngCore;
use serde::{Deserialize, Serialize};

use super::common::{
KeyShareChange, KeyShareChangePublic, KeyShareChangeSecret, PartyIdx, SchemeParams,
};
use super::common::{KeyShareChange, PartyIdx, PublicAuxInfo, SchemeParams, SecretAuxInfo};
use super::generic::{
BaseRound, FinalizeError, FinalizeSuccess, FirstRound, InitError, NonExistent, ReceiveError,
Round, ToSendTyped,
Expand Down Expand Up @@ -454,36 +452,35 @@ impl<P: SchemeParams> Round for Round3<P> {
payloads: HoleVec<Self::Payload>,
) -> Result<FinalizeSuccess<Self>, FinalizeError> {
let secrets = payloads.into_vec(self.context.xs_secret[self.context.party_idx.as_usize()]);
let share_change = secrets.iter().sum();
let secret_share_change = secrets.iter().sum();

let datas = self.datas.into_vec(self.context.data);

let public_share_changes: Vec<_> = (0..datas.len())
let public_share_changes = (0..datas.len())
.map(|idx| datas.iter().map(|data| data.xs_public[idx]).sum())
.collect();
.collect::<Box<_>>();

let public = datas
let public_aux = datas
.into_iter()
.enumerate()
.map(|(idx, data)| KeyShareChangePublic {
share_pk: public_share_changes[idx],
.map(|data| PublicAuxInfo {
el_gamal_pk: data.el_gamal_pk,
paillier_pk: data.paillier_pk,
rp_generator: data.rp_generator,
rp_power: data.rp_power,
})
.collect();

let secret = KeyShareChangeSecret {
share_sk: share_change,
let secret_aux = SecretAuxInfo {
paillier_sk: self.context.paillier_sk,
el_gamal_sk: self.context.el_gamal_sk,
};

let key_share_change = KeyShareChange {
index: self.context.party_idx,
secret,
public,
secret_share_change,
public_share_changes,
secret_aux,
public_aux,
};

Ok(FinalizeSuccess::Result(key_share_change))
Expand Down Expand Up @@ -543,19 +540,22 @@ mod tests {
for (idx, change) in results.iter().enumerate() {
for other_change in results.iter() {
assert_eq!(
change.secret.share_sk.mul_by_generator(),
other_change.public[idx].share_pk
change.secret_share_change.mul_by_generator(),
other_change.public_share_changes[idx]
);
assert_eq!(
change.secret.el_gamal_sk.mul_by_generator(),
other_change.public[idx].el_gamal_pk
change.secret_aux.el_gamal_sk.mul_by_generator(),
other_change.public_aux[idx].el_gamal_pk
);
}
}

// The resulting sum of masks should be zero, since the combined secret key
// should not change after applying the masks at each node.
let mask_sum: Scalar = results.iter().map(|change| change.secret.share_sk).sum();
let mask_sum: Scalar = results
.iter()
.map(|change| change.secret_share_change)
.sum();
assert_eq!(mask_sum, Scalar::ZERO);
}
}
Loading

0 comments on commit eccb5ea

Please sign in to comment.