Skip to content

Installation

View Markdown

ZeroJ is a set of Maven artifacts under the group org.zeroj. A single BOM, org.zeroj:zeroj-bom-core, keeps the core module versions in sync. This page gets a Gradle or Maven project ready for the Quickstart.

RequirementVersionNotes
Java25 or newerGraalVM is recommended if you want native images
Build toolGradle or MavenZeroJ itself builds with Gradle 9.2; use a Gradle version that runs on Java 25

The simplest way to install Java 25 is SDKMAN!:

Terminal window
sdk install java 25.0.2-graal
sdk use java 25.0.2-graal

The default path of circuit, witness, prove, and verify needs nothing installed beyond a JDK: no native toolchain and no external CLIs. Everything below the “Optional tools” heading is only for specific scenarios.

The dependencies below are everything the Quickstart needs: annotation-based circuits, the gadget library, the pure-Java Groth16 prover, and the pure-Java verifier.

build.gradle
plugins {
id 'java'
}
java {
toolchain { languageVersion = JavaLanguageVersion.of(25) }
}
repositories {
mavenCentral()
}
dependencies {
// One BOM for all core ZeroJ modules
implementation platform('org.zeroj:zeroj-bom-core:0.1.0-pre12')
// The BOM must also apply to the annotation processor path
annotationProcessor platform('org.zeroj:zeroj-bom-core:0.1.0-pre12')
// Circuits: @ZKCircuit annotations + the generated *Circuit companions
implementation 'org.zeroj:zeroj-circuit-annotation-api'
annotationProcessor 'org.zeroj:zeroj-circuit-annotation-processor'
// Gadgets (Poseidon, Merkle, comparators, ...)
implementation 'org.zeroj:zeroj-circuit-lib'
// Pure-Java Groth16 prover + setup
implementation 'org.zeroj:zeroj-crypto'
// Pure-Java verification: verifier, envelopes, snarkjs JSON codec
implementation 'org.zeroj:zeroj-verifier-groth16'
implementation 'org.zeroj:zeroj-codec'
}

zeroj-codec is listed explicitly because the verifier doesn’t expose it transitively on your compile classpath, and the Quickstart uses its SnarkjsJsonCodec class directly.

All modules in this table are managed by zeroj-bom-core, so you declare them without a version.

I want to…Add…
Write circuits with @ZKCircuit annotationszeroj-circuit-annotation-api + zeroj-circuit-annotation-processor (processor path)
Write circuits with the CircuitSpec or inline DSLzeroj-circuit-dsl
Use Poseidon, Merkle proofs, comparators, Blake2b, SHA-512, Ed25519, CIP-1852 gadgetszeroj-circuit-lib
Run trusted setup and prove with Groth16 (pure Java)zeroj-crypto
Speed up Groth16 proving with native blstzeroj-crypto-blst (opt-in; see below)
Verify Groth16 proofs off-chainzeroj-verifier-groth16 + zeroj-codec
Work with proof envelopes and verification resultszeroj-api (comes in transitively with most modules)
Route proofs through pluggable verifier backendszeroj-backend-spi
Verify proofs on-chain in a Plutus V3 validatorzeroj-onchain-julc plus JuLC and Cardano Client Lib (see below)
Contribute to a Groth16 ceremony from your own code (ZkeyContributor)zeroj-tools (also home of the zeroj-ceremony CLI)
Use BLS12-381 field, curve, and pairing primitives directlyzeroj-bls12381

For a description of every module, see Modules.

Four published modules are deliberately outside zeroj-bom-core, so they never slip into a dependency graph by accident. Give each one an explicit version:

dependencies {
implementation 'org.zeroj:zeroj-bbs:0.1.0-pre12' // BBS selective-disclosure credentials
implementation 'org.zeroj:zeroj-mpf-poseidon:0.1.0-pre12' // Poseidon MPF authenticated state (experimental)
implementation 'org.zeroj:zeroj-jmt-poseidon:0.1.0-pre12' // Poseidon JMT authenticated state (experimental)
implementation 'org.zeroj:zeroj-verifier-plonk:0.1.0-pre12' // PlonK verification (experimental)
}

To compile Plutus V3 validators in Java you also need JuLC, and to build and submit transactions you need Cardano Client Lib. Both keep their own com.bloxbean.cardano group and have their own versions. This block mirrors the builds in zeroj-usecases:

build.gradle (on-chain additions)
dependencies {
implementation 'org.zeroj:zeroj-onchain-julc'
// Put ZeroJ's on-chain libraries on the processor path so JuLC can compile validators that use them
annotationProcessor 'org.zeroj:zeroj-onchain-julc'
// JuLC: write Plutus V3 validators in Java
implementation "com.bloxbean.cardano:julc-stdlib:0.1.0-pre16"
annotationProcessor "com.bloxbean.cardano:julc-annotation-processor:0.1.0-pre16"
implementation "com.bloxbean.cardano:julc-cardano-client-lib:0.1.0-pre16"
runtimeOnly "com.bloxbean.cardano:julc-vm-java:0.1.0-pre16"
// Cardano Client Lib: build and submit transactions
implementation "com.bloxbean.cardano:cardano-client-lib:0.8.0-pre5"
implementation "com.bloxbean.cardano:cardano-client-backend-blockfrost:0.8.0-pre5"
}

The zeroj-usecases builds also fork javac with --enable-native-access=ALL-UNNAMED for the JuLC annotation processor on Java 25:

compileJava {
options.fork = true
options.forkOptions.jvmArgs = ['--enable-native-access=ALL-UNNAMED']
}

Verify your proof on Cardano walks through a complete on-chain setup.

Groth16 needs a trusted setup before you can prove anything. For local experiments ZeroJ can run a quick single-party setup in-process (PowersOfTauBLS381.generate, Groth16Keys.setupInMemory, Groth16SetupBLS381.setup). That setup is insecure by design: the process knows the secret randomness (the “toxic waste”) and could forge proofs. So ZeroJ refuses to run it unless you opt in, and the call fails with an IllegalStateException that explains why.

To opt in for local runs and tests, set the system property zeroj.allowInsecureTrustedSetup to true or the environment variable ZEROJ_ALLOW_INSECURE_TRUSTED_SETUP=true. In code, the property name is available as TrustedSetupPolicy.ALLOW_INSECURE_TRUSTED_SETUP_PROPERTY.

build.gradle
plugins {
id 'application' // only if you use the run task
}
application {
mainClass = 'com.example.Main'
}
// Dev/test only: allows the insecure single-party setup
tasks.named('test') {
systemProperty 'zeroj.allowInsecureTrustedSetup', 'true'
}
tasks.named('run') {
systemProperty 'zeroj.allowInsecureTrustedSetup', 'true'
}

Snapshot builds are published on demand to the Maven Central snapshot repository. Their versions embed the short Git commit they were built from, in the form <next-version>-<short-commit>-SNAPSHOT. Snapshots aren’t published for every commit, so check the repository for the exact version you want. Snapshots are development builds, so prefer a release for anything you share with others.

repositories {
mavenCentral()
maven {
url = uri('https://central.sonatype.com/repository/maven-snapshots')
mavenContent { snapshotsOnly() }
}
}

None of these are needed for the pure-Java path.

ToolVersionWhen you need it
Yaci DevKitlatestRunning on-chain verification against a local Cardano devnet
circom2.xCompiling existing circom circuits you want to prove with ZeroJ
snarkjs (Node.js)0.7.x (ZeroJ’s interop CI pins 0.7.6)Interop only: MPC ceremony tooling, or cross-checking ZeroJ proofs with snarkjs

Install them so they’re on your PATH. ZeroJ’s own interop tests find snarkjs through the SNARKJS_BIN environment variable, common npm locations, or PATH. See Bring circom & snarkjs circuits.

zeroj-crypto-blst plugs the native blst library into the Groth16 prover through Java’s Foreign Function & Memory API. It produces bit-identical proofs and is purely a performance option; since the large-circuit memory work, the pure-Java prover matches it at large sizes, so measure before you adopt it. The JVM needs native access at runtime:

Terminal window
java --enable-native-access=ALL-UNNAMED ...

See Performance for when it helps.

ZeroJ’s pure-Java path doesn’t call into JNI, so it suits GraalVM. (The blst-java jar that zeroj-verifier-groth16 brings along is only used by its native verifier; test your image with the verifier you actually use.) Several modules ship native-image metadata under META-INF/native-image/org.zeroj/<artifact>/, which native-image picks up from the classpath automatically: zeroj-api, zeroj-codec, zeroj-backend-spi, zeroj-verifier-groth16, zeroj-verifier-plonk, zeroj-bls12381, zeroj-blst, zeroj-bbs, and zeroj-onchain-julc. The zeroj-ceremony CLI is itself distributed as a native binary.

Build and test your own native image as part of your pipeline. If native-image reports missing reflection or resource configuration for your application classes, the GraalVM tracing agent is the usual way to generate it.