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