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