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;
 13
 14/// Represents an element of a group
 15/// This is currently tailored for an elliptic curve group
 16pub trait Group:
 17  Clone
 18  + Copy
 19  + Debug
 20  + Eq
 21  + Sized
 22  + GroupOps
 23  + GroupOpsOwned
 24  + ScalarMul<<Self as Group>::Scalar>
 25  + ScalarMulOwned<<Self as Group>::Scalar>
 26  + Send
 27  + Sync
 28{
 29  /// A type representing an element of the base field of the group
 30  type Base: PrimeField + PrimeFieldBits;
 31
 32  /// A type representing an element of the scalar field of the group
 33  type Scalar: PrimeField + PrimeFieldBits + ChallengeTrait + Send + Sync;
 34
 35  /// A type representing the compressed version of the group element
 36  type CompressedGroupElement: CompressedGroup<GroupElement = Self>;
 37
 38  /// A type representing preprocessed group element
 39  type PreprocessedGroupElement: Clone + Send + Sync;
 40
 41  /// A type that represents a hash function that consumes elements
 42  /// from the base field and squeezes out elements of the scalar field
 43  type RO: ROTrait<Self::Base, Self::Scalar>;
 44
 45  /// An alternate implementation of Self::RO in the circuit model
 46  type ROCircuit: ROCircuitTrait<Self::Base>;
 47
 48  /// A method to compute a multiexponentation
 49  fn vartime_multiscalar_mul(
 50    scalars: &[Self::Scalar],
 51    bases: &[Self::PreprocessedGroupElement],
 52  ) -> Self;
 53
 54  /// Compresses the group element
 55  fn compress(&self) -> Self::CompressedGroupElement;
 56
 57  /// Produces a preprocessed element
 58  fn preprocessed(&self) -> Self::PreprocessedGroupElement;
 59
 60  /// Produce a vector of group elements using a static label
 61  fn from_label(label: &'static [u8], n: usize) -> Vec<Self::PreprocessedGroupElement>;
 62
 63  /// Returns the affine coordinates (x, y, infinty) for the point
 64  fn to_coordinates(&self) -> (Self::Base, Self::Base, bool);
 65
 66  /// Returns an element that is the additive identity of the group
 67  fn zero() -> Self;
 68
 69  /// Returns the generator of the group
 70  fn get_generator() -> Self;
 71
 72  /// Returns A, B, and the order of the group as a big integer
 73  fn get_curve_params() -> (Self::Base, Self::Base, BigInt);
 74}
 75
 76/// Represents a compressed version of a group element
 77pub trait CompressedGroup: Clone + Copy + Debug + Eq + Sized + Send + Sync + 'static {
 78  /// A type that holds the decompressed version of the compressed group element
 79  type GroupElement: Group;
 80
 81  /// Decompresses the compressed group element
 82  fn decompress(&self) -> Option<Self::GroupElement>;
 83
 84  /// Returns a byte array representing the compressed group element
 85  fn as_bytes(&self) -> &[u8];
 86}
 87
 88/// A helper trait to append different types to the transcript
 89pub trait AppendToTranscriptTrait {
 90  /// appends the value to the transcript under the provided label
 91  fn append_to_transcript(&self, label: &'static [u8], transcript: &mut Transcript);
 92}
 93
 94/// A helper trait to absorb different objects in RO
 95pub trait AbsorbInROTrait<G: Group> {
 96  /// Absorbs the value in the provided RO
 97  fn absorb_in_ro(&self, ro: &mut G::RO);
 98}
 99
100/// A helper trait to generate challenges using a transcript object
101pub trait ChallengeTrait {
102  /// Returns a Scalar representing the challenge using the transcript
103  fn challenge(label: &'static [u8], transcript: &mut Transcript) -> Self;
104}
105
106/// A helper trait that defines the behavior of a hash function that we use as an RO
107pub trait ROTrait<Base, Scalar> {
108  /// A type representing constants/parameters associated with the hash function
109  type Constants: ROConstantsTrait<Base> + Clone + Send + Sync;
110
111  /// Initializes the hash function
112  fn new(constants: Self::Constants, num_absorbs: usize) -> Self;
113
114  /// Adds a scalar to the internal state
115  fn absorb(&mut self, e: Base);
116
117  /// Returns a challenge of `num_bits` by hashing the internal state
118  fn squeeze(&mut self, num_bits: usize) -> Scalar;
119}
120
121/// A helper trait that defines the behavior of a hash function that we use as an RO in the circuit model
122pub trait ROCircuitTrait<Base: PrimeField> {
123  /// A type representing constants/parameters associated with the hash function
124  type Constants: ROConstantsTrait<Base> + Clone + Send + Sync;
125
126  /// Initializes the hash function
127  fn new(constants: Self::Constants, num_absorbs: usize) -> Self;
128
129  /// Adds a scalar to the internal state
130  fn absorb(&mut self, e: AllocatedNum<Base>);
131
132  /// Returns a challenge of `num_bits` by hashing the internal state
133  fn squeeze<CS>(&mut self, cs: CS, num_bits: usize) -> Result<Vec<AllocatedBit>, SynthesisError>
134  where
135    CS: ConstraintSystem<Base>;
136}
137
138/// A helper trait that defines the constants associated with a hash function
139pub trait ROConstantsTrait<Base> {
140  /// produces constants/parameters associated with the hash function
141  fn new() -> Self;
142}
143
144/// An alias for constants associated with G::RO
145pub type ROConstants<G> =
146  <<G as Group>::RO as ROTrait<<G as Group>::Base, <G as Group>::Scalar>>::Constants;
147
148/// An alias for constants associated with G::ROCircuit
149pub type ROConstantsCircuit<G> =
150  <<G as Group>::ROCircuit as ROCircuitTrait<<G as Group>::Base>>::Constants;
151
152/// A helper trait for types with a group operation.
153pub trait GroupOps<Rhs = Self, Output = Self>:
154  Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
155{
156}
157
158impl<T, Rhs, Output> GroupOps<Rhs, Output> for T where
159  T: Add<Rhs, Output = Output> + Sub<Rhs, Output = Output> + AddAssign<Rhs> + SubAssign<Rhs>
160{
161}
162
163/// A helper trait for references with a group operation.
164pub trait GroupOpsOwned<Rhs = Self, Output = Self>: for<'r> GroupOps<&'r Rhs, Output> {}
165impl<T, Rhs, Output> GroupOpsOwned<Rhs, Output> for T where T: for<'r> GroupOps<&'r Rhs, Output> {}
166
167/// A helper trait for types implementing group scalar multiplication.
168pub trait ScalarMul<Rhs, Output = Self>: Mul<Rhs, Output = Output> + MulAssign<Rhs> {}
169
170impl<T, Rhs, Output> ScalarMul<Rhs, Output> for T where T: Mul<Rhs, Output = Output> + MulAssign<Rhs>
171{}
172
173/// A helper trait for references implementing group scalar multiplication.
174pub trait ScalarMulOwned<Rhs, Output = Self>: for<'r> ScalarMul<&'r Rhs, Output> {}
175impl<T, Rhs, Output> ScalarMulOwned<Rhs, Output> for T where T: for<'r> ScalarMul<&'r Rhs, Output> {}
176
177impl<F: PrimeField> AppendToTranscriptTrait for F {
178  fn append_to_transcript(&self, label: &'static [u8], transcript: &mut Transcript) {
179    transcript.append_message(label, self.to_repr().as_ref());
180  }
181}
182
183impl<F: PrimeField> AppendToTranscriptTrait for [F] {
184  fn append_to_transcript(&self, label: &'static [u8], transcript: &mut Transcript) {
185    for s in self {
186      s.append_to_transcript(label, transcript);
187    }
188  }
189}
190
191pub mod circuit;
192pub mod snark;