aries_bbssignatures/
verifier.rs

1use crate::errors::{BBSError, BBSErrorKind};
2use crate::keys::prelude::*;
3use crate::pok_sig::prelude::*;
4/// The verifier of a signature or credential asks for messages to be revealed from
5/// a prover and checks the signature proof of knowledge against a trusted issuer's public key.
6use crate::{
7    HashElem, ProofChallenge, ProofNonce, ProofRequest, RandomElem, SignatureMessage,
8    SignatureProof,
9};
10use std::collections::BTreeSet;
11
12/// This struct represents an Verifier of signatures.
13/// Provided are methods for generating a context to ask for revealed messages
14/// and the prover keep all others hidden.
15pub struct Verifier;
16
17impl Verifier {
18    /// Create a nonce used for the zero-knowledge proof context
19    /// verkey: issuer's public key
20    pub fn new_proof_request(
21        revealed_message_indices: &[usize],
22        verkey: &PublicKey,
23    ) -> Result<ProofRequest, BBSError> {
24        let revealed_messages = revealed_message_indices
25            .iter()
26            .copied()
27            .collect::<BTreeSet<usize>>();
28        for i in &revealed_messages {
29            if *i > verkey.h.len() {
30                return Err(BBSErrorKind::PublicKeyGeneratorMessageCountMismatch(
31                    *i,
32                    verkey.h.len(),
33                )
34                .into());
35            }
36        }
37        Ok(ProofRequest {
38            revealed_messages,
39            verification_key: verkey.clone(),
40        })
41    }
42
43    /// Check a signature proof of knowledge and selective disclosure proof
44    pub fn verify_signature_pok(
45        proof_request: &ProofRequest,
46        signature_proof: &SignatureProof,
47        nonce: &ProofNonce,
48    ) -> Result<Vec<SignatureMessage>, BBSError> {
49        let mut challenge_bytes = signature_proof.proof.get_bytes_for_challenge(
50            proof_request.revealed_messages.clone(),
51            &proof_request.verification_key,
52        );
53        challenge_bytes.extend_from_slice(&nonce.to_bytes_uncompressed_form()[..]);
54
55        let challenge_verifier = ProofChallenge::hash(&challenge_bytes);
56        match signature_proof.proof.verify(
57            &proof_request.verification_key,
58            &signature_proof.revealed_messages,
59            &challenge_verifier,
60        )? {
61            PoKOfSignatureProofStatus::Success => Ok(signature_proof
62                .revealed_messages
63                .iter()
64                .map(|(_, m)| *m)
65                .collect::<Vec<SignatureMessage>>()),
66            e => Err(BBSErrorKind::InvalidProof { status: e }.into()),
67        }
68    }
69
70    /// Create a nonce used for the proof request context
71    pub fn generate_proof_nonce() -> ProofNonce {
72        ProofNonce::random()
73    }
74
75    /// create the challenge hash for a set of proofs
76    ///
77    /// # Arguments
78    /// * `proofs` - a slice of SignatureProof objects
79    /// * `proof_requests` - a corresponding slice of ProofRequest objects
80    /// * `nonce` - a SignatureNonce
81    /// * `claims` - an optional slice of bytes the prover wishes to include in the challenge
82    pub fn create_challenge_hash(
83        proofs: &[SignatureProof],
84        proof_requests: &[ProofRequest],
85        nonce: &ProofNonce,
86        claims: Option<&[&[u8]]>,
87    ) -> Result<ProofChallenge, BBSError> {
88        let mut bytes = Vec::new();
89
90        for pr in proofs.iter().zip(proof_requests.iter()) {
91            let (p, r) = pr;
92            bytes.extend_from_slice(
93                p.proof
94                    .get_bytes_for_challenge(r.revealed_messages.clone(), &r.verification_key)
95                    .as_slice(),
96            );
97        }
98        bytes.extend_from_slice(&nonce.to_bytes_uncompressed_form()[..]);
99        if let Some(claim) = claims {
100            for c in claim {
101                bytes.extend_from_slice(c);
102            }
103        }
104        let challenge = ProofChallenge::hash(&bytes);
105        Ok(challenge)
106    }
107}