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
72/// variable (auxiliary).
73#[derive(Copy, Clone, PartialEq, Debug, Eq, Hash)]
74pub enum Index {
75    /// Index of a public variable.
76    Public(usize),
77    /// Index of a private variable.
78    Private(usize),
79}
80
81impl PartialOrd for Index {
82    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
83        Some(self.cmp(other))
84    }
85}
86
87impl Ord for Index {
88    fn cmp(&self, other: &Self) -> Ordering {
89        match (self, other) {
90            (Index::Public(ref idx1), Index::Public(ref idx2))
91            | (Index::Private(ref idx1), Index::Private(ref idx2)) => idx1.cmp(idx2),
92            (Index::Public(_), Index::Private(_)) => Ordering::Less,
93            (Index::Private(_), Index::Public(_)) => Ordering::Greater,
94        }
95    }
96}
97
98impl CanonicalSerialize for Index {
99    #[inline]
100    fn serialize_with_mode<W: Write>(&self, mut writer: W, _: Compress) -> Result<(), SerializationError> {
101        let (is_public, inner) = match *self {
102            Index::Public(inner) => (true, inner),
103            Index::Private(inner) => (false, inner),
104        };
105        // we use uncompressed here because the serialization of bool and usize
106        // don't change whether we use uncompressed or not.
107        is_public.serialize_uncompressed(&mut writer)?;
108        inner.serialize_uncompressed(&mut writer)?;
109        Ok(())
110    }
111
112    #[inline]
113    fn serialized_size(&self, _: Compress) -> usize {
114        // we use uncompressed here because the serialization of bool and usize
115        // don't change whether we use uncompressed or not.
116        0usize.uncompressed_size() + true.uncompressed_size()
117    }
118}
119
120impl Valid for Index {
121    fn check(&self) -> Result<(), SerializationError> {
122        Ok(())
123    }
124}
125impl CanonicalDeserialize for Index {
126    #[inline]
127    fn deserialize_with_mode<R: Read>(mut reader: R, _: Compress, _: Validate) -> Result<Self, SerializationError> {
128        // we use uncompressed here because the serialization of bool and usize
129        // don't change whether we use uncompressed or not.
130        let is_input = bool::deserialize_uncompressed(&mut reader)?;
131        let inner = usize::deserialize_uncompressed(&mut reader)?;
132        Ok(if is_input { Index::Public(inner) } else { Index::Private(inner) })
133    }
134}
135
136#[cfg(test)]
137mod test {
138    use super::*;
139
140    #[test]
141    fn serialize_index() {
142        serialize_index_test(true);
143        serialize_index_test(false);
144    }
145
146    fn serialize_index_test(input: bool) {
147        let idx = if input { Index::Public(32) } else { Index::Private(32) };
148
149        let mut v = vec![];
150        idx.serialize_compressed(&mut v).unwrap();
151        let idx2 = Index::deserialize_compressed(&v[..]).unwrap();
152        assert_eq!(idx, idx2);
153    }
154}