Skip to content

Status & maturity

View Markdown

ZeroJ is experimental research software. Some parts are feature-complete and heavily tested; others are opt-in experiments. None of it has been externally audited. This page tells you exactly where each component stands, so you can decide what is reasonable to build on and what to treat as a prototype.

As the repository README states, ZeroJ is generated using AI, with human-assisted design, testing, and verification. That’s one more reason to treat every component as unaudited until an external review says otherwise.

LabelMeaning in ZeroJ
BetaFeature-complete and correctness-tested. The repository has more than 3,500 tests, and the full Groth16 flow is verified end-to-end on-chain against Yaci DevKit. Not externally audited, and not for value-bearing or mainnet use.
Beta, testnet onlyBeta, and additionally limited to test networks. Nothing of value should depend on it.
Beta with caveatBeta, with a specific known limitation you must design around. The caveat is named in the matrix.
Beta, opt-inBeta, but you have to add it explicitly; it’s never pulled in by default.
ExperimentalOpt-in, may change, and may have known limitations. Use for evaluation and research, not as a foundation.
Disabled by defaultLegacy code kept for explicit experiments. It refuses to run unless you set a flag.
Assurance onlyIndependent implementations used to cross-check ZeroJ in CI. Never published and never a runtime option.

“Beta” is a statement about completeness and testing. It is not a security claim.

The matrix below restates the project’s support matrix. Groth16 on BLS12-381 is the focus of the current release and the default in every recommendation.

AreaModulesStatus
Core proof model, codecs, verifier SPI and orchestratorzeroj-api, zeroj-codec, zeroj-backend-spiBeta
Circuit definition: DSL, symbolic annotations, gadgetszeroj-circuit-dsl, zeroj-circuit-annotation-api, zeroj-circuit-annotation-processor, zeroj-circuit-libBeta, with per-gadget status (see Gadgets)
BLS12-381 pure-Java primitiveszeroj-bls12381Beta, verification-grade
AreaModulesStatus
Groth16 BLS12-381: pure-Java prove and verifyzeroj-crypto, zeroj-verifier-groth16Beta. Production keys require an external snarkjs MPC ceremony; the in-repo setup is dev-only and flag-gated.
Groth16 BLS12-381: on-chain (JuLC / Plutus V3)zeroj-onchain-julcBeta, testnet only, not value-bearing. Real validators must bind the proof to ScriptContext (see Verify proofs on Cardano).
blst native accelerationzeroj-blst, zeroj-crypto-blstBeta, opt-in. FFM binding, libblst built from source (pinned v0.3.15).
AreaModulesStatus
PlonK BLS12-381: pure-Java prove and verify, .ptau/.zkey importzeroj-crypto, zeroj-verifier-plonkExperimental
PlonK BLS12-381: on-chain (JuLC / Plutus V3)zeroj-onchain-julcExperimental. Labeled testnet trials only.
AreaModulesStatus
BBS (IRTF CFRG draft-10): verificationzeroj-bbsBeta. The spec is an IRTF draft, not yet an RFC.
BBS: issuance and proof generationzeroj-bbsBeta with caveat. The default pure-Java provider is not constant-time; prefer the blst provider for issuer keys.
AreaModulesStatus
Poseidon authenticated state (MPF, JMT)zeroj-mpf-poseidon, zeroj-jmt-poseidonExperimental. High-volume paths are benchmarked (5M-entry local end-to-end runs passed), but production ceremonies, external review, and Yaci/public-network gates remain open.
AreaModulesStatus
BN254 (Groth16 and PlonK, off-chain)legacy classesDisabled by default. Requires -Dzeroj.allowLegacyBn254=true. BN254 is not a Cardano curve.
BLS12-381 and BBS WASM differential providersassurance/zeroj-bls12381-wasm, assurance/zeroj-bbs-wasmAssurance only. Independent zkcrypto and zkryptium oracles, outside the default build and never published.

What “not for production” means in practice

Section titled “What “not for production” means in practice”

“Don’t use this in production” is easy to say and easy to ignore. Here is what it means concretely for ZeroJ today:

  • No external audit. No third party has reviewed the provers, verifiers, circuits, gadgets, or on-chain validators. Bugs that tests didn’t anticipate may exist, including soundness bugs that would let someone forge a proof.
  • Development setup is not a ceremony. The in-process trusted setup (PowersOfTauBLS381.generate, Groth16Keys.setupInMemory, Groth16SetupBLS381.setup) knows its own toxic waste and can forge proofs. It only runs with -Dzeroj.allowInsecureTrustedSetup=true. Anything beyond local testing needs keys from a multi-party ceremony. See Trusted setup, explained.
  • On-chain means testnet. The on-chain Groth16 verifier is tested on Yaci DevKit and is labeled testnet-only. Don’t lock real ADA or tokens behind it.
  • A valid proof isn’t authorization. The reusable on-chain verifiers only check the math. Your validator must still prevent replay, bind the proof to the transaction, track nullifiers, and enforce who may do what. See Application security.
  • No constant-time guarantee for Java code. The BBS pure-Java provider uses fixed-schedule arithmetic for secret scalars, but that is not a full JVM constant-time guarantee. For BBS issuer keys, select the native blst provider. ZeroJ doesn’t claim constant-time behavior for its Java code.
  • PlonK is experimental, off-chain and on-chain.
  • APIs and coordinates can still change. ZeroJ is pre-1.0. The move to org.zeroj in 0.1.0-pre12 is one example (see Migration).

What you can reasonably do today: learn ZK, prototype applications, run the demos, evaluate designs, benchmark, and run testnet experiments that protect nothing of value.

The project tries to avoid the classic trap of a library only ever agreeing with itself. Where possible, expected values come from somewhere other than the code under test.

Kind of evidenceExamples in ZeroJ
Unit and regression testsMore than 3,500 tests across modules, including invalid-witness, proof-tampering, wrong-public-input, and public-input-order tests
Official test vectorsIETF RFC 9380 hash-to-curve vectors for BLS12-381; the official CFRG BBS draft-10 fixtures (SHA-256 and SHAKE-256 ciphersuites)
Differential tests against independent implementationszkcrypto BLS12-381 and zkryptium BBS compiled to WASM and run as oracles in a dedicated assurance CI job; Poseidon checked against published circomlibjs vectors (BN254) and an independent SageMath implementation of the Poseidon paper spec (BLS12-381)
Cross-provider equivalenceThe same BBS vectors run against the pure-Java, blst, and WASM providers; the blst prover backend is tested for bit-identical Groth16 output against the pure-Java prover
Interop with other toolchainsA CI job where the pinned snarkjs 0.7.6 CLI verifies ZeroJ-produced proofs and keys, ZeroJ verifies live snarkjs proofs, and tampered proofs must be rejected; PlonK transcript checks against fixtures generated by gnark v0.14.0
End-to-end on-chain runsGroth16 proofs generated in pure Java and verified by a Plutus V3 validator in lock-and-unlock transactions on Yaci DevKit

Production gates and remediation status are tracked in ADR-0026. The module split between the stable BOM, opt-in modules, and assurance providers is described in ADR-0044.