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