This is a template for creating zkPDF projects using SP1 that verifies PDF document content and extracts information from PDF files to generate zero-knowledge proofs.
This is an example repository that demonstrates how to verify digitally signed PDFs in ZKVM:
- Digital Signature Verification: Shows how to validate PDF digital signatures
- Content Extraction: Demonstrates extracting information from PDF content (GST numbers, legal names, etc.)
- Zero-Knowledge Proofs: Example of generating proofs that verify document validity without revealing sensitive data
- On-Chain Verification: Complete example with smart contracts for verifying proofs on Ethereum
You can check out the digitally signed PDF in samples/ and see how the verification process works.
There are 3 main ways to run this project: execute a program, generate a core proof, and generate an EVM-compatible proof.
The program is automatically built through script/build.rs when the script is built.
To run the program without generating a proof:
cd script
RUST_LOG=info cargo run --release -- --executeThis will execute the program and display the output.
To generate an SP1 core proof for your program:
cd script
RUST_LOG=info cargo run --release -- --proveWarning
You will need at least 16GB RAM to generate a Groth16 or PLONK proof. View the SP1 docs for more information.
Generating a proof that is cheap to verify on the EVM (e.g. Groth16 or PLONK) is more intensive than generating a core proof.
To generate a Groth16 proof:
cd script
RUST_LOG=info cargo run --release --bin evm -- --system groth16To generate a PLONK proof:
cd script
RUST_LOG=info cargo run --release --bin evm -- --system plonkThese commands will also generate fixtures that can be used to test the verification of SP1 proofs inside Solidity.
To retrieve your programVKey for your on-chain contract, run the following command in script:
cargo run --release --bin vkeyWe highly recommend using the Succinct Prover Network for any non-trivial programs or benchmarking purposes. For more information, see the key setup guide to get started.
To get started, copy the example environment file:
cp .env.example .envThen, set the SP1_PROVER environment variable to network and set the NETWORK_PRIVATE_KEY environment variable to your whitelisted private key.
For example, to generate an EVM-compatible proof using the prover network, run the following command:
cd script
RUST_LOG=info SP1_PROVER=network NETWORK_PRIVATE_KEY=... cargo run --release --bin evmThe template includes a web API for easy integration:
cd script
RUST_LOG=info cargo run --package zkpdf-template-script --bin apiVisit http://localhost:3000 to use the web interface.
You can specify a custom PDF path:
RUST_LOG=info cargo run --package zkpdf-template-script -- --execute --pdf-path /path/to/your/certificate.pdfprogram/- Core ZK program for PDF verificationlib/- Shared library with verification logicscript/- CLI tools and web APIcontracts/- Solidity contracts for on-chain verificationsamples/- Example PDF documents
You can turn any unsigned PDF into a demo document with an embedded RSA + SHA256
signature using the helper script in tools/sign_pdf.py. The script relies on
pyHanko so you'll need a Python
environment with the necessary dependencies:
python3 -m venv .venv-signing
source .venv-signing/bin/activate
pip install pyhanko pyhanko-certvalidator cryptographyOnce the dependencies are installed, run the script with the PDF you want to sign:
python tools/sign_pdf.py --pdf-path samples/GST-certificate.pdfBy default the script:
- Creates a self-signed RSA key + certificate (stored under
samples/credentials/) if you do not provide your own PEM files. - Signs the pdf and writes the result to
samples/GST-certificate-signed.pdf.
You can customize the output path, signature field name, visible widget box,
reason/contact metadata, key/cert paths, and more. Run
python tools/sign_pdf.py --help for the full list of options.