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