arnaucube
arnaucube/NovaPublic Self-hosted repository
Nova/src/traits/mod.rs
src/traits/mod.rsRaw
  1//! This module defines various traits required by the users of the library to implement.
  2use crate::errors::NovaError;
  3use bellperson::{
  4  gadgets::{boolean::AllocatedBit, num::AllocatedNum},
  5  ConstraintSystem, SynthesisError,
  6};
  7use core::{
  8  fmt::Debug,
  9  ops::{Add, AddAssign, Mul, MulAssign, Sub, SubAssign},
 10};
 11use ff::{PrimeField, PrimeFieldBits};
 12use num_bigint::BigInt;
 13use serde::{Deserialize, Serialize};
 14
 15pub mod commitment;
 16
 17use commitment::CommitmentEngineTrait;
 18
 19/// Represents an element of a group
 20/// This is currently tailored for an elliptic curve group
 21pub trait Group:
 22  Clone
 23  + Copy
 24  + Debug
 25  + Eq
 26  + Sized
 27  + GroupOps
 28  + GroupOpsOwned
 29  + ScalarMul<<Self as Group>::Scalar>
 30  + ScalarMulOwned<<Self as Group>::Scalar>
 31  + Send
 32  + Sync
 33  + Serialize
 34  + for<'de> Deserialize<'de>
 35{
 36  /// A type representing an element of the base field of the group
 37  type Base: PrimeField
 38    + PrimeFieldBits
 39    + TranscriptReprTrait<Self>
 40    + Serialize
 41    + for<'de> Deserialize<'de>;
 42
 43  /// A type representing an element of the scalar field of the group
 44  type Scalar: PrimeFieldBits
 45    + PrimeFieldExt
 46    + Send
 47    + Sync
 48    + TranscriptReprTrait<Self>
 49    + Serialize
 50    + for<'de> Deserialize<'de>;
 51
 52  /// A type representing the compressed version of the group element
 53  type CompressedGroupElement: CompressedGroup<GroupElement = Self>
 54    + Serialize
 55    + for<'de> Deserialize<'de>;
 56
 57  /// A type representing preprocessed group element
 58  type PreprocessedGroupElement: Clone + Debug + Send + Sync + Serialize + for<'de> Deserialize<'de>;
 59
 60  /// A type that represents a circuit-friendly sponge that consumes elements
 61  /// from the base field and squeezes out elements of the scalar field
 62  type RO: ROTrait<Self::Base, Self::Scalar> + Serialize + for<'de> Deserialize<'de>;
 63
 64  /// An alternate implementation of Self::RO in the circuit model
 65  type ROCircuit: ROCircuitTrait<Self::Base> + Serialize + for<'de> Deserialize<'de>;
 66
 67  /// A type that provides a generic Fiat-Shamir transcript to be used when externalizing proofs
 68  type TE: TranscriptEngineTrait<Self>;
 69
 70  /// A type that defines a commitment engine over scalars in the group
 71  type CE: CommitmentEngineTrait<Self> + Serialize + for<'de> Deserialize<'de>;
 72
 73  /// A method to compute a multiexponentation
 74  fn vartime_multiscalar_mul(
 75    scalars: &[Self::Scalar],
 76    bases: &[Self::PreprocessedGroupElement],
 77  ) -> Self;
 78
 79  /// Compresses the group element
 80  fn compress(&self) -> Self::CompressedGroupElement;
 81
 82  /// Produces a preprocessed element
 83  fn preprocessed(&self) -> Self::PreprocessedGroupElement;
 84
 85  /// Produce a vector of group elements using a static label
 86  fn from_label(label: &'static [u8], n: usize) -> Vec<Self::PreprocessedGroupElement>;
 87
 88  /// Returns the affine coordinates (x, y, infinty) for the point
 89  fn to_coordinates(&self) -> (Self::Base, Self::Base, bool);
 90
 91  /// Returns an element that is the additive identity of the group
 92  fn zero() -> Self;
 93
 94  /// Returns the generator of the group
 95  fn get_generator() -> Self;
 96
 97  /// Returns A, B, and the order of the group as a big integer
 98  fn get_curve_params() -> (Self::Base, Self::Base, BigInt);
 99}
100
101/// Represents a compressed version of a group element
102pub trait CompressedGroup:
103  Clone
104  + Copy
105  + Debug
106  + Eq
107  + Sized
108  + Send
109  + Sync
110  + TranscriptReprTrait<Self::GroupElement>
111  + Serialize
112  + for<'de> Deserialize<'de>
113  + 'static
114{
115  /// A type that holds the decompressed version of the compressed group element
116  type GroupElement: Group + Serialize + for<'de> Deserialize<'de>;
117
118  /// Decompresses the compressed group element
119  fn decompress(&self) -> Option<Self::GroupElement>;
120}
121
122/// A helper trait to absorb different objects in RO
123pub trait AbsorbInROTrait<G: Group> {
124  /// Absorbs the value in the provided RO
125  fn absorb_in_ro(&self, ro: &mut G::RO);
126}
127
128/// A helper trait that defines the behavior of a hash function that we use as an RO
129pub trait ROTrait<Base, Scalar> {
130  /// A type representing constants/parameters associated with the hash function
131  type Constants: ROConstantsTrait<Base>
132    + Clone
133    + Send
134    + Sync
135    + Serialize
136    + for<'de> Deserialize<'de>;
137
138  /// Initializes the hash function
139  fn new(constants: Self::Constants, num_absorbs: usize) -> Self;
140
141  /// Adds a scalar to the internal state
142  fn absorb(&mut self, e: Base);
143
144  /// Returns a challenge of `num_bits` by hashing the internal state
145  fn squeeze(&mut self, num_bits: usize) -> Scalar;
146}
147
148/// A helper trait that defines the behavior of a hash function that we use as an RO in the circuit model
149pub trait ROCircuitTrait<Base: PrimeField> {
150  /// A type representing constants/parameters associated with the hash function
151  type Constants: ROConstantsTrait<Base>
152    + Clone
153    + Send
154    + Sync
155    + Serialize
156    + for<'de> Deserialize<'de>;
157
158  /// Initializes the hash function
159  fn new(constants: Self::Constants, num_absorbs: usize) -> Self;
160
161  /// Adds a scalar to the internal state
162  fn absorb(&mut self, e: AllocatedNum<Base>);
163
164  /// Returns a challenge of `num_bits` by hashing the internal state
165  fn squeeze<CS>(&mut self, cs: CS, num_bits: usize) -> Result<Vec<AllocatedBit>, SynthesisError>
166  where
167    CS: ConstraintSystem<Base>;
168}
169
170/// A helper trait that defines the constants associated with a hash function
171pub trait ROConstantsTrait<Base> {
172  /// produces constants/parameters associated with the hash function
173  fn new() -> Self;
174}
175
176/// An alias for constants associated with G::RO
177pub type ROConstants<G> =
178  <<G as Group>::RO as ROTrait<<G as Group>::Base, <G as Group>::Scalar>>::Constants;
179
180/// An alias for constants associated with G::ROCircuit
181pub type ROConstantsCircuit<G> =
182  <<G as Group>::ROCircuit as ROCircuitTrait<<G as Group>::Base>>::Constants;
183
184/// A helper trait for types with a group operation.
185pub trait GroupOps<Rhs = Self, Output = Self>:
186  Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
187{
188}
189
190impl<T, Rhs, Output> GroupOps<Rhs, Output> for T where
191  T: Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
192{
193}
194
195/// A helper trait for references with a group operation.
196pub trait GroupOpsOwned<Rhs = Self, Output = Self>: for<'r> GroupOps<&'r Rhs, Output> {}
197impl<T, Rhs, Output> GroupOpsOwned<Rhs, Output> for T where T: for<'r> GroupOps<&'r Rhs, Output> {}
198
199/// A helper trait for types implementing group scalar multiplication.
200pub trait ScalarMul<Rhs, Output = Self>: Mul<Rhs, Output = Output> + MulAssign<Rhs> {}
201
202impl<T, Rhs, Output> ScalarMul<Rhs, Output> for T where T: Mul<Rhs, Output = Output> + MulAssign<Rhs>
203{}
204
205/// A helper trait for references implementing group scalar multiplication.
206pub trait ScalarMulOwned<Rhs, Output = Self>: for<'r> ScalarMul<&'r Rhs, Output> {}
207impl<T, Rhs, Output> ScalarMulOwned<Rhs, Output> for T where T: for<'r> ScalarMul<&'r Rhs, Output> {}
208
209/// This trait allows types to implement how they want to be added to TranscriptEngine
210pub trait TranscriptReprTrait<G: Group>: Send + Sync {
211  /// returns a byte representation of self to be added to the transcript
212  fn to_transcript_bytes(&self) -> Vec<u8>;
213}
214
215/// This trait defines the behavior of a transcript engine compatible with Spartan
216pub trait TranscriptEngineTrait<G: Group>: Send + Sync {
217  /// initializes the transcript
218  fn new(label: &'static [u8]) -> Self;
219
220  /// returns a scalar element of the group as a challenge
221  fn squeeze(&mut self, label: &'static [u8]) -> Result<G::Scalar, NovaError>;
222
223  /// absorbs any type that implements TranscriptReprTrait under a label
224  fn absorb<T: TranscriptReprTrait<G>>(&mut self, label: &'static [u8], o: &T);
225
226  /// adds a domain separator
227  fn dom_sep(&mut self, bytes: &'static [u8]);
228}
229
230/// Defines additional methods on PrimeField objects
231pub trait PrimeFieldExt: PrimeField {
232  /// Returns a scalar representing the bytes
233  fn from_uniform(bytes: &[u8]) -> Self;
234}
235
236impl<G: Group, T: TranscriptReprTrait<G>> TranscriptReprTrait<G> for &[T] {
237  fn to_transcript_bytes(&self) -> Vec<u8> {
238    self
239      .iter()
240      .flat_map(|t| t.to_transcript_bytes())
241      .collect::<Vec<u8>>()
242  }
243}
244
245pub mod circuit;
246pub mod evaluation;
247pub mod snark;