rsnark_provers_core/backend.rs
1use rsnark_core::{
2 MetadataInfo,
3 types::{CircuitDefinition, PublicWitness, Witness},
4};
5
6/// Core trait defining the interface for zero-knowledge proof backends.
7///
8/// This trait abstracts over different ZK-SNARK implementations (such as Groth16, PLONK, Marlin, etc.)
9/// and provides a unified interface for circuit compilation, trusted setup, proof generation, and verification.
10///
11/// ## Type Parameters
12///
13/// The trait defines several associated types that must be implemented by concrete backends:
14/// - `CircuitConstraint`: The internal representation of compiled circuit constraints
15/// - `ProvingKey`: The proving key generated during the trusted setup phase
16/// - `VerifyingKey`: The verifying key generated during the trusted setup phase
17/// - `Error`: The error type for backend-specific operations
18///
19/// ## Workflow
20///
21/// The typical workflow when using a backend implementation:
22/// 1. Create a new backend instance with [`Backend::new()`]
23/// 2. Compile the circuit definition with [`Backend::compile()`]
24/// 3. Perform trusted setup with [`Backend::setup()`] to generate keys
25/// 4. Generate proofs with [`Backend::prove()`]
26/// 5. Verify proofs with [`Backend::verify()`]
27///
28pub trait Backend {
29 type CircuitConstraint;
30 type ProvingKey;
31 type VerifyingKey;
32 type Proof;
33
34 /// Error type for backend operations that must implement standard error traits.
35 type Error: std::error::Error + Send + Sync + 'static;
36
37 /// Creates a new instance of the backend.
38 ///
39 /// This is typically used to initialize any backend-specific state or configuration.
40 fn new() -> Self;
41
42 fn metadata(&self) -> MetadataInfo;
43
44 /// Compiles a circuit definition into the backend's internal constraint representation.
45 ///
46 /// This method takes a high-level circuit definition and converts it into the specific
47 /// constraint system format required by the backend implementation.
48 ///
49 /// # Arguments
50 ///
51 /// * `circuit` - The circuit definition to compile
52 ///
53 /// # Returns
54 ///
55 /// Returns the compiled circuit constraints on success, or an error if compilation fails.
56 ///
57 /// # Errors
58 ///
59 /// This function may return an error if:
60 /// - The circuit definition is malformed or invalid
61 /// - The backend cannot represent the given circuit constraints
62 /// - Internal compilation errors occur
63 fn compile(&self, circuit: &CircuitDefinition) -> Result<Self::CircuitConstraint, Self::Error>;
64
65 /// Performs the trusted setup phase to generate proving and verifying keys.
66 ///
67 /// This is a critical phase in ZK-SNARK systems that generates the cryptographic keys
68 /// required for proof generation and verification. The setup is specific to the compiled
69 /// circuit constraints.
70 ///
71 /// # Arguments
72 ///
73 /// * `cs` - The compiled circuit constraints from [`Backend::compile()`]
74 ///
75 /// # Returns
76 ///
77 /// Returns a tuple containing the proving key and verifying key on success.
78 ///
79 /// # Security Note
80 ///
81 /// The security of the entire proving system depends on this setup phase being performed
82 /// correctly and the setup randomness being properly discarded ("toxic waste").
83 fn setup(
84 &self,
85 cs: &Self::CircuitConstraint,
86 ) -> Result<(Self::ProvingKey, Self::VerifyingKey), Self::Error>;
87
88 /// Generates a zero-knowledge proof for the given witness.
89 ///
90 /// Creates a cryptographic proof that demonstrates knowledge of a valid witness
91 /// satisfying the circuit constraints, without revealing the witness itself.
92 ///
93 /// # Arguments
94 ///
95 /// * `cs` - The compiled circuit constraints
96 /// * `pk` - The proving key from the trusted setup
97 /// * `witness` - The complete witness (both public and private inputs)
98 ///
99 /// # Returns
100 ///
101 /// Returns the generated proof on success.
102 ///
103 /// # Errors
104 ///
105 /// This function may return an error if:
106 /// - The witness does not satisfy the circuit constraints
107 /// - The proving key is incompatible with the circuit constraints
108 /// - Cryptographic operations fail during proof generation
109 fn prove(
110 &self,
111 cs: &Self::CircuitConstraint,
112 pk: &Self::ProvingKey,
113 witness: &Witness,
114 ) -> Result<Self::Proof, Self::Error>;
115
116 /// Verifies a zero-knowledge proof against public inputs.
117 ///
118 /// Checks whether a given proof is valid for the specified public witness,
119 /// without requiring knowledge of the private witness components.
120 ///
121 /// # Arguments
122 ///
123 /// * `vk` - The verifying key from the trusted setup
124 /// * `proof` - The proof to verify
125 /// * `public_witness` - The public inputs and outputs
126 ///
127 /// # Returns
128 ///
129 /// Returns `true` if the proof is valid, `false` otherwise.
130 ///
131 /// # Errors
132 ///
133 /// This function may return an error if:
134 /// - The verifying key is malformed or incompatible
135 /// * The proof format is invalid
136 /// - Cryptographic verification operations fail
137 fn verify(
138 &self,
139 vk: &Self::VerifyingKey,
140 proof: &Self::Proof,
141 public_witness: &PublicWitness,
142 ) -> Result<bool, Self::Error>;
143}