-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathzkm.rs
63 lines (51 loc) · 1.77 KB
/
zkm.rs
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
use rand::prelude::*;
use sha2::{Digest, Sha256};
/*
This implementation includes the ZKProof struct, which contains the secret being proven, the commitment (hashed value of the secret), the challenge (hashed value of the commitment), and the response (random value modulo the secret).
It also includes functions to generate and verify a zero-knowledge proof.
Of course, this is just a simple example, and a real implementation would likely have many more features and be much more complex.
*/
struct ZKProof {
secret: u64,
commitment: [u8; 32],
challenge: [u8; 32],
response: u64,
}
fn compute_commitment(secret: u64) -> [u8; 32] {
let mut hasher = Sha256::new();
hasher.input(secret.to_string());
hasher.result()
}
fn compute_challenge(commitment: [u8; 32]) -> [u8; 32] {
let mut hasher = Sha256::new();
hasher.input(commitment);
hasher.result()
}
fn compute_response(secret: u64, challenge: [u8; 32]) -> u64 {
let mut rng = rand::thread_rng();
let response = rng.gen_range(0, secret);
(response + challenge[0] as u64) % secret
}
fn generate_proof(secret: u64) -> ZKProof {
let commitment = compute_commitment(secret);
let challenge = compute_challenge(commitment);
let response = compute_response(secret, challenge);
ZKProof {
secret,
commitment,
challenge,
response,
}
}
fn verify_proof(proof: ZKProof) -> bool {
let commitment = compute_commitment(proof.secret);
if commitment != proof.commitment {
return false;
}
let challenge = compute_challenge(proof.commitment);
if challenge != proof.challenge {
return false;
}
let expected_response = (proof.response + proof.challenge[0] as u64) % proof.secret;
expected_response == proof.response
}