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