#![cfg_attr(not(feature = "std"), no_std)] //! This crate implements common "gadgets" that make //! programming rank-1 constraint systems easier. #![deny( warnings, unused, future_incompatible, nonstandard_style, rust_2018_idioms )] #![allow(clippy::op_ref)] #[macro_use] extern crate ark_std; #[macro_use] extern crate ark_relations; #[doc(hidden)] #[macro_use] extern crate derivative; /// Some utility macros for making downstream impls easier. #[macro_use] pub mod macros; pub(crate) use ark_std::vec::Vec; use ark_ff::Field; /// This module implements gadgets related to bit manipulation, such as /// `Boolean` and `UInt`s. pub mod bits; pub use self::bits::*; /// This module implements gadgets related to field arithmetic. pub mod fields; /// This module implements gadgets related to group arithmetic, and specifically /// elliptic curve arithmetic. pub mod groups; /// This module implements gadgets related to computing pairings in bilinear /// groups. pub mod pairing; /// This module describes a trait for allocating new variables in a constraint /// system. pub mod alloc; /// This module describes a trait for checking equality of variables. pub mod eq; /// This module implements functions for manipulating polynomial variables over finite fields. pub mod poly; /// This module describes traits for conditionally selecting a variable from a /// list of variables. pub mod select; #[allow(missing_docs)] pub mod prelude { pub use crate::{ alloc::*, bits::{boolean::Boolean, uint32::UInt32, uint8::UInt8, ToBitsGadget, ToBytesGadget}, eq::*, fields::{FieldOpsBounds, FieldVar}, groups::{CurveVar, GroupOpsBounds}, pairing::PairingVar, select::*, R1CSVar, }; } /// This trait describes some core functionality that is common to high-level /// variables, such as `Boolean`s, `FieldVar`s, `GroupVar`s, etc. pub trait R1CSVar { /// The type of the "native" value that `Self` represents in the constraint /// system. type Value: core::fmt::Debug + Eq + Clone; /// Returns the underlying `ConstraintSystemRef`. /// /// If `self` is a constant value, then this *must* return /// `ark_relations::r1cs::ConstraintSystemRef::None`. fn cs(&self) -> ark_relations::r1cs::ConstraintSystemRef; /// Returns `true` if `self` is a circuit-generation-time constant. fn is_constant(&self) -> bool { self.cs().is_none() } /// Returns the value that is assigned to `self` in the underlying /// `ConstraintSystem`. fn value(&self) -> Result; } impl> R1CSVar for [T] { type Value = Vec; fn cs(&self) -> ark_relations::r1cs::ConstraintSystemRef { let mut result = ark_relations::r1cs::ConstraintSystemRef::None; for var in self { result = var.cs().or(result); } result } fn value(&self) -> Result { let mut result = Vec::new(); for var in self { result.push(var.value()?); } Ok(result) } } impl<'a, F: Field, T: 'a + R1CSVar> R1CSVar for &'a T { type Value = T::Value; fn cs(&self) -> ark_relations::r1cs::ConstraintSystemRef { (*self).cs() } fn value(&self) -> Result { (*self).value() } } /// A utility trait to convert `Self` to `Result pub trait Assignment { /// Converts `self` to `Result`. fn get(self) -> Result; } impl Assignment for Option { fn get(self) -> Result { self.ok_or(ark_relations::r1cs::SynthesisError::AssignmentMissing) } } /// Specifies how to convert a variable of type `Self` to variables of /// type `FpVar` pub trait ToConstraintFieldGadget { /// Converts `self` to `FpVar` variables. fn to_constraint_field( &self, ) -> Result>, ark_relations::r1cs::SynthesisError>; }