baseid_bbs/
signing.rs

1use crate::error::BbsError;
2use crate::keys::BbsKeyPair;
3use zkryptium::schemes::algorithms::BbsBls12381Sha256;
4use zkryptium::schemes::generics::Signature;
5
6/// Sign multiple messages with BBS+ producing a single constant-size signature.
7pub fn bbs_sign(
8    key_pair: &BbsKeyPair,
9    messages: &[Vec<u8>],
10    header: Option<&[u8]>,
11) -> Result<Vec<u8>, BbsError> {
12    let sk = key_pair.zk_secret_key()?;
13    let pk = key_pair.zk_public_key()?;
14
15    let msg_refs: Option<&[Vec<u8>]> = if messages.is_empty() {
16        None
17    } else {
18        Some(messages)
19    };
20
21    let signature = Signature::<BbsBls12381Sha256>::sign(msg_refs, &sk, &pk, header)
22        .map_err(|e| BbsError::SigningFailed(format!("{:?}", e)))?;
23
24    Ok(signature.to_bytes().to_vec())
25}
26
27/// Verify a BBS+ signature over multiple messages.
28pub fn bbs_verify(
29    public_key: &[u8],
30    signature: &[u8],
31    messages: &[Vec<u8>],
32    header: Option<&[u8]>,
33) -> Result<bool, BbsError> {
34    use zkryptium::bbsplus::keys::BBSplusPublicKey;
35
36    let pk = BBSplusPublicKey::from_bytes(public_key)
37        .map_err(|e| BbsError::VerificationFailed(format!("invalid public key: {:?}", e)))?;
38
39    let sig_bytes: [u8; 80] = signature
40        .try_into()
41        .map_err(|_| BbsError::VerificationFailed("signature must be 80 bytes".to_string()))?;
42
43    let sig = Signature::<BbsBls12381Sha256>::from_bytes(&sig_bytes)
44        .map_err(|e| BbsError::VerificationFailed(format!("{:?}", e)))?;
45
46    let msg_refs: Option<&[Vec<u8>]> = if messages.is_empty() {
47        None
48    } else {
49        Some(messages)
50    };
51
52    match sig.verify(&pk, msg_refs, header) {
53        Ok(()) => Ok(true),
54        Err(_) => Ok(false),
55    }
56}