Skip to content

Commit

Permalink
Use SecretBox for all secret values (#144)
Browse files Browse the repository at this point in the history
Use `SecretBox` for all secret values (#144)
  • Loading branch information
dvdplm authored Sep 30, 2024
1 parent 9f9a0c4 commit 6a38f1f
Show file tree
Hide file tree
Showing 16 changed files with 287 additions and 120 deletions.
3 changes: 2 additions & 1 deletion synedrion/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,10 @@ displaydoc = { version = "0.2", default-features = false}
getrandom = { version = "0.2", features = ["js"]}

[dev-dependencies]
rand_chacha = "0.3"
serde_assert = "0.8"
tokio = { version = "1", features = ["rt", "sync", "time", "macros"] }
rand = "0.8"
rand_chacha = "0.3"
criterion = "0.5"
k256 = {version = "0.14.0-pre.2", default-features = false, features = ["ecdsa", "arithmetic", "pem", "serde"]}
impls = "1"
Expand Down
12 changes: 8 additions & 4 deletions synedrion/src/cggmp21/entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub struct PresigningData<P: SchemeParams, I> {

#[derive(Debug, Clone)]
pub(crate) struct PresigningValues<P: SchemeParams> {
pub(crate) hat_beta: Signed<<P::Paillier as PaillierParams>::Uint>,
pub(crate) hat_beta: SecretBox<Signed<<P::Paillier as PaillierParams>::Uint>>,
pub(crate) hat_r: Randomizer<P::Paillier>,
pub(crate) hat_s: Randomizer<P::Paillier>,
pub(crate) cap_k: CiphertextMod<P::Paillier>,
Expand Down Expand Up @@ -276,7 +276,11 @@ impl<P: SchemeParams, I: Ord + Clone> AuxInfo<P, I> {
}
}

impl<P: SchemeParams, I: Ord + Clone + PartialEq> PresigningData<P, I> {
impl<P, I> PresigningData<P, I>
where
P: SchemeParams,
I: Ord + Clone + PartialEq,
{
/// Creates a consistent set of presigning data for testing purposes.
#[cfg(any(test, feature = "bench-internals"))]
pub(crate) fn new_centralized(
Expand Down Expand Up @@ -346,7 +350,7 @@ impl<P: SchemeParams, I: Ord + Clone + PartialEq> PresigningData<P, I> {
let id_ji = (id_j.clone(), id_i.clone());

hat_betas.insert(id_ij.clone(), hat_beta);
hat_ss.insert(id_ij.clone(), hat_s);
hat_ss.insert(id_ij.clone(), hat_s.clone());
hat_rs.insert(id_ij.clone(), hat_r);

hat_cap_ds.insert(id_ji.clone(), hat_cap_d);
Expand All @@ -368,7 +372,7 @@ impl<P: SchemeParams, I: Ord + Clone + PartialEq> PresigningData<P, I> {
values.insert(
id_j.clone(),
PresigningValues {
hat_beta: hat_betas[&id_ij],
hat_beta: SecretBox::new(Box::new(hat_betas[&id_ij])),
hat_r: hat_rs[&id_ij].clone(),
hat_s: hat_ss[&id_ij].clone(),
hat_cap_d_received: hat_cap_ds[&id_ij].clone(),
Expand Down
58 changes: 37 additions & 21 deletions synedrion/src/cggmp21/protocols/presigning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,12 @@ pub struct Round2Message<P: SchemeParams> {

#[derive(Debug, Clone)]
pub struct Round2Artifact<P: SchemeParams> {
beta: Signed<<P::Paillier as PaillierParams>::Uint>, // TODO (#77): secret
hat_beta: Signed<<P::Paillier as PaillierParams>::Uint>, // TODO (#77): secret
r: Randomizer<P::Paillier>, // TODO (#77): secret
s: Randomizer<P::Paillier>, // TODO (#77): secret
hat_r: Randomizer<P::Paillier>, // TODO (#77): secret
hat_s: Randomizer<P::Paillier>, // TODO (#77): secret
beta: SecretBox<Signed<<P::Paillier as PaillierParams>::Uint>>,
hat_beta: SecretBox<Signed<<P::Paillier as PaillierParams>::Uint>>,
r: Randomizer<P::Paillier>,
s: Randomizer<P::Paillier>,
hat_r: Randomizer<P::Paillier>,
hat_s: Randomizer<P::Paillier>,
cap_d: CiphertextMod<P::Paillier>,
cap_f: CiphertextMod<P::Paillier>,
hat_cap_d: CiphertextMod<P::Paillier>,
Expand Down Expand Up @@ -344,25 +344,38 @@ impl<P: SchemeParams, I: Debug + Clone + Ord + Serialize> Round<I> for Round2<P,
let aux = (&self.context.ssid_hash, &self.my_id());

let cap_gamma = self.context.gamma.mul_by_generator();
let pk = &self.context.aux_info.secret_aux.paillier_sk.public_key();
let pk = self.context.aux_info.secret_aux.paillier_sk.public_key();

let target_pk = &self.context.aux_info.public_aux[destination].paillier_pk;

let beta = Signed::random_bounded_bits(rng, P::LP_BOUND);
let hat_beta = Signed::random_bounded_bits(rng, P::LP_BOUND);
let beta = SecretBox::new(Box::new(Signed::random_bounded_bits(rng, P::LP_BOUND)));
let hat_beta = SecretBox::new(Box::new(Signed::random_bounded_bits(rng, P::LP_BOUND)));
let r = RandomizerMod::random(rng, pk);
let s = RandomizerMod::random(rng, target_pk);
let hat_r = RandomizerMod::random(rng, pk);
let hat_s = RandomizerMod::random(rng, target_pk);

let cap_f = CiphertextMod::new_with_randomizer_signed(pk, &beta, &r.retrieve());
let cap_f =
CiphertextMod::new_with_randomizer_signed(pk, beta.expose_secret(), &r.retrieve());
let cap_d = &self.all_cap_k[destination] * P::signed_from_scalar(&self.context.gamma)
+ CiphertextMod::new_with_randomizer_signed(target_pk, &-beta, &s.retrieve());
+ CiphertextMod::new_with_randomizer_signed(
target_pk,
&-beta.expose_secret(),
&s.retrieve(),
);

let hat_cap_f = CiphertextMod::new_with_randomizer_signed(pk, &hat_beta, &hat_r.retrieve());
let hat_cap_f = CiphertextMod::new_with_randomizer_signed(
pk,
hat_beta.expose_secret(),
&hat_r.retrieve(),
);
let hat_cap_d = &self.all_cap_k[destination]
* P::signed_from_scalar(self.context.key_share.secret_share.expose_secret())
+ CiphertextMod::new_with_randomizer_signed(target_pk, &-hat_beta, &hat_s.retrieve());
+ CiphertextMod::new_with_randomizer_signed(
target_pk,
&-hat_beta.expose_secret(),
&hat_s.retrieve(),
);

let public_aux = &self.context.aux_info.public_aux[destination];
let rp = &public_aux.rp_params;
Expand All @@ -371,8 +384,8 @@ impl<P: SchemeParams, I: Debug + Clone + Ord + Serialize> Round<I> for Round2<P,
rng,
&P::signed_from_scalar(&self.context.gamma),
&beta,
&s,
&r,
s.clone(),
r.clone(),
target_pk,
pk,
&self.all_cap_k[destination],
Expand All @@ -387,8 +400,8 @@ impl<P: SchemeParams, I: Debug + Clone + Ord + Serialize> Round<I> for Round2<P,
rng,
&P::signed_from_scalar(self.context.key_share.secret_share.expose_secret()),
&hat_beta,
&hat_s,
&hat_r,
hat_s.clone(),
hat_r.clone(),
target_pk,
pk,
&self.all_cap_k[destination],
Expand Down Expand Up @@ -542,14 +555,17 @@ impl<P: SchemeParams, I: Debug + Clone + Ord + Serialize> FinalizableToNextRound
let cap_delta = cap_gamma * self.context.k;

let alpha_sum: Signed<_> = payloads.values().map(|p| p.alpha).sum();
let beta_sum: Signed<_> = artifacts.values().map(|p| p.beta).sum();
let beta_sum: Signed<_> = artifacts.values().map(|p| p.beta.expose_secret()).sum();
let delta = P::signed_from_scalar(&self.context.gamma)
* P::signed_from_scalar(&self.context.k)
+ alpha_sum
+ beta_sum;

let hat_alpha_sum: Signed<_> = payloads.values().map(|payload| payload.hat_alpha).sum();
let hat_beta_sum: Signed<_> = artifacts.values().map(|artifact| artifact.hat_beta).sum();
let hat_beta_sum: Signed<_> = artifacts
.values()
.map(|artifact| artifact.hat_beta.expose_secret())
.sum();
let chi = P::signed_from_scalar(self.context.key_share.secret_share.expose_secret())
* P::signed_from_scalar(&self.context.k)
+ hat_alpha_sum
Expand Down Expand Up @@ -770,8 +786,8 @@ impl<P: SchemeParams, I: Debug + Clone + Ord + Serialize> FinalizableToResult<I>
rng,
&P::signed_from_scalar(&self.context.gamma),
beta,
&s.to_mod(target_pk),
&r.to_mod(pk),
s.to_mod(target_pk),
r.to_mod(pk),
target_pk,
pk,
&self.all_cap_k[id_j],
Expand Down
6 changes: 3 additions & 3 deletions synedrion/src/cggmp21/protocols/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,14 +182,14 @@ impl<P: SchemeParams, I: Debug + Clone + Ord + Serialize> FinalizableToResult<I>
let target_pk = &self.aux_info.public_aux[id_j].paillier_pk;
let rp = &self.aux_info.public_aux[id_l].rp_params;

let values = &self.inputs.presigning.values.get(id_j).unwrap();
let values = self.inputs.presigning.values.get(id_j).unwrap();

let p_aff_g = AffGProof::<P>::new(
rng,
&P::signed_from_scalar(self.inputs.key_share.secret_share.expose_secret()),
&values.hat_beta,
&values.hat_s.to_mod(target_pk),
&values.hat_r.to_mod(pk),
values.hat_s.to_mod(target_pk),
values.hat_r.to_mod(pk),
target_pk,
pk,
&values.cap_k,
Expand Down
41 changes: 24 additions & 17 deletions synedrion/src/cggmp21/sigma/aff_g.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
//! Paillier Affine Operation with Group Commitment in Range ($\Pi^{aff-g}$, Section 6.2, Fig. 15)

use rand_core::CryptoRngCore;
use secrecy::{ExposeSecret, SecretBox};
use serde::{Deserialize, Serialize};

use super::super::SchemeParams;
Expand Down Expand Up @@ -59,9 +60,9 @@ impl<P: SchemeParams> AffGProof<P> {
pub fn new(
rng: &mut impl CryptoRngCore,
x: &Signed<<P::Paillier as PaillierParams>::Uint>,
y: &Signed<<P::Paillier as PaillierParams>::Uint>,
rho: &RandomizerMod<P::Paillier>,
rho_y: &RandomizerMod<P::Paillier>,
y: &SecretBox<Signed<<P::Paillier as PaillierParams>::Uint>>,
rho: RandomizerMod<P::Paillier>,
rho_y: RandomizerMod<P::Paillier>,
pk0: &PublicKeyPaillierPrecomputed<P::Paillier>,
pk1: &PublicKeyPaillierPrecomputed<P::Paillier>,
cap_c: &CiphertextMod<P::Paillier>,
Expand All @@ -72,7 +73,7 @@ impl<P: SchemeParams> AffGProof<P> {
aux: &impl Hashable,
) -> Self {
x.assert_bound(P::L_BOUND);
y.assert_bound(P::LP_BOUND);
y.expose_secret().assert_bound(P::LP_BOUND);
assert!(cap_c.public_key() == pk0);
assert!(cap_d.public_key() == pk0);
assert!(cap_y.public_key() == pk1);
Expand All @@ -96,14 +97,14 @@ impl<P: SchemeParams> AffGProof<P> {
let cap_b_x = P::scalar_from_signed(&alpha).mul_by_generator();
let cap_b_y =
CiphertextMod::new_with_randomizer_signed(pk1, &beta, &r_y_mod.retrieve()).retrieve();
let cap_e = setup.commit(&alpha, &gamma).retrieve();
let cap_s = setup.commit(x, &m).retrieve();
let cap_f = setup.commit(&beta, &delta).retrieve();
let cap_e = setup.commit(&alpha.into(), &gamma).retrieve();
let cap_s = setup.commit(&x.into(), &m).retrieve();
let cap_f = setup.commit(&beta.into(), &delta).retrieve();

// NOTE: deviation from the paper to support a different $D$
// (see the comment in `AffGProof`)
// Original: $s^y$. Modified: $s^{-y}$
let cap_t = setup.commit(&-y, &mu).retrieve();
let cap_t = setup.commit(&(-y.expose_secret()).into(), &mu).retrieve();

let mut reader = XofHasher::new_with_dst(HASH_TAG)
// commitments
Expand Down Expand Up @@ -135,7 +136,7 @@ impl<P: SchemeParams> AffGProof<P> {
// (see the comment in `AffGProof`)
// Original: $z_2 = \beta + e y$
// Modified: $z_2 = \beta - e y$
let z2 = beta + e * (-y);
let z2 = beta + e * (-y.expose_secret());

let z3 = gamma + e_wide * m;
let z4 = delta + e_wide * mu;
Expand Down Expand Up @@ -249,14 +250,16 @@ impl<P: SchemeParams> AffGProof<P> {
// s^{z_1} t^{z_3} = E S^e \mod \hat{N}
let cap_e_mod = self.cap_e.to_mod(aux_pk);
let cap_s_mod = self.cap_s.to_mod(aux_pk);
if setup.commit(&self.z1, &self.z3) != &cap_e_mod * &cap_s_mod.pow_signed_vartime(&e) {
if setup.commit(&self.z1.into(), &self.z3) != &cap_e_mod * &cap_s_mod.pow_signed_vartime(&e)
{
return false;
}

// s^{z_2} t^{z_4} = F T^e \mod \hat{N}
let cap_f_mod = self.cap_f.to_mod(aux_pk);
let cap_t_mod = self.cap_t.to_mod(aux_pk);
if setup.commit(&self.z2, &self.z4) != &cap_f_mod * &cap_t_mod.pow_signed_vartime(&e) {
if setup.commit(&self.z2.into(), &self.z4) != &cap_f_mod * &cap_t_mod.pow_signed_vartime(&e)
{
return false;
}

Expand All @@ -267,6 +270,7 @@ impl<P: SchemeParams> AffGProof<P> {
#[cfg(test)]
mod tests {
use rand_core::OsRng;
use secrecy::{ExposeSecret, SecretBox};

use super::AffGProof;
use crate::cggmp21::{SchemeParams, TestParams};
Expand All @@ -290,21 +294,24 @@ mod tests {
let aux: &[u8] = b"abcde";

let x = Signed::random_bounded_bits(&mut OsRng, Params::L_BOUND);
let y = Signed::random_bounded_bits(&mut OsRng, Params::LP_BOUND);
let y = SecretBox::new(Box::new(Signed::random_bounded_bits(
&mut OsRng,
Params::LP_BOUND,
)));

let rho = RandomizerMod::random(&mut OsRng, pk0);
let rho_y = RandomizerMod::random(&mut OsRng, pk1);
let secret = Signed::random(&mut OsRng);
let cap_c = CiphertextMod::new_signed(&mut OsRng, pk0, &secret);

let cap_d =
&cap_c * x + CiphertextMod::new_with_randomizer_signed(pk0, &-y, &rho.retrieve());
let cap_y = CiphertextMod::new_with_randomizer_signed(pk1, &y, &rho_y.retrieve());
let cap_d = &cap_c * x
+ CiphertextMod::new_with_randomizer_signed(pk0, &-y.expose_secret(), &rho.retrieve());
let cap_y =
CiphertextMod::new_with_randomizer_signed(pk1, y.expose_secret(), &rho_y.retrieve());
let cap_x = Params::scalar_from_signed(&x).mul_by_generator();

let proof = AffGProof::<Params>::new(
&mut OsRng, &x, &y, &rho, &rho_y, pk0, pk1, &cap_c, &cap_d, &cap_y, &cap_x, &setup,
&aux,
&mut OsRng, &x, &y, rho, rho_y, pk0, pk1, &cap_c, &cap_d, &cap_y, &cap_x, &setup, &aux,
);
assert!(proof.verify(pk0, pk1, &cap_c, &cap_d, &cap_y, &cap_x, &setup, &aux));
}
Expand Down
8 changes: 5 additions & 3 deletions synedrion/src/cggmp21/sigma/dec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ impl<P: SchemeParams> DecProof<P> {
let nu = Signed::random_bounded_bits_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);
let r = RandomizerMod::random(rng, pk0);

let cap_s = setup.commit(y, &mu).retrieve();
let cap_t = setup.commit(&alpha, &nu).retrieve();
let cap_s = setup.commit(&y.into(), &mu).retrieve();
let cap_t = setup.commit(&alpha.into(), &nu).retrieve();
let cap_a =
CiphertextMod::new_with_randomizer_signed(pk0, &alpha, &r.retrieve()).retrieve();
let gamma = P::scalar_from_signed(&alpha);
Expand Down Expand Up @@ -150,7 +150,9 @@ impl<P: SchemeParams> DecProof<P> {
// s^{z_1} t^{z_2} == T S^e
let cap_s_mod = self.cap_s.to_mod(setup.public_key());
let cap_t_mod = self.cap_t.to_mod(setup.public_key());
if setup.commit_wide(&self.z1, &self.z2) != &cap_t_mod * &cap_s_mod.pow_signed_vartime(&e) {
if setup.commit_wide(&self.z1.into(), &self.z2)
!= &cap_t_mod * &cap_s_mod.pow_signed_vartime(&e)
{
return false;
}

Expand Down
7 changes: 4 additions & 3 deletions synedrion/src/cggmp21/sigma/enc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ impl<P: SchemeParams> EncProof<P> {
let r = RandomizerMod::random(rng, pk0);
let gamma = Signed::random_bounded_bits_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);

let cap_s = setup.commit(k, &mu).retrieve();
let cap_s = setup.commit(&k.into(), &mu).retrieve();
let cap_a =
CiphertextMod::new_with_randomizer_signed(pk0, &alpha, &r.retrieve()).retrieve();
let cap_c = setup.commit(&alpha, &gamma).retrieve();
let cap_c = setup.commit(&alpha.into(), &gamma).retrieve();

let mut reader = XofHasher::new_with_dst(HASH_TAG)
// commitments
Expand Down Expand Up @@ -135,7 +135,8 @@ impl<P: SchemeParams> EncProof<P> {
// s^{z_1} t^{z_3} == C S^e \mod \hat{N}
let cap_c_mod = self.cap_c.to_mod(setup.public_key());
let cap_s_mod = self.cap_s.to_mod(setup.public_key());
if setup.commit(&self.z1, &self.z3) != &cap_c_mod * &cap_s_mod.pow_signed_vartime(&e) {
if setup.commit(&self.z1.into(), &self.z3) != &cap_c_mod * &cap_s_mod.pow_signed_vartime(&e)
{
return false;
}

Expand Down
Loading

0 comments on commit 6a38f1f

Please sign in to comment.