arnaucube
arnaucube/ark-r1cs-stdPublic Self-hosted repository
ark-r1cs-std/r1cs-std/src/alloc.rs
r1cs-std/src/alloc.rsRaw
 1use crate::Vec;
 2use algebra::Field;
 3use core::borrow::Borrow;
 4use r1cs_core::{Namespace, SynthesisError};
 5
 6#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone)]
 7pub enum AllocationMode {
 8    Constant = 0,
 9    Input = 1,
10    Witness = 2,
11}
12
13impl AllocationMode {
14    // Outputs the maximum according to the relation `Constant < Input < Witness`.
15    pub fn max(&self, other: Self) -> Self {
16        use AllocationMode::*;
17        match (self, other) {
18            (Constant, _) => other,
19            (Input, Constant) => *self,
20            (Input, _) => other,
21            (Witness, _) => *self,
22        }
23    }
24}
25
26pub trait AllocVar<V, F: Field>
27where
28    Self: Sized,
29    V: ?Sized,
30{
31    fn new_variable<T: Borrow<V>>(
32        cs: impl Into<Namespace<F>>,
33        f: impl FnOnce() -> Result<T, SynthesisError>,
34        mode: AllocationMode,
35    ) -> Result<Self, SynthesisError>;
36
37    #[tracing::instrument(target = "r1cs", skip(cs, t))]
38    fn new_constant(
39        cs: impl Into<Namespace<F>>,
40        t: impl Borrow<V>,
41    ) -> Result<Self, SynthesisError> {
42        Self::new_variable(cs, || Ok(t), AllocationMode::Constant)
43    }
44
45    #[tracing::instrument(target = "r1cs", skip(cs, f))]
46    fn new_input<T: Borrow<V>>(
47        cs: impl Into<Namespace<F>>,
48        f: impl FnOnce() -> Result<T, SynthesisError>,
49    ) -> Result<Self, SynthesisError> {
50        Self::new_variable(cs, f, AllocationMode::Input)
51    }
52
53    #[tracing::instrument(target = "r1cs", skip(cs, f))]
54    fn new_witness<T: Borrow<V>>(
55        cs: impl Into<Namespace<F>>,
56        f: impl FnOnce() -> Result<T, SynthesisError>,
57    ) -> Result<Self, SynthesisError> {
58        Self::new_variable(cs, f, AllocationMode::Witness)
59    }
60}
61
62impl<I, F: Field, A: AllocVar<I, F>> AllocVar<[I], F> for Vec<A> {
63    fn new_variable<T: Borrow<[I]>>(
64        cs: impl Into<Namespace<F>>,
65        f: impl FnOnce() -> Result<T, SynthesisError>,
66        mode: AllocationMode,
67    ) -> Result<Self, SynthesisError> {
68        let ns = cs.into();
69        let cs = ns.cs();
70        let mut vec = Vec::new();
71        for value in f()?.borrow().iter() {
72            vec.push(A::new_variable(cs.clone(), || Ok(value), mode)?);
73        }
74        Ok(vec)
75    }
76}