Skip to content

Commit

Permalink
Group mul* inputs
Browse files Browse the repository at this point in the history
  • Loading branch information
fjarri committed Dec 19, 2024
1 parent 5422f23 commit a2fe42a
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 56 deletions.
29 changes: 21 additions & 8 deletions synedrion/src/cggmp21/interactive_signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use super::{
sigma::{
AffGProof, AffGPublicInputs, AffGSecretInputs, DecProof, DecPublicInputs, DecSecretInputs, EncProof,
EncPublicInputs, EncSecretInputs, LogStarProof, LogStarPublicInputs, LogStarSecretInputs, MulProof,
MulPublicInputs, MulSecretInputs, MulStarProof,
MulPublicInputs, MulSecretInputs, MulStarProof, MulStarPublicInputs, MulStarSecretInputs,
},
};
use crate::{
Expand Down Expand Up @@ -1297,17 +1297,30 @@ impl<P: SchemeParams, I: PartyId> Round<I> for Round4<P, I> {
let paux = self.context.public_aux(id_l)?;
let p_mul = MulStarProof::<P>::new(
rng,
&secret_signed_from_scalar::<P>(x),
&rho,
pk,
&self.presigning.cap_k,
&hat_cap_h,
cap_x,
MulStarSecretInputs {
x: &secret_signed_from_scalar::<P>(x),
rho: &rho,
},
MulStarPublicInputs {
pk0: pk,
cap_c: &self.presigning.cap_k,
cap_d: &hat_cap_h,
cap_x,
},
&paux.rp_params,
&aux,
);

assert!(p_mul.verify(pk, &self.presigning.cap_k, &hat_cap_h, cap_x, &paux.rp_params, &aux,));
assert!(p_mul.verify(
MulStarPublicInputs {
pk0: pk,
cap_c: &self.presigning.cap_k,
cap_d: &hat_cap_h,
cap_x
},
&paux.rp_params,
&aux,
));

mul_star_proofs.push((id_l.clone(), p_mul));
}
Expand Down
2 changes: 1 addition & 1 deletion synedrion/src/cggmp21/sigma.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ pub(crate) use fac::FacProof;
pub(crate) use log_star::{LogStarProof, LogStarPublicInputs, LogStarSecretInputs};
pub(crate) use mod_::ModProof;
pub(crate) use mul::{MulProof, MulPublicInputs, MulSecretInputs};
pub(crate) use mul_star::MulStarProof;
pub(crate) use mul_star::{MulStarProof, MulStarPublicInputs, MulStarSecretInputs};
pub(crate) use prm::PrmProof;
pub(crate) use sch::{SchCommitment, SchProof, SchSecret};
116 changes: 69 additions & 47 deletions synedrion/src/cggmp21/sigma/mul_star.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,25 @@ use crate::{

const HASH_TAG: &[u8] = b"P_mul*";

/**
ZK proof: Multiplication Paillier vs Group.
Secret inputs:
- $x \in +- 2^\ell$,
- $\rho$, a Paillier randomizer for the public key $N_0$.
Public inputs:
- Paillier public key $N_0$,
- Paillier ciphertext $C$ encrypted with $N_0$,
- Paillier ciphertext $D = (C (*) x) * \rho^{N_0} \mod N_0^2$,
- Point $X = g * x$, where $g$ is the curve generator,
- Setup parameters ($\hat{N}$, $s$, $t$).
*/
pub(crate) struct MulStarSecretInputs<'a, P: SchemeParams> {
/// $x \in +- 2^\ell$.
pub x: &'a SecretSigned<<P::Paillier as PaillierParams>::Uint>,
/// $\rho$, a Paillier randomizer for the public key $N_0$.
pub rho: &'a Randomizer<P::Paillier>,
}

pub(crate) struct MulStarPublicInputs<'a, P: SchemeParams> {
/// Paillier public key $N_0$.
pub pk0: &'a PublicKeyPaillier<P::Paillier>,
/// Paillier ciphertext $C$ encrypted with $N_0$.
pub cap_c: &'a Ciphertext<P::Paillier>,
/// Paillier ciphertext $D = (C (*) x) * \rho^{N_0} \mod N_0^2$.
pub cap_d: &'a Ciphertext<P::Paillier>,
/// Point $X = g * x$, where $g$ is the curve generator.
pub cap_x: &'a Point,
}

/// ZK proof: Multiplication Paillier vs Group.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct MulStarProof<P: SchemeParams> {
e: PublicSigned<<P::Paillier as PaillierParams>::Uint>,
Expand All @@ -49,12 +54,8 @@ impl<P: SchemeParams> MulStarProof<P> {
#[allow(clippy::too_many_arguments)]
pub fn new(
rng: &mut impl CryptoRngCore,
x: &SecretSigned<<P::Paillier as PaillierParams>::Uint>,
rho: &Randomizer<P::Paillier>,
pk0: &PublicKeyPaillier<P::Paillier>,
cap_c: &Ciphertext<P::Paillier>,
cap_d: &Ciphertext<P::Paillier>,
cap_x: &Point,
secret: MulStarSecretInputs<'_, P>,
public: MulStarPublicInputs<'_, P>,
setup: &RPParams<P::Paillier>,
aux: &impl Hashable,
) -> Self {
Expand All @@ -65,21 +66,21 @@ impl<P: SchemeParams> MulStarProof<P> {
- $\beta$ used to create $A$ is not mentioned anywhere else - a typo, it is effectively == 0
*/

x.assert_exponent_range(P::L_BOUND);
assert_eq!(cap_c.public_key(), pk0);
assert_eq!(cap_d.public_key(), pk0);
secret.x.assert_exponent_range(P::L_BOUND);
assert_eq!(public.cap_c.public_key(), public.pk0);
assert_eq!(public.cap_d.public_key(), public.pk0);

let hat_cap_n = setup.modulus(); // $\hat{N}$

let r = Randomizer::random(rng, pk0);
let r = Randomizer::random(rng, public.pk0);
let alpha = SecretSigned::random_in_exp_range(rng, P::L_BOUND + P::EPS_BOUND);
let gamma = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND + P::EPS_BOUND, hat_cap_n);
let m = SecretSigned::random_in_exp_range_scaled(rng, P::L_BOUND, hat_cap_n);

let cap_a = (cap_c * &alpha).mul_randomizer(&r).to_wire();
let cap_a = (public.cap_c * &alpha).mul_randomizer(&r).to_wire();
let cap_b_x = secret_scalar_from_signed::<P>(&alpha).mul_by_generator();
let cap_e = setup.commit(&alpha, &gamma).to_wire();
let cap_s = setup.commit(x, &m).to_wire();
let cap_s = setup.commit(secret.x, &m).to_wire();

let mut reader = XofHasher::new_with_dst(HASH_TAG)
// commitments
Expand All @@ -88,20 +89,20 @@ impl<P: SchemeParams> MulStarProof<P> {
.chain(&cap_e)
.chain(&cap_s)
// public parameters
.chain(pk0.as_wire())
.chain(&cap_c.to_wire())
.chain(&cap_d.to_wire())
.chain(cap_x)
.chain(public.pk0.as_wire())
.chain(&public.cap_c.to_wire())
.chain(&public.cap_d.to_wire())
.chain(public.cap_x)
.chain(&setup.to_wire())
.chain(aux)
.finalize_to_reader();

// Non-interactive challenge
let e = PublicSigned::from_xof_reader_bounded(&mut reader, &P::CURVE_ORDER);

let z1 = (alpha + x * e).to_public();
let z1 = (alpha + secret.x * e).to_public();
let z2 = (gamma + m * e.to_wide()).to_public();
let omega = rho.to_masked(&r, &e);
let omega = secret.rho.to_masked(&r, &e);

Self {
e,
Expand All @@ -119,15 +120,12 @@ impl<P: SchemeParams> MulStarProof<P> {
#[allow(clippy::too_many_arguments)]
pub fn verify(
&self,
pk0: &PublicKeyPaillier<P::Paillier>,
cap_c: &Ciphertext<P::Paillier>,
cap_d: &Ciphertext<P::Paillier>,
cap_x: &Point,
public: MulStarPublicInputs<'_, P>,
setup: &RPParams<P::Paillier>,
aux: &impl Hashable,
) -> bool {
assert_eq!(cap_c.public_key(), pk0);
assert_eq!(cap_d.public_key(), pk0);
assert_eq!(public.cap_c.public_key(), public.pk0);
assert_eq!(public.cap_d.public_key(), public.pk0);

let mut reader = XofHasher::new_with_dst(HASH_TAG)
// commitments
Expand All @@ -136,10 +134,10 @@ impl<P: SchemeParams> MulStarProof<P> {
.chain(&self.cap_e)
.chain(&self.cap_s)
// public parameters
.chain(pk0.as_wire())
.chain(&cap_c.to_wire())
.chain(&cap_d.to_wire())
.chain(cap_x)
.chain(public.pk0.as_wire())
.chain(&public.cap_c.to_wire())
.chain(&public.cap_d.to_wire())
.chain(public.cap_x)
.chain(&setup.to_wire())
.chain(aux)
.finalize_to_reader();
Expand All @@ -157,12 +155,16 @@ impl<P: SchemeParams> MulStarProof<P> {
}

// C (*) z_1 * \omega^{N_0} == A (+) D (*) e
if (cap_c * &self.z1).mul_masked_randomizer(&self.omega) != self.cap_a.to_precomputed(pk0) + cap_d * &e {
if (public.cap_c * &self.z1).mul_masked_randomizer(&self.omega)
!= self.cap_a.to_precomputed(public.pk0) + public.cap_d * &e
{
return false;
}

// g^{z_1} == B_x X^e
if scalar_from_signed::<P>(&self.z1).mul_by_generator() != self.cap_b_x + cap_x * &scalar_from_signed::<P>(&e) {
if scalar_from_signed::<P>(&self.z1).mul_by_generator()
!= self.cap_b_x + public.cap_x * &scalar_from_signed::<P>(&e)
{
return false;
}

Expand All @@ -181,7 +183,7 @@ impl<P: SchemeParams> MulStarProof<P> {
mod tests {
use rand_core::OsRng;

use super::MulStarProof;
use super::{MulStarProof, MulStarPublicInputs, MulStarSecretInputs};
use crate::{
cggmp21::{conversion::secret_scalar_from_signed, SchemeParams, TestParams},
paillier::{Ciphertext, RPParams, Randomizer, SecretKeyPaillierWire},
Expand All @@ -207,7 +209,27 @@ mod tests {
let cap_d = (&cap_c * &x).mul_randomizer(&rho);
let cap_x = secret_scalar_from_signed::<Params>(&x).mul_by_generator();

let proof = MulStarProof::<Params>::new(&mut OsRng, &x, &rho, pk, &cap_c, &cap_d, &cap_x, &setup, &aux);
assert!(proof.verify(pk, &cap_c, &cap_d, &cap_x, &setup, &aux));
let proof = MulStarProof::<Params>::new(
&mut OsRng,
MulStarSecretInputs { x: &x, rho: &rho },
MulStarPublicInputs {
pk0: pk,
cap_c: &cap_c,
cap_d: &cap_d,
cap_x: &cap_x,
},
&setup,
&aux,
);
assert!(proof.verify(
MulStarPublicInputs {
pk0: pk,
cap_c: &cap_c,
cap_d: &cap_d,
cap_x: &cap_x
},
&setup,
&aux
));
}
}

0 comments on commit a2fe42a

Please sign in to comment.