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