Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use SecretBox for all secret values #144

Merged
merged 26 commits into from
Sep 30, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7b44069
Use more SecretBox-es
dvdplm Aug 23, 2024
7073b93
Remove TODO
dvdplm Aug 24, 2024
965aaf8
Use SecretBox for SecretKeyPaillier members
dvdplm Aug 24, 2024
bdeca27
CiphertextMod takes randomizer in a SecretBox
dvdplm Aug 24, 2024
1c668ef
SecretKeyPaillierPrecomputed::primes wrapped in SecretBox (and associ…
dvdplm Aug 26, 2024
7cdf476
SecretKeyPaillierPrecomputed::totient is wrapped in SecretBox
dvdplm Aug 26, 2024
1ca1671
Add comment on why `totient_nonzero` cannot be wrapped in a SecretBox…
dvdplm Aug 26, 2024
e4efcc1
Enable the `zeroize` feature of `crypto-bigint`
dvdplm Aug 27, 2024
1c28c15
SecretKeyPaillierPrecomputed::inv_totient is now wrapped in a `Secret…
dvdplm Aug 27, 2024
b388d9c
Cleanup
dvdplm Aug 27, 2024
5c107c6
Add question about commit_wide
dvdplm Aug 27, 2024
8ecd879
Impl Serialize for SecretKeyPaillier
dvdplm Aug 27, 2024
a0e9623
Make AffGProof rho and rho_y SecretBoxes
dvdplm Aug 27, 2024
28b36e9
Merge branch 'master' into dp-wrap-secrets-in-secretbox-77
dvdplm Aug 27, 2024
f4368b7
typo
dvdplm Aug 29, 2024
8e2ae99
Remove SecretBox around Randomizer and RandomizerMod given they are a…
dvdplm Sep 5, 2024
f72c393
Revert to passing references
dvdplm Sep 5, 2024
555cca7
Fix clippy complaints
dvdplm Sep 5, 2024
ed43266
Remove unneeded trait impls
dvdplm Sep 6, 2024
183bc7d
Test for debug output
dvdplm Sep 7, 2024
dcb95ce
Test secret paillier key serialization
dvdplm Sep 7, 2024
f5e4db8
Review feedback
dvdplm Sep 16, 2024
3386bb1
Impl PartialEq for SecretkeyPaillier
dvdplm Sep 16, 2024
01c7c03
Use secrecy 0.10
dvdplm Sep 18, 2024
5623b40
Merge branch 'master' into dp-wrap-secrets-in-secretbox-77
dvdplm Sep 26, 2024
66b313f
Cleanup
dvdplm Sep 26, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion synedrion/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ bip32 = { version = "0.5.2", default-features = false, features = ["alloc", "sec

# Note: `alloc` is needed for `crytpto-bigint`'s dependency `serdect` to be able
# to serialize Uints in human-readable formats.
crypto-bigint = { version = "0.5.3", default-features = false, features = ["serde", "alloc"] }
crypto-bigint = { version = "0.5.5", default-features = false, features = ["serde", "alloc", "zeroize"] }
crypto-primes = { version = "0.5", default-features = false }

serde = { version = "1", default-features = false, features = ["derive"] }
Expand Down
21 changes: 12 additions & 9 deletions synedrion/src/cggmp21/entities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,9 @@ 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_r: Randomizer<P::Paillier>,
pub(crate) hat_s: Randomizer<P::Paillier>,
pub(crate) hat_beta: SecretBox<Signed<<P::Paillier as PaillierParams>::Uint>>,
pub(crate) hat_r: SecretBox<Randomizer<P::Paillier>>,
pub(crate) hat_s: SecretBox<Randomizer<P::Paillier>>,
pub(crate) cap_k: CiphertextMod<P::Paillier>,
/// Received $\hat{D}_{i,j}$.
pub(crate) hat_cap_d_received: CiphertextMod<P::Paillier>,
Expand Down Expand Up @@ -331,22 +331,25 @@ impl<P: SchemeParams, I: Ord + Clone + PartialEq> PresigningData<P, I> {

for id_j in ids.iter().filter(|id| id != &id_i) {
let hat_beta = Signed::random_bounded_bits(rng, P::LP_BOUND);
let hat_s = RandomizerMod::random(rng, &public_keys[&id_j]).retrieve();
let hat_r = RandomizerMod::random(rng, pk_i).retrieve();
let hat_s = RandomizerMod::random(rng, &public_keys[&id_j])
.retrieve()
.secret_box();
let hat_r = RandomizerMod::random(rng, pk_i).retrieve().secret_box();

let hat_cap_d = &all_cap_k[id_j] * P::signed_from_scalar(x_i.expose_secret())
+ CiphertextMod::new_with_randomizer_signed(
&public_keys[&id_j],
&-hat_beta,
&hat_s,
hat_s.clone(),
dvdplm marked this conversation as resolved.
Show resolved Hide resolved
);
let hat_cap_f = CiphertextMod::new_with_randomizer_signed(pk_i, &hat_beta, &hat_r);
let hat_cap_f =
CiphertextMod::new_with_randomizer_signed(pk_i, &hat_beta, hat_r.clone());

let id_ij = (id_i.clone(), id_j.clone());
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 +371,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: hat_betas[&id_ij].secret_box(),
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
5 changes: 3 additions & 2 deletions synedrion/src/cggmp21/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ use crate::uint::{
};

use serde::{Deserialize, Serialize};
use zeroize::Zeroize;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
dvdplm marked this conversation as resolved.
Show resolved Hide resolved
pub struct PaillierTest;

impl PaillierParams for PaillierTest {
Expand Down Expand Up @@ -65,7 +66,7 @@ impl PaillierParams for PaillierTest {
type ExtraWideUint = U4096;
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize, Zeroize)]
pub struct PaillierProduction;

impl PaillierParams for PaillierProduction {
Expand Down
95 changes: 60 additions & 35 deletions synedrion/src/cggmp21/protocols/presigning.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,18 @@ impl<P: SchemeParams, I: Debug + Clone + Ord + Serialize> FirstRound<I> for Roun
let pk = aux_info.secret_aux.paillier_sk.public_key();

let nu = RandomizerMod::<P::Paillier>::random(rng, pk);
let cap_g =
CiphertextMod::new_with_randomizer(pk, &P::uint_from_scalar(&gamma), &nu.retrieve());
let cap_g = CiphertextMod::new_with_randomizer(
pk,
&P::uint_from_scalar(&gamma),
Box::new(nu.retrieve()).into(),
);

let rho = RandomizerMod::<P::Paillier>::random(rng, pk);
let cap_k =
CiphertextMod::new_with_randomizer(pk, &P::uint_from_scalar(&k), &rho.retrieve());
let cap_k = CiphertextMod::new_with_randomizer(
pk,
&P::uint_from_scalar(&k),
rho.retrieve().secret_box(),
);

Ok(Self {
context: Context {
Expand Down Expand Up @@ -295,12 +301,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: SecretBox<Randomizer<P::Paillier>>,
s: SecretBox<Randomizer<P::Paillier>>,
hat_r: SecretBox<Randomizer<P::Paillier>>,
hat_s: SecretBox<Randomizer<P::Paillier>>,
dvdplm marked this conversation as resolved.
Show resolved Hide resolved
cap_d: CiphertextMod<P::Paillier>,
cap_f: CiphertextMod<P::Paillier>,
hat_cap_d: CiphertextMod<P::Paillier>,
Expand Down Expand Up @@ -344,25 +350,41 @@ 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 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 beta = Signed::random_bounded_bits(rng, P::LP_BOUND).secret_box();
let hat_beta = Signed::random_bounded_bits(rng, P::LP_BOUND).secret_box();
let r = RandomizerMod::random(rng, pk).secret_box();
let s = RandomizerMod::random(rng, target_pk).secret_box();
let hat_r = RandomizerMod::random(rng, pk).secret_box();
let hat_s = RandomizerMod::random(rng, target_pk).secret_box();

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.expose_secret().retrieve().secret_box(),
);
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.expose_secret().retrieve().secret_box(),
dvdplm marked this conversation as resolved.
Show resolved Hide resolved
);

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.expose_secret().retrieve().secret_box(),
);
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.expose_secret().retrieve().secret_box(),
);

let public_aux = &self.context.aux_info.public_aux[destination];
let rp = &public_aux.rp_params;
Expand All @@ -371,8 +393,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.expose_secret(), // TODO(dp): Fix AffGProof
r.expose_secret(), // TODO(dp): Fix AffGProof
target_pk,
pk,
&self.all_cap_k[destination],
Expand All @@ -387,8 +409,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.expose_secret(),
hat_r.expose_secret(),
target_pk,
pk,
&self.all_cap_k[destination],
Expand Down Expand Up @@ -425,10 +447,10 @@ impl<P: SchemeParams, I: Debug + Clone + Ord + Serialize> Round<I> for Round2<P,
let artifact = Round2Artifact {
beta,
hat_beta,
r: r.retrieve(),
s: s.retrieve(),
hat_r: hat_r.retrieve(),
hat_s: hat_s.retrieve(),
r: r.expose_secret().retrieve().secret_box(), // TODO(dp): Ugggh, this is clunky af.
s: s.expose_secret().retrieve().secret_box(),
hat_r: hat_r.expose_secret().retrieve().secret_box(),
hat_s: hat_s.expose_secret().retrieve().secret_box(),
cap_d,
cap_f,
hat_cap_d,
Expand Down Expand Up @@ -542,14 +564,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();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how far should we go to protect the secrets? In this sum, for example, the safest way to do it is to actually write out an explicit loop mutating the sum inside a SecretBox.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I have the same concern and a poor intuition for what "good enough" means here.

By explicit loop, do you mean something like this?

       let beta_sum =
            artifacts
                .values()
                .fold(SecretBox::new(Box::new(Signed::default())), |mut sum, p| {
                    *sum.expose_secret_mut() = sum.expose_secret().add(p.beta.expose_secret());
                    sum
                });

In this case here I'm not so sure it's worth it. One line below we'd expose_secret again to add beta_sum to delta. But perhaps delta is a secret too? 😱

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 @@ -721,8 +746,8 @@ impl<P: SchemeParams, I: Debug + Clone + Ord + Serialize> FinalizableToResult<I>
.map(|(id, artifact)| {
let values = PresigningValues {
hat_beta: artifact.hat_beta,
hat_r: artifact.hat_r,
hat_s: artifact.hat_s,
hat_r: artifact.hat_r.expose_secret().clone().secret_box(),
hat_s: artifact.hat_s.expose_secret().clone().secret_box(),
cap_k: self.all_cap_k[&id].clone(),
hat_cap_d_received: self.hat_cap_ds[&id].clone(),
hat_cap_d: artifact.hat_cap_d,
Expand Down Expand Up @@ -770,8 +795,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.expose_secret().to_mod(target_pk),
&r.expose_secret().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.expose_secret().to_mod(target_pk),
&values.hat_r.expose_secret().to_mod(pk),
target_pk,
pk,
&values.cap_k,
Expand Down
Loading
Loading