snarkvm_r1cs/
lib.rs

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