Skip to content

Commit

Permalink
Reduce the amount of different Ciphertext::homomorphic_mul methods
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Dec 17, 2024
1 parent f6ad957 commit f817f12
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 76 deletions.
2 changes: 1 addition & 1 deletion synedrion/src/cggmp21/interactive_signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,7 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round2<P, I> {
.all_cap_k
.get(destination)
.ok_or(LocalError::new("Missing destination={destination:?} in all_cap_k"))?
* secret_signed_from_scalar::<P>(&self.context.key_share.secret_share)
* &secret_signed_from_scalar::<P>(&self.context.key_share.secret_share)
+ Ciphertext::new_with_randomizer_signed(target_pk, &-&hat_beta, &hat_s);

let rp = &self.context.public_aux(destination)?.rp_params;
Expand Down
6 changes: 1 addition & 5 deletions synedrion/src/cggmp21/sigma/mul.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,7 @@ impl<P: SchemeParams> MulProof<P> {
}

// Y^z u^N = A * C^e \mod N^2
if cap_y
.homomorphic_mul_wide_public(&self.z)
.mul_masked_randomizer(&self.u)
!= self.cap_a.to_precomputed(pk) + cap_c * &e
{
if (cap_y * &self.z).mul_masked_randomizer(&self.u) != self.cap_a.to_precomputed(pk) + cap_c * &e {
return false;
}

Expand Down
92 changes: 22 additions & 70 deletions synedrion/src/paillier/encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,49 +304,23 @@ impl<P: PaillierParams> Ciphertext<P> {
// compared to what we would get if we used the signed `rhs` faithfully in the original formula.
// So if we want to replicate the Paillier encryption manually and get the same ciphertext
// (e.g. in the P_enc sigma-protocol), we need to process the sign correctly.
fn homomorphic_mul(self, rhs: &SecretSigned<P::Uint>) -> Self {
Self {
pk: self.pk,
ciphertext: self.ciphertext.pow(&rhs.to_wide()),
}
}

fn homomorphic_mul_ref_public(&self, rhs: &PublicSigned<P::Uint>) -> Self {
Self {
pk: self.pk.clone(),
ciphertext: self.ciphertext.pow(&rhs.to_wide()),
}
}

fn homomorphic_mul_public(self, rhs: &PublicSigned<P::Uint>) -> Self {
fn homomorphic_mul<V>(self, rhs: &V) -> Self
where
P::WideUintMod: Exponentiable<V>,
{
Self {
pk: self.pk,
ciphertext: self.ciphertext.pow(&rhs.to_wide()),
}
}

fn homomorphic_mul_ref(&self, rhs: &SecretSigned<P::Uint>) -> Self {
Self {
pk: self.pk.clone(),
ciphertext: self.ciphertext.pow(&rhs.to_wide()),
}
}

pub fn homomorphic_mul_wide_public(&self, rhs: &PublicSigned<P::WideUint>) -> Self {
// Unfortunately we cannot implement `Mul` for `SecretSigned<P::Uint>` and `SecretSigned<P::WideUint>`
// at the same time, since they can be the same type.
// But this method is only used once, so it's not a problem to spell it out.
Self {
pk: self.pk.clone(),
ciphertext: self.ciphertext.pow(rhs),
}
}

fn homomorphic_mul_unsigned_ref(&self, rhs: &SecretUnsigned<P::Uint>) -> Self {
let rhs_wide = rhs.to_wide();
fn homomorphic_mul_ref<V>(&self, rhs: &V) -> Self
where
P::WideUintMod: Exponentiable<V>,
{
Self {
pk: self.pk.clone(),
ciphertext: self.ciphertext.pow(&rhs_wide),
ciphertext: self.ciphertext.pow(rhs),
}
}

Expand Down Expand Up @@ -406,48 +380,26 @@ impl<P: PaillierParams> Add<&Ciphertext<P>> for Ciphertext<P> {
}
}

impl<P: PaillierParams> Mul<&PublicSigned<P::Uint>> for Ciphertext<P> {
type Output = Ciphertext<P>;
fn mul(self, rhs: &PublicSigned<P::Uint>) -> Ciphertext<P> {
self.homomorphic_mul_public(rhs)
}
}

impl<P: PaillierParams> Mul<&PublicSigned<P::Uint>> for &Ciphertext<P> {
type Output = Ciphertext<P>;
fn mul(self, rhs: &PublicSigned<P::Uint>) -> Ciphertext<P> {
self.homomorphic_mul_ref_public(rhs)
}
}

impl<P: PaillierParams> Mul<SecretSigned<P::Uint>> for Ciphertext<P> {
type Output = Ciphertext<P>;
fn mul(self, rhs: SecretSigned<P::Uint>) -> Ciphertext<P> {
self.homomorphic_mul(&rhs)
}
}

impl<P: PaillierParams> Mul<SecretSigned<P::Uint>> for &Ciphertext<P> {
impl<P: PaillierParams, V> Mul<&V> for Ciphertext<P>
where
P::WideUintMod: Exponentiable<V>,
{
type Output = Ciphertext<P>;
fn mul(self, rhs: SecretSigned<P::Uint>) -> Ciphertext<P> {
self.homomorphic_mul_ref(&rhs)
fn mul(self, rhs: &V) -> Ciphertext<P> {
self.homomorphic_mul(rhs)
}
}

impl<'a, P: PaillierParams> Mul<&'a SecretSigned<P::Uint>> for &Ciphertext<P> {
impl<P: PaillierParams, V> Mul<&V> for &Ciphertext<P>
where
P::WideUintMod: Exponentiable<V>,
{
type Output = Ciphertext<P>;
fn mul(self, rhs: &'a SecretSigned<P::Uint>) -> Ciphertext<P> {
fn mul(self, rhs: &V) -> Ciphertext<P> {
self.homomorphic_mul_ref(rhs)
}
}

impl<'a, P: PaillierParams> Mul<&'a SecretUnsigned<P::Uint>> for &Ciphertext<P> {
type Output = Ciphertext<P>;
fn mul(self, rhs: &'a SecretUnsigned<P::Uint>) -> Ciphertext<P> {
self.homomorphic_mul_unsigned_ref(rhs)
}
}

#[cfg(test)]
mod tests {
use crypto_bigint::{
Expand Down Expand Up @@ -556,7 +508,7 @@ mod tests {
let ciphertext = Ciphertext::<PaillierTest>::new(&mut OsRng, pk, &plaintext);

let coeff = SecretSigned::random_in_exp_range(&mut OsRng, <PaillierTest as PaillierParams>::Uint::BITS - 2);
let new_ciphertext = ciphertext * coeff.clone();
let new_ciphertext = ciphertext * &coeff;
let new_plaintext = new_ciphertext.decrypt(&sk);

assert_eq!(
Expand Down Expand Up @@ -615,7 +567,7 @@ mod tests {

let ciphertext1 = Ciphertext::<PaillierTest>::new(&mut OsRng, pk, &plaintext1);
let ciphertext3 = Ciphertext::<PaillierTest>::new(&mut OsRng, pk, &plaintext3);
let result = ciphertext1 * plaintext2.clone() + ciphertext3;
let result = ciphertext1 * &plaintext2 + ciphertext3;

let plaintext_back = result.decrypt(&sk);
assert_eq!(
Expand Down
1 change: 1 addition & 0 deletions synedrion/src/paillier/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ pub trait PaillierParams: core::fmt::Debug + PartialEq + Eq + Clone + Send + Syn

/// A modulo-residue counterpart of `WideUint`.
type WideUintMod: Monty<Integer = Self::WideUint>
+ PowBoundedExp<Self::Uint>
+ PowBoundedExp<Self::WideUint>
+ ConditionallyNegatable
+ ConditionallySelectable
Expand Down

0 comments on commit f817f12

Please sign in to comment.