Skip to content

Commit

Permalink
Update generic security level
Browse files Browse the repository at this point in the history
  • Loading branch information
drewstone committed Oct 27, 2022
1 parent 6504d4d commit 9534af1
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 43 deletions.
10 changes: 5 additions & 5 deletions src/add_party_message.rs
Expand Up @@ -32,15 +32,15 @@ use crate::ring_pedersen_proof::{RingPedersenProof, RingPedersenStatement};

/// Message used by new parties to join the protocol.
#[derive(Clone, Deserialize, Serialize, Debug)]
pub struct JoinMessage<E: Curve, H: Digest + Clone> {
pub struct JoinMessage<E: Curve, H: Digest + Clone, const M: usize> {
pub(crate) ek: EncryptionKey,
pub(crate) dk_correctness_proof: NiCorrectKeyProof,
pub(crate) party_index: Option<u16>,
pub(crate) dlog_statement: DLogStatement,
pub(crate) composite_dlog_proof_base_h1: CompositeDLogProof,
pub(crate) composite_dlog_proof_base_h2: CompositeDLogProof,
pub(crate) ring_pedersen_statement: RingPedersenStatement<E, H>,
pub(crate) ring_pedersen_proof: RingPedersenProof<E, H>,
pub(crate) ring_pedersen_proof: RingPedersenProof<E, H, M>,
}

/// Generates the parameters needed for the h1_h2_N_tilde_vec. These parameters can be seen as
Expand Down Expand Up @@ -90,7 +90,7 @@ fn generate_dlog_statement_proofs() -> (DLogStatement, CompositeDLogProof, Compo
)
}

impl<E: Curve, H: Digest + Clone> JoinMessage<E, H> {
impl<E: Curve, H: Digest + Clone, const M: usize> JoinMessage<E, H, M> {
pub fn set_party_index(&mut self, new_party_index: u16) {
self.party_index = Some(new_party_index);
}
Expand Down Expand Up @@ -134,9 +134,9 @@ impl<E: Curve, H: Digest + Clone> JoinMessage<E, H> {
/// the other join messages (multiple parties can be added/replaced at once).
pub fn collect(
&self,
refresh_messages: &[RefreshMessage<E, H>],
refresh_messages: &[RefreshMessage<E, H, M>],
paillier_key: Keys,
join_messages: &[JoinMessage<E, H>],
join_messages: &[JoinMessage<E, H, M>],
t: u16,
n: u16,
) -> FsDkrResult<LocalKey<E>> {
Expand Down
12 changes: 6 additions & 6 deletions src/refresh_message.rs
Expand Up @@ -27,7 +27,7 @@ use crate::ring_pedersen_proof::{RingPedersenProof, RingPedersenStatement};

// Everything here can be broadcasted
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RefreshMessage<E: Curve, H: Digest + Clone> {
pub struct RefreshMessage<E: Curve, H: Digest + Clone, const M: usize> {
pub(crate) old_party_index: u16,
pub(crate) party_index: u16,
pdl_proof_vec: Vec<PDLwSlackProof<E, H>>,
Expand All @@ -41,17 +41,17 @@ pub struct RefreshMessage<E: Curve, H: Digest + Clone> {
pub(crate) remove_party_indices: Vec<u16>,
pub(crate) public_key: Point<E>,
pub(crate) ring_pedersen_statement: RingPedersenStatement<E, H>,
pub(crate) ring_pedersen_proof: RingPedersenProof<E, H>,
pub(crate) ring_pedersen_proof: RingPedersenProof<E, H, M>,
#[serde(skip)]
pub hash_choice: HashChoice<H>,
}

impl<E: Curve, H: Digest + Clone> RefreshMessage<E, H> {
impl<E: Curve, H: Digest + Clone, const M: usize> RefreshMessage<E, H, M> {
pub fn distribute(
old_party_index: u16,
local_key: &mut LocalKey<E>,
new_n: u16,
) -> FsDkrResult<(RefreshMessage<E, H>, DecryptionKey)> {
) -> FsDkrResult<(RefreshMessage<E, H, M>, DecryptionKey)> {
assert!(local_key.t <= new_n / 2);
let secret = local_key.keys_linear.x_i.clone();
// secret share old key
Expand Down Expand Up @@ -236,7 +236,7 @@ impl<E: Curve, H: Digest + Clone> RefreshMessage<E, H> {
}

pub fn replace(
new_parties: &[JoinMessage<E, H>],
new_parties: &[JoinMessage<E, H, M>],
key: &mut LocalKey<E>,
old_to_new_map: &HashMap<u16, u16>,
new_n: u16,
Expand Down Expand Up @@ -321,7 +321,7 @@ impl<E: Curve, H: Digest + Clone> RefreshMessage<E, H> {
refresh_messages: &[Self],
mut local_key: &mut LocalKey<E>,
new_dk: DecryptionKey,
join_messages: &[JoinMessage<E, H>],
join_messages: &[JoinMessage<E, H, M>],
) -> FsDkrResult<()> {
let new_n = refresh_messages.len() + join_messages.len();
RefreshMessage::validate_collect(refresh_messages, local_key.t, new_n as u16)?;
Expand Down
33 changes: 20 additions & 13 deletions src/ring_pedersen_proof.rs
Expand Up @@ -73,23 +73,23 @@ impl<E: Curve, H: Digest + Clone> RingPedersenStatement<E, H> {
}

#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RingPedersenProof<E: Curve, H: Digest + Clone> {
pub struct RingPedersenProof<E: Curve, H: Digest + Clone, const M: usize> {
A: Vec<BigInt>,
Z: Vec<BigInt>,
phantom: PhantomData<(E, H)>,
}

// Link to the UC non-interactive threshold ECDSA paper
impl<E: Curve, H: Digest + Clone> RingPedersenProof<E, H> {
impl<E: Curve, H: Digest + Clone, const M: usize> RingPedersenProof<E, H, M> {
pub fn prove(
witness: &RingPedersenWitness<E, H>,
statement: &RingPedersenStatement<E, H>,
) -> RingPedersenProof<E, H> {
) -> RingPedersenProof<E, H, M> {
// 1. Sample alphas from 1 -> m from \phi(N)
let mut a = [(); crate::M_SECURITY].map(|_| BigInt::zero());
let mut A = [(); crate::M_SECURITY].map(|_| BigInt::zero());
let mut a = [(); M].map(|_| BigInt::zero());
let mut A = [(); M].map(|_| BigInt::zero());
let mut hash = H::new();
for i in 0..crate::M_SECURITY {
for i in 0..M {
// TODO: Consider ensuring we get a unit element of this subgroup
let a_i = BigInt::sample_below(&statement.phi);
a[i] = a_i.clone();
Expand All @@ -101,8 +101,8 @@ impl<E: Curve, H: Digest + Clone> RingPedersenProof<E, H> {
let e: BigInt = hash.result_bigint();
let bitwise_e: BitVec<u8, Lsb0> = BitVec::from_vec(e.to_bytes());

let mut Z = [(); crate::M_SECURITY].map(|_| BigInt::zero());
for i in 0..crate::M_SECURITY {
let mut Z = [(); M].map(|_| BigInt::zero());
for i in 0..M {
let e_i = if bitwise_e[i] {
BigInt::one()
} else {
Expand All @@ -120,18 +120,18 @@ impl<E: Curve, H: Digest + Clone> RingPedersenProof<E, H> {
}

pub fn verify(
proof: &RingPedersenProof<E, H>,
proof: &RingPedersenProof<E, H, M>,
statement: &RingPedersenStatement<E, H>,
) -> FsDkrResult<()> {
let mut hash = H::new();
for i in 0..crate::M_SECURITY {
for i in 0..M {
hash = H::chain_bigint(hash, &proof.A[i]);
}

let e: BigInt = hash.result_bigint();
let bitwise_e: BitVec<u8, Lsb0> = BitVec::from_vec(e.to_bytes());

for i in 0..crate::M_SECURITY {
for i in 0..M {
let mut e_i = 0;
if bitwise_e[i] {
e_i = 1;
Expand Down Expand Up @@ -162,7 +162,14 @@ mod tests {
#[test]
fn test_ring_pedersen() {
let (statement, witness) = RingPedersenStatement::<Secp256k1, Sha256>::generate();
let proof = RingPedersenProof::<Secp256k1, Sha256>::prove(&witness, &statement);
assert!(RingPedersenProof::<Secp256k1, Sha256>::verify(&proof, &statement).is_ok());
let proof = RingPedersenProof::<Secp256k1, Sha256, { crate::M_SECURITY }>::prove(
&witness, &statement,
);
assert!(
RingPedersenProof::<Secp256k1, Sha256, { crate::M_SECURITY }>::verify(
&proof, &statement
)
.is_ok()
);
}
}
48 changes: 29 additions & 19 deletions src/test.rs
Expand Up @@ -35,7 +35,7 @@ mod tests {
let mut keys = simulate_keygen(t, n);

let old_keys = keys.clone();
simulate_dkr(&mut keys);
simulate_dkr::<{ crate::M_SECURITY }>(&mut keys);

// check that sum of old keys is equal to sum of new keys
let old_linear_secret_key: Vec<_> = (0..old_keys.len())
Expand Down Expand Up @@ -65,10 +65,10 @@ mod tests {
let mut keys = simulate_keygen(2, 5);
let offline_sign = simulate_offline_stage(keys.clone(), &[1, 2, 3]);
simulate_signing(offline_sign, b"ZenGo");
simulate_dkr(&mut keys);
simulate_dkr::<{ crate::M_SECURITY }>(&mut keys);
let offline_sign = simulate_offline_stage(keys.clone(), &[2, 3, 4]);
simulate_signing(offline_sign, b"ZenGo");
simulate_dkr(&mut keys);
simulate_dkr::<{ crate::M_SECURITY }>(&mut keys);
let offline_sign = simulate_offline_stage(keys, &[1, 3, 5]);
simulate_signing(offline_sign, b"ZenGo");
}
Expand All @@ -78,37 +78,40 @@ mod tests {
let mut keys = simulate_keygen(2, 5);
let offline_sign = simulate_offline_stage(keys.clone(), &[1, 2, 3]);
simulate_signing(offline_sign, b"ZenGo");
simulate_dkr_removal(&mut keys, [1].to_vec());
simulate_dkr_removal::<{ crate::M_SECURITY }>(&mut keys, [1].to_vec());
let offline_sign = simulate_offline_stage(keys.clone(), &[2, 3, 4]);
simulate_signing(offline_sign, b"ZenGo");
simulate_dkr_removal(&mut keys, [1, 2].to_vec());
simulate_dkr_removal::<{ crate::M_SECURITY }>(&mut keys, [1, 2].to_vec());
let offline_sign = simulate_offline_stage(keys, &[3, 4, 5]);
simulate_signing(offline_sign, b"ZenGo");
}

#[test]
fn test_add_party_with_permute() {
fn simulate_replace(
fn simulate_replace<const M: usize>(
keys: &mut Vec<LocalKey<Secp256k1>>,
party_indices: &[u16],
old_to_new_map: &HashMap<u16, u16>,
t: u16,
n: u16,
) -> FsDkrResult<()> {
fn generate_join_messages_and_keys(
fn generate_join_messages_and_keys<const M: usize>(
number_of_new_parties: usize,
) -> (Vec<JoinMessage<Secp256k1, Sha256>>, Vec<Keys>) {
) -> (Vec<JoinMessage<Secp256k1, Sha256, M>>, Vec<Keys>) {
// the new party generates it's join message to start joining the computation
(0..number_of_new_parties)
.map(|_| JoinMessage::distribute())
.unzip()
}

fn generate_refresh_parties_replace(
fn generate_refresh_parties_replace<const M: usize>(
keys: &mut [LocalKey<Secp256k1>],
old_to_new_map: &HashMap<u16, u16>,
join_messages: &[JoinMessage<Secp256k1, Sha256>],
) -> (Vec<RefreshMessage<Secp256k1, Sha256>>, Vec<DecryptionKey>) {
join_messages: &[JoinMessage<Secp256k1, Sha256, M>],
) -> (
Vec<RefreshMessage<Secp256k1, Sha256, M>>,
Vec<DecryptionKey>,
) {
let new_n = (&keys.len() + join_messages.len()) as u16;
keys.iter_mut()
.map(|key| {
Expand All @@ -119,7 +122,7 @@ mod tests {

// each party that wants to join generates a join message and a pair of paillier keys.
let (mut join_messages, new_keys) =
generate_join_messages_and_keys(party_indices.len());
generate_join_messages_and_keys::<{ crate::M_SECURITY }>(party_indices.len());

// each new party has to be informed through offchannel communication what party index
// it has been assigned (the information is public).
Expand Down Expand Up @@ -184,7 +187,8 @@ mod tests {
old_to_new_map.insert(6, 5);

// Simulate the replace
simulate_replace(&mut keys, &[2, 7], &old_to_new_map, t, n).unwrap();
simulate_replace::<{ crate::M_SECURITY }>(&mut keys, &[2, 7], &old_to_new_map, t, n)
.unwrap();
// check that sum of old keys is equal to sum of new keys
let old_linear_secret_key: Vec<_> = (0..all_keys.len())
.map(|i| all_keys[i].keys_linear.x_i.clone())
Expand Down Expand Up @@ -223,11 +227,14 @@ mod tests {
simulation.run().unwrap()
}

fn simulate_dkr_removal(keys: &mut Vec<LocalKey<Secp256k1>>, remove_party_indices: Vec<u16>) {
let mut broadcast_messages: HashMap<usize, Vec<RefreshMessage<Secp256k1, Sha256>>> =
fn simulate_dkr_removal<const M: usize>(
keys: &mut Vec<LocalKey<Secp256k1>>,
remove_party_indices: Vec<u16>,
) {
let mut broadcast_messages: HashMap<usize, Vec<RefreshMessage<Secp256k1, Sha256, M>>> =
HashMap::new();
let mut new_dks: HashMap<usize, DecryptionKey> = HashMap::new();
let mut refresh_messages: Vec<RefreshMessage<Secp256k1, Sha256>> = Vec::new();
let mut refresh_messages: Vec<RefreshMessage<Secp256k1, Sha256, M>> = Vec::new();
let mut party_key: HashMap<usize, LocalKey<Secp256k1>> = HashMap::new();
// TODO: Verify this is correct
let new_n = keys.len() as u16;
Expand Down Expand Up @@ -293,10 +300,13 @@ mod tests {
}
}

fn simulate_dkr(
fn simulate_dkr<const M: usize>(
keys: &mut Vec<LocalKey<Secp256k1>>,
) -> (Vec<RefreshMessage<Secp256k1, Sha256>>, Vec<DecryptionKey>) {
let mut broadcast_vec: Vec<RefreshMessage<Secp256k1, Sha256>> = Vec::new();
) -> (
Vec<RefreshMessage<Secp256k1, Sha256, M>>,
Vec<DecryptionKey>,
) {
let mut broadcast_vec: Vec<RefreshMessage<Secp256k1, Sha256, M>> = Vec::new();
let mut new_dks: Vec<DecryptionKey> = Vec::new();
let keys_len = keys.len();
for key in keys.iter_mut() {
Expand Down

0 comments on commit 9534af1

Please sign in to comment.