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