Post-Quantum Cryptography for Java, powered by Rust.
A quantum-safe Key Encapsulation Mechanism (KEM) SDK implementing
NIST FIPS 203 (ML-KEM-768 / CRYSTALS-Kyber) with zero-copy JNI,
off-heap memory safety, and drop-in JCA compliance.
import java.security.*;
import javax.crypto.KEM;
import com.obsidianq.jce.ObsidianQProvider;
// Register once
Security.addProvider(new ObsidianQProvider());
// Generate a quantum-safe keypair
KeyPairGenerator kpg = KeyPairGenerator.getInstance("Kyber768", "ObsidianQ");
KeyPair kp = kpg.generateKeyPair();
// Encapsulate β Bob creates a shared secret using Alice's public key
KEM kem = KEM.getInstance("ML-KEM-768", "ObsidianQ");
KEM.Encapsulator enc = kem.newEncapsulator(kp.getPublic());
KEM.Encapsulated encapsulated = enc.encapsulate();
SecretKey bobSecret = encapsulated.key(); // 32-byte AES key
byte[] ciphertext = encapsulated.encapsulation(); // Send to Alice
// Decapsulate β Alice recovers the same shared secret
KEM.Decapsulator dec = kem.newDecapsulator(kp.getPrivate());
SecretKey aliceSecret = dec.decapsulate(ciphertext);
// bobSecret == aliceSecret β
That's it. No custom APIs. No Rust knowledge required. Standard Java.
In August 2024, the National Institute of Standards and Technology (NIST) formalized FIPS 203, standardizing ML-KEM (formerly known as CRYSTALS-Kyber).
Traditional cryptography (like RSA and Elliptic Curve) relies on the difficulty of factoring prime numbers or solving discrete logarithms. A sufficiently large quantum computer running Shor's Algorithm will break these mathematical foundations in seconds.
ML-KEM uses Lattice-Based Cryptography, specifically a problem called Module Learning with Errors (MLWE). Instead of prime factorization, the math involves finding the shortest vector in a multi-dimensional lattice grid, combined with intentional, structured mathematical "noise." To date, no quantum algorithm (nor classical algorithm) has been discovered that can efficiently solve MLWE.
ObsidianQ specifically implements ML-KEM-768, which maps to NIST Security Level 3 (equivalent to the strength of AES-192), making it the gold standard for enterprise forward secrecy.
| Problem | How ObsidianQ Solves It |
|---|---|
| Quantum computers will break RSA/ECC | Implements NIST FIPS 203 (ML-KEM-768) β quantum-resistant by design |
| Java GC leaks keys in heap memory | Keys live off-heap in Rust buffers β invisible to GC, zeroized on drop |
| JNI data copying kills performance | Zero-copy DirectByteBuffer architecture β no serialization overhead |
| Adopting new crypto = rewriting everything | Drop-in JCA Provider β works with existing KeyPairGenerator, KEM APIs |
| Pure-Java lattice math is slow | NTT, Montgomery, Barrett reductions run as optimized native Rust |
graph TB
subgraph "Java Application Layer"
A["Your Code<br/><code>KEM.getInstance('ML-KEM-768')</code>"]
end
subgraph "ObsidianQ Java Wrapper"
B["JCA Provider<br/><code>ObsidianQProvider</code>"]
C["KEM SPI<br/><code>KyberKEMSpi</code>"]
D["Native Bridge<br/><code>ObsidianNativeBridge</code>"]
end
subgraph "Zero-Copy JNI Boundary"
E["DirectByteBuffer<br/>Off-Heap Memory"]
end
subgraph "Rust Cryptographic Core"
F["KEM Engine<br/><code>kem.rs</code>"]
G["IND-CPA<br/><code>indcpa.rs</code>"]
H["NTT / Montgomery<br/><code>ntt.rs, reduce.rs</code>"]
I["SHAKE / SHA3<br/><code>symmetric.rs</code>"]
J["Zeroize on Drop<br/>Memory Safety"]
end
A --> B --> C --> D
D <-->|"Raw pointers<br/>No copies"| E
E <-->|"JNI FFI"| F
F --> G --> H
G --> I
F --> J
style E fill:#ff6b6b,stroke:#333,color:#fff
style J fill:#51cf66,stroke:#333,color:#fff
The red boundary is the security perimeter. Secret key material never crosses into Java heap memory. Rust owns the keys, performs the math, and zeroizes on drop.
Why not just write the ML-KEM math in pure Java using BouncyCastle? Memory Safety.
When you perform cryptographic operations in pure Java, your byte[] arrays containing highly sensitive Private Keys and Shared Secrets are allocated on the JVM Heap.
- The Garbage Collector (GC) moves these objects around, leaving invisible, uncontrolled ghost copies of your private keys across RAM.
- When an object goes out of scope, it is not deleted immediately. It waits for a GC pause, meaning your keys linger in memory indefinitely.
- If an attacker triggers a heap dump (
.hprof) or scrapes the server's RAM via a side-channel vulnerability, your post-quantum keys are exposed.
ObsidianQ moves the cryptographic math completely off the JVM heap.
- Direct Allocation: Java allocates a
DirectByteBufferwhich exists in native OS memory, outside the JVM's control. - Zero-Copy: The memory address pointer is passed directly to the Rust engine (
core-rust). No bytes are copied. - Hardened Zeroization: Rust executes the constant-time NTT math. The exact microsecond the operation finishes, ObsidianQ triggers a native
zeroizecommand, deterministically overwriting the native RAM with zeroes before the function even returns to Java.
Your keys never touch the Java Heap.
Benchmarks comparing ObsidianQ against pure-Java implementations on a typical development machine:
| Operation | ObsidianQ (Rust+JNI) | Bouncy Castle (Pure Java) | Speedup |
|---|---|---|---|
| KeyGen | ~0.12 ms | ~0.45 ms | 3.7Γ |
| Encapsulate | ~0.15 ms | ~0.52 ms | 3.5Γ |
| Decapsulate | ~0.14 ms | ~0.48 ms | 3.4Γ |
β οΈ Benchmarks are indicative and will vary by hardware. Formal benchmarks with criterion are in progress.
- Off-Heap Keys:
DirectByteBufferensures private keys never touch JVM heap β immune to GC memory scraping - Zeroize on Drop: Rust's
zeroizecrate deterministically overwrites key material when it goes out of scope - Constant-Time Math: NTT and Montgomery reduction are branch-free β resistant to timing side-channels
- FIPS 203 Compliant: Implements the standardized ML-KEM-768 parameter set (NIST Level 3 security)
- "Store Now, Decrypt Later" Defense: Nation-state actors are recording encrypted web traffic today, waiting for quantum computers to mature so they can decrypt it tomorrow. Upgrading your TLS/VPN handshakes with ObsidianQ provides immediate Forward Secrecy.
- Financial HSMs: High-frequency trading and core banking systems can utilize ObsidianQ for exchanging wrapping keys.
- Spring Boot Microservices: Secure internal network communication (mTLS) between microservices using ML-KEM key exchanges.
Warning
JitPack Limitations (Linux Only Builds)
JitPack builds libraries inside Ubuntu Linux containers. This means that when JitPack compiles ObsidianQ from source, it will only compile the Linux Native Library (libobsidian_core.so).
If you are developing on Windows or macOS and try to run the JitPack-provided dependency, you will get an UnsatisfiedLinkError because the .dll or .dylib will be missing from the packaged JAR.
How to fix this on Windows/Mac:
- We highly recommend downloading the pre-compiled
obsidianq-sdk-1.1.0.jardirectly from the GitHub Releases page. The pre-compiled releases are built via GitHub Actions and contain the native libraries for all three major operating systems (Windows.dll, Mac.dylib, Linux.so). You can manually add this JAR to your project's build path. - Alternatively, you can Build From Source directly on your machine.
Add the JitPack repository to your pom.xml:
<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>Add the ObsidianQ dependency:
<dependency>
<groupId>com.github.Sarvesh2005-code</groupId>
<artifactId>obsidianQ</artifactId>
<version>v1.1.0</version>
</dependency>Add it in your root build.gradle at the end of repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}Add the dependency:
dependencies {
implementation 'com.github.Sarvesh2005-code:obsidianQ:v1.1.0'
}# Prerequisites: Rust (stable), Java 21+, Maven 3.9+
git clone https://github.com/Sarvesh2005-code/obsidianQ.git
cd obsidianQ
mvn clean compile test-compilejava -cp "target/classes;target/test-classes" com.obsidianq.JCAIntegrityTestobsidianQ/
βββ core-rust/ # Rust cryptographic engine
β βββ src/
β β βββ lib.rs # JNI FFI boundary (zero-copy)
β β βββ kem.rs # ML-KEM KeyGen / Encap / Decap
β β βββ indcpa.rs # IND-CPA secure encryption
β β βββ ntt.rs # Number Theoretic Transform
β β βββ reduce.rs # Montgomery & Barrett reductions
β β βββ poly.rs # Polynomial arithmetic
β β βββ polyvec.rs # Polynomial vector operations
β β βββ symmetric.rs # SHA3 / SHAKE128 / SHAKE256
β β βββ cbd.rs # Centered Binomial Distribution
β β βββ pack.rs # Bit-packing & serialization
β βββ tests/
β β βββ kat_test.rs # NIST Known Answer Test vectors
β βββ benches/
β βββ dudect_bench.rs # Constant-time verification
βββ wrapper-java/ # Java JCA integration
β βββ src/main/java/com/obsidianq/
β βββ jce/
β β βββ ObsidianQProvider.java
β β βββ KyberKEMSpi.java # javax.crypto.KEMSpi (Java 21)
β β βββ KyberKeyPairGeneratorSpi.java
β β βββ ...
β βββ util/
β β βββ NativeExtractor.java # Auto-extracts .dll/.so/.dylib
β βββ ObsidianNativeBridge.java # JNI declarations
βββ .github/workflows/ci.yml # Cross-platform CI
βββ HANDBOOK.md # Complete technical reference
βββ CONTRIBUTING.md # Contribution guidelines
βββ SECURITY.md # Vulnerability disclosure policy
βββ pom.xml # Maven build (triggers Cargo)
- Phase 1: FIPS 203 Core Math (NTT, CBD, SHAKE, IND-CPA, bit-packing)
- Phase 2: Java 21
javax.crypto.KEMintegration & cross-platform CI - Phase 3: Constant-time verification & ASN.1 X.509/PKCS#8 Key Wrapping
- Phase 4: Memory zeroization hardening & dynamic rejection sampling (
v1.1.0) - Phase 5: Publish
obsidianq-spring-boot-starterfor seamless web integration - Phase 6: Publish directly to Maven Central (
repo1.maven.org) - Phase 7: Support for ML-KEM-512 and ML-KEM-1024
See CONTRIBUTING.md for guidelines. Security-critical contributions require extra scrutiny β see SECURITY.md. Licensed under the MIT License.
Built with π¦ Rust + β Java | Defending against quantum threats today.