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