1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
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,
})
}
}