Skip to main content

sigma_proof_compiler/
absorb.rs

1use curve25519_dalek::{RistrettoPoint, Scalar};
2use rand_core::CryptoRngCore;
3
4use crate::errors::{SigmaProofError, SigmaProofResult};
5
6//
7// Traits only available in this crate
8//
9
10pub(crate) mod sealed_witness {
11    pub trait Sealed {}
12
13    impl Sealed for super::SymScalar {}
14}
15
16pub(crate) mod sealed_instance {
17    pub trait Sealed {}
18
19    impl Sealed for super::SymScalar {}
20    impl Sealed for super::SymPoint {}
21}
22
23pub trait SymWitness: sealed_witness::Sealed {
24    fn rand<R: CryptoRngCore + ?Sized>(rng: &mut R) -> Self;
25    fn values(&self) -> SigmaProofResult<Vec<Scalar>>;
26    fn from_values(scalars: &[Scalar]) -> SigmaProofResult<Self>
27    where
28        Self: Sized;
29    fn num_scalars() -> usize;
30    fn get_var_name(index: usize) -> &'static str;
31}
32
33pub trait SymInstance: sealed_instance::Sealed {
34    fn num_scalars() -> usize;
35    fn num_points() -> usize;
36    fn from_values(scalars: &[Scalar], points: &[RistrettoPoint]) -> SigmaProofResult<Self>
37    where
38        Self: Sized;
39    fn get_field_names() -> Vec<&'static str>;
40    fn points(&self) -> Vec<SymPoint>;
41    fn scalars(&self) -> Vec<SymScalar>;
42}
43
44//
45// Implementations
46//
47
48pub use crate::equations::{SymPoint, SymScalar};
49pub use sigma_proof_compiler_derive::{SymInstance, SymWitness};
50
51impl SymWitness for SymScalar {
52    fn rand<R: CryptoRngCore + ?Sized>(rng: &mut R) -> Self {
53        SymScalar::Const(Scalar::random(rng))
54    }
55
56    fn values(&self) -> SigmaProofResult<Vec<Scalar>> {
57        match self {
58            SymScalar::Var(None) => Err(SigmaProofError::UninstantiatedScalar),
59            _ => Ok(vec![self.evaluate()?]),
60        }
61    }
62
63    fn from_values(scalars: &[Scalar]) -> SigmaProofResult<Self> {
64        if scalars.len() == 1 {
65            Ok(SymScalar::Var(Some(scalars[0])))
66        } else {
67            Err(SigmaProofError::TooManyScalars {
68                expected: 1,
69                actual: scalars.len(),
70            })
71        }
72    }
73
74    fn num_scalars() -> usize {
75        1
76    }
77
78    fn get_var_name(index: usize) -> &'static str {
79        if index == 0 {
80            "s"
81        } else {
82            "unknown"
83        }
84    }
85}
86
87impl SymInstance for SymScalar {
88    fn num_scalars() -> usize {
89        1
90    }
91
92    fn num_points() -> usize {
93        0
94    }
95
96    fn from_values(scalars: &[Scalar], points: &[RistrettoPoint]) -> SigmaProofResult<Self> {
97        if scalars.len() == 1 && points.is_empty() {
98            Ok(SymScalar::Const(scalars[0]))
99        } else {
100            Err(SigmaProofError::TooManyScalars {
101                expected: 1,
102                actual: scalars.len(),
103            })
104        }
105    }
106
107    fn get_field_names() -> Vec<&'static str> {
108        vec!["scalar"]
109    }
110
111    fn points(&self) -> Vec<SymPoint> {
112        vec![]
113    }
114
115    fn scalars(&self) -> Vec<SymScalar> {
116        vec![self.clone()]
117    }
118}
119
120impl SymInstance for SymPoint {
121    fn num_scalars() -> usize {
122        0
123    }
124
125    fn num_points() -> usize {
126        1
127    }
128
129    fn from_values(scalars: &[Scalar], points: &[RistrettoPoint]) -> SigmaProofResult<Self> {
130        if scalars.is_empty() && points.len() == 1 {
131            Ok(SymPoint::Const(points[0]))
132        } else {
133            Err(SigmaProofError::TooManyScalars {
134                expected: 0,
135                actual: scalars.len(),
136            })
137        }
138    }
139
140    fn get_field_names() -> Vec<&'static str> {
141        vec!["point"]
142    }
143
144    fn points(&self) -> Vec<SymPoint> {
145        vec![self.clone()]
146    }
147
148    fn scalars(&self) -> Vec<SymScalar> {
149        vec![]
150    }
151}