From b7b000a914e7db3f6405385331661fe5faa12a58 Mon Sep 17 00:00:00 2001 From: Ralph Ankele Date: Fri, 17 May 2024 12:29:42 +0200 Subject: [PATCH 1/7] implement dleq proof for zeta = h_vec --- acl/src/sign.rs | 30 ++++++++++++++++++++++++- acl/src/verify.rs | 48 +++++++++++++++++++++++++++++++++++----- boomerang/src/server.rs | 8 ++++++- macros/src/bench_tacl.rs | 9 +++++++- macros/src/test_acl.rs | 18 +++++++++++++-- 5 files changed, 103 insertions(+), 10 deletions(-) diff --git a/acl/src/sign.rs b/acl/src/sign.rs index 95ac5e2..a22e819 100644 --- a/acl/src/sign.rs +++ b/acl/src/sign.rs @@ -396,6 +396,8 @@ pub struct SigProof { pub pi1: SigProofD, /// p2: the second proof. pub pi2: SigProofO, + /// p3: the third proof. + pub pi3: Vec>, /// h_vec: the commitment to the sub values. pub h_vec: Vec>, /// val: the first message value. @@ -457,7 +459,32 @@ impl SigProof { let pi1 = SigProofD { t1, t2, a1 }; - // Equality proofs of zeta = h_vec -> TODO + // Equality proofs of zeta = h_vec + let pi_hvec: Vec> = gens + .iter() + .take(vals.len()) + .skip(1) + .map(|&item| { + let r = ::ScalarField::rand(rng); + let t1 = (tag_key.mul(r)).into_affine(); + let t2 = (item.mul(sig_m.opening.gamma)).into_affine(); + + let label3 = b"Chall ACLZK3"; + let mut transcript_v = Transcript::new(label3); + Self::make_transcript(&mut transcript_v, &t1, &t2); + + let mut buf3 = [0u8; 64]; + let _ = &transcript_v.challenge_bytes(b"challzk3", &mut buf3); + + let ch: ::ScalarField = + ::ScalarField::deserialize_compressed(&buf[..]).unwrap(); + + let a1 = r + sig_m.opening.gamma * ch; + + let pi = SigProofD { t1, t2, a1 }; + pi + }) + .collect(); // Compute partial commitment //let mut total: sw::Affine = sw::Affine::identity(); @@ -498,6 +525,7 @@ impl SigProof { b_gamma, pi1, pi2, + pi3: pi_hvec, h_vec, val, } diff --git a/acl/src/verify.rs b/acl/src/verify.rs index 3762d76..8e67c88 100644 --- a/acl/src/verify.rs +++ b/acl/src/verify.rs @@ -244,7 +244,12 @@ impl SigVerifProof { transcript.append_message(b"c1", &compressed_bytes[..]); } - pub fn verify(proof: &SigProof, tag_key: sw::Affine, sig_m: &SigSign) -> bool { + pub fn verify( + proof: &SigProof, + tag_key: sw::Affine, + sig_m: &SigSign, + gens: &Vec>, + ) -> bool { // Equality proof of zeta = b_gamma let rhs1 = (tag_key.mul(proof.pi1.a1)).into_affine(); let rhs2 = (A::GENERATOR.mul(proof.pi1.a1)).into_affine(); @@ -262,9 +267,40 @@ impl SigVerifProof { let lhs1 = proof.pi1.t1 + (sig_m.sigma.zeta.mul(ch)); let lhs2 = proof.pi1.t2 + (proof.b_gamma.mul(ch)); - let c = rhs1 == lhs1 && rhs2 == lhs2; + if (rhs1 == lhs1 && rhs2 == lhs2) == false { + // Only continue if above proof verifies to true, otherwise we can + // return early + return false; + } - // Equality proofs of zeta = h_vec -> TODO + // Equality proofs of zeta = h_vec + for ((pi, h), gen) in proof + .pi3 + .iter() + .zip(proof.h_vec.iter()) + .zip(gens.iter().take(proof.pi3.len())) + { + let rhs4 = (tag_key.mul(pi.a1)).into_affine(); + let rhs5 = (gen.mul(pi.a1)).into_affine(); + + let label3 = b"Chall ACLZK3"; + let mut transcript_v = Transcript::new(label3); + Self::make_transcript(&mut transcript_v, &pi.t1, &pi.t2); + + let mut buf3 = [0u8; 64]; + let _ = &transcript_v.challenge_bytes(b"challzk", &mut buf3); + + let ch3: ::ScalarField = + ::ScalarField::deserialize_compressed(&buf3[..]).unwrap(); + + let lhs4 = pi.t1 + (sig_m.sigma.zeta.mul(ch3)); + let lhs5 = pi.t2 + (h.mul(ch3)); + + if (rhs4 == lhs4 && rhs5 == lhs5) == false { + // if any of the proof is false, return immediately + return false; + } + } // For our cases, we will always prove knowledge of all signed committed values, // but this is not for all cases. @@ -283,8 +319,10 @@ impl SigVerifProof { let rhs3 = proof.val.mul(ch2) + proof.pi2.t3; let lhs3 = (A::GENERATOR2.mul(proof.pi2.a4) + A::GENERATOR.mul(proof.pi2.a3)).into_affine(); - let c2 = rhs3 == lhs3; + if (rhs3 == lhs3) == false { + return false; + } - c && c2 + true } } diff --git a/boomerang/src/server.rs b/boomerang/src/server.rs index 6e7c781..4f8ea75 100644 --- a/boomerang/src/server.rs +++ b/boomerang/src/server.rs @@ -289,7 +289,13 @@ impl CollectionStateS { panic!("Boomerang collection: invalid signature"); } - let check2 = SigVerifProof::verify(&c_m.s_proof, key_pair.s_key_pair.tag_key, &c_m.sig); + let check2 = SigVerifProof::verify( + &c_m.s_proof, + key_pair.s_key_pair.tag_key, + &c_m.sig, + &c_m.prev_gens.generators, + ); + if !check2 { panic!("Boomerang collection: invalid proof sig"); } diff --git a/macros/src/bench_tacl.rs b/macros/src/bench_tacl.rs index aba5aee..c35bcdb 100644 --- a/macros/src/bench_tacl.rs +++ b/macros/src/bench_tacl.rs @@ -200,7 +200,14 @@ macro_rules! bench_tacl_sign_verify_time { // Now we can just benchmark how long it takes to create a new multi proof. c.bench_function(concat!($curve_name, " acl proof verify time"), |b| { - b.iter(|| ACLSPV::verify(&proof, kp.tag_key, &m4)); + b.iter(|| { + ACLSPV::verify( + &proof, + kp.tag_key, + &m4, + &gens.generators, + ) + }); }); } }; diff --git a/macros/src/test_acl.rs b/macros/src/test_acl.rs index ba3652a..17086ca 100644 --- a/macros/src/test_acl.rs +++ b/macros/src/test_acl.rs @@ -233,6 +233,13 @@ macro_rules! __test_acl { assert!(proof.pi1.t1.is_on_curve()); assert!(proof.pi1.t2.is_on_curve()); assert!(proof.pi2.t3.is_on_curve()); + for h in proof.h_vec.iter() { + assert!(h.is_on_curve()); + } + for pi in proof.pi3.iter() { + assert!(pi.t1.is_on_curve()); + assert!(pi.t2.is_on_curve()); + } } #[test] @@ -279,8 +286,15 @@ macro_rules! __test_acl { assert!(proof.pi1.t1.is_on_curve()); assert!(proof.pi1.t2.is_on_curve()); assert!(proof.pi2.t3.is_on_curve()); - - let check = ACLSPV::verify(&proof, kp.tag_key, &m4); + for h in proof.h_vec.iter() { + assert!(h.is_on_curve()); + } + for pi in proof.pi3.iter() { + assert!(pi.t1.is_on_curve()); + assert!(pi.t2.is_on_curve()); + } + + let check = ACLSPV::verify(&proof, kp.tag_key, &m4, &gens.generators); assert!(check == true); } }; From 528923525f6fe093aac168bb4944daddb534761f Mon Sep 17 00:00:00 2001 From: Ralph Ankele Date: Fri, 17 May 2024 12:32:52 +0200 Subject: [PATCH 2/7] fix using wrong label in challenge_bytes --- acl/src/verify.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acl/src/verify.rs b/acl/src/verify.rs index 8e67c88..6d43ef2 100644 --- a/acl/src/verify.rs +++ b/acl/src/verify.rs @@ -288,7 +288,7 @@ impl SigVerifProof { Self::make_transcript(&mut transcript_v, &pi.t1, &pi.t2); let mut buf3 = [0u8; 64]; - let _ = &transcript_v.challenge_bytes(b"challzk", &mut buf3); + let _ = &transcript_v.challenge_bytes(b"challzk3", &mut buf3); let ch3: ::ScalarField = ::ScalarField::deserialize_compressed(&buf3[..]).unwrap(); From 4ea517b87ce29b12262d551583149ac6cd9fcfd4 Mon Sep 17 00:00:00 2001 From: Ralph Giles Date: Thu, 30 May 2024 15:23:02 -0700 Subject: [PATCH 3/7] clippy Address some clippy lints abaout the new acl hvec proof code. --- acl/src/sign.rs | 4 ++-- acl/src/verify.rs | 11 ++++------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/acl/src/sign.rs b/acl/src/sign.rs index a22e819..b1519e9 100644 --- a/acl/src/sign.rs +++ b/acl/src/sign.rs @@ -481,8 +481,8 @@ impl SigProof { let a1 = r + sig_m.opening.gamma * ch; - let pi = SigProofD { t1, t2, a1 }; - pi + // Opening proof `pi` + SigProofD { t1, t2, a1 } }) .collect(); diff --git a/acl/src/verify.rs b/acl/src/verify.rs index 6d43ef2..e9d3059 100644 --- a/acl/src/verify.rs +++ b/acl/src/verify.rs @@ -267,7 +267,7 @@ impl SigVerifProof { let lhs1 = proof.pi1.t1 + (sig_m.sigma.zeta.mul(ch)); let lhs2 = proof.pi1.t2 + (proof.b_gamma.mul(ch)); - if (rhs1 == lhs1 && rhs2 == lhs2) == false { + if !(rhs1 == lhs1 && rhs2 == lhs2) { // Only continue if above proof verifies to true, otherwise we can // return early return false; @@ -296,7 +296,7 @@ impl SigVerifProof { let lhs4 = pi.t1 + (sig_m.sigma.zeta.mul(ch3)); let lhs5 = pi.t2 + (h.mul(ch3)); - if (rhs4 == lhs4 && rhs5 == lhs5) == false { + if !(rhs4 == lhs4 && rhs5 == lhs5) { // if any of the proof is false, return immediately return false; } @@ -319,10 +319,7 @@ impl SigVerifProof { let rhs3 = proof.val.mul(ch2) + proof.pi2.t3; let lhs3 = (A::GENERATOR2.mul(proof.pi2.a4) + A::GENERATOR.mul(proof.pi2.a3)).into_affine(); - if (rhs3 == lhs3) == false { - return false; - } - - true + // Proof succeeds if these final sides also agree. + rhs3 == lhs3 } } From 6c1b32883017ebe93985ed3970f769cb5b10c959 Mon Sep 17 00:00:00 2001 From: Ralph Ankele Date: Mon, 24 Jun 2024 15:45:51 +0200 Subject: [PATCH 4/7] fix wrong buffer variable --- acl/src/sign.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/acl/src/sign.rs b/acl/src/sign.rs index b1519e9..0351416 100644 --- a/acl/src/sign.rs +++ b/acl/src/sign.rs @@ -477,7 +477,7 @@ impl SigProof { let _ = &transcript_v.challenge_bytes(b"challzk3", &mut buf3); let ch: ::ScalarField = - ::ScalarField::deserialize_compressed(&buf[..]).unwrap(); + ::ScalarField::deserialize_compressed(&buf3[..]).unwrap(); let a1 = r + sig_m.opening.gamma * ch; From aa666ce5953bb38094c914bf6ad09c1d70cafa80 Mon Sep 17 00:00:00 2001 From: Ralph Ankele Date: Fri, 30 Aug 2024 14:09:10 +0200 Subject: [PATCH 5/7] fix rebasing conflict --- boomerang/src/server.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/boomerang/src/server.rs b/boomerang/src/server.rs index 4f8ea75..baeeb74 100644 --- a/boomerang/src/server.rs +++ b/boomerang/src/server.rs @@ -499,7 +499,7 @@ impl SpendVerifyStateS { panic!("Boomerang spend-verify: invalid signature"); } - let check2 = SigVerifProof::verify(&c_m.s_proof, key_pair.s_key_pair.tag_key, &c_m.sig); + let check2 = SigVerifProof::verify(&c_m.s_proof, key_pair.s_key_pair.tag_key, &c_m.sig, &c_m.prev_gens.generators); if !check2 { panic!("Boomerang spend-verify: invalid proof sig"); } From c9fd762b7c3a7a620f35036295f7bf8f1e4b42d8 Mon Sep 17 00:00:00 2001 From: Ralph Ankele Date: Mon, 2 Sep 2024 12:48:32 +0200 Subject: [PATCH 6/7] fix equality proof zeta=h_vec --- acl/src/sign.rs | 2 +- acl/src/verify.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/acl/src/sign.rs b/acl/src/sign.rs index 0351416..d608126 100644 --- a/acl/src/sign.rs +++ b/acl/src/sign.rs @@ -467,7 +467,7 @@ impl SigProof { .map(|&item| { let r = ::ScalarField::rand(rng); let t1 = (tag_key.mul(r)).into_affine(); - let t2 = (item.mul(sig_m.opening.gamma)).into_affine(); + let t2 = (item.mul(r)).into_affine(); let label3 = b"Chall ACLZK3"; let mut transcript_v = Transcript::new(label3); diff --git a/acl/src/verify.rs b/acl/src/verify.rs index e9d3059..7541f5c 100644 --- a/acl/src/verify.rs +++ b/acl/src/verify.rs @@ -278,7 +278,7 @@ impl SigVerifProof { .pi3 .iter() .zip(proof.h_vec.iter()) - .zip(gens.iter().take(proof.pi3.len())) + .zip(gens.iter().take(proof.pi3.len()).skip(1)) { let rhs4 = (tag_key.mul(pi.a1)).into_affine(); let rhs5 = (gen.mul(pi.a1)).into_affine(); From 86f1356940f51a61a0e976bd55b751ed405d9538 Mon Sep 17 00:00:00 2001 From: Ralph Ankele Date: Mon, 2 Sep 2024 13:09:01 +0200 Subject: [PATCH 7/7] cargo fmt --- boomerang/src/server.rs | 7 ++++++- macros/src/bench_tacl.rs | 9 +-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/boomerang/src/server.rs b/boomerang/src/server.rs index baeeb74..aeefd5c 100644 --- a/boomerang/src/server.rs +++ b/boomerang/src/server.rs @@ -499,7 +499,12 @@ impl SpendVerifyStateS { panic!("Boomerang spend-verify: invalid signature"); } - let check2 = SigVerifProof::verify(&c_m.s_proof, key_pair.s_key_pair.tag_key, &c_m.sig, &c_m.prev_gens.generators); + let check2 = SigVerifProof::verify( + &c_m.s_proof, + key_pair.s_key_pair.tag_key, + &c_m.sig, + &c_m.prev_gens.generators, + ); if !check2 { panic!("Boomerang spend-verify: invalid proof sig"); } diff --git a/macros/src/bench_tacl.rs b/macros/src/bench_tacl.rs index c35bcdb..c252157 100644 --- a/macros/src/bench_tacl.rs +++ b/macros/src/bench_tacl.rs @@ -200,14 +200,7 @@ macro_rules! bench_tacl_sign_verify_time { // Now we can just benchmark how long it takes to create a new multi proof. c.bench_function(concat!($curve_name, " acl proof verify time"), |b| { - b.iter(|| { - ACLSPV::verify( - &proof, - kp.tag_key, - &m4, - &gens.generators, - ) - }); + b.iter(|| ACLSPV::verify(&proof, kp.tag_key, &m4, &gens.generators)); }); } };