Skip to content

Latest commit

 

History

62 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Privacy-Preserving Credential Circuits

Open-source Noir reference implementations and EVM verifiers for privacy-preserving credential CIPs.

This repository contains executable circuit code, shared Noir libraries, generated verifier contracts, scripts, and deployment records. Normative statement semantics, trust assumptions, privacy boundaries, and conformance requirements are documented separately in the CIPs repository.

CIP mapping and maturity

CIP Specification Reference path Implementation maturity
CIP-1 Coinbase KYC Attestation coinbase-attestation Reference
CIP-2 Coinbase Country Predicate coinbase-country-attestation Reference
CIP-3 OIDC Domain Attestation oidc-domain-attestation Reference
CIP-4 GIWA Dojang Verified Address Proof giwa-attestation PoC
CIP-5 Korean Mobile ID Selective Disclosure Profile mdl/kr-* Experimental

coinbase-libs is a shared implementation library. coinbase-kyc is an older reference-only circuit. _archived-poc and zktls are outside the current credential CIP mapping.

Implemented circuits

Coinbase KYC attestation — Reference

Proves control of an address named by a signed Coinbase attestAccount(address) transaction while keeping the address, transaction, and signatures private. The circuit verifies user ownership, EIP-1559 transaction structure and signature, signer membership in a public Merkle root, target calldata, and a signal- and scope-bound nullifier.

Coinbase country predicate — Reference

Extends the Coinbase transaction profile with a private two-byte country code and a public inclusion or exclusion list of up to ten ISO 3166-1 alpha-2 values.

OIDC domain attestation — Reference

Verifies a Google Workspace or Microsoft 365 OIDC JWT with RSA-2048 and proves that its private email ends in a public domain. It exposes a provider identifier and an email-derived scope-bound nullifier.

Provider key authorization, JWT freshness, issuer, audience, and nonce policy are not enforced by the current circuit and must be handled by an integration profile.

GIWA attestation — PoC

GIWA Sepolia proof flow using a test MockGiwaAttester, mobile-compatible UltraHonk proof generation, and an EVM verifier. Production Dojang issuer and schema parameters remain unresolved.

Korean Mobile ID predicates — Experimental

Three circuits under mdl/ implement ownership/selective field commitment, year-based age threshold, and region-token predicates. They share keccak256(keccak256(ci) || scope) nullifiers.

The active circuits do not yet cryptographically authenticate claims against a canonical Mobile ID issuer trust anchor.

Shared nullifier schemes

Coinbase and GIWA transaction profiles

user_secret = keccak256(user_address || signal_hash)
nullifier   = keccak256(user_secret || scope)

Duplicate-detection behavior depends on both signal_hash and scope remaining stable for the relevant action.

OIDC domain profile

nullifier = keccak256(keccak256(email) || scope)

Korean Mobile ID experimental profile

nullifier = keccak256(keccak256(ci) || scope)

Nullifier storage is application-specific. NullifierRegistry and ZKProofportNullifierRegistry are deprecated and are retained only as historical source references.

Building

Ledger House staking demo on Arc Testnet

src/LedgerHouseStaking.sol holds real testnet USDC deposits for the calling delegate. It offers no yield. The delegate can withdraw its own balance without another proof; no administrator can withdraw it. The token is Arc's six-decimal ERC-20 USDC interface at 0x3600000000000000000000000000000000000000, on chain 5042002. It uses the Arc eligibility verifier at 0xCbC8E63fF92659E8B44cFF117D33005Bb669a018. The staking contract is deployed at 0xD0F3eE648386B59B484157332E736388Fcc41F47, in transaction 0x92f07f307b0b597b4786ca2f9c816297ad3db63694874842a213709f88ae4ba7.

The signed EIP-712 domain is Ledger House Staking, version 1, the current chain ID and the staking contract's address. The struct is CredentialDelegation(address delegate,string action,uint256 amount,uint256 expiresAt,string nonce); action must be stake, and amount is in six-decimal token units. The constructor pins the accepted Coinbase signer Merkle root. SCOPE is keccak256("ledger-house").

stake(amount, proof, publicInputs, expiresAt, nonce) requires exactly 192 byte-valued fields: signal at 0, domain at 32, action at 64, signer root at 96, scope at 128 and nullifier at 160. stakePacked accepts the same fields as 6144 concatenated bytes (192 ABI words, without an array header), for wallet CLIs. Both entrypoints share validation and replay state. A nonempty nonce is limited to 128 bytes; a nonempty proof is limited to 65536 bytes. Deadlines must be strictly later than the current block timestamp. Reuse of a sender's nonce or an action hash is refused, including after withdrawal. A fresh signed action can reuse the credential's nullifier for a repeat demonstration.

balances(delegate) reads the position. withdraw(amount) sends only to msg.sender. Staked(delegate, amount, actionHash) and Withdrawn(delegate, amount) describe completed token movements. Failed proof verification or token transfer rolls back balances and replay markers.

With pinned Foundry 1.4.3, run forge test --match-contract LedgerHouseStakingTest. The deployment entrypoint is script/DeployLedgerHouseStaking.s.sol; it reads PRIVATE_KEY and LEDGER_HOUSE_SIGNER_ROOT from the environment. Use Arc's RPC and execute a dry run before adding --broadcast:

forge script script/DeployLedgerHouseStaking.s.sol:DeployLedgerHouseStaking \
  --rpc-url https://rpc.testnet.arc.io

The SDK buildSignerMerkleTree(0) root for the current four authorized signers is 0xb60da9815c76261b61a1e91f199de5845fc171a6500e57c4240d2ac61d85e2bf. Recompute it from the SDK when the signer list changes; do not accept a root supplied by a proof. Foundry writes the deployment receipt under broadcast/DeployLedgerHouseStaking.s.sol/5042002/run-latest.json.

The current generated artifacts were built with:

  • nargo 1.0.0-beta.8
  • bb v1.0.0-nightly.20250723
./scripts/build.sh coinbase-attestation
./scripts/build.sh coinbase-country-attestation
./scripts/build.sh oidc-domain-attestation
./scripts/build.sh giwa-attestation
./scripts/build.sh mdl/kr-ownership
./scripts/build.sh mdl/kr-age
./scripts/build.sh mdl/kr-region

Generated Solidity verifiers expose the common interface:

function verify(bytes calldata proof, bytes32[] calldata publicInputs)
    external
    view
    returns (bool);

See each pinned CIP for semantic public-input ordering and conformance requirements.

Reference deployments

The tables below are synchronized with broadcast/**/run-latest.json at revision 28bbc303e04b732eb612d419b44dfd39d8a38a9a.

Ethereum Sepolia — chain ID 11155111

Circuit Verifier Deployment record
Coinbase KYC 0xcbc8e63ff92659e8b44cff117d33005bb669a018 DeployCoinbaseAttestation
Coinbase Country 0x6646d970499bbed728636823a5a7e551e811b414 DeployCoinbaseCountryAttestation
OIDC Domain 0x07121eb50b2ebe1675e7cb96c84b580a3ff6589e DeployOidcDomainAttestation

Base Sepolia — chain ID 84532

Circuit Verifier Deployment record
Coinbase KYC 0x0036b61dbfab8f3cfeef77dd5d45f7efbfe2035c DeployCoinbaseAttestation
Coinbase Country 0xdee363585926c3c28327efd1edd01cf4559738cf DeployCoinbaseCountryAttestation
OIDC Domain 0x27afdea349f247cf698f97fdfab59e1bf8bd0550 DeployOidcDomainAttestation
Mobile ID ownership 0x7602d09d24e6e16eff5ab981646872886376763e DeployMdlKrOwnership
Mobile ID age 0xcff90ff8ceadc98f625300dc976ed85a3aa943ba DeployMdlKrAge
Mobile ID region 0x435f0448f02f5df9659d460181116bcaf37e518e DeployMdlKrRegion

Base Mainnet — chain ID 8453

Circuit Verifier Deployment record
Coinbase KYC 0xf7ded73e7a7fc8fb030c35c5a88d40abe6865382 DeployCoinbaseAttestation
Coinbase Country 0xf3d5a09d2c85b28c52ef2905c1be3a852b609d0c DeployCoinbaseCountryAttestation
OIDC Domain 0x9677ba46ad226ce8b3c4517d9c0143e4d458beae DeployOidcDomainAttestation

GIWA Sepolia — chain ID 91342

Circuit Verifier Deployment record
GIWA attestation PoC 0xeb9eb5452790cfe549ff83ceb3dbe1c432231492 DeployGiwaAttestation

Deploying verifiers

Deployment scripts are under script/, with generated verifier sources under each circuit's target/ directory. The generic helper accepts configured network names:

./scripts/deploy_verifier.sh coinbase-attestation base-sepolia

Environment-specific keys, RPC URLs, and explorer credentials are required.

Security status

No external security audit or formal verification is documented for the current circuits. Review each CIP's trust assumptions and known limitations before relying on a reference implementation or deployment.

License

MIT, preserving the repository's existing license intent. Vendored dependencies retain their respective licenses.

About

No description or website provided.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages