Skip to main content

ark_r1cs_std/
gr1cs_var.rs

1use ark_ff::Field;
2use ark_relations::gr1cs::{ConstraintSystemRef, SynthesisError};
3use ark_std::vec::Vec;
4
5/// This trait describes some core functionality that is common to high-level
6/// variables, such as `Boolean`s, `FieldVar`s, `GroupVar`s, etc.
7pub trait GR1CSVar<F: Field> {
8    /// The type of the "native" value that `Self` represents in the constraint
9    /// system.
10    type Value: core::fmt::Debug + Eq + Clone;
11
12    /// Returns the underlying `ConstraintSystemRef`.
13    ///
14    /// If `self` is a constant value, then this *must* return
15    /// `ark_relations::gr1cs::ConstraintSystemRef::None`.
16    fn cs(&self) -> ConstraintSystemRef<F>;
17
18    /// Returns `true` if `self` is a circuit-generation-time constant.
19    fn is_constant(&self) -> bool {
20        self.cs().is_none()
21    }
22
23    /// Returns the value that is assigned to `self` in the underlying
24    /// `ConstraintSystem`.
25    fn value(&self) -> Result<Self::Value, SynthesisError>;
26}
27
28impl<F: Field, T: GR1CSVar<F>> GR1CSVar<F> for [T] {
29    type Value = Vec<T::Value>;
30
31    fn cs(&self) -> ConstraintSystemRef<F> {
32        let mut result = ConstraintSystemRef::None;
33        for var in self {
34            result = var.cs().or(result);
35        }
36        result
37    }
38
39    fn value(&self) -> Result<Self::Value, SynthesisError> {
40        let mut result = Vec::new();
41        for var in self {
42            result.push(var.value()?);
43        }
44        Ok(result)
45    }
46}
47
48impl<'a, F: Field, T: 'a + GR1CSVar<F>> GR1CSVar<F> for &'a T {
49    type Value = T::Value;
50
51    fn cs(&self) -> ConstraintSystemRef<F> {
52        (*self).cs()
53    }
54
55    fn value(&self) -> Result<Self::Value, SynthesisError> {
56        (*self).value()
57    }
58}
59
60impl<F: Field, T: GR1CSVar<F>, const N: usize> GR1CSVar<F> for [T; N] {
61    type Value = [T::Value; N];
62
63    fn cs(&self) -> ConstraintSystemRef<F> {
64        let mut result = ConstraintSystemRef::None;
65        for var in self {
66            result = var.cs().or(result);
67        }
68        result
69    }
70
71    fn value(&self) -> Result<Self::Value, SynthesisError> {
72        Ok(core::array::from_fn(|i| self[i].value().unwrap()))
73    }
74}
75
76impl<F: Field> GR1CSVar<F> for () {
77    type Value = ();
78
79    fn cs(&self) -> ConstraintSystemRef<F> {
80        ConstraintSystemRef::None
81    }
82
83    fn value(&self) -> Result<Self::Value, SynthesisError> {
84        Ok(())
85    }
86}