snarkvm_algorithms/r1cs/
mod.rs

1// Copyright 2024 Aleo Network Foundation
2// This file is part of the snarkVM library.
3
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at:
7
8// http://www.apache.org/licenses/LICENSE-2.0
9
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16mod assignment;
17pub use assignment::*;
18
19mod constraint_counter;
20pub use constraint_counter::*;
21
22mod constraint_system;
23pub use constraint_system::{ConstraintSynthesizer, ConstraintSystem};
24
25pub mod errors;
26pub use errors::*;
27
28mod linear_combination;
29pub use linear_combination::*;
30
31mod namespace;
32pub use namespace::*;
33
34#[cfg(feature = "test")]
35mod optional_vec;
36#[cfg(feature = "test")]
37pub use optional_vec::*;
38
39#[cfg(feature = "test")]
40mod test_constraint_system;
41#[cfg(feature = "test")]
42pub use test_constraint_system::{Fr, TestConstraintSystem};
43
44#[cfg(feature = "test")]
45mod test_constraint_checker;
46#[cfg(feature = "test")]
47pub use test_constraint_checker::TestConstraintChecker;
48
49use snarkvm_utilities::serialize::*;
50
51use core::cmp::Ordering;
52
53/// Represents a variable in a constraint system.
54#[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, Debug, Hash)]
55pub struct Variable(Index);
56
57impl Variable {
58    /// This constructs a variable with an arbitrary index.
59    /// Circuit implementations are not recommended to use this.
60    pub fn new_unchecked(idx: Index) -> Variable {
61        Variable(idx)
62    }
63
64    /// This returns the index underlying the variable.
65    /// Circuit implementations are not recommended to use this.
66    pub fn get_unchecked(&self) -> Index {
67        self.0
68    }
69}
70
71/// Represents the index of either a public variable (input) or a private variable (auxiliary).
72#[derive(Copy, Clone, PartialEq, Debug, Eq, Hash)]
73pub enum Index {
74    /// Index of a public variable.
75    Public(usize),
76    /// Index of a private variable.
77    Private(usize),
78}
79
80impl PartialOrd for Index {
81    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
82        Some(self.cmp(other))
83    }
84}
85
86impl Ord for Index {
87    fn cmp(&self, other: &Self) -> Ordering {
88        match (self, other) {
89            (Index::Public(ref idx1), Index::Public(ref idx2))
90            | (Index::Private(ref idx1), Index::Private(ref idx2)) => idx1.cmp(idx2),
91            (Index::Public(_), Index::Private(_)) => Ordering::Less,
92            (Index::Private(_), Index::Public(_)) => Ordering::Greater,
93        }
94    }
95}
96
97impl CanonicalSerialize for Index {
98    #[inline]
99    fn serialize_with_mode<W: Write>(&self, mut writer: W, _: Compress) -> Result<(), SerializationError> {
100        let (is_public, inner) = match *self {
101            Index::Public(inner) => (true, inner),
102            Index::Private(inner) => (false, inner),
103        };
104        // we use uncompressed here because the serialization of bool and usize
105        // don't change whether we use uncompressed or not.
106        is_public.serialize_uncompressed(&mut writer)?;
107        inner.serialize_uncompressed(&mut writer)?;
108        Ok(())
109    }
110
111    #[inline]
112    fn serialized_size(&self, _: Compress) -> usize {
113        // we use uncompressed here because the serialization of bool and usize
114        // don't change whether we use uncompressed or not.
115        0usize.uncompressed_size() + true.uncompressed_size()
116    }
117}
118
119impl Valid for Index {
120    fn check(&self) -> Result<(), SerializationError> {
121        Ok(())
122    }
123}
124impl CanonicalDeserialize for Index {
125    #[inline]
126    fn deserialize_with_mode<R: Read>(mut reader: R, _: Compress, _: Validate) -> Result<Self, SerializationError> {
127        // we use uncompressed here because the serialization of bool and usize
128        // don't change whether we use uncompressed or not.
129        let is_input = bool::deserialize_uncompressed(&mut reader)?;
130        let inner = usize::deserialize_uncompressed(&mut reader)?;
131        Ok(if is_input { Index::Public(inner) } else { Index::Private(inner) })
132    }
133}
134
135#[cfg(test)]
136mod test {
137    use super::*;
138
139    #[test]
140    fn serialize_index() {
141        serialize_index_test(true);
142        serialize_index_test(false);
143    }
144
145    fn serialize_index_test(input: bool) {
146        let idx = if input { Index::Public(32) } else { Index::Private(32) };
147
148        let mut v = vec![];
149        idx.serialize_compressed(&mut v).unwrap();
150        let idx2 = Index::deserialize_compressed(&v[..]).unwrap();
151        assert_eq!(idx, idx2);
152    }
153}