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