Skip to content

Sarvesh2005-code/obsidianQ

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

20 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

FIPS 203 Rust Java 21+ License Build

πŸ›‘οΈ ObsidianQ

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.


⚑ Quickstart β€” 4 Lines to Quantum Safety

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.


πŸ”¬ Deep Dive: What is ML-KEM (FIPS 203)?

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.


πŸ”‘ Why ObsidianQ?

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

πŸ—οΈ Architecture

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
Loading

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.


πŸ’€ The Java Garbage Collection Vulnerability

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.

How ObsidianQ Fixes It: Zero-Copy JNI

ObsidianQ moves the cryptographic math completely off the JVM heap.

  1. Direct Allocation: Java allocates a DirectByteBuffer which exists in native OS memory, outside the JVM's control.
  2. Zero-Copy: The memory address pointer is passed directly to the Rust engine (core-rust). No bytes are copied.
  3. Hardened Zeroization: Rust executes the constant-time NTT math. The exact microsecond the operation finishes, ObsidianQ triggers a native zeroize command, deterministically overwriting the native RAM with zeroes before the function even returns to Java.

Your keys never touch the Java Heap.


πŸ“Š Performance

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.


πŸ”’ Security Model

  • Off-Heap Keys: DirectByteBuffer ensures private keys never touch JVM heap β†’ immune to GC memory scraping
  • Zeroize on Drop: Rust's zeroize crate 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)

πŸ’Ό Real-World Use Cases

  • "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.

πŸ“¦ Installation

Maven (via JitPack)

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:

  1. We highly recommend downloading the pre-compiled obsidianq-sdk-1.1.0.jar directly 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.
  2. 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>

Gradle (via JitPack)

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'
}

Build From Source

# Prerequisites: Rust (stable), Java 21+, Maven 3.9+

git clone https://github.com/Sarvesh2005-code/obsidianQ.git
cd obsidianQ
mvn clean compile test-compile

Run the Integrity Test

java -cp "target/classes;target/test-classes" com.obsidianq.JCAIntegrityTest

🧬 Project Structure

obsidianQ/
β”œβ”€β”€ 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)

πŸ—ΊοΈ Roadmap & Future Plans

  • Phase 1: FIPS 203 Core Math (NTT, CBD, SHAKE, IND-CPA, bit-packing)
  • Phase 2: Java 21 javax.crypto.KEM integration & 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-starter for seamless web integration
  • Phase 6: Publish directly to Maven Central (repo1.maven.org)
  • Phase 7: Support for ML-KEM-512 and ML-KEM-1024

🀝 Contributing & License

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.

About

A quantum-safe cryptographic SDK bridging high-performance Rust natively into Java via zero-copy JNI. Implements NIST FIPS 203 (ML-KEM).

Topics

Resources

License

Contributing

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors