ssi_bbs/
lib.rs

1use ssi_claims_core::{InvalidProof, MessageSignatureError, ProofValidationError, ProofValidity};
2use ssi_crypto::algorithm::BbsParameters;
3pub use zkryptium::{
4    bbsplus::keys::{BBSplusPublicKey, BBSplusSecretKey},
5    errors::Error,
6};
7use zkryptium::{
8    bbsplus::{
9        ciphersuites::{BbsCiphersuite, Bls12381Sha256},
10        commitment::BlindFactor,
11    },
12    keys::pair::KeyPair,
13    schemes::{
14        algorithms::BBSplus,
15        generics::{BlindSignature, Signature},
16    },
17};
18
19pub use ssi_crypto::algorithm::Bbs;
20
21#[derive(Debug)]
22pub struct ProofGenFailed;
23
24pub fn proof_gen(
25    pk: &BBSplusPublicKey,
26    signature: &[u8],
27    header: &[u8],
28    ph: Option<&[u8]>,
29    messages: &[Vec<u8>],
30    disclosed_indexes: &[usize],
31) -> Result<Vec<u8>, ProofGenFailed> {
32    Ok(
33        zkryptium::schemes::generics::PoKSignature::<BBSplus<Bls12381Sha256>>::proof_gen(
34            pk,
35            signature,
36            Some(header),
37            ph,
38            Some(messages),
39            Some(disclosed_indexes),
40        )
41        .map_err(|_| ProofGenFailed)?
42        .to_bytes(),
43    )
44}
45
46pub fn proof_verify(
47    pk: &BBSplusPublicKey,
48    signature: &[u8],
49    header: &[u8],
50    ph: Option<&[u8]>,
51    disclosed_messages: &[Vec<u8>],
52    disclosed_indexes: &[usize],
53) -> Result<ProofValidity, ProofValidationError> {
54    let signature =
55        zkryptium::schemes::generics::PoKSignature::<BBSplus<Bls12381Sha256>>::from_bytes(
56            signature,
57        )
58        .map_err(|_| ProofValidationError::InvalidSignature)?;
59
60    Ok(signature
61        .proof_verify(
62            pk,
63            Some(disclosed_messages),
64            Some(disclosed_indexes),
65            Some(header),
66            ph,
67        )
68        .map_err(|_| InvalidProof::Signature))
69}
70
71pub fn sign(
72    params: BbsParameters,
73    sk: &BBSplusSecretKey,
74    pk: &BBSplusPublicKey,
75    messages: &[Vec<u8>],
76) -> Result<Vec<u8>, MessageSignatureError> {
77    match params {
78        BbsParameters::Baseline { header } => {
79            Ok(
80                Signature::<BBSplus<Bls12381Sha256>>::sign(Some(messages), sk, pk, Some(&header))
81                    .map_err(MessageSignatureError::signature_failed)?
82                    .to_bytes()
83                    .to_vec(),
84            )
85        }
86        BbsParameters::Blind {
87            header,
88            commitment_with_proof,
89            signer_blind,
90        } => {
91            let signer_blind = signer_blind.map(|b| BlindFactor::from_bytes(&b).unwrap());
92            Ok(BlindSignature::<BBSplus<Bls12381Sha256>>::blind_sign(
93                sk,
94                pk,
95                commitment_with_proof.as_deref(),
96                Some(&header),
97                Some(messages),
98                signer_blind.as_ref(),
99            )
100            .map_err(MessageSignatureError::signature_failed)?
101            .to_bytes()
102            .to_vec())
103        }
104    }
105}
106
107pub fn generate_secret_key(rng: &mut impl rand::RngCore) -> BBSplusSecretKey {
108    let mut key_material = [0; Bls12381Sha256::IKM_LEN];
109    rng.fill_bytes(&mut key_material);
110    let pair = KeyPair::<BBSplus<Bls12381Sha256>>::generate(&key_material, None, None).unwrap();
111    pair.into_parts().0
112}