Skip to content
This repository has been archived by the owner on Sep 1, 2023. It is now read-only.

Commit

Permalink
Merge branch 'master' into dlog-sec-param
Browse files Browse the repository at this point in the history
Signed-off-by: Oleg Burundukov <[email protected]>

# Conflicts:
#	src/algorithms/dlog_proof.rs
  • Loading branch information
Oleg Burundukov committed Mar 19, 2021
2 parents c2b5b43 + f0114f1 commit f7c06b2
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 48 deletions.
6 changes: 4 additions & 2 deletions src/algorithms/dlog_proof.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::algorithms::sha::HSha512Trunc256;
use curv::arithmetic::traits::Samplable;
use curv::arithmetic::traits::ZeroizeBN;
use curv::cryptographic_primitives::hashing::traits::Hash;
use curv::BigInt;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -27,11 +28,12 @@ impl DlogProof {
) -> Self {
let log_r = max_secret_length + DIGEST_BIT_LENGTH + security_param;
let R = BigInt::from(2).pow(log_r);
let r = BigInt::sample_below(&R);
let mut r = BigInt::sample_below(&R);
let x = g.powm_sec(&r, N);
let c = HSha512Trunc256::create_hash(&[&BigInt::from(security_param), N, g, V, &x]);

let y = r - c.borrow() * s;
let y = r.borrow() - c.borrow() * s;
r.zeroize_bn();
Self { y, c }
}

Expand Down
11 changes: 5 additions & 6 deletions src/algorithms/nizk_rsa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ pub enum NIZKError {
use std::ops::Shl;

use crate::algorithms::sha::HSha512Trunc256;
use crate::ecdsa::{PaillierKeys, PRIME_BIT_LENGTH_IN_PAILLIER_SCHEMA};
use crate::ecdsa::PRIME_BIT_LENGTH_IN_PAILLIER_SCHEMA;
use curv::cryptographic_primitives::hashing::traits::Hash;
use paillier::{extract_nroot, BigInt, DecryptionKey, EncryptionKey};
use std::borrow::Borrow;
use std::convert::TryFrom;

/// Initializes the PRNG used for random sampling of points in the algorithm
Expand All @@ -31,7 +32,6 @@ use std::convert::TryFrom;
/// 459561513849871375704710178795731042296906667021449863746459528082436944578977
///
///
///
const SALT: &str = "459561513849871375704710178795731042296906667021449863746459528082436944578977";

/// Parameters are as suggested in 6.2.3 of [link](https://eprint.iacr.org/2018/987.pdf)
Expand Down Expand Up @@ -99,14 +99,13 @@ pub fn get_rho_vec(n: &BigInt) -> Vec<BigInt> {
}

/// generates non-interactive proof of correctness of public Paillier key
pub fn gen_proof(mut dk: DecryptionKey) -> Vec<BigInt> {
let n = &dk.q * &dk.p;
pub fn gen_proof(dk: &DecryptionKey) -> Vec<BigInt> {
let n = dk.q.borrow() * dk.p.borrow();

let result = get_rho_vec(&n)
.into_iter()
.map(|rho| extract_nroot(&dk, &rho))
.collect();
PaillierKeys::zeroize_dk(&mut dk);
result
}

Expand Down Expand Up @@ -175,7 +174,7 @@ mod tests {
let (encryption, decryption) =
Paillier::keypair_with_modulus_size(2 * PRIME_BIT_LENGTH_IN_PAILLIER_SCHEMA).keys();
for _ in 0..=10 {
let proof = gen_proof(decryption.clone());
let proof = gen_proof(&decryption);
verify(&encryption, &proof)?
}
Ok(())
Expand Down
65 changes: 33 additions & 32 deletions src/ecdsa/keygen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ use crate::ecdsa::messages::{FeldmanVSS, SecretShare};

use crate::algorithms::nizk_rsa;
use crate::ecdsa::{
from_secp256k1_pk, is_valid_curve_point, CommitmentScheme, InitialPublicKeys, PaillierKeys,
Parameters,
from_secp256k1_pk, is_valid_curve_point, CommitmentScheme, InitialPublicKeys,
ManagedPaillierDecryptionKey, ManagedSecretKey, PaillierKeys, Parameters,
};
use crate::protocol::{Address, PartyIndex};
pub use paillier::DecryptionKey;
Expand Down Expand Up @@ -350,15 +350,17 @@ impl Phase1 {
secret_key_loader: ASecretKeyLoader,
timeout: Option<Duration>,
) -> Result<Self, KeygenError> {
let dk = secret_key_loader
.get_paillier_secret()
.map_err(|e| KeygenError::ProtocolSetupError(e.0))?;
if !PaillierKeys::is_valid(&init_keys.paillier_encryption_key, &dk) {
let dk = ManagedPaillierDecryptionKey(
secret_key_loader
.get_paillier_secret()
.map_err(|e| KeygenError::ProtocolSetupError(e.0))?,
);
if !PaillierKeys::is_valid(&init_keys.paillier_encryption_key, &dk.0) {
return Err(KeygenError::ProtocolSetupError(
"invalid own Paillier key".to_string(),
));
}
let proof = nizk_rsa::gen_proof(dk);
let proof = nizk_rsa::gen_proof(&dk.0);
let scheme = CommitmentScheme::from_GE(&init_keys.y_i);

let acting_parties = BTreeSet::from_iter(parties.iter().cloned());
Expand Down Expand Up @@ -641,24 +643,26 @@ impl State<KeyGeneratorTraits> for Phase2 {
.map(|(party, msg)| (*party, msg.e.clone()))
.collect::<HashMap<PartyIndex, EncryptionKey>>();

let sk = self.secret_key_loader.get_initial_secret();
if let Err(e) = &sk {
let sk_loader_result = self
.secret_key_loader
.get_initial_secret()
.map(|s| ManagedSecretKey(s));
if let Err(e) = &sk_loader_result {
errors.push(KeygenError::GeneralError(e.0.clone()));
}

if !errors.is_empty() {
let error_state = ErrorState::new(errors);
log::error!("Phase2 returns {:?}", error_state);
return Transition::FinalState(Err(error_state));
log::error!("Phase2 returns errors {:?}", errors);
return Transition::FinalState(Err(ErrorState::new(errors)));
//sk_loader_result is dropped here
}

let (vss_scheme, outgoing_shares) = {
let mut sk = sk.unwrap();
let sk = sk_loader_result.unwrap();
let vss_sharing =
VerifiableSS::share(self.params.threshold, self.params.share_count, &sk);
sk.zeroize();
VerifiableSS::share(self.params.threshold, self.params.share_count, &sk.0);
vss_sharing
};
}; // sk is dropped here

let mapped_shares = self.map_parties_to_shares(party_list, outgoing_shares);
let (parties_points, own_point): (Vec<(_, _)>, Vec<(_, _)>) = mapped_shares
Expand Down Expand Up @@ -835,25 +839,23 @@ impl State<KeyGeneratorTraits> for Phase3 {
Ok(pk) => Some(pk),
};

let dk = match self.secret_key_loader.get_paillier_secret() {
Ok(dk) if PaillierKeys::is_valid(&self.keys.paillier_encryption_key, &dk) => Some(dk),
Err(e) => {
errors.push(KeygenError::GeneralError(e.0));
None
}
_ => {
errors.push(KeygenError::ProtocolSetupError(
"invalid Paillier key".to_string(),
));
None
}
};
let dk_loader_result = self
.secret_key_loader
.get_paillier_secret()
.map(|dk| ManagedPaillierDecryptionKey(dk));

if let Err(e) = &dk_loader_result {
errors.push(KeygenError::GeneralError(e.0.clone()));
}

if !errors.is_empty() {
log::error!("Phase3 returns errors {:?}", errors);
return Transition::FinalState(Err(ErrorState::new(errors)));
}
let mut dk = dk.expect("invalid paillier decryption key");

// panic() on dk_loader_result.unwrap() is unreachable as dk_loader_result.is_err() is checked above
let dk = dk_loader_result.unwrap();
// panic() on public_key.unwrap() is unreachable as try_computing_public_key().is_err() is checked above
let public_key = from_secp256k1_pk(public_key.unwrap()).expect("invalid full public key");
let points = self
.other_points
Expand All @@ -871,15 +873,14 @@ impl State<KeyGeneratorTraits> for Phase3 {
public_key,
own_he_keys: PaillierKeys {
ek: self.keys.paillier_encryption_key.clone(),
dk: dk.clone(),
dk: dk.0.clone(),
},
party_he_keys: self.paillier_keys.clone(),
party_to_point_map: Party2PointMap { points },
range_proof_setups: self.range_proof_setups.clone(),
},
timeout: self.timeout,
}));
PaillierKeys::zeroize_dk(&mut dk);
new_state
}

Expand Down
26 changes: 19 additions & 7 deletions src/ecdsa/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,13 +219,6 @@ impl PaillierKeys {
}
}

///erases private key using CPU's memory fence
pub fn zeroize_dk(dk: &mut DecryptionKey) {
dk.p = BigInt::zero();
dk.q = BigInt::zero();
atomic::compiler_fence(atomic::Ordering::SeqCst);
}

/// produces new Paiiliier key pair
pub fn random() -> Self {
let (ek, dk) =
Expand Down Expand Up @@ -265,6 +258,25 @@ impl Debug for PaillierKeys {
}
}

struct ManagedPaillierDecryptionKey(DecryptionKey);

impl Drop for ManagedPaillierDecryptionKey {
fn drop(&mut self) {
self.0.p = BigInt::zero();
self.0.q = BigInt::zero();
atomic::compiler_fence(atomic::Ordering::SeqCst);
}
}

struct ManagedSecretKey(FE);

impl Drop for ManagedSecretKey {
fn drop(&mut self) {
self.0.zeroize();
atomic::compiler_fence(atomic::Ordering::SeqCst);
}
}

///current recommended bit size for the primes in Paillier schema
pub(crate) const PRIME_BIT_LENGTH_IN_PAILLIER_SCHEMA: usize = 1024;

Expand Down
2 changes: 1 addition & 1 deletion src/ecdsa/resharing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ pub mod new_member {
.range_proof_setup
.as_ref()
.map(|s| ZkpPublicSetup::from_private_zkp_setup(s));
let proof = nizk_rsa::gen_proof(self.my_paillier_keys.dk.clone());
let proof = nizk_rsa::gen_proof(&self.my_paillier_keys.dk);
#[allow(clippy::if_not_else)]
let output = self
.previous_phase
Expand Down
7 changes: 7 additions & 0 deletions src/ecdsa/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,13 @@ impl State<SigningTraits> for Phase4 {
}
}

impl Drop for Phase4 {
fn drop(&mut self) {
self.k_i = FE::zero();
self.gamma_i = FE::zero();
}
}

/// Discriminates the sub phase in Phase 5 protocol
#[derive(Copy, Clone, PartialEq)]
enum SubPhaseAB {
Expand Down

0 comments on commit f7c06b2

Please sign in to comment.