Modern financial applications increasingly require users to prove financial information such as account balances or income. As Coinbase explains in its post “The Bank Secrecy Act is broken. Technology can fix it”, today’s compliance systems rely heavily on collecting and storing raw user data rather than verifying specific claims. In practice, this means users are asked to upload full bank statements, grant broad API access, or rely on centralized data aggregators, exposing far more information than necessary and creating unnecessary trust, custody, and security risks.
From a product and protocol-design perspective, this led us to a fundamental question:
Is it possible to prove specific properties of a financial document without revealing the document itself and/or trusting an intermediary?
This question is especially relevant in decentralized systems, where permissioned APIs, OAuth flows, and institutional integrations are either undesirable or fundamentally incompatible with self-sovereign design principles. If verification and compliance are to exist in decentralized environments, they must be derived from cryptographic guarantees, not privileged access.
To explore this, we conducted an experiment using zkPDF, developed by PSE at the Ethereum Foundation. zkPDF enables zero-knowledge proofs over cryptographically signed PDF documents, allowing verifiable statements about real-world documents without disclosing their contents.
Rather than building new infrastructure or modifying existing banking systems, our focus was on identifying already-deployed products that unintentionally support this model.
During this research, we came across Enpara, a digital bank in Turkiye. Enpara issues official bank statements as PDFs containing embedded cryptographic signatures, enabling independent verification of document authenticity and integrity. Although Enpara does not explicitly target zero-knowledge use cases, this design choice makes its statements a natural fit for zkPDF-based verification.
This case study demonstrates how existing banking products with digital transformation and without APIs, permissions, or cooperation from the issuer can already support privacy-preserving verification workflows when combined with zero-knowledge tooling.
The Problem
The problem is simple but precise. How can we prove: "User X has > $10,000 balance" based on an official document?
Approaches
The Traditional Approach: The user uploads the PDF to a server. The server gains full visibility into the document. Privacy is effectively zero.
The Desired Approach: The user proves a claim client-side. The raw PDF never leaves their device. The verifier only receives a cryptographic proof asserting whether the claim is true or false.
Technical Discovery
When we analyzed the structure of Enpara’s bank statement PDFs, we discovered a well-structured and standards-compliant trust model which aligns closely with zkPDF’s functionalities.
Document Signatures (CAdES)
Each Enpara bank statement PDF contains 2 CAdES detached signatures from bank employees and 2 RFC3161 timestamps embedded in the document:
- Signature format: ETSI CAdES (CMS / PKCS#7)
- Signing algorithm: RSA with SHA-256 (PKCS#1 v1.5)
- Signer: Enpara bank employees (individual signing certificates)
These signatures cryptographically bind the PDF contents, including balances, transactions, and metadata to the signer’s private key. Any modification to the document would make the signature verification fail.
Certificate Authorities and Root of Trust
The signing certificates used by Enpara employees are issued by E-Tugra, which is an electronic certificate service provider authorized by the Information and Communication Technologies Authority (BTK), Turkiye's national telecom and information technology regulator.
- E-Tugra CA algorithm: ECDSA with SHA-384 (P-384)
- Purpose: Signing the certificates, not the PDF contents
In addition, Enpara PDFs include RFC3161 DocTimeStamp signatures issued by TurkTrust, which is also an electronic certificate service provider, providing cryptographic proof of when the document existed:
- TSA signature algorithm: RSA-SHA256
- TSA certificate issuer: TurkTrust (ECDSA-SHA256, P-384)
The resulting trust chain is:
- E-Tugra (ECDSA-SHA384) signs Enpara employee certificates
- Enpara signers (RSA-SHA256) sign the PDF document (CAdES)
- TurkTrust TSA (RSA-SHA256) timestamps the signatures (RFC3161)
This separation is important for understanding what zkPDF is responsible for and how it is used:
- ECDSA-SHA384 is used only at the CA layer
- RSA-SHA256 is used at the document and timestamp layers
Since zkPDF does not yet support ECDSA verification or certificate chain validation, verification is currently limited to the document and timestamp layers. In addition, because multiple-signature verification is not yet supported, zkPDF can verify only a single signature per PDF document.
You can track supported and unsupported features here.
Once the signature is verified, zkPDF performs regex-based text extraction, knowing that the extracted fields are from an authentic and unmodified document.
TODO: We need to host the image on our Github repo rather than using the Twitter/X link.
Verification Flow
Here's an example flow :
For more details, feel free to explore our open-source Enpara PDF parser and signature verifier here.
Why This Works
This relies on the deterministic execution inside the zkVM. In this case it's SP1.
Integrity: Signature verification happens first. Any modification would cause verification to fail.
Privacy: The PDF never leaves the zkVM assuming that proof is generated on client-side. Only a succinct proof is revealed.
The CMap Bug
After we analyzed Enpara's PDF documents and started using it with zkPDF, we were not able to do selective disclosure properly because the extracted text was showing `` replacement characters instead of Turkish text and for example the balance field was unreadable.
After debugging the issue, we found out that the root cause was Enpara PDFs use concatenated hex format in ToUnicode CMaps:
<0003><0003><0020> // Enpara format (concatenated)
<0003> <0003> <0020> // Expected format (spaced)
The function that parses text ( split_ascii_whitespace()) was silently failing on concatenated sequences and that's why character mappings were lost.
Our Fix
To resolve this issue, we submitted PR #8 to the zkPDF repository.
We updated the split_hex_values() function to correctly handle both concatenated and whitespace-separated hex formats in ToUnicode CMaps.
After this change, Turkish characters were extracted correctly and the affected fields became parseable and we were able to do selective disclosure successfully.
Validated Use Cases
Using this pipeline, we were able to prove claims mentioned below about the Enpara bank statements without revealing the full documents:
- Proof of funds, the account balance exceeds a specified threshold (visas, rentals, due diligence).
- Account ownership, a specific account holder name appears in the document
- Transaction proof, a transfer to a specific IBAN exists in the statement.
- Asset purchase proof, a gold purchase is recorded in the statement.
Current Limitations / Bottlenecks & Future Work
zkPDF currently verifies a single document signature per proof. Documents containing multiple signatures or requiring full certificate chain verification (CA-level signatures etc.) would require additional changes. Supporting multi-signature verification and additional signature schemes like ECDSA would really improve zkPDF’s adaptability for these types of use cases.
zkPDF is integrated with SP1’s prover network. Prover networks make it much easier to use since generating proofs is very expensive to run on a typical personal device. However, the downside is that it adds a trust assumption compared to doing everything fully on the client. While client-side proving is possible, it usually requires powerful hardware. For users who want full self-sovereignty, or for production and enterprise use, this means either running your own prover infrastructure or accepting the trust model. Fully client-side proving on everyday devices is still a future goal.
Conclusion
This case study shows that privacy-preserving financial verification is already possible today without new banking APIs, special permissions, or cooperation from the issuer. By combining zkPDF with Enpara’s existing digitally signed PDF statements, we were able to prove concrete financial claims without revealing the underlying documents.
The key insight is not that zkPDF introduces new cryptography, but that it connects existing cryptographic guarantees to zero-knowledge proofs. Enpara already signs its documents using well-established standards. zkPDF simply enforces those guarantees inside a zkVM and proves statements about the verified content.
The real bottleneck is therefore not zero-knowledge technology, it is adoption. Most financial institutions still do not cryptographically sign user-facing documents in a verifiable way. Enpara is an exception, and that exception is enough to unlock entirely new, privacy-first compliance and verification workflows.
The takeaway from this experiment is simple: compliance does not need more data collection, it needs better verification. Zero-knowledge proofs over signed documents offer a solid path toward selective disclosure, reduced data custody, and self-sovereign compliance.
If you are exploring self-sovereign or decentralized identities, self-sovereign compliance, or regulatory technologies powered by zero-knowledge proofs, we’d be happy to connect. Feel free to reach out at contact[at]trionlabs.dev or send us a DM on Twitter/X.