use crate::errors::prelude::*;
use crate::keys::prelude::*;
use crate::messages::*;
use crate::pok_sig::prelude::*;
use crate::pok_vc::prelude::*;
use crate::signature::prelude::*;
use crate::{
BlindSignatureContext, CommitmentBuilder, HashElem, ProofChallenge, ProofNonce, ProofRequest,
RandomElem, SignatureBlinding, SignatureMessage, SignatureProof,
};
use std::collections::BTreeMap;
pub struct Prover {}
impl Prover {
pub fn new_link_secret() -> SignatureMessage {
SignatureMessage::random()
}
pub fn new_blind_signature_context(
verkey: &PublicKey,
messages: &BTreeMap<usize, SignatureMessage>,
nonce: &ProofNonce,
) -> Result<(BlindSignatureContext, SignatureBlinding), BBSError> {
let blinding_factor = Signature::generate_blinding();
let mut builder = CommitmentBuilder::new();
builder.add(&verkey.h0, &blinding_factor);
let mut committing = ProverCommittingG1::new();
committing.commit(&verkey.h0);
let mut secrets = Vec::new();
secrets.push(SignatureMessage(blinding_factor.0));
for (i, m) in messages {
if *i > verkey.h.len() {
return Err(BBSErrorKind::PublicKeyGeneratorMessageCountMismatch(
*i,
verkey.h.len(),
)
.into());
}
secrets.push(m.clone());
builder.add(&verkey.h[*i], &m);
committing.commit(&verkey.h[*i]);
}
let commitment = builder.finalize();
let committed = committing.finish();
let mut extra = Vec::new();
extra.extend_from_slice(&commitment.to_bytes_uncompressed_form()[..]);
extra.extend_from_slice(&nonce.to_bytes_uncompressed_form()[..]);
let challenge_hash = committed.gen_challenge(extra);
let proof_of_hidden_messages = committed
.gen_proof(&challenge_hash, secrets.as_slice())
.unwrap();
Ok((
BlindSignatureContext {
challenge_hash,
commitment,
proof_of_hidden_messages,
},
blinding_factor,
))
}
pub fn complete_signature(
verkey: &PublicKey,
messages: &[SignatureMessage],
blind_signature: &BlindSignature,
blinding_factor: &SignatureBlinding,
) -> Result<Signature, BBSError> {
let signature = blind_signature.to_unblinded(blinding_factor);
if signature.verify(messages, verkey)? {
Ok(signature)
} else {
Err(BBSErrorKind::GeneralError {
msg: "Invalid signature.".to_string(),
}
.into())
}
}
pub fn commit_signature_pok(
request: &ProofRequest,
proof_messages: &[ProofMessage],
signature: &Signature,
) -> Result<PoKOfSignature, BBSError> {
PoKOfSignature::init(&signature, &request.verification_key, proof_messages)
}
pub fn create_challenge_hash(
pok_sigs: &[PoKOfSignature],
claims: Option<&[&[u8]]>,
nonce: &ProofNonce,
) -> Result<ProofChallenge, BBSError> {
let mut bytes = Vec::new();
for p in pok_sigs {
bytes.extend_from_slice(p.to_bytes().as_slice());
}
bytes.extend_from_slice(&nonce.to_bytes_uncompressed_form()[..]);
if let Some(add_claims) = claims {
for c in add_claims {
bytes.extend_from_slice(c);
}
}
let challenge = ProofChallenge::hash(&bytes);
Ok(challenge)
}
pub fn generate_signature_pok(
pok_sig: PoKOfSignature,
challenge: &ProofChallenge,
) -> Result<SignatureProof, BBSError> {
let revealed_messages = (&pok_sig.revealed_messages).clone();
let proof = pok_sig.gen_proof(challenge)?;
Ok(SignatureProof {
revealed_messages,
proof,
})
}
}