Skip to content

Commit

Permalink
Use Secret everywhere, remove redundant trait impls
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Nov 28, 2024
1 parent 0a8bb7b commit b5a62ab
Show file tree
Hide file tree
Showing 10 changed files with 97 additions and 140 deletions.
14 changes: 9 additions & 5 deletions synedrion/src/cggmp21/sigma/aff_g.rs
Original file line number Diff line number Diff line change
@@ -1,7 +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 secrecy::ExposeSecret;
use serde::{Deserialize, Serialize};

use super::super::SchemeParams;
Expand All @@ -11,7 +11,10 @@ use crate::{
Ciphertext, CiphertextWire, PaillierParams, PublicKeyPaillier, RPCommitmentWire, RPParams, Randomizer,
RandomizerWire,
},
tools::hashing::{Chain, Hashable, XofHasher},
tools::{
hashing::{Chain, Hashable, XofHasher},
Secret,
},
uint::Signed,
};

Expand Down Expand Up @@ -62,7 +65,7 @@ impl<P: SchemeParams> AffGProof<P> {
pub fn new(
rng: &mut impl CryptoRngCore,
x: &Signed<<P::Paillier as PaillierParams>::Uint>,
y: &SecretBox<Signed<<P::Paillier as PaillierParams>::Uint>>,
y: &Secret<Signed<<P::Paillier as PaillierParams>::Uint>>,
rho: Randomizer<P::Paillier>,
rho_y: Randomizer<P::Paillier>,
pk0: &PublicKeyPaillier<P::Paillier>,
Expand Down Expand Up @@ -263,12 +266,13 @@ impl<P: SchemeParams> AffGProof<P> {
#[cfg(test)]
mod tests {
use rand_core::OsRng;
use secrecy::{ExposeSecret, SecretBox};
use secrecy::ExposeSecret;

use super::AffGProof;
use crate::{
cggmp21::{SchemeParams, TestParams},
paillier::{Ciphertext, RPParams, Randomizer, SecretKeyPaillierWire},
tools::Secret,
uint::Signed,
};

Expand All @@ -288,7 +292,7 @@ mod tests {
let aux: &[u8] = b"abcde";

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

let rho = Randomizer::random(&mut OsRng, pk0);
let rho_y = Randomizer::random(&mut OsRng, pk1);
Expand Down
7 changes: 5 additions & 2 deletions synedrion/src/cggmp21/sigma/fac.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use serde::{Deserialize, Serialize};
use super::super::SchemeParams;
use crate::{
paillier::{PaillierParams, PublicKeyPaillier, RPCommitmentWire, RPParams, SecretKeyPaillier},
tools::hashing::{Chain, Hashable, XofHasher},
tools::{
hashing::{Chain, Hashable, XofHasher},
Secret,
},
uint::{Bounded, Integer, Signed},
};

Expand Down Expand Up @@ -161,7 +164,7 @@ impl<P: SchemeParams> FacProof<P> {
}

// R = s^{N_0} t^\sigma
let cap_r = &setup.commit_xwide(&pk0.modulus_bounded().into(), &self.sigma);
let cap_r = &setup.commit_xwide(&Secret::init_with(|| pk0.modulus_bounded()), &self.sigma);

// s^{z_1} t^{\omega_1} == A * P^e \mod \hat{N}
let cap_a_mod = self.cap_a.to_precomputed(setup);
Expand Down
4 changes: 2 additions & 2 deletions synedrion/src/cggmp21/sigma/sch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//! where $g$ is a EC generator.
use rand_core::CryptoRngCore;
use secrecy::{ExposeSecret, SecretBox};
use secrecy::ExposeSecret;
use serde::{Deserialize, Serialize};
use zeroize::ZeroizeOnDrop;

Expand All @@ -27,7 +27,7 @@ pub(crate) struct SchSecret(

impl SchSecret {
pub fn random(rng: &mut impl CryptoRngCore) -> Self {
Self(SecretBox::init_with(|| Scalar::random(rng)).into())
Self(Secret::init_with(|| Scalar::random(rng)))
}
}

Expand Down
11 changes: 2 additions & 9 deletions synedrion/src/curve/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,9 @@ use k256::{
Secp256k1,
};
use rand_core::CryptoRngCore;
use secrecy::{CloneableSecret, SerializableSecret};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use serde_encoded_bytes::{Hex, SliceLike};
use zeroize::DefaultIsZeroes;
use zeroize::Zeroize;

use crate::tools::{
hashing::{Chain, HashableType},
Expand Down Expand Up @@ -57,7 +56,7 @@ impl HashableType for Curve {
}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, PartialOrd, Ord)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, PartialOrd, Ord, Zeroize)]
pub struct Scalar(BackendScalar);

impl Scalar {
Expand Down Expand Up @@ -173,12 +172,6 @@ impl<'de> Deserialize<'de> for Scalar {
}
}

impl DefaultIsZeroes for Scalar {}

impl CloneableSecret for Scalar {}

impl SerializableSecret for Scalar {}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Point(BackendPoint);

Expand Down
53 changes: 26 additions & 27 deletions synedrion/src/paillier/keys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use core::{

use crypto_bigint::{InvMod, Monty, Odd, ShrVartime, Square, WrappingAdd};
use rand_core::CryptoRngCore;
use secrecy::{ExposeSecret, ExposeSecretMut, SecretBox};
use secrecy::{ExposeSecret, ExposeSecretMut};
use serde::{Deserialize, Serialize};

use super::{
Expand Down Expand Up @@ -74,10 +74,10 @@ where
let primes = secret_key.primes.into_precomputed();
let modulus = primes.modulus_wire().into_precomputed();

let monty_params_mod_p = P::HalfUintMod::new_params_vartime(*primes.p_half_odd().expose_secret());
let monty_params_mod_q = P::HalfUintMod::new_params_vartime(*primes.q_half_odd().expose_secret());
let monty_params_mod_p = P::HalfUintMod::new_params_vartime(primes.p_half_odd().expose_secret().clone());
let monty_params_mod_q = P::HalfUintMod::new_params_vartime(primes.q_half_odd().expose_secret().clone());

let inv_totient = SecretBox::init_with(|| {
let inv_totient = Secret::init_with(|| {
primes
.totient()
.expose_secret()
Expand All @@ -87,64 +87,63 @@ where
"The modulus is pq. ϕ(pq) = (p-1)(q-1) is invertible mod pq because ",
"neither (p-1) nor (q-1) share factors with pq."
])
})
.into();
});

let inv_modulus = SecretBox::init_with(|| {
let inv_modulus = Secret::init_with(|| {
Bounded::new(
(*modulus.modulus())
.inv_mod(primes.totient().expose_secret())
.expect("pq is invertible mod ϕ(pq) because gcd(pq, (p-1)(q-1)) = 1"),
P::MODULUS_BITS,
)
.expect("We assume `P::MODULUS_BITS` is properly configured")
})
.into();
});

let inv_p_mod_q = Secret::from(SecretBox::init_with(|| {
let inv_p_mod_q = Secret::init_with(|| {
primes
.p_half()
.expose_secret()
.clone()
// NOTE: `monty_params_mod_q` is cloned here and can remain on the stack.
// See https://github.com/RustCrypto/crypto-bigint/issues/704
.to_montgomery(&monty_params_mod_q)
.invert()
.expect("All non-zero integers mod a prime have a multiplicative inverse")
}));
});

// Calculate $u$ such that $u = -1 \mod p$ and $u = 1 \mod q$.
// Using one step of Garner's algorithm:
// $u = p - 1 + p (2 p^{-1} - 1 \mod q)$

// Calculate $t = 2 p^{-1} - 1 \mod q$

let one = SecretBox::init_with(|| {
let one = Secret::init_with(|| {
// NOTE: `monty_params_mod_q` is cloned here and can remain on the stack.
// See https://github.com/RustCrypto/crypto-bigint/issues/704
P::HalfUintMod::one(monty_params_mod_q.clone())
});
let mut t_mod = inv_p_mod_q.clone();
t_mod.expose_secret_mut().add_assign(inv_p_mod_q.expose_secret());
t_mod.expose_secret_mut().sub_assign(one.expose_secret());
let t = SecretBox::init_with(|| t_mod.expose_secret().retrieve());
let t = Secret::init_with(|| t_mod.expose_secret().retrieve());

// Calculate $u$
// I am not entirely sure if it can be used to learn something about `p` and `q`,
// so just to be on the safe side it lives in the secret key.

let u = SecretBox::init_with(|| t.expose_secret().mul_wide(primes.p_half().expose_secret()));
let u = SecretBox::init_with(|| {
let u = Secret::init_with(|| t.expose_secret().mul_wide(primes.p_half().expose_secret()));
let u = Secret::init_with(|| {
u.expose_secret()
.checked_add(primes.p().expose_secret())
.expect("does not overflow by construction")
});
let u = SecretBox::init_with(|| {
let u = Secret::init_with(|| {
u.expose_secret()
.checked_sub(&<P::Uint as Integer>::one())
.expect("does not overflow by construction")
});
let nonsquare_sampling_constant =
SecretBox::init_with(|| P::UintMod::new(*u.expose_secret(), modulus.monty_params_mod_n().clone())).into();
Secret::init_with(|| P::UintMod::new(*u.expose_secret(), modulus.monty_params_mod_n().clone()));

let public_key = PublicKeyPaillier::new(modulus);

Expand All @@ -166,30 +165,30 @@ where
}
}

pub fn p_signed(&self) -> SecretBox<Signed<P::Uint>> {
pub fn p_signed(&self) -> Secret<Signed<P::Uint>> {
self.primes.p_signed()
}

pub fn q_signed(&self) -> SecretBox<Signed<P::Uint>> {
pub fn q_signed(&self) -> Secret<Signed<P::Uint>> {
self.primes.q_signed()
}

pub fn p_wide_signed(&self) -> SecretBox<Signed<P::WideUint>> {
pub fn p_wide_signed(&self) -> Secret<Signed<P::WideUint>> {
self.primes.p_wide_signed()
}

/// Returns Euler's totient function (`φ(n)`) of the modulus, wrapped in a [`SecretBox`].
pub fn totient_wide_bounded(&self) -> SecretBox<Bounded<P::WideUint>> {
/// Returns Euler's totient function (`φ(n)`) of the modulus, wrapped in a [`Secret`].
pub fn totient_wide_bounded(&self) -> Secret<Bounded<P::WideUint>> {
self.primes.totient_wide_bounded()
}

/// Returns $\phi(N)^{-1} \mod N$
pub fn inv_totient(&self) -> &SecretBox<P::UintMod> {
pub fn inv_totient(&self) -> &Secret<P::UintMod> {
&self.inv_totient
}

/// Returns $N^{-1} \mod \phi(N)$
pub fn inv_modulus(&self) -> &SecretBox<Bounded<P::Uint>> {
pub fn inv_modulus(&self) -> &Secret<Bounded<P::Uint>> {
&self.inv_modulus
}

Expand All @@ -213,12 +212,12 @@ where
(p_rem_mod, q_rem_mod)
}

fn sqrt_part(&self, x: &P::HalfUintMod, modulus: &SecretBox<P::HalfUint>) -> Option<P::HalfUintMod> {
fn sqrt_part(&self, x: &P::HalfUintMod, modulus: &Secret<P::HalfUint>) -> Option<P::HalfUintMod> {
// Both `p` and `q` are safe primes, so they're 3 mod 4.
// This means that if square root exists, it must be of the form `+/- x^((modulus+1)/4)`.
// Also it means that `(modulus+1)/4 == modulus/4+1`
// (this will help avoid a possible overflow).
let power = SecretBox::init_with(|| {
let power = Secret::init_with(|| {
modulus
.expose_secret()
.wrapping_shr_vartime(2)
Expand Down Expand Up @@ -252,7 +251,7 @@ where
let (a_mod_p, b_mod_q) = rns;

let a_half = a_mod_p.retrieve();
let a_mod_q = a_half.to_montgomery(&self.monty_params_mod_q);
let a_mod_q = a_half.clone().to_montgomery(&self.monty_params_mod_q);
let x = ((b_mod_q.clone() - a_mod_q) * self.inv_p_mod_q.expose_secret()).retrieve();
let a = a_half.into_wide();

Expand Down
8 changes: 5 additions & 3 deletions synedrion/src/paillier/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crypto_bigint::{
};
use crypto_primes::RandomPrimeWithRng;
use serde::{Deserialize, Serialize};
use zeroize::{DefaultIsZeroes, Zeroize};
use zeroize::Zeroize;

#[cfg(test)]
use crate::uint::{U1024Mod, U2048Mod, U512Mod, U1024, U2048, U4096, U512};
Expand All @@ -17,8 +17,10 @@ use crate::{
pub trait PaillierParams: core::fmt::Debug + PartialEq + Eq + Clone + Send + Sync {
/// The size of one of the pair of RSA primes.
const PRIME_BITS: u32;

/// The size of the RSA modulus (a product of two primes).
const MODULUS_BITS: u32 = Self::PRIME_BITS * 2;

/// An integer that fits a single RSA prime.
type HalfUint: Integer<Monty = Self::HalfUintMod>
+ Bounded
Expand All @@ -28,8 +30,7 @@ pub trait PaillierParams: core::fmt::Debug + PartialEq + Eq + Clone + Send + Syn
+ for<'de> Deserialize<'de>
+ HasWide<Wide = Self::Uint>
+ ToMontgomery
+ Zeroize
+ DefaultIsZeroes;
+ Zeroize;

/// A modulo-residue counterpart of `HalfUint`.
type HalfUintMod: Monty<Integer = Self::HalfUint>
Expand All @@ -51,6 +52,7 @@ pub trait PaillierParams: core::fmt::Debug + PartialEq + Eq + Clone + Send + Syn
+ for<'de> Deserialize<'de>
+ ToMontgomery
+ Zeroize;

/// A modulo-residue counterpart of `Uint`.
type UintMod: ConditionallySelectable
+ Exponentiable<Self::Uint>
Expand Down
15 changes: 7 additions & 8 deletions synedrion/src/paillier/ring_pedersen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use core::ops::Mul;

use crypto_bigint::{Monty, NonZero, RandomMod, ShrVartime};
use rand_core::CryptoRngCore;
use secrecy::{ExposeSecret, SecretBox};
use secrecy::ExposeSecret;
use serde::{Deserialize, Serialize};

use super::{
Expand All @@ -26,28 +26,27 @@ impl<P: PaillierParams> RPSecret<P> {
pub fn random(rng: &mut impl CryptoRngCore) -> Self {
let primes = SecretPrimesWire::<P>::random_safe(rng).into_precomputed();

let bound = SecretBox::init_with(|| {
let bound = Secret::init_with(|| {
NonZero::new(primes.totient().expose_secret().wrapping_shr_vartime(2))
.expect("totient / 4 is still non-zero because p, q >= 5")
});
let lambda = SecretBox::init_with(|| {
let lambda = Secret::init_with(|| {
Bounded::new(P::Uint::random_mod(rng, bound.expose_secret()), P::MODULUS_BITS - 2)
.expect("totient < N < 2^MODULUS_BITS, so totient / 4 < 2^(MODULUS_BITS - 2)")
})
.into();
});

Self { primes, lambda }
}

pub fn lambda(&self) -> &SecretBox<Bounded<P::Uint>> {
pub fn lambda(&self) -> &Secret<Bounded<P::Uint>> {
&self.lambda
}

pub fn random_field_elem(&self, rng: &mut impl CryptoRngCore) -> Bounded<P::Uint> {
self.primes.random_field_elem(rng)
}

pub fn totient_nonzero(&self) -> SecretBox<NonZero<P::Uint>> {
pub fn totient_nonzero(&self) -> Secret<NonZero<P::Uint>> {
self.primes.totient_nonzero()
}
}
Expand Down Expand Up @@ -112,7 +111,7 @@ impl<P: PaillierParams> RPParams<P> {

pub fn commit_xwide(
&self,
secret: &SecretBox<Bounded<P::Uint>>,
secret: &Secret<Bounded<P::Uint>>,
randomizer: &Signed<P::ExtraWideUint>,
) -> RPCommitment<P> {
// $t^\rho * s^m mod N$ where $\rho$ is the randomizer and $m$ is the secret.
Expand Down
Loading

0 comments on commit b5a62ab

Please sign in to comment.