In January 2023, the U.S. Department of Justice charged 25 people in a scheme that sold more than 7,600 fake nursing diplomas from three Florida schools. The buyers used those diplomas to sit for national board exams, obtain state licenses, and get jobs in hospitals across at least nine states – nurses who had never completed clinical training, treating real patients. The federal investigation, dubbed “Operation Nightingale,” is still active: a second wave of charges landed in 2025. The scheme only came to light through a federal enforcement action, not through any built-in safeguard in the credentialing system itself.
This is what happens when credentials live in disconnected silos, verified by manual processes that assume documents are genuine because they look genuine. Every credential issuer – every university, employer, certification body – operates its own database with its own format and its own verification mechanism (if any). There is no common standard, no universal way for a third party to independently check authenticity, and no mechanism for the holder to control where and how their credentials are shared. The result is a multi-billion-dollar background check industry built on the difficulty of doing something that should be straightforward.
We built a protocol and working proof of concept that takes a different approach. It combines W3C Verifiable Credentials v2.0 – an open web standard for machine-verifiable credentials, finalized in May 2025 – with blockchain as an accountability layer for anchoring credential hashes and managing revocation. We’re publishing a research paper with the full protocol design, architecture, cross-chain comparison, and results, alongside the source code on GitHub.
How It Works
The system has three layers: off-chain credential operations (key generation, credential creation, JWT signing, signature verification), a user interface (CLI and web), and blockchain backends that implement the same logical interface on each supported chain.
The flow has four stages. An issuer creates a credential following the W3C VC v2.0 format, signs it as a JWT with their Ed25519 private key, and delivers it to the holder. The issuer then computes the SHA-256 hash of the complete signed JWT and registers it on a blockchain – this establishes that the credential existed at a specific point in time and provides a revocation channel. When the holder wants to prove a credential, they present the signed JWT directly to a verifier. The verifier performs two independent checks: validating the JWT signature using the issuer’s public key (extracted from the did:key in the header – no network call needed), and querying the blockchain for the credential’s hash to confirm it is registered, not revoked, and not expired.
The credential content – who you worked for, what certification you hold, which skills your peers endorse – stays with the holder. The blockchain sees only hashes. This keeps costs low, preserves privacy, and avoids the scalability constraints of on-chain data storage.
To demonstrate that the protocol is genuinely chain-agnostic, we implemented it on two architecturally different blockchains: Ethereum (Solidity) and IOTA Rebased (Move). Both chains implement the same smart contract interface – register, revoke, query status, check validity – and the same credential, signed the same way, produces the same hash on either chain. The proof of concept includes a CLI for the full credential lifecycle, a web interface with three views (Issue, Credentials, Verify) and a chain selector, and automated end-to-end scenarios exercising three credential types: employment credentials, professional certifications, and peer endorsements.
What We Found
We ran all three credential scenarios on both chains. Each scenario issues credentials, registers them on-chain, verifies them, and – in the employment scenario – revokes and re-verifies.
When we issued an employment credential, registered it on Ethereum, then revoked it and verified again, the system correctly returned REVOKED. The signature was still valid (the JWT itself hadn’t changed), but the on-chain status showed the issuer had withdrawn their attestation. This is the core value proposition working as designed: revocation is transparent and immediate, and any verifier sees the current status without contacting the issuer.
Registration cost on EVM was consistent at approximately 140,000 gas units per credential. Revocation was significantly cheaper at around 32,000 gas – it only flips a boolean in an existing storage slot. Verification costs zero gas on both chains (a read operation, not a transaction). On IOTA, the first registration cost approximately 5 million NANOS, with subsequent ones settling at around 4 million. On IOTA’s mainnet, basic transactions are feeless, making high-volume credential anchoring economically attractive.
The most practically useful finding was the developer experience comparison. Ethereum’s mature Python tooling (web3.py) made the backend implementation straightforward at 220 lines. IOTA’s lack of a Python SDK required constructing raw JSON-RPC calls, implementing the signing scheme manually, and parsing BCS-encoded responses – 640 lines to achieve the same result. This is a maturity gap, not a fundamental limitation. Move’s type safety caught issues at compile time that Solidity would only surface at runtime, and IOTA’s object model enables an elegant read pattern (direct dynamic field lookups instead of executing contract code). But a Python developer working with IOTA today should expect to do more manual work.
The most significant finding is that the JWT credential itself – not the smart contract, not the backend code – is the portability layer. A credential issued for Ethereum is bit-for-bit identical to one issued for IOTA, because issuance and signing happen entirely off-chain. Adding a third blockchain would require only a new backend module and contract, with zero changes to the credential format, signing, or verification logic.

Challenges and Honest Limitations
This is a proof of concept, not a production system. Several real limitations remain.
No selective disclosure. Presenting a credential means presenting all of it. You can’t prove you worked at a company without also revealing your job title and dates. The credential architecture is designed so that selective disclosure can be added later (flat fields, no nested structures), but it’s not implemented yet.
No key rotation. The did:key method used in this PoC encodes the public key directly in the identifier. If a private key is compromised, the corresponding DID must be abandoned. Production systems would use DID methods with rotation support.
Trust bootstrapping. The protocol uses an open issuer model – anyone can register a credential hash. Trust is the verifier’s responsibility, just as in the physical world: you trust a university degree because you trust the university, not because a central authority certified it. But the protocol doesn’t address how a verifier discovers which issuers to trust. In practice, this would involve issuer directories or institutional trust frameworks.
Credential recovery. If the holder loses their signed JWT, the on-chain hash alone can’t reconstruct it. Backup and recovery is a wallet-level concern not addressed here.
What’s Next
Selective disclosure is the next research project in this series. The goal is to let a credential holder prove specific claims – “I hold a valid AWS certification” – without revealing the full credential. We’re evaluating SD-JWT, BBS+ signatures, and hash-based field commitments as implementation approaches. The foundation laid in this project was designed specifically to support this extension without reworking the on-chain contracts or verification protocol.
Beyond selective disclosure, the IOTA Python SDK gap we encountered led directly to pyiota, our open-source Python SDK for IOTA Rebased. The credential wallet concept connects to our C6 Test Wallet project. Both are part of the broader Consensix Labs effort to build practical multi-chain infrastructure.
The full discussion of the protocol, architecture, cross-chain comparison, and future directions is in the research paper. The source code, including both smart contracts, the CLI, the web interface, and automated scenario scripts, is available on GitHub. The code is provided for research and educational purposes and has not been audited for production use.
