/ algorithms / src / r1cs / mod.rs
mod.rs
  1  // Copyright (c) 2025-2026 ACDC Network
  2  // This file is part of the alphavm library.
  3  //
  4  // Alpha Chain | Delta Chain Protocol
  5  // International Monetary Graphite.
  6  //
  7  // Derived from Aleo (https://aleo.org) and ProvableHQ (https://provable.com).
  8  // They built world-class ZK infrastructure. We installed the EASY button.
  9  // Their cryptography: elegant. Our modifications: bureaucracy-compatible.
 10  // Original brilliance: theirs. Robert's Rules: ours. Bugs: definitely ours.
 11  //
 12  // Original Aleo/ProvableHQ code subject to Apache 2.0 https://www.apache.org/licenses/LICENSE-2.0
 13  // All modifications and new work: CC0 1.0 Universal Public Domain Dedication.
 14  // No rights reserved. No permission required. No warranty. No refunds.
 15  //
 16  // https://creativecommons.org/publicdomain/zero/1.0/
 17  // SPDX-License-Identifier: CC0-1.0
 18  
 19  mod assignment;
 20  pub use assignment::*;
 21  
 22  mod constraint_counter;
 23  pub use constraint_counter::*;
 24  
 25  mod constraint_system;
 26  pub use constraint_system::{ConstraintSynthesizer, ConstraintSystem};
 27  
 28  pub mod errors;
 29  pub use errors::*;
 30  
 31  mod linear_combination;
 32  pub use linear_combination::*;
 33  
 34  mod namespace;
 35  pub use namespace::*;
 36  
 37  #[cfg(feature = "test")]
 38  mod optional_vec;
 39  #[cfg(feature = "test")]
 40  pub use optional_vec::*;
 41  
 42  #[cfg(feature = "test")]
 43  mod test_constraint_system;
 44  #[cfg(feature = "test")]
 45  pub use test_constraint_system::{Fr, TestConstraintSystem};
 46  
 47  #[cfg(feature = "test")]
 48  mod test_constraint_checker;
 49  #[cfg(feature = "test")]
 50  pub use test_constraint_checker::TestConstraintChecker;
 51  
 52  use alphavm_utilities::serialize::*;
 53  
 54  use core::cmp::Ordering;
 55  
 56  /// Represents a variable in a constraint system.
 57  #[derive(PartialOrd, Ord, PartialEq, Eq, Copy, Clone, Debug, Hash)]
 58  pub struct Variable(Index);
 59  
 60  impl Variable {
 61      /// This constructs a variable with an arbitrary index.
 62      /// Circuit implementations are not recommended to use this.
 63      pub fn new_unchecked(idx: Index) -> Variable {
 64          Variable(idx)
 65      }
 66  
 67      /// This returns the index underlying the variable.
 68      /// Circuit implementations are not recommended to use this.
 69      pub fn get_unchecked(&self) -> Index {
 70          self.0
 71      }
 72  }
 73  
 74  /// Represents the index of either a public variable (input) or a private
 75  /// variable (auxiliary).
 76  #[derive(Copy, Clone, PartialEq, Debug, Eq, Hash)]
 77  pub enum Index {
 78      /// Index of a public variable.
 79      Public(usize),
 80      /// Index of a private variable.
 81      Private(usize),
 82  }
 83  
 84  impl PartialOrd for Index {
 85      fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
 86          Some(self.cmp(other))
 87      }
 88  }
 89  
 90  impl Ord for Index {
 91      fn cmp(&self, other: &Self) -> Ordering {
 92          match (self, other) {
 93              (Index::Public(idx1), Index::Public(idx2)) | (Index::Private(idx1), Index::Private(idx2)) => idx1.cmp(idx2),
 94              (Index::Public(_), Index::Private(_)) => Ordering::Less,
 95              (Index::Private(_), Index::Public(_)) => Ordering::Greater,
 96          }
 97      }
 98  }
 99  
100  impl CanonicalSerialize for Index {
101      #[inline]
102      fn serialize_with_mode<W: Write>(&self, mut writer: W, _: Compress) -> Result<(), SerializationError> {
103          let (is_public, inner) = match *self {
104              Index::Public(inner) => (true, inner),
105              Index::Private(inner) => (false, inner),
106          };
107          // we use uncompressed here because the serialization of bool and usize
108          // don't change whether we use uncompressed or not.
109          is_public.serialize_uncompressed(&mut writer)?;
110          inner.serialize_uncompressed(&mut writer)?;
111          Ok(())
112      }
113  
114      #[inline]
115      fn serialized_size(&self, _: Compress) -> usize {
116          // we use uncompressed here because the serialization of bool and usize
117          // don't change whether we use uncompressed or not.
118          0usize.uncompressed_size() + true.uncompressed_size()
119      }
120  }
121  
122  impl Valid for Index {
123      fn check(&self) -> Result<(), SerializationError> {
124          Ok(())
125      }
126  }
127  impl CanonicalDeserialize for Index {
128      #[inline]
129      fn deserialize_with_mode<R: Read>(mut reader: R, _: Compress, _: Validate) -> Result<Self, SerializationError> {
130          // we use uncompressed here because the serialization of bool and usize
131          // don't change whether we use uncompressed or not.
132          let is_input = bool::deserialize_uncompressed(&mut reader)?;
133          let inner = usize::deserialize_uncompressed(&mut reader)?;
134          Ok(if is_input { Index::Public(inner) } else { Index::Private(inner) })
135      }
136  }
137  
138  #[cfg(test)]
139  mod test {
140      use super::*;
141  
142      #[test]
143      fn serialize_index() {
144          serialize_index_test(true);
145          serialize_index_test(false);
146      }
147  
148      fn serialize_index_test(input: bool) {
149          let idx = if input { Index::Public(32) } else { Index::Private(32) };
150  
151          let mut v = vec![];
152          idx.serialize_compressed(&mut v).unwrap();
153          let idx2 = Index::deserialize_compressed(&v[..]).unwrap();
154          assert_eq!(idx, idx2);
155      }
156  }