diff --git a/bbs_plus/src/proof.rs b/bbs_plus/src/proof.rs index 3be476cd..d0f13860 100644 --- a/bbs_plus/src/proof.rs +++ b/bbs_plus/src/proof.rs @@ -152,6 +152,8 @@ pub struct PoKOfSignatureG1Proof { /// Proof of relation `g1 + h1*m1 + h2*m2 +.... + h_i*m_i` = `d*r3 + {h_0}*{-s'} + h1*{-m1} + h2*{-m2} + .... + h_j*{-m_j}` for all disclosed messages `m_i` and for all undisclosed messages `m_j` #[serde_as(as = "ArkObjectBytes")] pub T2: E::G1Affine, + /// The following could be achieved by using Either but serialization + /// for Either is not supported out of the box and had to be implemented pub sc_resp_2: Option>, pub sc_partial_resp_2: Option>, } diff --git a/bbs_plus/src/proof_23_cdl.rs b/bbs_plus/src/proof_23_cdl.rs index 0625f977..5cea7a06 100644 --- a/bbs_plus/src/proof_23_cdl.rs +++ b/bbs_plus/src/proof_23_cdl.rs @@ -104,6 +104,8 @@ pub struct PoKOfSignature23G1Proof { /// Proof of relation `g1 + h1*m1 + h2*m2 +.... + h_i*m_i` = `d*r3 + h1*{-m1} + h2*{-m2} + .... + h_j*{-m_j}` for all disclosed messages `m_i` and for all undisclosed messages `m_j` #[serde_as(as = "ArkObjectBytes")] pub T2: E::G1Affine, + /// The following could be achieved by using Either but serialization + /// for Either is not supported out of the box and had to be implemented pub sc_resp_2: Option>, pub sc_partial_resp_2: Option>, } diff --git a/bbs_plus/src/proof_23_ietf.rs b/bbs_plus/src/proof_23_ietf.rs index 7e80c77c..a976be10 100644 --- a/bbs_plus/src/proof_23_ietf.rs +++ b/bbs_plus/src/proof_23_ietf.rs @@ -87,6 +87,8 @@ pub struct PoKOfSignature23G1Proof { /// Proof of relation `\sum_{j \notin D}{h_j * m_j} - B_bar * 1/r - A_bar * e * 1/r = g + \sum_{i \in D}{h_i * m_i}` #[serde_as(as = "ArkObjectBytes")] pub T: E::G1Affine, + /// The following could be achieved by using Either but serialization + /// for Either is not supported out of the box and had to be implemented pub sc_resp: Option>, pub sc_partial_resp: Option>, } diff --git a/kvac/src/bbdt_2016/proof_cdh.rs b/kvac/src/bbdt_2016/proof_cdh.rs index 5d1bffb4..9d825454 100644 --- a/kvac/src/bbdt_2016/proof_cdh.rs +++ b/kvac/src/bbdt_2016/proof_cdh.rs @@ -101,6 +101,8 @@ pub struct PoKOfMAC { pub sc_C: PokTwoDiscreteLogs, #[serde_as(as = "ArkObjectBytes")] pub t_msgs: G, + /// The following could be achieved by using Either but serialization + /// for Either is not supported out of the box and had to be implemented pub sc_resp_msgs: Option>, pub sc_partial_resp_msgs: Option>, } diff --git a/proof_system/src/error.rs b/proof_system/src/error.rs index 56784482..3a2e62e0 100644 --- a/proof_system/src/error.rs +++ b/proof_system/src/error.rs @@ -110,6 +110,7 @@ pub enum ProofSystemError { UnequalCiphertextChunksAndSchnorrResponses(usize, usize), UnequalResponseOfSaverCiphertextAndChunk(usize), ResponseForWitnessNotFoundForStatement(usize), + NoResponseFoundForWitnessRef(usize, usize), } impl From for ProofSystemError { diff --git a/proof_system/src/statement_proof.rs b/proof_system/src/statement_proof.rs index d8b3e235..a7dfd6f7 100644 --- a/proof_system/src/statement_proof.rs +++ b/proof_system/src/statement_proof.rs @@ -284,10 +284,17 @@ pub struct BoundCheckLegoGroth16ProofWhenAggregatingSnarks { pub struct R1CSLegoGroth16Proof { #[serde_as(as = "ArkObjectBytes")] pub snark_proof: legogroth16::Proof, - pub sp: PedersenCommitmentPartialProof, + pub sp: PedersenCommitmentProof, } impl R1CSLegoGroth16Proof { + pub fn get_schnorr_response_for_message( + &self, + index: usize, + ) -> Result<&E::ScalarField, ProofSystemError> { + self.sp.response.get_response(index).map_err(|e| e.into()) + } + pub fn for_aggregation(&self) -> R1CSLegoGroth16ProofWhenAggregatingSnarks { R1CSLegoGroth16ProofWhenAggregatingSnarks { commitment: self.snark_proof.d, @@ -304,7 +311,16 @@ impl R1CSLegoGroth16Proof { pub struct R1CSLegoGroth16ProofWhenAggregatingSnarks { #[serde_as(as = "ArkObjectBytes")] pub commitment: E::G1Affine, - pub sp: PedersenCommitmentPartialProof, + pub sp: PedersenCommitmentProof, +} + +impl R1CSLegoGroth16ProofWhenAggregatingSnarks { + pub fn get_schnorr_response_for_message( + &self, + index: usize, + ) -> Result<&E::ScalarField, ProofSystemError> { + self.sp.response.get_response(index).map_err(|e| e.into()) + } } #[serde_as] diff --git a/proof_system/src/sub_protocols/r1cs_legogorth16.rs b/proof_system/src/sub_protocols/r1cs_legogorth16.rs index ab5da629..47c6a0c8 100644 --- a/proof_system/src/sub_protocols/r1cs_legogorth16.rs +++ b/proof_system/src/sub_protocols/r1cs_legogorth16.rs @@ -7,13 +7,7 @@ use crate::{ }; use ark_ec::pairing::Pairing; use ark_serialize::CanonicalSerialize; -use ark_std::{ - collections::{BTreeMap, BTreeSet}, - io::Write, - rand::RngCore, - vec::Vec, - UniformRand, -}; +use ark_std::{collections::BTreeMap, io::Write, rand::RngCore, vec::Vec, UniformRand}; use dock_crypto_utils::randomized_pairing_check::RandomizedPairingChecker; use legogroth16::{ calculate_d, @@ -156,15 +150,13 @@ impl<'a, E: Pairing> R1CSLegogroth16Protocol<'a, E> { self.id, )); } - let comm_wit_count = self.proving_key.as_ref().unwrap().vk.commit_witness_count as usize; - let skip_responses_for = BTreeSet::from_iter(0..comm_wit_count); Ok(StatementProof::R1CSLegoGroth16(R1CSLegoGroth16Proof { snark_proof: self.snark_proof.take().unwrap(), sp: self .sp .take() .unwrap() - .gen_partial_proof_contribution_as_struct(challenge, &skip_responses_for)?, + .gen_proof_contribution_as_struct(challenge)?, })) } @@ -177,7 +169,6 @@ impl<'a, E: Pairing> R1CSLegogroth16Protocol<'a, E> { comm_key: &[E::G1Affine], pvk: &PreparedVerifyingKey, pairing_checker: &mut Option>, - missing_responses: BTreeMap, ) -> Result<(), ProofSystemError> { let snark_proof = &proof.snark_proof; match pairing_checker { @@ -201,7 +192,7 @@ impl<'a, E: Pairing> R1CSLegogroth16Protocol<'a, E> { // NOTE: value of id is dummy let sp = SchnorrProtocol::new(10000, comm_key, proof.snark_proof.d); - sp.verify_partial_proof_contribution(challenge, &proof.sp, missing_responses) + sp.verify_proof_contribution(challenge, &proof.sp) .map_err(|e| ProofSystemError::SchnorrProofContributionFailed(self.id as u32, e)) } @@ -210,11 +201,10 @@ impl<'a, E: Pairing> R1CSLegogroth16Protocol<'a, E> { challenge: &E::ScalarField, proof: &R1CSLegoGroth16ProofWhenAggregatingSnarks, comm_key: &[E::G1Affine], - missing_responses: BTreeMap, ) -> Result<(), ProofSystemError> { // NOTE: value of id is dummy let sp = SchnorrProtocol::new(10000, comm_key, proof.commitment); - sp.verify_partial_proof_contribution(challenge, &proof.sp, missing_responses) + sp.verify_proof_contribution(challenge, &proof.sp) .map_err(|e| ProofSystemError::SchnorrProofContributionFailed(self.id as u32, e)) } diff --git a/proof_system/src/verifier.rs b/proof_system/src/verifier.rs index f46c0977..cd827e53 100644 --- a/proof_system/src/verifier.rs +++ b/proof_system/src/verifier.rs @@ -505,27 +505,6 @@ impl Proof { StatementProof::PoKPSSignature(p) => { let sig_params = s.get_params(&proof_spec.setup_params, s_idx)?; let pk = s.get_public_key(&proof_spec.setup_params, s_idx)?; - // // Check witness equalities for this statement. - // let revealed_msg_ids: Vec<_> = - // s.revealed_messages.keys().copied().collect(); - // for i in 0..sig_params.supported_message_count() { - // let w_ref = (s_idx, i); - // for j in 0..witness_equalities.len() { - // if witness_equalities[j].contains(&w_ref) { - // let resp = p.response_for_message( - // i, - // revealed_msg_ids.iter().copied(), - // )?; - // Self::check_response_for_equality( - // s_idx, - // i, - // j, - // &mut responses_for_equalities, - // resp, - // )?; - // } - // } - // } transcript.set_label(PS_LABEL); p.challenge_contribution(&mut transcript, pk, sig_params)?; } @@ -1295,37 +1274,38 @@ impl Proof { let pub_inp = s .get_public_inputs(&proof_spec.setup_params, s_idx)? .to_vec(); - let mut resp = BTreeMap::new(); - for i in 0..verifying_key.commit_witness_count as usize { - let wit_ref = (s_idx, i); - for (i, eq) in disjoint_equalities.iter().enumerate() { - if eq.has_wit_ref(&wit_ref) { - if let Some(r) = resp_for_equalities.get(&i) { - resp.insert(i, *r); - } else { - return Err( - ProofSystemError::ResponseForWitnessNotFoundForStatement( - s_idx, - ), - ); - } - // Exit loop because equalities are disjoint - break; - } - } - } match proof { - StatementProof::R1CSLegoGroth16(ref r1cs_proof) => sp - .verify_proof_contribution( + StatementProof::R1CSLegoGroth16(ref r1cs_proof) => { + for w_id in 0..verifying_key.commit_witness_count as usize { + let w_ref = (s_idx, w_id); + for (i, eq) in disjoint_equalities.iter().enumerate() { + if eq.has_wit_ref(&w_ref) { + let resp = + r1cs_proof.get_schnorr_response_for_message(w_id)?; + if let Some(r) = resp_for_equalities.get(&i) { + if resp != r { + return Err( + ProofSystemError::WitnessResponseNotEqual( + s_idx, w_id, + ), + ); + } + } else { + resp_for_equalities.insert(i, *resp); + } + } + } + } + sp.verify_proof_contribution( &challenge, &pub_inp, r1cs_proof, r1cs_comm_keys.get(s_idx).unwrap(), derived_lego_vk.get(s_idx).unwrap(), &mut pairing_checker, - resp, - )?, + )? + } StatementProof::R1CSLegoGroth16WithAggregation(ref r1cs_proof) => { let agg_idx = agg_lego_stmts.get(&s_idx).ok_or_else(|| { ProofSystemError::InvalidStatementProofIndex(s_idx) @@ -1333,11 +1313,31 @@ impl Proof { agg_lego[*agg_idx].0.push(r1cs_proof.commitment); agg_lego[*agg_idx].1.push(pub_inp); + for w_id in 0..verifying_key.commit_witness_count as usize { + let w_ref = (s_idx, w_id); + for (i, eq) in disjoint_equalities.iter().enumerate() { + if eq.has_wit_ref(&w_ref) { + let resp = + r1cs_proof.get_schnorr_response_for_message(w_id)?; + if let Some(r) = resp_for_equalities.get(&i) { + if resp != r { + return Err( + ProofSystemError::WitnessResponseNotEqual( + s_idx, w_id, + ), + ); + } + } else { + resp_for_equalities.insert(i, *resp); + } + } + } + } + sp.verify_proof_contribution_using_prepared_when_aggregating_snark( &challenge, r1cs_proof, r1cs_comm_keys.get(s_idx).unwrap(), - resp, )? } _ => { @@ -1774,14 +1774,12 @@ impl Proof { if let Some(r) = resp_for_equalities.get(&i) { resp = Some(*r); } else { - return Err(ProofSystemError::ResponseForWitnessNotFoundForStatement( - s_idx, - )); + return Err(ProofSystemError::NoResponseFoundForWitnessRef(s_idx, 0)); } // Exit loop because equalities are disjoint break; } } - resp.ok_or_else(|| ProofSystemError::ResponseForWitnessNotFoundForStatement(s_idx)) + resp.ok_or_else(|| ProofSystemError::NoResponseFoundForWitnessRef(s_idx, 0)) } }