From 065862903ed9ccbeee395478f5d02d2e49b55c48 Mon Sep 17 00:00:00 2001 From: Ben Savage Date: Mon, 18 Mar 2024 15:02:51 +1000 Subject: [PATCH 1/4] Added the different logic for the last ZKP --- .../ipa_prf/malicious_security/prover.rs | 105 ++++++++++++++---- 1 file changed, 81 insertions(+), 24 deletions(-) diff --git a/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs b/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs index 9536b5349..02649c3bd 100644 --- a/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs +++ b/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs @@ -23,6 +23,7 @@ pub struct ProofGenerator { } type TwoNMinusOne = Diff, U1>; +type TwoNPlusOne = Sum, U1>; /// /// Distributed Zero Knowledge Proofs algorithm drawn from @@ -91,53 +92,109 @@ where }; (proof, next_proof_generator) } + + pub fn compute_final_proof<λ: ArrayLength>( + &self, + p_0: F, + q_0: F, + ) -> ZeroKnowledgeProof> + where + λ: ArrayLength + Add + Add, + <λ as Add>::Output: Add, + <<λ as Add>::Output as Add>::Output: ArrayLength, + <λ as Add>::Output: ArrayLength, + { + assert_eq!(self.u.len(), λ::USIZE); // We should pad with zeroes eventually + + let denominator = CanonicalLagrangeDenominator::>::new(); + //let lagrange_table_r = LagrangeTable::::new(&denominator, &r); + let lagrange_table = LagrangeTable::, λ>::from(denominator); + + let mut p = vec![p_0]; + p.extend_from_slice(&self.u); + let mut q = vec![q_0]; + q.extend_from_slice(&self.v); + let p_extrapolated = lagrange_table.eval(&p); + let q_extrapolated = lagrange_table.eval(&q); + + // let p_r = lagrange_table_r.eval(&p)[0]; + // let q_r = lagrange_table_r.eval(&q)[0]; + + ZeroKnowledgeProof { + g: zip(p, q) + .map(|(a, b)| a * b) + .chain(zip(p_extrapolated, q_extrapolated).map(|(a, b)| a * b)) + .collect(), + } + } } #[cfg(all(test, unit_test))] mod test { - use typenum::U4; + use typenum::{U2, U4}; use super::ProofGenerator; use crate::ff::{Fp31, U128Conversions}; #[test] fn sample_proof() { - const U: [u128; 32] = [ + const U_1: [u128; 32] = [ 0, 30, 0, 16, 0, 1, 0, 15, 0, 0, 0, 16, 0, 30, 0, 16, 29, 1, 1, 15, 0, 0, 1, 15, 2, 30, 30, 16, 0, 0, 30, 16, ]; - const V: [u128; 32] = [ + const V_1: [u128; 32] = [ 0, 0, 0, 30, 0, 0, 0, 1, 30, 30, 30, 30, 0, 0, 30, 30, 0, 30, 0, 30, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, ]; - const EXPECTED: [u128; 7] = [0, 30, 29, 30, 5, 28, 13]; - const R1: u128 = 22; - const EXPECTED_NEXT_U: [u128; 8] = [0, 0, 26, 0, 7, 18, 24, 13]; - const EXPECTED_NEXT_V: [u128; 8] = [10, 21, 30, 28, 15, 21, 3, 3]; + const EXPECTED_1: [u128; 7] = [0, 30, 29, 30, 5, 28, 13]; + const R_1: u128 = 22; + const U_2: [u128; 8] = [0, 0, 26, 0, 7, 18, 24, 13]; + const V_2: [u128; 8] = [10, 21, 30, 28, 15, 21, 3, 3]; + + const EXPECTED_2: [u128; 7] = [12, 6, 15, 8, 29, 30, 6]; + const R_2: u128 = 17; + const U_3: [u128; 2] = [3, 3]; + const V_3: [u128; 2] = [5, 24]; + + const EXPECTED_3: [u128; 5] = [12, 15, 10, 14, 17]; + const P_RANDOM_WEIGHT: u128 = 12; + const Q_RANDOM_WEIGHT: u128 = 1; + let pg: ProofGenerator = ProofGenerator::new( - U.into_iter().map(|x| Fp31::try_from(x).unwrap()).collect(), - V.into_iter().map(|x| Fp31::try_from(x).unwrap()).collect(), + U_1.into_iter() + .map(|x| Fp31::try_from(x).unwrap()) + .collect(), + V_1.into_iter() + .map(|x| Fp31::try_from(x).unwrap()) + .collect(), ); - let (proof, next_proof_generator) = pg.compute_proof::(Fp31::try_from(R1).unwrap()); + + // first iteration + let (proof, pg_2) = pg.compute_proof::(Fp31::try_from(R_1).unwrap()); assert_eq!( - proof.g.into_iter().map(|x| x.as_u128()).collect::>(), - EXPECTED, + proof.g.iter().map(Fp31::as_u128).collect::>(), + EXPECTED_1, ); + assert_eq!(pg_2.u.iter().map(Fp31::as_u128).collect::>(), U_2,); + assert_eq!(pg_2.v.iter().map(Fp31::as_u128).collect::>(), V_2,); + + // next iteration + let (proof_2, pg_3) = pg_2.compute_proof::(Fp31::try_from(R_2).unwrap()); assert_eq!( - next_proof_generator - .u - .into_iter() - .map(|x| x.as_u128()) - .collect::>(), - EXPECTED_NEXT_U, + proof_2.g.iter().map(Fp31::as_u128).collect::>(), + EXPECTED_2, + ); + assert_eq!(pg_3.u.iter().map(Fp31::as_u128).collect::>(), U_3,); + assert_eq!(pg_3.v.iter().map(Fp31::as_u128).collect::>(), V_3,); + + // final iteration + let proof_3 = pg_3.compute_final_proof::( + Fp31::try_from(P_RANDOM_WEIGHT).unwrap(), + Fp31::try_from(Q_RANDOM_WEIGHT).unwrap(), ); assert_eq!( - next_proof_generator - .v - .into_iter() - .map(|x| x.as_u128()) - .collect::>(), - EXPECTED_NEXT_V, + proof_3.g.iter().map(Fp31::as_u128).collect::>(), + EXPECTED_3, ); } } From 94e5da70f79e927995700e686780b5b435b48dde Mon Sep 17 00:00:00 2001 From: Ben Savage Date: Mon, 18 Mar 2024 15:14:02 +1000 Subject: [PATCH 2/4] a few bits of cleanup --- .../protocol/ipa_prf/malicious_security/prover.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs b/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs index 02649c3bd..2147908b7 100644 --- a/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs +++ b/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs @@ -106,8 +106,8 @@ where { assert_eq!(self.u.len(), λ::USIZE); // We should pad with zeroes eventually + // We need a table of size `λ + 1` since we add a random point at x=0 let denominator = CanonicalLagrangeDenominator::>::new(); - //let lagrange_table_r = LagrangeTable::::new(&denominator, &r); let lagrange_table = LagrangeTable::, λ>::from(denominator); let mut p = vec![p_0]; @@ -117,14 +117,13 @@ where let p_extrapolated = lagrange_table.eval(&p); let q_extrapolated = lagrange_table.eval(&q); - // let p_r = lagrange_table_r.eval(&p)[0]; - // let q_r = lagrange_table_r.eval(&q)[0]; - ZeroKnowledgeProof { - g: zip(p, q) - .map(|(a, b)| a * b) - .chain(zip(p_extrapolated, q_extrapolated).map(|(a, b)| a * b)) - .collect(), + g: zip( + p.into_iter().chain(p_extrapolated), + q.into_iter().chain(q_extrapolated), + ) + .map(|(a, b)| a * b) + .collect(), } } } From 944e695267781266e28ab43ef3295a1137ef5310 Mon Sep 17 00:00:00 2001 From: Ben Savage Date: Mon, 18 Mar 2024 18:17:08 +1000 Subject: [PATCH 3/4] martins feedback --- .../ipa_prf/malicious_security/prover.rs | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs b/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs index 2147908b7..7ed47f0b8 100644 --- a/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs +++ b/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs @@ -17,6 +17,7 @@ pub struct ZeroKnowledgeProof { g: GenericArray, } +#[derive(Debug)] pub struct ProofGenerator { u: Vec, v: Vec, @@ -128,6 +129,30 @@ where } } +impl PartialEq<(&[u128], &[u128])> for ProofGenerator +where + F: PrimeField + std::cmp::PartialEq, +{ + fn eq(&self, other: &(&[u128], &[u128])) -> bool { + let (cmp_a, cmp_b) = other; + for (i, elem) in cmp_a.iter().enumerate() { + if !self.u[i].eq(elem) { + return false; + } + } + for (i, elem) in cmp_b.iter().enumerate() { + if !self.v[i].eq(elem) { + return false; + } + } + true + } + + fn ne(&self, other: &(&[u128], &[u128])) -> bool { + !self.eq(other) + } +} + #[cfg(all(test, unit_test))] mod test { use typenum::{U2, U4}; @@ -174,8 +199,7 @@ mod test { proof.g.iter().map(Fp31::as_u128).collect::>(), EXPECTED_1, ); - assert_eq!(pg_2.u.iter().map(Fp31::as_u128).collect::>(), U_2,); - assert_eq!(pg_2.v.iter().map(Fp31::as_u128).collect::>(), V_2,); + assert_eq!(pg_2, (&U_2[..], &V_2[..])); // next iteration let (proof_2, pg_3) = pg_2.compute_proof::(Fp31::try_from(R_2).unwrap()); @@ -183,8 +207,7 @@ mod test { proof_2.g.iter().map(Fp31::as_u128).collect::>(), EXPECTED_2, ); - assert_eq!(pg_3.u.iter().map(Fp31::as_u128).collect::>(), U_3,); - assert_eq!(pg_3.v.iter().map(Fp31::as_u128).collect::>(), V_3,); + assert_eq!(pg_3, (&U_3[..], &V_3[..])); // final iteration let proof_3 = pg_3.compute_final_proof::( From f32f4c3a63ad3029d805f8d8c1860757c1c44678 Mon Sep 17 00:00:00 2001 From: Ben Savage Date: Mon, 18 Mar 2024 18:18:53 +1000 Subject: [PATCH 4/4] removing ne implementation --- ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs b/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs index 7ed47f0b8..377838c3e 100644 --- a/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs +++ b/ipa-core/src/protocol/ipa_prf/malicious_security/prover.rs @@ -147,10 +147,6 @@ where } true } - - fn ne(&self, other: &(&[u128], &[u128])) -> bool { - !self.eq(other) - } } #[cfg(all(test, unit_test))]