zkp_fiat_shamir_lib/
lib.rs

1use sha2::{Digest, Sha256};
2
3/// modular exponentiation: computes base^exp % modulus
4pub fn mod_exp(base: u64, exp: u64, modulus: u64) -> u64 {
5    let mut result = 1;
6    let mut base = base % modulus;
7    let mut exp = exp;
8
9    while exp > 0 {
10        if exp % 2 == 1 {
11            result = (result * base) % modulus;
12        }
13        exp /= 2;
14        base = (base * base) % modulus;
15    }
16    result
17}
18
19/// commitment generation: computes t = g^r % p
20pub fn generate_commitment(g: u64, r: u64, p: u64) -> u64 {
21    mod_exp(g, r, p)
22}
23
24/// challenge generation using Fiat-Shamir heuristic
25pub fn generate_challenge(t: u64, y: u64, g: u64, p: u64) -> u64 {
26    // concatenate inputs as a single string
27    let input = format!("{},{},{},{}", t, y, g, p);
28    let hash = Sha256::digest(input.as_bytes());
29    // convert the first 8 bytes of the hash to a u64 and mod it with p-1
30    let challenge = u64::from_be_bytes(hash[0..8].try_into().unwrap()) % (p - 1);
31    challenge
32}
33
34/// response generation: computes s = (r + c * x) % (p-1)
35pub fn generate_response(r: u64, c: u64, x: u64, p: u64) -> u64 {
36    (r + c * x) % (p - 1)
37}
38
39/// verifies the proof: checks if g^s % p == t * y^c % p
40pub fn verify_proof(t: u64, y: u64, g: u64, s: u64, c: u64, p: u64) -> bool {
41    let left = mod_exp(g, s, p); // g^s % p
42    let right = (t * mod_exp(y, c, p)) % p; // t * y^c % p
43    left == right
44}