
High-speed, pure-language cryptography implementing TweetNaCl primitives (Box, SecretBox, Ed25519), Base58Check, PBKDF2, secure key import/export, encoding utilities and opinionated APIs—no native dependencies.
Secure. Portable. Pure Kotlin.
Kodium is a comprehensive, pure Kotlin Multiplatform (KMP) cryptography library. It acts as a faithful port of the renowned TweetNaCl C library, providing high-speed, high-security cryptographic primitives, advanced Double Ratchet session management, and Post-Quantum Cryptography (PQC) protocols without any native dependencies.
Write once, encrypt everywhere. Even in a post-quantum world.
Kodium.pqc namespace with support for Hybrid ML-KEM-768 + X25519 encryption.| Platform | Support |
|---|---|
| Android | ✅ |
| iOS (Arm64, X64, Sim) | ✅ |
| JVM (Java 17+) | ✅ |
| JavaScript (Browser/Node) | ✅ |
| Wasm (WebAssembly) | ✅ |
| macOS (Arm64, X64) | ✅ |
| Linux (X64) | ✅ |
| Windows (MinGW X64) | ✅ |
Add Kodium to your common module's dependencies.
Gradle (Kotlin DSL)
implementation("eu.livotov.labs:kodium:1.0.0")Gradle (Groovy)
implementation 'eu.livotov.labs:kodium:1.0.0'Maven
<dependency>
<groupId>eu.livotov.labs</groupId>
<artifactId>kodium</artifactId>
<version>1.0.0</version>
</dependency>Kodium provides a complete implementation of the Double Ratchet algorithm for secure E2EE messaging.
// Alice initializes her session as the initiator
val aliceSession = DoubleRatchetSession.initializeAsInitiator(sharedSecret, responderRatchetKey)
// Encrypt a message to a Base58 string
val encrypted = aliceSession.encryptToEncodedString("Hello Bob!".encodeToByteArray()).getOrThrow()
// Bob decrypts it back
val bobSession = DoubleRatchetSession.initializeAsResponder(sharedSecret, responderRatchetKeyPair)
val decrypted = bobSession.decryptFromEncodedString(encrypted).getOrThrow()Upgrade your E2EE sessions to be resistant to quantum computer attacks using the PQDoubleRatchetSession.
// Alice initializes her PQ session using the secrets from PQXDH
val aliceSession = PQDoubleRatchetSession.initializeAsInitiator(
sharedSecret = aliceSharedSecret.masterSecret,
responderPqcPublicKey = fetchedBobBundle.pqcKey,
ourPqcPrivateKey = aliceHybridKeys
)
val encrypted = aliceSession.encryptToEncodedString("Post-Quantum Hello!".encodeToByteArray()).getOrThrow()
// Bob initializes his session using his keys and Alice's provided payload
val bobSession = PQDoubleRatchetSession.initializeAsResponder(
sharedSecret = bobSharedSecret,
ourPqcPrivateKey = bobHybridKeys,
initiatorPqcPublicKey = fetchedAlicePayload.pqcPublicKey!!
)
val decrypted = bobSession.decryptFromEncodedString(encrypted).getOrThrow()Protect your data against future quantum computer attacks using the hybrid Kodium.pqc suite.
// 1. Generate Hybrid Keys (X25519 + ML-KEM-768)
val myKeys = Kodium.pqc.generateKeyPair()
val theirPublicKey = ... // Received from peer
// 2. Encrypt
val encrypted = Kodium.pqc.encryptToEncodedString(
mySecretKey = myKeys,
theirPublicKey = theirPublicKey,
data = "Secret message".encodeToByteArray()
).getOrThrow()
// 3. Decrypt
val decrypted = Kodium.pqc.decryptFromEncodedString(
mySecretKey = myKeys,
theirPublicKey = theirPublicKey,
data = encrypted
).getOrThrow()Securely exchange messages between Alice and Bob without session management.
// 1. Generate keys
val alice = Kodium.generateKeyPair()
val bob = Kodium.generateKeyPair()
// 2. Alice encrypts a message for Bob
val message = "The eagle flies at midnight.".encodeToByteArray()
val encryptedResult = Kodium.encryptToEncodedString(
mySecretKey = alice,
theirPublicKey = bob.getPublicKey(),
data = message
)
// 3. Bob decrypts the message
encryptedResult.onSuccess { cipherText ->
Kodium.decryptFromEncodedString(
mySecretKey = bob,
theirPublicKey = alice.getPublicKey(),
data = cipherText
).onSuccess { decryptedBytes ->
println("Decrypted: ${decryptedBytes.decodeToString()}")
}
}Protect data with a shared password/secret.
val password = "CorrectHorseBatteryStaple"
val secretData = "Launch codes: 12345".encodeToByteArray()
// Encrypt
val encryptedResult = Kodium.encryptSymmetricToEncodedString(password, secretData)
// Decrypt
encryptedResult.onSuccess { cipherText ->
val decryptedResult = Kodium.decryptSymmetricFromEncodedString(password, cipherText)
println("Restored: ${decryptedResult.getOrThrow().decodeToString()}")
}Easily store keys using Base58Check encoding.
val keyPair = Kodium.generateKeyPair()
// Export Public Key (Safe to share)
val pubKeyString = keyPair.getPublicKey().exportToEncodedString()
// Export Private Key (Encrypted with a password)
val privKeyString = keyPair.exportToEncryptedString("StrongPassword")
// Import later
val restoredKeyPair = KodiumPrivateKey.importFromEncryptedString(
data = privKeyString.getOrThrow(),
password = "StrongPassword"
)The complete documentation for Kodium is available online and within the repository.
👉 Online Documentation (Manual & API Reference)
The docs/ directory is structured for GitBook and contains:
For advanced usage and detailed technical explanations, refer to our deep-dive standalone guides.
Learn how to build a fully secure, asynchronous peer-to-peer chat application using the classical Double Ratchet protocol. This guide covers the complete lifecycle:
👉 Read the full Double Ratchet & X3DH Guide
Future-proof your application against "Harvest Now, Decrypt Later" attacks by upgrading to Kodium's Hybrid PQC suite. This guide covers:
👉 Read the full PQC Reference Guide
We welcome contributions! If you're interested in building Kodium from source, running tests, or updating the documentation, please refer to our Developer Guide.
Kodium is licensed under the Apache 2.0 License.
The Post-Quantum ML-KEM math implementation in this project is based on the excellent KyberKotlin project by Ron Lauren Hombre.
Copyright 2026 Livotov Labs Ltd.
Disclaimer: While this library implements standard cryptographic primitives based on TweetNaCl, it has not been audited by a security expert. Users should always review security requirements for their specific use case and use at their own risk.
Secure. Portable. Pure Kotlin.
Kodium is a comprehensive, pure Kotlin Multiplatform (KMP) cryptography library. It acts as a faithful port of the renowned TweetNaCl C library, providing high-speed, high-security cryptographic primitives, advanced Double Ratchet session management, and Post-Quantum Cryptography (PQC) protocols without any native dependencies.
Write once, encrypt everywhere. Even in a post-quantum world.
Kodium.pqc namespace with support for Hybrid ML-KEM-768 + X25519 encryption.| Platform | Support |
|---|---|
| Android | ✅ |
| iOS (Arm64, X64, Sim) | ✅ |
| JVM (Java 17+) | ✅ |
| JavaScript (Browser/Node) | ✅ |
| Wasm (WebAssembly) | ✅ |
| macOS (Arm64, X64) | ✅ |
| Linux (X64) | ✅ |
| Windows (MinGW X64) | ✅ |
Add Kodium to your common module's dependencies.
Gradle (Kotlin DSL)
implementation("eu.livotov.labs:kodium:1.0.0")Gradle (Groovy)
implementation 'eu.livotov.labs:kodium:1.0.0'Maven
<dependency>
<groupId>eu.livotov.labs</groupId>
<artifactId>kodium</artifactId>
<version>1.0.0</version>
</dependency>Kodium provides a complete implementation of the Double Ratchet algorithm for secure E2EE messaging.
// Alice initializes her session as the initiator
val aliceSession = DoubleRatchetSession.initializeAsInitiator(sharedSecret, responderRatchetKey)
// Encrypt a message to a Base58 string
val encrypted = aliceSession.encryptToEncodedString("Hello Bob!".encodeToByteArray()).getOrThrow()
// Bob decrypts it back
val bobSession = DoubleRatchetSession.initializeAsResponder(sharedSecret, responderRatchetKeyPair)
val decrypted = bobSession.decryptFromEncodedString(encrypted).getOrThrow()Upgrade your E2EE sessions to be resistant to quantum computer attacks using the PQDoubleRatchetSession.
// Alice initializes her PQ session using the secrets from PQXDH
val aliceSession = PQDoubleRatchetSession.initializeAsInitiator(
sharedSecret = aliceSharedSecret.masterSecret,
responderPqcPublicKey = fetchedBobBundle.pqcKey,
ourPqcPrivateKey = aliceHybridKeys
)
val encrypted = aliceSession.encryptToEncodedString("Post-Quantum Hello!".encodeToByteArray()).getOrThrow()
// Bob initializes his session using his keys and Alice's provided payload
val bobSession = PQDoubleRatchetSession.initializeAsResponder(
sharedSecret = bobSharedSecret,
ourPqcPrivateKey = bobHybridKeys,
initiatorPqcPublicKey = fetchedAlicePayload.pqcPublicKey!!
)
val decrypted = bobSession.decryptFromEncodedString(encrypted).getOrThrow()Protect your data against future quantum computer attacks using the hybrid Kodium.pqc suite.
// 1. Generate Hybrid Keys (X25519 + ML-KEM-768)
val myKeys = Kodium.pqc.generateKeyPair()
val theirPublicKey = ... // Received from peer
// 2. Encrypt
val encrypted = Kodium.pqc.encryptToEncodedString(
mySecretKey = myKeys,
theirPublicKey = theirPublicKey,
data = "Secret message".encodeToByteArray()
).getOrThrow()
// 3. Decrypt
val decrypted = Kodium.pqc.decryptFromEncodedString(
mySecretKey = myKeys,
theirPublicKey = theirPublicKey,
data = encrypted
).getOrThrow()Securely exchange messages between Alice and Bob without session management.
// 1. Generate keys
val alice = Kodium.generateKeyPair()
val bob = Kodium.generateKeyPair()
// 2. Alice encrypts a message for Bob
val message = "The eagle flies at midnight.".encodeToByteArray()
val encryptedResult = Kodium.encryptToEncodedString(
mySecretKey = alice,
theirPublicKey = bob.getPublicKey(),
data = message
)
// 3. Bob decrypts the message
encryptedResult.onSuccess { cipherText ->
Kodium.decryptFromEncodedString(
mySecretKey = bob,
theirPublicKey = alice.getPublicKey(),
data = cipherText
).onSuccess { decryptedBytes ->
println("Decrypted: ${decryptedBytes.decodeToString()}")
}
}Protect data with a shared password/secret.
val password = "CorrectHorseBatteryStaple"
val secretData = "Launch codes: 12345".encodeToByteArray()
// Encrypt
val encryptedResult = Kodium.encryptSymmetricToEncodedString(password, secretData)
// Decrypt
encryptedResult.onSuccess { cipherText ->
val decryptedResult = Kodium.decryptSymmetricFromEncodedString(password, cipherText)
println("Restored: ${decryptedResult.getOrThrow().decodeToString()}")
}Easily store keys using Base58Check encoding.
val keyPair = Kodium.generateKeyPair()
// Export Public Key (Safe to share)
val pubKeyString = keyPair.getPublicKey().exportToEncodedString()
// Export Private Key (Encrypted with a password)
val privKeyString = keyPair.exportToEncryptedString("StrongPassword")
// Import later
val restoredKeyPair = KodiumPrivateKey.importFromEncryptedString(
data = privKeyString.getOrThrow(),
password = "StrongPassword"
)The complete documentation for Kodium is available online and within the repository.
👉 Online Documentation (Manual & API Reference)
The docs/ directory is structured for GitBook and contains:
For advanced usage and detailed technical explanations, refer to our deep-dive standalone guides.
Learn how to build a fully secure, asynchronous peer-to-peer chat application using the classical Double Ratchet protocol. This guide covers the complete lifecycle:
👉 Read the full Double Ratchet & X3DH Guide
Future-proof your application against "Harvest Now, Decrypt Later" attacks by upgrading to Kodium's Hybrid PQC suite. This guide covers:
👉 Read the full PQC Reference Guide
We welcome contributions! If you're interested in building Kodium from source, running tests, or updating the documentation, please refer to our Developer Guide.
Kodium is licensed under the Apache 2.0 License.
The Post-Quantum ML-KEM math implementation in this project is based on the excellent KyberKotlin project by Ron Lauren Hombre.
Copyright 2026 Livotov Labs Ltd.
Disclaimer: While this library implements standard cryptographic primitives based on TweetNaCl, it has not been audited by a security expert. Users should always review security requirements for their specific use case and use at their own risk.