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

116 AuxInfo Tests #472

Merged
merged 19 commits into from
Sep 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 14 additions & 17 deletions src/auxinfo/participant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::{
auxinfo::{
auxinfo_commit::{Commitment, CommitmentScheme},
info::{AuxInfoPrivate, AuxInfoPublic, AuxInfoWitnesses},
proof::AuxInfoProof,
proof::{AuxInfoProof, CommonInput},
Output,
},
broadcast::participant::{BroadcastOutput, BroadcastParticipant, BroadcastTag},
Expand Down Expand Up @@ -493,23 +493,18 @@ impl AuxInfoParticipant {

let witness = self.local_storage.retrieve::<storage::Witnesses>(self.id)?;
let product = &witness.p * &witness.q;

self.other_participant_ids
.iter()
.map(|&pid| {
// Grab the other participant's decommitment record from storage...
let verifier_decommit = self.local_storage.retrieve::<storage::Decommit>(pid)?;
let setup_params = verifier_decommit.clone().into_public();
let params = setup_params.params();
let shared_context = &self.retrieve_context();
// ... and use its setup parameters in the proof.
let proof = AuxInfoProof::prove(
rng,
&self.retrieve_context(),
sid,
global_rid,
verifier_decommit.clone().into_public().params(),
&product,
&witness.p,
&witness.q,
)?;
let common_input =
CommonInput::new(shared_context, sid, global_rid, params, &product);
let proof = AuxInfoProof::prove(rng, &common_input, &witness.p, &witness.q)?;
Message::new(
MessageType::Auxinfo(AuxinfoMessageType::R3Proof),
sid,
Expand Down Expand Up @@ -552,15 +547,17 @@ impl AuxInfoParticipant {
let my_public = self.local_storage.retrieve::<storage::Public>(self.id)?;

let proof = AuxInfoProof::from_message(message)?;
// Verify the public parameters for the given participant. Note that
// this verification verifies _both_ the `𝚷[mod]` and `𝚷[fac]` proofs.
proof.verify(
&self.retrieve_context(),
let shared_context = &self.retrieve_context();
let common_input = CommonInput::new(
shared_context,
message.id(),
*global_rid,
my_public.params(),
auxinfo_pub.pk().modulus(),
)?;
);
// Verify the public parameters for the given participant. Note that
// this verification verifies _both_ the `𝚷[mod]` and `𝚷[fac]` proofs.
proof.verify(&common_input)?;

self.local_storage
.store::<storage::Public>(message.from(), auxinfo_pub);
Expand Down
202 changes: 177 additions & 25 deletions src/auxinfo/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,35 @@ pub(crate) struct AuxInfoProof {
pifac: pifac::PiFacProof,
}

/// Common input and setup parameters known to both the prover and the verifier.
#[derive(Clone)]
pub(crate) struct CommonInput<'a> {
shared_context: &'a <AuxInfoParticipant as InnerProtocolParticipant>::Context,
sid: Identifier,
rho: [u8; 32],
setup_parameters: &'a VerifiedRingPedersen,
modulus: &'a BigNumber,
}

impl<'a> CommonInput<'a> {
/// Collect common parameters for proving or verifying a [`AuxInfoProof`]
pub(crate) fn new(
shared_context: &'a <AuxInfoParticipant as InnerProtocolParticipant>::Context,
sid: Identifier,
rho: [u8; 32],
verifier_setup_parameters: &'a VerifiedRingPedersen,
modulus: &'a BigNumber,
) -> CommonInput<'a> {
Self {
shared_context,
sid,
rho,
setup_parameters: verifier_setup_parameters,
modulus,
}
}
}

impl AuxInfoProof {
marsella marked this conversation as resolved.
Show resolved Hide resolved
/// Generate a fresh transcript to be used in [`AuxInfoProof`].
fn new_transcript() -> Transcript {
Expand All @@ -56,28 +85,34 @@ impl AuxInfoProof {
#[allow(clippy::too_many_arguments)]
pub(crate) fn prove<R: RngCore + CryptoRng>(
rng: &mut R,
context: &<AuxInfoParticipant as InnerProtocolParticipant>::Context,
sid: Identifier,
rho: [u8; 32],
verifier_params: &VerifiedRingPedersen,
N: &BigNumber,
common_input: &CommonInput,
p: &BigNumber,
q: &BigNumber,
) -> Result<Self> {
let mut transcript = Self::new_transcript();
Self::append_pimod_transcript(&mut transcript, context, sid, rho)?;
Self::append_pimod_transcript(
&mut transcript,
common_input.shared_context,
common_input.sid,
common_input.rho,
)?;
let pimod = pimod::PiModProof::prove(
pimod::CommonInput::new(N),
pimod::CommonInput::new(common_input.modulus),
pimod::ProverSecret::new(p, q),
context,
common_input.shared_context,
&mut transcript,
rng,
)?;
Self::append_pifac_transcript(&mut transcript, context, sid, rho)?;
Self::append_pifac_transcript(
&mut transcript,
common_input.shared_context,
common_input.sid,
common_input.rho,
)?;
let pifac = pifac::PiFacProof::prove(
pifac::CommonInput::new(verifier_params, N),
pifac::CommonInput::new(common_input.setup_parameters, common_input.modulus),
pifac::ProverSecret::new(p, q),
context,
common_input.shared_context,
&mut transcript,
rng,
)?;
Expand All @@ -91,22 +126,28 @@ impl AuxInfoProof {
///
/// Note: The [`VerifiedRingPedersen`] argument **must be** provided by the
/// verifier!
pub(crate) fn verify(
self,
context: &<AuxInfoParticipant as InnerProtocolParticipant>::Context,
sid: Identifier,
rho: [u8; 32],
verifier_params: &VerifiedRingPedersen,
N: &BigNumber,
) -> Result<()> {
pub(crate) fn verify(self, common_input: &CommonInput) -> Result<()> {
let mut transcript = Self::new_transcript();
Self::append_pimod_transcript(&mut transcript, context, sid, rho)?;
self.pimod
.verify(pimod::CommonInput::new(N), context, &mut transcript)?;
Self::append_pifac_transcript(&mut transcript, context, sid, rho)?;
Self::append_pimod_transcript(
&mut transcript,
common_input.shared_context,
common_input.sid,
common_input.rho,
)?;
self.pimod.verify(
pimod::CommonInput::new(common_input.modulus),
common_input.shared_context,
&mut transcript,
)?;
Self::append_pifac_transcript(
&mut transcript,
common_input.shared_context,
common_input.sid,
common_input.rho,
)?;
self.pifac.verify(
pifac::CommonInput::new(verifier_params, N),
context,
pifac::CommonInput::new(common_input.setup_parameters, common_input.modulus),
common_input.shared_context,
&mut transcript,
)?;
Ok(())
Expand Down Expand Up @@ -142,3 +183,114 @@ impl AuxInfoProof {
Ok(())
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::{paillier::prime_gen, protocol::SharedContext, utils::testing::init_testing};
use rand::{rngs::StdRng, Rng, SeedableRng};

fn random_auxinfo_proof<R: RngCore + CryptoRng>(
rng: &mut R,
test_code: impl FnOnce(CommonInput, AuxInfoProof) -> Result<()>,
) -> Result<()> {
let sid = Identifier::random(rng);
let rho = rng.gen();
let setup_params = VerifiedRingPedersen::gen(rng, &()).unwrap();
let (p, q) = prime_gen::get_prime_pair_from_pool_insecure(rng).unwrap();
let modulus = &p * &q;
let shared_context = SharedContext::random(rng);
let common_input = CommonInput::new(&shared_context, sid, rho, &setup_params, &modulus);
let proof = AuxInfoProof::prove(rng, &common_input, &p, &q).unwrap();
test_code(common_input, proof)
}

#[test]
fn auxinfo_proof_verifies() -> Result<()> {
let mut rng = init_testing();
let sid = Identifier::random(&mut rng);
let rho = rng.gen();
let setup_params = VerifiedRingPedersen::gen(&mut rng, &())?;
let (p, q) = prime_gen::get_prime_pair_from_pool_insecure(&mut rng).unwrap();
let modulus = &p * &q;
let shared_context = SharedContext::random(&mut rng);
let common_input = CommonInput::new(&shared_context, sid, rho, &setup_params, &modulus);
let proof = AuxInfoProof::prove(&mut rng, &common_input, &p, &q)?;
assert!(proof.verify(&common_input).is_ok());
Ok(())
}

#[test]
fn each_constituent_proof_must_be_valid() -> Result<()> {
marsella marked this conversation as resolved.
Show resolved Hide resolved
let mut rng = init_testing();
let mut rng2 = StdRng::from_rng(&mut rng).unwrap();
let f = |input: CommonInput, proof: AuxInfoProof| {
let f1 = |input1: CommonInput, proof1: AuxInfoProof| {
let mix_one = AuxInfoProof {
pifac: proof.pifac,
pimod: proof1.pimod,
};
let mix_two = AuxInfoProof {
pifac: proof1.pifac,
pimod: proof.pimod,
};
assert!(mix_one.verify(&input).is_err());
assert!(mix_two.verify(&input1).is_err());
Ok(())
};
random_auxinfo_proof(&mut rng2, f1)?;
Ok(())
};
random_auxinfo_proof(&mut rng, f)?;
Ok(())
}

#[test]
fn modulus_factors_must_be_correct() -> Result<()> {
let mut rng = init_testing();
let sid = Identifier::random(&mut rng);
let rho = rng.gen();
let setup_params = VerifiedRingPedersen::gen(&mut rng, &())?;
let (p, q) = prime_gen::get_prime_pair_from_pool_insecure(&mut rng).unwrap();
let (p1, q1) = prime_gen::get_prime_pair_from_pool_insecure(&mut rng).unwrap();
let modulus = &p * &q;
let shared_context = &SharedContext::random(&mut rng);
let common_input = CommonInput::new(shared_context, sid, rho, &setup_params, &modulus);
match AuxInfoProof::prove(&mut rng, &common_input, &p1, &q1) {
Ok(proof) => assert!(proof.verify(&common_input).is_err()),
Err(_) => return Ok(()),
}
Ok(())
}

#[test]
fn context_must_be_correct() -> Result<()> {
let mut rng = init_testing();
let sid = Identifier::random(&mut rng);
let rho = rng.gen();
let setup_params = VerifiedRingPedersen::gen(&mut rng, &())?;
let (p, q) = prime_gen::get_prime_pair_from_pool_insecure(&mut rng).unwrap();
let modulus = &p * &q;
let shared_context = &SharedContext::random(&mut rng);
let bad_shared_context = &SharedContext::random(&mut rng);
let common_input = CommonInput {
shared_context,
sid,
rho,
setup_parameters: &setup_params,
modulus: &modulus,
};
let bad_common_input = CommonInput {
shared_context: bad_shared_context,
sid,
rho,
setup_parameters: &setup_params,
modulus: &modulus,
};
match AuxInfoProof::prove(&mut rng, &common_input, &p, &q) {
Ok(proof) => assert!(proof.verify(&bad_common_input).is_err()),
Err(_) => return Ok(()),
}
Ok(())
}
}
19 changes: 18 additions & 1 deletion src/protocol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ impl ParticipantIdentifier {

/// The `SharedContext` contains fixed known parameters across the entire
/// protocol. It does not however contain the entire protocol context.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub(crate) struct SharedContext {
sid: Identifier,
participants: Vec<ParticipantIdentifier>,
Expand All @@ -511,6 +511,23 @@ impl ProofContext for SharedContext {
}

impl SharedContext {
/// This function should not be used outside of the tests.
#[cfg(test)]
pub fn random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
let sid = Identifier::random(rng);
let participant = ParticipantIdentifier::random(rng);
let participant2 = ParticipantIdentifier::random(rng);
let participants = vec![participant, participant2];
let generator = CurvePoint::GENERATOR;
let order = k256_order();
SharedContext {
sid,
participants,
generator,
order,
}
}

pub(crate) fn collect<P: InnerProtocolParticipant>(p: &P) -> Self {
let mut participants = p.all_participants();
participants.sort();
Expand Down