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