sigma_proof_compiler/sigmas/
zero.rs1use crate::{
2 absorb::{SymInstance, SymPoint, SymScalar, SymWitness},
3 compiler::SigmaProof,
4 sigmas::G,
5};
6
7pub struct ZeroCheckProtocol;
8
9#[derive(SymWitness, Clone)]
10pub struct ZeroCheckWitness {
11 secret_key: SymScalar,
12}
13
14#[derive(SymInstance, Clone)]
15pub struct ZeroCheckInstance {
16 pubkey: SymPoint,
17 commitment: SymPoint,
18 handle: SymPoint,
19}
20
21impl SigmaProof for ZeroCheckProtocol {
22 const LABEL: &'static [u8] = b"zero-check-protocol";
23
24 type WITNESS = ZeroCheckWitness;
25 type INSTANCE = ZeroCheckInstance;
26
27 fn f(instance: &Self::INSTANCE) -> Vec<SymPoint> {
28 let Self::INSTANCE {
29 pubkey: _,
30 commitment,
31 handle,
32 } = instance.clone();
33 vec![commitment, handle]
34 }
35
36 fn psi(witness: &Self::WITNESS, instance: &Self::INSTANCE) -> Vec<SymPoint> {
37 let ZeroCheckWitness { secret_key } = witness;
38
39 vec![
40 secret_key * SymPoint::Const(*G),
41 secret_key * instance.pubkey.clone(),
42 ]
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49 use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT;
50 use curve25519_dalek::Scalar;
51
52 #[test]
53 fn test_zero_check_protocol() {
54 let rng = &mut rand::rngs::OsRng;
55
56 let secret = Scalar::random(rng);
58 let witness = ZeroCheckWitness {
59 secret_key: SymScalar::Const(secret),
60 };
61
62 let public_key_scalar = Scalar::random(rng);
64 let public_key = public_key_scalar * *G;
65
66 let h_generator = *G;
69 let commitment = secret * h_generator;
70
71 let handle = secret * public_key;
73
74 let instance = ZeroCheckInstance {
75 pubkey: SymPoint::Const(public_key),
76 commitment: SymPoint::Const(commitment),
77 handle: SymPoint::Const(handle),
78 };
79
80 let proof = ZeroCheckProtocol::prove(&witness, &instance).unwrap();
82 println!("Zero check proof: {} bytes", proof.len());
83
84 ZeroCheckProtocol::verify(&instance, &proof).unwrap();
85 }
86
87 #[test]
88 fn test_zero_check_spec_generation() {
89 let spec = ZeroCheckProtocol::spec();
90 println!("{spec}");
91 }
92
93 #[test]
94 fn test_zero_check_invalid_proof() {
95 let rng = &mut rand::rngs::OsRng;
96
97 let secret = Scalar::random(rng);
99 let witness = ZeroCheckWitness {
100 secret_key: SymScalar::Const(secret),
101 };
102
103 let public_key_scalar = Scalar::random(rng);
105 let public_key = public_key_scalar * RISTRETTO_BASEPOINT_POINT;
106
107 let wrong_secret = Scalar::random(rng);
109 let h_generator = RISTRETTO_BASEPOINT_POINT;
110 let commitment = wrong_secret * h_generator; let handle = wrong_secret * public_key; let instance = ZeroCheckInstance {
114 pubkey: SymPoint::Const(public_key),
115 commitment: SymPoint::Const(commitment),
116 handle: SymPoint::Const(handle),
117 };
118
119 let proof = ZeroCheckProtocol::prove(&witness, &instance).unwrap();
121
122 assert!(ZeroCheckProtocol::verify(&instance, &proof).is_err());
124 }
125}