PLONK verification
This guide explains how PLONK (Permutations over Lagrange-bases for Oecumenical Noninteractive arguments of Knowledge) verification is implemented in the zkp-demo dapp to ensure the integrity of private token operations.
What is PLONK verification?
PLONK verification is the process of cryptographically validating that a zero-knowledge proof was generated correctly without revealing the underlying private information. In our course, it ensures that operations like private transfers, shielding, and unshielding are mathematically valid while maintaining privacy.
Core verification function: zkp.check_plonk_proof
Function overview
The zkp.check_plonk_proof
method is Chromia's built-in function for verifying PLONK proofs within blockchain operations:
/**
* Checks whether or not the current transaction contains a valid PLONK proof.
*
* @param verification_key_id ID of the verification key that the proof must have been validated with
* @param public_signals The public signals that the proof must have been validated with
*/
function check_plonk_proof(
verification_key_id: text,
public_signals: list<big_integer>
)
Verification requirements
For PLONK verification to work in the dapp, the transaction must include a zkp_plonk_verify
GTX operation containing:
- Verification key ID: Must match a key configured in
chromia.yml
- PLONK proof: The cryptographic proof data generated by the circuit
- Public signals: Public values that the proof validates
Dapp verification keys
The course uses three different verification keys for different operations:
# chromia.yml configuration
zkp:
plonk:
verification_keys:
private_transfer: # For anonymous transfers
curve: bn128
nPublic: 5
shield_operation: # For converting public to private tokens
curve: bn128
nPublic: 4
unshield_operation: # For converting private to public tokens
curve: bn128
nPublic: 4
Verification security features
Double-spending prevention
The verification process includes nullifier checks to prevent the same proof from being used multiple times:
// Check if nullifier has been used before
require_not_exists(nullifier_registry @* { .nullifier == nullifier });
// Register the nullifier after successful verification
create nullifier_registry(nullifier = nullifier, block_height = op_context.block_height);
Signal integrity
check_plonk_proof
ensures that:
- Public signals match exactly what was submitted in the proof
- The proof was generated with the correct circuit constraints
- No tampering occurred during transmission
Circuit constraint validation
The PLONK proof mathematically guarantees that:
- The prover knows the private key for the commitment
- Arithmetic relationships (like balances) are correctly maintained
- All circuit logic was properly executed
This PLONK verification system ensures that all private operations in the course maintain both privacy and mathematical correctness, forming the foundation of the secure private token transfer system.