Skip to content

Commit

Permalink
Merge pull request #100 from brave-experiments/acl-hvec-proof
Browse files Browse the repository at this point in the history
Acl hvec proof
  • Loading branch information
claucece authored Sep 2, 2024
2 parents 454aa80 + 86f1356 commit f619828
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 12 deletions.
30 changes: 29 additions & 1 deletion acl/src/sign.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,8 @@ pub struct SigProof<A: ACLConfig> {
pub pi1: SigProofD<A>,
/// p2: the second proof.
pub pi2: SigProofO<A>,
/// p3: the third proof.
pub pi3: Vec<SigProofD<A>>,
/// h_vec: the commitment to the sub values.
pub h_vec: Vec<sw::Affine<A>>,
/// val: the first message value.
Expand Down Expand Up @@ -457,7 +459,32 @@ impl<A: ACLConfig> SigProof<A> {

let pi1 = SigProofD { t1, t2, a1 };

// Equality proofs of zeta = h_vec -> TODO
// Equality proofs of zeta = h_vec
let pi_hvec: Vec<SigProofD<A>> = gens
.iter()
.take(vals.len())
.skip(1)
.map(|&item| {
let r = <A as CurveConfig>::ScalarField::rand(rng);
let t1 = (tag_key.mul(r)).into_affine();
let t2 = (item.mul(r)).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: <A as CurveConfig>::ScalarField =
<A as CurveConfig>::ScalarField::deserialize_compressed(&buf3[..]).unwrap();

let a1 = r + sig_m.opening.gamma * ch;

// Opening proof `pi`
SigProofD { t1, t2, a1 }
})
.collect();

// Compute partial commitment
//let mut total: sw::Affine<A> = sw::Affine::identity();
Expand Down Expand Up @@ -498,6 +525,7 @@ impl<A: ACLConfig> SigProof<A> {
b_gamma,
pi1,
pi2,
pi3: pi_hvec,
h_vec,
val,
}
Expand Down
47 changes: 41 additions & 6 deletions acl/src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,12 @@ impl<A: ACLConfig> SigVerifProof<A> {
transcript.append_message(b"c1", &compressed_bytes[..]);
}

pub fn verify(proof: &SigProof<A>, tag_key: sw::Affine<A>, sig_m: &SigSign<A>) -> bool {
pub fn verify(
proof: &SigProof<A>,
tag_key: sw::Affine<A>,
sig_m: &SigSign<A>,
gens: &Vec<sw::Affine<A>>,
) -> 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();
Expand All @@ -262,9 +267,40 @@ impl<A: ACLConfig> SigVerifProof<A> {
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) {
// 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()).skip(1))
{
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"challzk3", &mut buf3);

let ch3: <A as CurveConfig>::ScalarField =
<A as CurveConfig>::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) {
// 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.
Expand All @@ -283,8 +319,7 @@ impl<A: ACLConfig> SigVerifProof<A> {
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;

c && c2
// Proof succeeds if these final sides also agree.
rhs3 == lhs3
}
}
15 changes: 13 additions & 2 deletions boomerang/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,13 @@ impl<B: BoomerangConfig> CollectionStateS<B> {
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");
}
Expand Down Expand Up @@ -493,7 +499,12 @@ impl<B: BoomerangConfig> SpendVerifyStateS<B> {
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");
}
Expand Down
2 changes: 1 addition & 1 deletion macros/src/bench_tacl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +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));
b.iter(|| ACLSPV::verify(&proof, kp.tag_key, &m4, &gens.generators));
});
}
};
Expand Down
18 changes: 16 additions & 2 deletions macros/src/test_acl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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);
}
};
Expand Down

0 comments on commit f619828

Please sign in to comment.