Skip to content

Commit 68f72a9

Browse files
test: blind_bbs_plus_sig_and_message_equality (#29)
* test: blind_bbs_plus_sig_and_message_equality Signed-off-by: Harold Carr <harold.carr@oracle.com> * Review: remove redundant line Signed-off-by: Mark Moir <mark.moir@oracle.com> * Review: simplify expected-to-fail test Signed-off-by: Mark Moir <mark.moir@oracle.com> --------- Signed-off-by: Mark Moir <mark.moir@oracle.com> Co-authored-by: Harold Carr <harold.carr@oracle.com>
1 parent e775611 commit 68f72a9

2 files changed

Lines changed: 156 additions & 0 deletions

File tree

NOTICE.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
This project contains contributions subject to:
3+
4+
Copyright © 2025, Oracle and/or its affiliates.
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
// cargo-fmt makes this much harder to read
2+
use ark_bls12_381::{Bls12_381, Fr};
3+
use ark_std::{
4+
collections::{BTreeMap, BTreeSet},
5+
rand::{prelude::StdRng, SeedableRng},
6+
UniformRand,
7+
};
8+
use bbs_plus::prelude::SignatureG1;
9+
use blake2::Blake2b512;
10+
use proof_system::{
11+
prelude::{EqualWitnesses, MetaStatements, Proof, ProofSystemError, WitnessRef, Witnesses},
12+
proof_spec::ProofSpec,
13+
statement::{
14+
bbs_plus::{
15+
PoKBBSSignatureG1Prover as PoKSignatureBBSG1ProverStmt,
16+
PoKBBSSignatureG1Verifier as PoKSignatureBBSG1VerifierStmt,
17+
},
18+
Statements,
19+
},
20+
witness::PoKBBSSignatureG1 as PoKSignatureBBSG1Wit,
21+
};
22+
use test_utils::bbs::*;
23+
24+
#[test]
25+
fn blind_bbs_plus_sig_and_message_equality() {
26+
// This test
27+
// - creates two issuers/signers
28+
// - creates one signature for each signer, including a common attribute, blinded (by the holder) for each signature
29+
// - it then unblinds the signatures and
30+
// - creates a proof of knowledge of both signatures and equality of the blinded attributes
31+
// It tests that
32+
// - when the blinded values are equal, proof creation and verification both succeeds
33+
// - when the blinded values are unequal, either proof creation fails, or verification of the created proof fails
34+
//
35+
// This test was motivated by the fact that the existing blinding tests
36+
// proof_system/tests/bbs_plus_and_accumulators.rs
37+
// requesting_partially_blind_bbs_plus_sig
38+
// requesting_partially_blind_bbs_sig
39+
// do not use the unblinded/blind signature in proofs. Hence, this test.
40+
41+
blind_bbs_plus_sig_and_message_equality_aux(true).unwrap();
42+
// NOTE: current behaviour is that proof creation succeeds and verification of the created proof yields:
43+
// Err(ProofSystemError::BBSPlusProofContributionFailed(1,BBSPlusError::SecondSchnorrVerificationFailed))
44+
// but this test requires only that proof creation and verification do not BOTH succeed
45+
assert!(blind_bbs_plus_sig_and_message_equality_aux(false).is_err());
46+
}
47+
48+
#[cfg_attr(rustfmt, rustfmt_skip)]
49+
fn blind_bbs_plus_sig_and_message_equality_aux(eq : bool) -> Result<(), ProofSystemError> {
50+
let mut rng = StdRng::seed_from_u64(0u64);
51+
let total_msg_count = 4;
52+
let ( msgs_1, sig_params_1, sig_keypair_1, _) = bbs_plus_sig_setup(&mut rng, total_msg_count as u32);
53+
let (mut msgs_2, sig_params_2, sig_keypair_2, _) = bbs_plus_sig_setup(&mut rng, total_msg_count as u32);
54+
55+
let blinding_1 = Fr::rand(&mut rng);
56+
let committed_messages_1 = BTreeMap::from([ (1, &msgs_1[1])]); // aka blinded messages
57+
let uncommitted_messages_1 = BTreeMap::from([(0, &msgs_1[0]), (2, &msgs_1[2]), (3, &msgs_1[3])]);
58+
let commitment_1 = sig_params_1.commit_to_messages(committed_messages_1.clone(), &blinding_1).unwrap();
59+
60+
if eq {
61+
// make the values in the blinded attribute of the two credentials the same
62+
msgs_2[1] = msgs_1[1];
63+
}
64+
let blinding_2 = Fr::rand(&mut rng);
65+
let committed_messages_2 = BTreeMap::from([ (1, &msgs_2[1])]); // aka blinded messages
66+
let uncommitted_messages_2 = BTreeMap::from([(0, &msgs_2[0]), (2, &msgs_2[2]), (3, &msgs_2[3])]);
67+
let commitment_2 = sig_params_2.commit_to_messages(committed_messages_2.clone(), &blinding_2).unwrap();
68+
69+
let blinded_sig_1 = SignatureG1::<Bls12_381>::new_with_committed_messages(
70+
&mut rng,
71+
&commitment_1,
72+
uncommitted_messages_1.clone(),
73+
&sig_keypair_1.secret_key,
74+
&sig_params_1,
75+
).unwrap();
76+
let blinded_sig_2 = SignatureG1::<Bls12_381>::new_with_committed_messages(
77+
&mut rng,
78+
&commitment_2,
79+
uncommitted_messages_2.clone(),
80+
&sig_keypair_2.secret_key,
81+
&sig_params_2,
82+
).unwrap();
83+
84+
let sig_1 = blinded_sig_1.clone().unblind(&blinding_1);
85+
sig_1.verify(&msgs_1, sig_keypair_1.public_key.clone(), sig_params_1.clone()).unwrap();
86+
let sig_2 = blinded_sig_2.clone().unblind(&blinding_2);
87+
sig_2.verify(&msgs_2, sig_keypair_2.public_key.clone(), sig_params_2.clone()).unwrap();
88+
89+
// --------------------------------------------------
90+
// Prover
91+
92+
let mut prover_statements = Statements::<Bls12_381>::new();
93+
let revealed_messages_1 = uncommitted_messages_1.into_iter()
94+
.map(|(i, m)| (i, *m)) // this is because new_with_committed_messages takes
95+
// BTreeMap<usize, &E::ScalarField>
96+
// but new_statement_from_params takes
97+
// BTreeMap<usize, E::ScalarField>,
98+
.collect::<BTreeMap<_, _>>();
99+
prover_statements.add(
100+
PoKSignatureBBSG1ProverStmt::new_statement_from_params(sig_params_1.clone(), revealed_messages_1.clone()));
101+
let revealed_messages_2 = uncommitted_messages_2.into_iter()
102+
.map(|(i, m)| (i, *m))
103+
.collect::<BTreeMap<_, _>>();
104+
prover_statements.add(
105+
PoKSignatureBBSG1ProverStmt::new_statement_from_params(sig_params_2.clone(), revealed_messages_2.clone()));
106+
107+
let mut meta_statements = MetaStatements::new();
108+
meta_statements.add_witness_equality(EqualWitnesses(
109+
vec![(0, 1), (1, 1)] // 0th statement's 1st witness is equal to 1st statement's 1st witness
110+
.into_iter()
111+
.collect::<BTreeSet<WitnessRef>>(),
112+
));
113+
114+
let context = Some(b"test_context".to_vec());
115+
let prover_proof_spec = ProofSpec::new(prover_statements.clone(), meta_statements.clone(), vec![], context.clone());
116+
prover_proof_spec.validate().unwrap();
117+
118+
let mut witnesses = Witnesses::new();
119+
let unrevealed_messages_1 = committed_messages_1.into_iter()
120+
.map(|(i, m)| (i, *m))
121+
.collect::<BTreeMap<_, _>>();
122+
witnesses.add(PoKSignatureBBSG1Wit::new_as_witness(sig_1, unrevealed_messages_1.clone()));
123+
let unrevealed_messages_2 = committed_messages_2.into_iter()
124+
.map(|(i, m)| (i, *m))
125+
.collect::<BTreeMap<_, _>>();
126+
witnesses.add(PoKSignatureBBSG1Wit::new_as_witness(sig_2, unrevealed_messages_2.clone()));
127+
128+
// Proof
129+
130+
let nonce = Some(b"test nonce".to_vec());
131+
let proof = Proof::new::<StdRng, Blake2b512>(
132+
&mut rng,
133+
prover_proof_spec,
134+
witnesses.clone(),
135+
nonce.clone(),
136+
Default::default(),
137+
).unwrap().0;
138+
139+
// --------------------------------------------------
140+
// Verifier
141+
142+
let mut verifier_statements = Statements::<Bls12_381>::new();
143+
verifier_statements.add(
144+
PoKSignatureBBSG1VerifierStmt::new_statement_from_params(
145+
sig_params_1, sig_keypair_1.public_key.clone(), revealed_messages_1));
146+
verifier_statements.add(
147+
PoKSignatureBBSG1VerifierStmt::new_statement_from_params(
148+
sig_params_2, sig_keypair_2.public_key.clone(), revealed_messages_2));
149+
150+
let verifier_proof_spec = ProofSpec::new(verifier_statements.clone(), meta_statements, vec![], context);
151+
proof.verify::<StdRng, Blake2b512>(&mut rng, verifier_proof_spec, nonce, Default::default())
152+
}

0 commit comments

Comments
 (0)