Google Open Sources Longfellow ZK for Privacy-First Age Verification
The newly released cryptographic library aims to help developers comply with strict age laws without storing sensitive user identities.
Age verification is quickly shifting from a compliance checkbox to a major engineering and privacy challenge. Driven by legislative mandates like Texas H.B. 1181, which was upheld by the U.S. Supreme Court in Free Speech Coalition v. Paxton, and the European Union's upcoming eIDAS regulations set for 2026, developers are being forced to verify user ages.
The traditional approach of uploading government IDs, checking credit cards, or running facial estimation is a security liability. It forces applications to collect and store highly sensitive personally identifiable information (PII), creating high-value targets for data breaches. A 2022 analysis by the French regulator CNIL concluded that no existing mainstream age assurance method could simultaneously guarantee reliability, complete population coverage, and data privacy.
To address this, Google has open-sourced longfellow-zk, a library containing the Zero-Knowledge Proof (ZKP) technology built into Google Wallet. By moving the industry toward ZKPs, the goal is to shift the paradigm from verifying raw identity data to verifying cryptographic proofs of predicates.
The Cryptographic Shift: From PII to Predicates
In a standard identity transaction, a user hands over a birthdate (the "witness" in cryptographic terms), and the application verifies if that birthdate is older than a threshold. In a zero-knowledge architecture, the user's device generates a mathematical proof that the witness satisfies a predicate (such as $age \ge 18$) without ever revealing the witness itself.
This architecture relies on a three-party trust model:
- The Issuer: A trusted authority (like a government agency or a bank, such as Google's partner Sparkasse) cryptographically signs a digital credential containing the user's birthdate.
- The Holder: The user's device (running a digital wallet) stores this credential. When prompted, it uses a ZKP library to generate a proof that the credential's birthdate satisfies the application's age requirement.
- The Verifier: Your application receives only the proof and the issuer's public key. It verifies the mathematical proof without ever seeing the user's actual birthdate, name, or identity.
sequenceDiagram
autonumber
participant Issuer as Credential Issuer (Bank/Gov)
participant Wallet as User Wallet (Holder)
participant App as Web App (Verifier)
Issuer->>Wallet: Issue signed credential (Birthdate)
App->>Wallet: Request age proof (Predicate: >= 18)
Wallet->>Wallet: Generate ZK proof using Longfellow
Wallet->>App: Send ZK proof (No birthdate shared)
App->>App: Verify proof against Issuer's public key
This approach decouples identity verification from data collection. If your database is breached, there are no birthdates or driver's licenses to steal, significantly reducing your regulatory and security liability.
Inside the Longfellow ZK Architecture
Google's release of the longfellow-zk library is designed to standardize how these proofs are generated and verified, particularly in the context of the European Digital Identity (EUDI) Wallet.
For developers, the open-sourcing of this codebase solves a major implementation hurdle. Writing secure cryptographic circuits for ZKPs from scratch is notoriously difficult and error-prone. A single bug in a proof-verification routine can allow malicious users to bypass checks entirely. By using a library tested within Google Wallet, developers can leverage audited cryptographic primitives.
While the library handles the heavy lifting of the mathematics, implementing it requires a clear understanding of where the computation happens. The prover side of the library runs on the client device (the wallet), which must be performant enough to generate proofs without causing noticeable latency. The verifier side runs on your backend or within a lightweight API, checking the proof against the issuer's public key in milliseconds.
The Developer Angle: Integration and Real-World Trade-offs
Integrating longfellow-zk into an existing stack is not as simple as calling a standard OAuth endpoint. It requires a fundamental change in how your backend handles user sessions and trust.
1. Trust Anchors and Key Management
Your application must maintain a registry of trusted issuers. If a malicious issuer signs a credential with a fake birthdate, the ZK proof generated by the wallet will still be mathematically valid. Your backend must verify not just the proof, but that the proof was generated from a credential signed by an approved, cryptographically verified issuer (like a state DMV or an authorized financial institution).
2. Client-Side Performance
Generating zero-knowledge proofs is computationally expensive. While verification is fast, generating the proof on a low-end mobile device can take several seconds. Developers must design user interfaces that handle this asynchronous proof-generation step gracefully, ensuring that the app does not appear frozen to the user.
3. Handling Revocation
If an issuer revokes a credential (for example, if a physical ID is reported stolen), your verifier needs a way to check this status. Implementing cryptographic revocation checks, such as checking a cryptographic accumulator or a credential revocation list (CRL), adds complexity to the verification pipeline.
Here is a conceptual Go representation of how a backend verifier might process an incoming age proof using a ZKP library:
package main
import (
"errors"
"fmt"
)
// ProofPayload represents the data sent by the user's wallet
type ProofPayload struct {
Proof []byte
IssuerID string
PredicateValue int
}
// Verifier handles the cryptographic verification of the proof
type Verifier struct {
TrustedIssuers map[string][]byte // Maps IssuerID to Public Key
}
func (v *Verifier) VerifyAgeProof(payload ProofPayload) (bool, error) {
pubKey, exists := v.TrustedIssuers[payload.IssuerID]
if !exists {
return false, errors.New("untrusted credential issuer")
}
// In practice, this calls the underlying C++ or Rust bindings of longfellow-zk
isValid := mockVerifyZKP(payload.Proof, pubKey, payload.PredicateValue)
if !isValid {
return false, errors.New("invalid cryptographic proof")
}
return true, nil
}
func mockVerifyZKP(proof []byte, pubKey []byte, predicate int) bool {
// Cryptographic verification logic occurs here
return len(proof) > 0 && len(pubKey) > 0 && predicate >= 18
}
func main() {
verifier := Verifier{
TrustedIssuers: map[string][]byte{
"gov-id-authority": []byte("public-key-data"),
},
}
payload := ProofPayload{
Proof: []byte("zk-proof-bytes"),
IssuerID: "gov-id-authority",
PredicateValue: 18,
}
valid, err := verifier.VerifyAgeProof(payload)
if err != nil || !valid {
fmt.Println("Verification failed:", err)
return
}
fmt.Println("User age verified successfully without revealing birthdate.")
}
The Path to Production
We are seeing the first real-world deployments of this architecture. Beyond Google's work with Sparkasse, the nonprofit euCONSENT project launched a proof-of-concept for its AgeAware App in April 2025, which issues reusable tokens based on ZKPs to facilitate age verification across different platforms.
For developers, the immediate path forward is to monitor the adoption of digital wallets in your target jurisdictions. If you are building applications that serve European users, preparing your backend to ingest and verify eIDAS-compliant ZK proofs is a highly defensive engineering move. It prepares your infrastructure for upcoming compliance mandates while completely removing the risk of storing sensitive user identification documents on your servers.
Sources & further reading
- Opening up 'Zero-Knowledge Proof' technology to promote privacy in age assurance — blog.google
- Exploring Privacy-Preserving Age Verification: A Close Look at Zero-Knowledge Proofs — newamerica.org
- Google has open sourced its privacy-focused age verification technology. | The Verge — theverge.com
- Google open-sources privacy tech for age verification - Help Net Security — helpnetsecurity.com
Ji-ho covers the increasingly tangled overlap between cloud architecture and security, drawing on a background as a penetration tester to keep his reporting grounded in real-world attack paths. He never lets a vendor claim go unquestioned and insists that every buzzword come with a proof of concept.
Discussion 1
i'm intrigued by longfellow zk's potential to balance age verification with user privacy, but i'd love to see more discussion on the library's licensing and how it plans to ensure community involvement in its development and maintenance 🤔