Proof Lifecycle
Proof Lifecycle - From Generation to Verification
This document describes the complete lifecycle of zero-knowledge proofs in the Roru Protocol, from generation through verification to finalization.
Lifecycle Overview
Stages
The proof lifecycle consists of five main stages:
Witness Construction: Building the witness from private inputs
Circuit Execution: Running the zero-knowledge circuit
Proof Generation: Creating the cryptographic proof
Proof Verification: Verifying the proof validity
State Update: Updating the shielded state
Stage 1: Witness Construction
Witness Components
Witness Structure:
pub struct Witness {
pub input_notes: Vec<Note>,
pub output_notes: Vec<Note>,
pub input_randomness: Vec<Scalar>,
pub output_randomness: Vec<Scalar>,
pub nullifier_keys: Vec<Scalar>,
pub merkle_paths: Vec<MerklePath>,
pub balance: u64,
pub fee: u64,
}Construction Process
Steps:
Select input notes
Generate output notes
Collect randomness values
Build Merkle paths
Calculate balance
Assemble witness
Construction Code:
fn construct_witness(
inputs: &[Note],
outputs: &[Note],
state: &StateTree,
) -> Witness {
let mut merkle_paths = Vec::new();
for note in inputs {
let path = state.get_merkle_path(note.index);
merkle_paths.push(path);
}
Witness {
input_notes: inputs.to_vec(),
output_notes: outputs.to_vec(),
input_randomness: inputs.iter().map(|n| n.randomness).collect(),
output_randomness: outputs.iter().map(|n| n.randomness).collect(),
nullifier_keys: inputs.iter().map(|n| n.nullifier_key).collect(),
merkle_paths,
balance: calculate_balance(inputs, outputs),
fee: calculate_fee(inputs.len(), outputs.len()),
}
}Stage 2: Circuit Execution
Circuit Structure
Circuit Components:
Input validation
Output validation
Balance verification
Nullifier generation
Merkle path verification
Authorization check
Execution Process
Execution Steps:
Load witness into circuit
Execute input constraints
Execute output constraints
Execute balance constraints
Execute nullifier constraints
Execute Merkle path constraints
Generate constraint system
Execution Code:
fn execute_circuit(witness: &Witness) -> ConstraintSystem {
let mut cs = ConstraintSystem::new();
// Input constraints
for (i, note) in witness.input_notes.iter().enumerate() {
add_input_constraints(&mut cs, note, &witness.merkle_paths[i]);
}
// Output constraints
for note in &witness.output_notes {
add_output_constraints(&mut cs, note);
}
// Balance constraints
add_balance_constraints(&mut cs, &witness);
// Nullifier constraints
add_nullifier_constraints(&mut cs, &witness);
cs
}Stage 3: Proof Generation
Generation Process
Generation Steps:
Load proving key
Execute circuit
Generate proof using Groth16
Serialize proof
Verify proof locally
Generation Code:
fn generate_proof(witness: &Witness, proving_key: &ProvingKey) -> Proof {
let constraint_system = execute_circuit(witness);
let proof = groth16::prove(proving_key, constraint_system, witness)?;
let serialized = proof.serialize();
// Local verification
verify_proof_locally(&proof, &verifying_key)?;
Proof {
proof: serialized,
public_inputs: extract_public_inputs(witness),
}
}Proof Format
Proof Structure:
pub struct Proof {
pub a: Point, // Proof component A
pub b: Point, // Proof component B
pub c: Point, // Proof component C
pub public_inputs: Vec<Scalar>, // Public inputs
}Stage 4: Proof Verification
Verification Process
Verification Steps:
Load verifying key
Deserialize proof
Extract public inputs
Verify pairing equation
Check all constraints
Verification Code:
fn verify_proof(proof: &Proof, verifying_key: &VerifyingKey, state: &State) -> bool {
// Verify pairing equation
let pairing_check = pairing(proof.a, proof.b) ==
pairing(proof.c, verifying_key.gamma) *
pairing(public_inputs, verifying_key.delta);
if !pairing_check {
return false;
}
// Verify public inputs match state
verify_public_inputs(&proof.public_inputs, state)?;
true
}Batch Verification
Batch Process:
Collect multiple proofs
Batch verify using pairing
Verify all public inputs
Check consistency
Batch Code:
fn batch_verify(proofs: &[Proof], verifying_key: &VerifyingKey) -> bool {
let mut batch_a = Vec::new();
let mut batch_b = Vec::new();
let mut batch_c = Vec::new();
for proof in proofs {
batch_a.push(proof.a);
batch_b.push(proof.b);
batch_c.push(proof.c);
}
batch_pairing_verify(&batch_a, &batch_b, &batch_c, verifying_key)
}Stage 5: State Update
Update Process
Update Steps:
Verify proof
Check nullifiers
Add new notes to tree
Add nullifiers to set
Update state root
Publish update
Update Code:
fn update_state(
state: &mut StateTree,
proof: &Proof,
nullifiers: &[Nullifier],
new_notes: &[Note],
) -> Result<StateRoot> {
// Verify proof
if !verify_proof(proof, &verifying_key, state) {
return Err(Error::InvalidProof);
}
// Check nullifiers
for nullifier in nullifiers {
if state.nullifier_set.contains(nullifier) {
return Err(Error::DoubleSpend);
}
}
// Add new notes
for note in new_notes {
let commitment = commit_note(note);
state.insert_commitment(commitment)?;
}
// Add nullifiers
for nullifier in nullifiers {
state.nullifier_set.insert(nullifier);
}
// Update root
let new_root = state.update_root();
Ok(new_root)
}Proof Storage
Storage Format
Storage Structure:
Proof data: Serialized proof
Metadata: Proof metadata
Timestamp: Creation time
Status: Verification status
Storage Locations
Storage Options:
Local device storage
Encrypted storage
Backup storage
Network storage (encrypted)
Proof Transmission
Transmission Format
Transmission Structure:
Proof bundle
Encryption
Signature
Metadata
Transmission Channels
Channels:
Network: Encrypted HTTP/WebSocket
Offline: NFC/Bluetooth/QR
Direct: Device-to-device
Error Handling
Error Types
Proof Errors:
Invalid witness
Circuit execution failure
Proof generation failure
Verification failure
State update failure
Error Recovery
Recovery Strategies:
Retry proof generation
Validate inputs
Check state consistency
Reconstruct witness
Performance
Generation Time
Typical Times:
Witness construction: <100ms
Circuit execution: 1-3 seconds
Proof generation: 1-2 seconds
Total: 2-5 seconds
Verification Time
Typical Times:
Proof deserialization: <10ms
Verification: <100ms
State update: <50ms
Total: <200ms
Security
Security Properties
Proof Security:
Zero-knowledge property
Soundness
Completeness
Non-malleability
Security Guarantees
Guarantees:
Cannot forge proofs
Cannot extract witness
Cannot modify proofs
Cryptographically secure
Conclusion
The proof lifecycle provides:
Completeness: All stages covered
Security: Cryptographic guarantees
Efficiency: Optimized operations
Reliability: Error handling
Privacy: Zero-knowledge property
Understanding the lifecycle is essential for proof system development.
Last updated
