Expand description
BBS+ signature and verification as per section 4.3 of the paper
§Examples
Creating signature and verifying it:
use ark_bls12_381::Bls12_381;
use bbs_plus::setup::{SignatureParamsG1, SignatureParamsG2, KeypairG1, KeypairG2};
use bbs_plus::signature::{SignatureG1, SignatureG2};
let params_g1 = SignatureParamsG1::<Bls12_381>::generate_using_rng(&mut rng, 5);
let params_g2 = SignatureParamsG2::<Bls12_381>::generate_using_rng(&mut rng, 5);
let keypair_g2 = KeypairG2::<Bls12_381>::generate(&mut rng, ¶ms_g1);
let keypair_g1 = KeypairG1::<Bls12_381>::generate(&mut rng, ¶ms_g2);
let pk_g2 = &keypair_g2.public_key;
let pk_g1 = &keypair_g1.public_key;
// `messages` contains elements of the scalar field
// Verifiers should check that the signature parameters and public key are valid before verifying
// any signatures. This just needs to be done once when the verifier fetches/receives them.
assert!(params_g1.is_valid());
assert!(params_g2.is_valid());
assert!(pk_g2.is_valid());
assert!(pk_g1.is_valid());
let sig_g1 = SignatureG1::<Bls12_381>::new(&mut rng, &messages, &keypair_g2.secret_key, ¶ms_g1).unwrap();
sig_g1.verify(&messages, pk_g2, ¶ms_g1).unwrap();
let sig_g2 = SignatureG2::<Bls12_381>::new(&mut rng, &messages, &keypair_g1.secret_key, ¶ms_g2).unwrap();
sig_g2.verify(&messages, pk_g1, ¶ms_g2).unwrap();
// Requesting a partially blind signature from the signer, i.e. where signer does not know all the messages
// Requester creates a Pedersen commitment over the messages he wants to hide from the signer.
// Requester creates a map of message index to message as `committed_messages` and random field element
// `blinding` and commits as:
let commitment_g1 = params_g1
.commit_to_messages(committed_messages, &blinding)
.unwrap();
// Its upto the signer to verify that the commitment was created with the correct bases and checking
// a proof of knowledge is sufficient for that. Check the `proof_system` crate in this repo on
// how to such proof of knowledge, there is test to show this workflow.
// Once the signer is satisfied, he creates a blind signature as:
let blinded_sig_g1 = SignatureG1::<Bls12_381>::new_with_committed_messages(
&mut rng,
&commitment_g1,
uncommitted_messages,
&keypair_g2.secret_key,
¶ms_g1,
)
.unwrap();
// The requester unblinds the signature and verifies it to ensure correct sig.
let sig_g1 = blinded_sig_g1.unblind(&blinding);
sig_g1.verify(&messages, &keypair_g2.public_key, ¶ms_g1).unwrap();
// Similar process is followed to create blind signature is group G2 but the commitment here
// would also be in G2 as `commitment_g2`.
let commitment_g2 = params_g2
.commit_to_messages(committed_messages, &blinding)
.unwrap();
// Signer creates blind signature
let blinded_sig_g2 = SignatureG2::<Bls12_381>::new_with_committed_messages(
&mut rng,
&commitment_g2,
uncommitted_messages,
&keypair_g1.secret_key,
¶ms_g2,
)
.unwrap();
let sig_g2 = blinded_sig_g2.unblind(&blinding);
sig_g2.verify(&messages, &keypair_g1.public_key, ¶ms_g2).unwrap();
Structs§
- BBS+ signature created by the signer after signing a multi-message
- BBS+ signature created by the signer after signing a multi-message