Plonky2 Verifier
settlementPlonky2Palletâ
Statement hash componentsâ
- context:
keccak256(b"plonky2") - vk:
keccak256(vk.encode()) - pubs:
keccak256(pubs)
Verifier implementationâ
Assume we have built plonky2 circuit and proved it:
let data = builder.build::<C>();let proof = data.prove(pw)?;
Verification Keyâ
Plonky2 needs the GateSerializer trait to serialize VerifierCircuitData; for that please use ZKVerifyGateSerializer, since we will deserialize against it as well.
use plonky2_verifier::ZKVerifyGateSerializer;let vk_bytes = data.verifier_data().to_bytes(&ZKVerifyGateSerializer)?;
Proofâ
let mut proof_bytes = Vec::new();proof_bytes.write_proof(&proof.proof)?;
Public Inputsâ
Plonky2 keeps Proof with Pubs in one struct, while zkVerify requires these to be split.
let mut pubs_bytes = Vec::new();pubs_bytes.write_usize(proof.public_inputs.len())?;pubs_bytes.write_field_vec(proof.public_inputs.as_slice())?;
Configâ
Plonky2 has generic-based configuration for its plonk: config.rs. Things like hashing algorithm, field, etc. Due to limited support for passing them in zkVerify, we support only two preset configs over Keccak with Goldilocks and Poseidon with Goldilocks.
Therefore, we use custom format for representing Vk - particularly, JSON of this form:
{"config": "Poseidon","bytes": "392093829392..."}
Here bytes is hex-encoded representation of vk_bytes we computed earlier, and config is merely either Keccak or Poseidon.
You can leverage our CLI tool in order to transform your Vk into the one acceptable by zkVerify format - please see plonky2-converter.
Resultâ
The submitProof exstrinsic can fail either if it's not possible to deserialize the proof (InvalidProofData), or if the proof doesn't
verify (VerifyError).