/ algorithms / src / r1cs / mod.rs
mod.rs
  1  // Copyright (c) 2025 ADnet Contributors
  2  // This file is part of the AlphaVM 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  
 16  mod assignment;
 17  pub use assignment::*;
 18  
 19  mod constraint_counter;
 20  pub use constraint_counter::*;
 21  
 22  mod constraint_system;
 23  pub use constraint_system::{ConstraintSynthesizer, ConstraintSystem};
 24  
 25  pub mod errors;
 26  pub use errors::*;
 27  
 28  mod linear_combination;
 29  pub use linear_combination::*;
 30  
 31  mod namespace;
 32  pub use namespace::*;
 33  
 34  #[cfg(feature = "test")]
 35  mod optional_vec;
 36  #[cfg(feature = "test")]
 37  pub use optional_vec::*;
 38  
 39  #[cfg(feature = "test")]
 40  mod test_constraint_system;
 41  #[cfg(feature = "test")]
 42  pub use test_constraint_system::{Fr, TestConstraintSystem};
 43  
 44  #[cfg(feature = "test")]
 45  mod test_constraint_checker;
 46  #[cfg(feature = "test")]
 47  pub use test_constraint_checker::TestConstraintChecker;
 48  
 49  use alphavm_utilities::serialize::*;
 50  
 51  use core::cmp::Ordering;
 52  
 53  /// Represents a variable in a constraint system.
 54  #[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, Debug, Hash)]
 55  pub struct Variable(Index);
 56  
 57  impl 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)]
 74  pub enum Index {
 75      /// Index of a public variable.
 76      Public(usize),
 77      /// Index of a private variable.
 78      Private(usize),
 79  }
 80  
 81  impl PartialOrd for Index {
 82      fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
 83          Some(self.cmp(other))
 84      }
 85  }
 86  
 87  impl Ord for Index {
 88      fn cmp(&self, other: &Self) -> Ordering {
 89          match (self, other) {
 90              (Index::Public(idx1), Index::Public(idx2)) | (Index::Private(idx1), Index::Private(idx2)) => idx1.cmp(idx2),
 91              (Index::Public(_), Index::Private(_)) => Ordering::Less,
 92              (Index::Private(_), Index::Public(_)) => Ordering::Greater,
 93          }
 94      }
 95  }
 96  
 97  impl 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  
119  impl Valid for Index {
120      fn check(&self) -> Result<(), SerializationError> {
121          Ok(())
122      }
123  }
124  impl 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)]
136  mod 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  }