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
use crate::{MessageGenerators, PokSignatureProof};
use blake2::VarBlake2b;
use bls12_381_plus::Scalar;
use digest::{Update, VariableOutput};
use rand_core::{CryptoRng, RngCore};
use signature_bls::PublicKey;
use signature_core::{constants::*, lib::*};
pub struct Verifier;
impl Verifier {
pub fn generate_proof_nonce(rng: impl RngCore + CryptoRng) -> Nonce {
Nonce::random(rng)
}
pub fn verify_signature_pok(
revealed_msgs: &[(usize, Message)],
public_key: PublicKey,
proof: PokSignatureProof,
generators: &MessageGenerators,
nonce: Nonce,
challenge: Challenge,
) -> bool {
let mut res = [0u8; COMMITMENT_BYTES];
let mut hasher = VarBlake2b::new(COMMITMENT_BYTES).unwrap();
proof.add_challenge_contribution(generators, revealed_msgs, challenge, &mut hasher);
hasher.update(&nonce.to_bytes()[..]);
hasher.finalize_variable(|out| {
res.copy_from_slice(out);
});
let v_challenge = Scalar::from_okm(&res);
proof.verify(public_key) && challenge.0 == v_challenge
}
}
#[test]
fn pok_sig_proof_works() {
use crate::{util::MockRng, Issuer, PokSignature};
use rand_core::*;
let seed = [1u8; 16];
let mut rng = MockRng::from_seed(seed);
let (pk, sk) = Issuer::new_keys(&mut rng).unwrap();
let generators = MessageGenerators::from_public_key(pk, 4);
let messages = [
Message::random(&mut rng),
Message::random(&mut rng),
Message::random(&mut rng),
Message::random(&mut rng),
];
let res = Issuer::sign(&sk, &generators, &messages);
assert!(res.is_ok());
let signature = res.unwrap();
let proof_messages = [
ProofMessage::Hidden(HiddenMessage::ProofSpecificBlinding(messages[0])),
ProofMessage::Hidden(HiddenMessage::ProofSpecificBlinding(messages[1])),
ProofMessage::Revealed(messages[2]),
ProofMessage::Revealed(messages[3]),
];
let res = PokSignature::init(signature, &generators, &proof_messages, &mut rng);
assert!(res.is_ok());
let mut tv = [0u8; 48];
let mut pok_sig = res.unwrap();
let nonce = Verifier::generate_proof_nonce(&mut rng);
let mut hasher = VarBlake2b::new(COMMITMENT_BYTES).unwrap();
pok_sig.add_proof_contribution(&mut hasher);
hasher.update(&nonce.to_bytes()[..]);
hasher.finalize_variable(|out| {
tv.copy_from_slice(out);
});
let challenge = Challenge::from_okm(&tv);
let res = pok_sig.generate_proof(challenge);
assert!(res.is_ok());
let proof = res.unwrap();
assert!(proof.verify(pk));
let mut hasher = VarBlake2b::new(COMMITMENT_BYTES).unwrap();
proof.add_challenge_contribution(
&generators,
&[(2, messages[2]), (3, messages[3])][..],
challenge,
&mut hasher,
);
hasher.update(&nonce.to_bytes()[..]);
hasher.finalize_variable(|out| {
tv.copy_from_slice(out);
});
let challenge2 = Challenge::from_okm(&tv);
assert_eq!(challenge, challenge2);
assert!(Verifier::verify_signature_pok(
&[(2, messages[2]), (3, messages[3])][..],
pk,
proof,
&generators,
nonce,
challenge
));
}