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