KyberKotlin

ML-KEM's Kotlin Implementation

APACHE-2.0 License

Stars
3

Bot releases are visible (Hide)

KyberKotlin - v0.8.1 Latest Release

Published by ronhombre 6 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Faster by 14-20% compared to previous version.
  • Optimized multiplyNTTs with Karatsuba Multiplication.
  • Optimized bitsToBytes and bytesToBits.
  • Reduced Barrett Reduction Operations in NTT and invNTT.
  • Lazy Montgomery Reduction.

Platforms:

  • JVM (Kotlin and Java)
  • C#
  • JS (NPM)

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Import as Dependency:

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.8.1")
}

Native C# DLL

Extract kyber-0.8.1-native-mingw-windows.zip and copy the contents inside your C# project.

NPM JS

npm i [email protected]
KyberKotlin - v0.8.0

Published by ronhombre 6 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Updated keccak to 0.2.0 which greatly boosted performance by 50-70%! This performance difference is too big to stay in 0.7.x.

Platforms:

  • JVM (Kotlin and Java)
  • C#
  • JS (NPM)

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Import as Dependency:

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.8.0")
}

Native C# DLL

Extract kyber-0.8.0-native-mingw-windows.zip and copy the contents inside your C# project.

NPM JS

npm i [email protected]
KyberKotlin - v0.7.1

Published by ronhombre 6 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Fix non-JvmStatic KyberAgreement.encapsulate.
  • Updated keccak to 0.1.3.

Platforms:

  • JVM (Kotlin and Java)
  • C#
  • JS (NPM)

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Import as Dependency:

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.7.1")
}

Native C# DLL

Extract kyber-0.7.1-native-mingw-windows.zip and copy the contents inside your C# project.

NPM JS

npm i [email protected]
KyberKotlin - v0.7.0

Published by ronhombre 6 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Fix unable to use externally generated Kyber keys with KyberAgreement.
  • Breaking changes to KyberAgreement constructor and KyberAgreement.encapsulate() is now a static/companion method.

Platforms:

  • JVM (Kotlin and Java)
  • C#
  • JS (NPM)

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Import as Dependency:

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.7.0")
}

Native C# DLL

Extract kyber-0.7.0-native-mingw-windows.zip and copy the contents inside your C# project.

NPM JS

npm i [email protected]
KyberKotlin - v0.6.1

Published by ronhombre 6 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Removed LittleEndians.
  • Fixed bug with zero filling in samplePolyCBD. The last byte was not getting zero filled.

Platforms:

  • JVM (Kotlin and Java)
  • C#
  • JS (NPM)

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) //kyber-0.6.1-full.jar
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.6.1")
}

Native C# DLL

Extract kyber-0.6.1-native-mingw-windows.zip and copy the contents inside your C# project.

NPM JS

npm i [email protected]
KyberKotlin - v0.6.0

Published by ronhombre 6 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Replace KotlinCrypto SHA3 and SHAKE functions with KeccakKotlin.
  • Significant performance improvement!

Platforms:

  • JVM (Kotlin and Java)
  • C#
  • JS (NPM)

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) //kyber-0.6.0-full.jar
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.6.0")
}

Native C# DLL

Extract kyber-0.6.0-native-mingw-windows.zip and copy the contents inside your C# project.

NPM JS

npm i [email protected]
KyberKotlin - v0.5.1

Published by ronhombre 7 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Removed explicit modulus and key length checks for encapsulation and decapsulation.
  • Moved modulus check to KyberEncryptionKey's init function.
  • Made value classes copyable.
  • Implemented .equals().
  • Implemented .hashCode().
  • Improved documentation.
  • Updated secure-random to 0.3.1 to fix bunjs issue.
  • Removed unneeded exception classes.
  • Improved security by copying mutable byte arrays to prevent malicious modifications.

Platforms:

  • JVM (Kotlin and Java)
  • C#
  • JS (NPM)

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) //kyber-0.5.1-full.jar
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.5.1")
}

Native C# DLL

Extract kyber-0.5.1-native-mingw-windows.zip and copy the contents inside your C# project.

NPM JS

npm i [email protected]
KyberKotlin - v0.5.0

Published by ronhombre 7 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Raise version number from 0.4.10 to 0.5.0.
  • Include NPM package source.
  • Gradle build process for NPM.
  • Improved test cases for NPM.
  • Add custom footerMessage for Dokka.
  • Moved package.json to project directory as npm.json.
  • Updated my email in pom.xml.
  • Automated pom.xml updating of versions to always stay consistent with the Gradle build.
  • Moved version numbers into the gradle.properties file.
  • Updated dependencies.
  • Better build processes.

Platforms:

  • JVM (Kotlin and Java)
  • C#
  • JS (NPM)

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) //kyber-0.5.0-full.jar
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.5.0")
}

Native C# DLL

Extract kyber-0.4.10-native-mingw-windows.zip and copy the contents inside your C# project.

NPM JS

npm i kyberkotlin
KyberKotlin - v0.4.10

Published by ronhombre 7 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Sealed KyberKeyGenerator class.
  • Updated keyBytes to 'internal' to prevent unwanted modifications.
  • Added explicit JvmName for parameters of KyberEncapsulationResult.

Platforms:

  • JVM (Kotlin and Java)
  • C#
  • JS (NPM)

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) //kyber-0.4.10-full.jar
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.4.10")
}

Native C# DLL

Extract kyber-0.4.10-native-mingw-windows.zip and copy the contents inside your C# project.

NPM JS

npm i kyberkotlin
KyberKotlin - v0.4.8

Published by ronhombre 8 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • KDocs made for all methods, classes, and parameters.
  • Hid sensitive parameters for classes like KyberEncryptionKey.
  • Added new KDocs as javadocs. Deleted emptyjavadocs.zip.
  • Explicitly reset digests.
  • toHex(format: HexFormat) added.
  • Added explicitly @Throws for methods using external methods that can throw exceptions.
  • Change size to length for KyberParameter find methods.
  • Explicitly say that Encapsulation Key size was invalid.
  • Removed testReturn for Native.
  • Explicitly define the gpg key to be used when signing.

Platforms:

  • JVM

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Usage:

JVM

Kotlin

val aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)
val bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)

val aliceAgreement = KyberAgreement(aliceKeys)
val bobAgreement = KyberAgreement(bobKeys)

val encapsResult = aliceAgreement.encapsulate(bobAgreement.keypair.encapsulationKey)

val decapsSecretKey = bobAgreement.decapsulate(encapsResult.cipherText)

println(encapsResult.secretKey.contentToString())
println(decapsSecretKey.contentToString())

Java

KyberKEMKeyPair aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);
KyberKEMKeyPair bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);

KyberAgreement aliceAgreement = new KyberAgreement(aliceKeys);
KyberAgreement bobAgreement = new KyberAgreement(bobKeys);

KyberEncapsulationResult encapsResult = aliceAgreement.encapsulate(bobAgreement.getKeypair().getEncapsulationKey());

byte[] decapsSecretKey = bobAgreement.decapsulate(encapsResult.getCipherText());

System.out.println(Arrays.toString(encapsResult.getSecretKey()));
System.out.println(Arrays.toString(decapsSecretKey));

C#

using System.Runtime.InteropServices;

//Use absolute path if relative does not work.
const string dllName = "KyberKotlin.dll";

//Declare methods from the DLL.
[DllImport(dllName, EntryPoint = "generateKeyPair")]
static extern IntPtr generateKeyPair(int parameterId);

[DllImport(dllName, EntryPoint = "getEncapsulationKeySize")]
static extern int getEncapsulationKeySize(int parameterId);

[DllImport(dllName, EntryPoint = "getDecapsulationKeySize")]
static extern int getDecapsulationKeySize(int parameterId);

[DllImport(dllName, EntryPoint = "getCipherTextSize")]
static extern int getCipherTextSize(int parameterId);

[DllImport(dllName, EntryPoint = "getSecretKeySize")]
static extern int getSecretKeySize();

[DllImport(dllName, EntryPoint = "encapsulate")]
static extern IntPtr encapsulate(byte[] encapsulationKey, int parameterId);

[DllImport(dllName, EntryPoint = "decapsulate")]
static extern IntPtr decapsulate(byte[] decapsulationKey, byte[] cipherText, int parameterId);

//Get sizes
int encapsulationKeySize = getEncapsulationKeySize(0); //0 = 512, 1 = 768, 2 = 1024
int decapsulationKeySize = getDecapsulationKeySize(0);
int cipherTextSize = getCipherTextSize(0);

//Generate Key Pair
IntPtr keysPtr = generateKeyPair(0);

byte[] encapsulationKey = new byte[encapsulationKeySize];
byte[] decapsulationKey = new byte[decapsulationKeySize];

Marshal.Copy(keysPtr, encapsulationKey, 0, encapsulationKey.Length);
Marshal.Copy(keysPtr + encapsulationKey.Length, decapsulationKey, 0, decapsulationKey.Length);

//Send encapsulation key to Bob
//Bob encapsulates using it
IntPtr cipherPtr = encapsulate(encapsulationKey, 0);

//Bob receives the Secret Key
byte[] secretKey = new byte[getSecretKeySize()];
byte[] cipherText = new byte[cipherTextSize];

Marshal.Copy(cipherPtr, secretKey, 0, secretKey.Length);
Marshal.Copy(cipherPtr + secretKey.Length, cipherText, 0, cipherText.Length);

//Bob sends the Cipher Text to Alice
//Alice uses it to get a copy of the Secret Key
IntPtr secretKeyPtr = decapsulate(decapsulationKey, cipherText, 0);

//Alice's Copy of the Secret Key
byte[] secretKey2 = new byte[getSecretKeySize()];

Marshal.Copy(secretKeyPtr, secretKey2, 0, secretKey2.Length);

//Use the debugger to see the values.

Output:
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.4.8")
}

Native C# DLL

Extract kyber-0.4.8-native-mingw-windows.zip and copy the contents inside your C# project.

KyberKotlin - v0.4.7

Published by ronhombre 8 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Fixed unexposed KyberKeyGenerator.generate() static method for Java.

Platforms:

  • JVM

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Usage:

JVM

Kotlin

val aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)
val bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)

val aliceAgreement = KyberAgreement(aliceKeys)
val bobAgreement = KyberAgreement(bobKeys)

val encapsResult = aliceAgreement.encapsulate(bobAgreement.keypair.encapsulationKey)

val decapsSecretKey = bobAgreement.decapsulate(encapsResult.cipherText)

println(encapsResult.secretKey.contentToString())
println(decapsSecretKey.contentToString())

Java

KyberKEMKeyPair aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);
KyberKEMKeyPair bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);

KyberAgreement aliceAgreement = new KyberAgreement(aliceKeys);
KyberAgreement bobAgreement = new KyberAgreement(bobKeys);

KyberEncapsulationResult encapsResult = aliceAgreement.encapsulate(bobAgreement.getKeypair().getEncapsulationKey());

byte[] decapsSecretKey = bobAgreement.decapsulate(encapsResult.getCipherText());

System.out.println(Arrays.toString(encapsResult.getSecretKey()));
System.out.println(Arrays.toString(decapsSecretKey));

C#

using System.Runtime.InteropServices;

//Use absolute path if relative does not work.
const string dllName = "KyberKotlin.dll";

//Declare methods from the DLL.
[DllImport(dllName, EntryPoint = "generateKeyPair")]
static extern IntPtr generateKeyPair(int parameterId);

[DllImport(dllName, EntryPoint = "getEncapsulationKeySize")]
static extern int getEncapsulationKeySize(int parameterId);

[DllImport(dllName, EntryPoint = "getDecapsulationKeySize")]
static extern int getDecapsulationKeySize(int parameterId);

[DllImport(dllName, EntryPoint = "getCipherTextSize")]
static extern int getCipherTextSize(int parameterId);

[DllImport(dllName, EntryPoint = "getSecretKeySize")]
static extern int getSecretKeySize();

[DllImport(dllName, EntryPoint = "encapsulate")]
static extern IntPtr encapsulate(byte[] encapsulationKey, int parameterId);

[DllImport(dllName, EntryPoint = "decapsulate")]
static extern IntPtr decapsulate(byte[] decapsulationKey, byte[] cipherText, int parameterId);

//Get sizes
int encapsulationKeySize = getEncapsulationKeySize(0); //0 = 512, 1 = 768, 2 = 1024
int decapsulationKeySize = getDecapsulationKeySize(0);
int cipherTextSize = getCipherTextSize(0);

//Generate Key Pair
IntPtr keysPtr = generateKeyPair(0);

byte[] encapsulationKey = new byte[encapsulationKeySize];
byte[] decapsulationKey = new byte[decapsulationKeySize];

Marshal.Copy(keysPtr, encapsulationKey, 0, encapsulationKey.Length);
Marshal.Copy(keysPtr + encapsulationKey.Length, decapsulationKey, 0, decapsulationKey.Length);

//Send encapsulation key to Bob
//Bob encapsulates using it
IntPtr cipherPtr = encapsulate(encapsulationKey, 0);

//Bob receives the Secret Key
byte[] secretKey = new byte[getSecretKeySize()];
byte[] cipherText = new byte[cipherTextSize];

Marshal.Copy(cipherPtr, secretKey, 0, secretKey.Length);
Marshal.Copy(cipherPtr + secretKey.Length, cipherText, 0, cipherText.Length);

//Bob sends the Cipher Text to Alice
//Alice uses it to get a copy of the Secret Key
IntPtr secretKeyPtr = decapsulate(decapsulationKey, cipherText, 0);

//Alice's Copy of the Secret Key
byte[] secretKey2 = new byte[getSecretKeySize()];

Marshal.Copy(secretKeyPtr, secretKey2, 0, secretKey2.Length);

//Use the debugger to see the values.

Output:
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.4.7")
}

Native C# DLL

Extract kyber-0.4.7-native-mingw-windows.zip and copy the contents inside your C# project.

KyberKotlin - v0.4.6

Published by ronhombre 8 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Fixed duplicate dependencies for dependents.
  • jvmFullJar.

Platforms:

  • JVM

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Usage:

JVM

Kotlin

val aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)
val bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)

val aliceAgreement = KyberAgreement(aliceKeys)
val bobAgreement = KyberAgreement(bobKeys)

val encapsResult = aliceAgreement.encapsulate(bobAgreement.keypair.encapsulationKey)

val decapsSecretKey = bobAgreement.decapsulate(encapsResult.cipherText)

println(encapsResult.secretKey.contentToString())
println(decapsSecretKey.contentToString())

Java

KyberKEMKeyPair aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);
KyberKEMKeyPair bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);

KyberAgreement aliceAgreement = new KyberAgreement(aliceKeys);
KyberAgreement bobAgreement = new KyberAgreement(bobKeys);

KyberEncapsulationResult encapsResult = aliceAgreement.encapsulate(bobAgreement.getKeypair().getEncapsulationKey());

byte[] decapsSecretKey = bobAgreement.decapsulate(encapsResult.getCipherText());

System.out.println(Arrays.toString(encapsResult.getSecretKey()));
System.out.println(Arrays.toString(decapsSecretKey));

Output:
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.4.6")
}
KyberKotlin - v0.4.5

Published by ronhombre 8 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Zero fill sensitive data to improve security.

Platforms:

  • JVM

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Usage:

JVM

Kotlin

val aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)
val bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)

val aliceAgreement = KyberAgreement(aliceKeys)
val bobAgreement = KyberAgreement(bobKeys)

val encapsResult = aliceAgreement.encapsulate(bobAgreement.keypair.encapsulationKey)

val decapsSecretKey = bobAgreement.decapsulate(encapsResult.cipherText)

println(encapsResult.secretKey.contentToString())
println(decapsSecretKey.contentToString())

Java

KyberKEMKeyPair aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);
KyberKEMKeyPair bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);

KyberAgreement aliceAgreement = new KyberAgreement(aliceKeys);
KyberAgreement bobAgreement = new KyberAgreement(bobKeys);

KyberEncapsulationResult encapsResult = aliceAgreement.encapsulate(bobAgreement.getKeypair().getEncapsulationKey());

byte[] decapsSecretKey = bobAgreement.decapsulate(encapsResult.getCipherText());

System.out.println(Arrays.toString(encapsResult.getSecretKey()));
System.out.println(Arrays.toString(decapsSecretKey));

Output:
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Add to libs/ folder

KyberKotlin - v0.4.4

Published by ronhombre 8 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Fixed unexposed encapsulate() and decapsulate() methods in KyberAgreement.

Platforms:

  • JVM

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Usage:

JVM

Kotlin

val aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)
val bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)

val aliceAgreement = KyberAgreement(aliceKeys)
val bobAgreement = KyberAgreement(bobKeys)

val encapsResult = aliceAgreement.encapsulate(bobAgreement.keypair.encapsulationKey)

val decapsSecretKey = bobAgreement.decapsulate(encapsResult.cipherText)

println(encapsResult.secretKey.contentToString())
println(decapsSecretKey.contentToString())

Java

KyberKEMKeyPair aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);
KyberKEMKeyPair bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);

KyberAgreement aliceAgreement = new KyberAgreement(aliceKeys);
KyberAgreement bobAgreement = new KyberAgreement(bobKeys);

KyberEncapsulationResult encapsResult = aliceAgreement.encapsulate(bobAgreement.getKeypair().getEncapsulationKey());

byte[] decapsSecretKey = bobAgreement.decapsulate(encapsResult.getCipherText());

System.out.println(Arrays.toString(encapsResult.getSecretKey()));
System.out.println(Arrays.toString(decapsSecretKey));

Output:
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Add to libs/ folder

KyberKotlin - v0.4.3

Published by ronhombre 8 months ago

WARNING: BROKEN RELEASE! USE A LATER VERSION!

OPTIMIZED/MASTER VERSION

Changelog:

  • Added dependencies for pom file.
  • qodana.yaml for Code Analysis.

Platforms:

  • JVM

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Usage:

JVM

Kotlin

val aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)
val bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)

val aliceAgreement = KyberAgreement(aliceKeys)
val bobAgreement = KyberAgreement(bobKeys)

val encapsResult = aliceAgreement.encapsulate(bobAgreement.keypair.encapsulationKey)

val decapsSecretKey = bobAgreement.decapsulate(encapsResult.cipherText)

println(encapsResult.secretKey.contentToString())
println(decapsSecretKey.contentToString())

Java

KyberKEMKeyPair aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);
KyberKEMKeyPair bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);

KyberAgreement aliceAgreement = new KyberAgreement(aliceKeys);
KyberAgreement bobAgreement = new KyberAgreement(bobKeys);

KyberEncapsulationResult encapsResult = aliceAgreement.encapsulate(bobAgreement.getKeypair().getEncapsulationKey());

byte[] decapsSecretKey = bobAgreement.decapsulate(encapsResult.getCipherText());

System.out.println(Arrays.toString(encapsResult.getSecretKey()));
System.out.println(Arrays.toString(decapsSecretKey));

Output:
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.4.3")
}
KyberKotlin - v0.4.2

Published by ronhombre 8 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Faster.
  • Replaced SecureRandom.kt with a dedicated external library.

Platforms:

  • JVM

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Usage:

JVM

Kotlin

val aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)
val bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)

val aliceAgreement = KyberAgreement(aliceKeys)
val bobAgreement = KyberAgreement(bobKeys)

val encapsResult = aliceAgreement.encapsulate(bobAgreement.keypair.encapsulationKey)

val decapsSecretKey = bobAgreement.decapsulate(encapsResult.cipherText)

println(encapsResult.secretKey.contentToString())
println(decapsSecretKey.contentToString())

Java

KyberKEMKeyPair aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);
KyberKEMKeyPair bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);

KyberAgreement aliceAgreement = new KyberAgreement(aliceKeys);
KyberAgreement bobAgreement = new KyberAgreement(bobKeys);

KyberEncapsulationResult encapsResult = aliceAgreement.encapsulate(bobAgreement.getKeypair().getEncapsulationKey());

byte[] decapsSecretKey = bobAgreement.decapsulate(encapsResult.getCipherText());

System.out.println(Arrays.toString(encapsResult.getSecretKey()));
System.out.println(Arrays.toString(decapsSecretKey));

Output:
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.4.2")
}
KyberKotlin - v0.4.1

Published by ronhombre 8 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Faster.
  • Removed all Double usages.
  • Fixed build.gradle.kts.
  • Reduced type conversions.
  • Q_HALF constant.
  • Optimized byteDecode().
  • Removed sumOf() and diffOf().
  • Longer test for Encrypt/Decrypt.

Platforms:

  • JVM

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Usage:

JVM

Kotlin

val aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)
val bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)

val aliceAgreement = KyberAgreement(aliceKeys)
val bobAgreement = KyberAgreement(bobKeys)

val encapsResult = aliceAgreement.encapsulate(bobAgreement.keypair.encapsulationKey)

val decapsSecretKey = bobAgreement.decapsulate(encapsResult.cipherText)

println(encapsResult.secretKey.contentToString())
println(decapsSecretKey.contentToString())

Java

KyberKEMKeyPair aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);
KyberKEMKeyPair bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);

KyberAgreement aliceAgreement = new KyberAgreement(aliceKeys);
KyberAgreement bobAgreement = new KyberAgreement(bobKeys);

KyberEncapsulationResult encapsResult = aliceAgreement.encapsulate(bobAgreement.getKeypair().getEncapsulationKey());

byte[] decapsSecretKey = bobAgreement.decapsulate(encapsResult.getCipherText());

System.out.println(Arrays.toString(encapsResult.getSecretKey()));
System.out.println(Arrays.toString(decapsSecretKey));

Output:
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.4.1")
}
KyberKotlin - v0.4.0

Published by ronhombre 8 months ago

OPTIMIZED/MASTER VERSION

Changelog:

  • Edited some comments.
  • Improved benchmarks.
  • Added new test cases.
  • Montgomery Forms and Montgomery Reduction.
  • Barrett Reduction.
  • Zetas now in Montgomery Form.
  • Optimized single bit decompress.
  • Negated Q_INV constant.
  • More constants

Platforms:

  • JVM

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Usage:

JVM

Kotlin

val aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)
val bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)

val aliceAgreement = KyberAgreement(aliceKeys)
val bobAgreement = KyberAgreement(bobKeys)

val encapsResult = aliceAgreement.encapsulate(bobAgreement.keypair.encapsulationKey)

val decapsSecretKey = bobAgreement.decapsulate(encapsResult.cipherText)

println(encapsResult.secretKey.contentToString())
println(decapsSecretKey.contentToString())

Java

KyberKEMKeyPair aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);
KyberKEMKeyPair bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);

KyberAgreement aliceAgreement = new KyberAgreement(aliceKeys);
KyberAgreement bobAgreement = new KyberAgreement(bobKeys);

KyberEncapsulationResult encapsResult = aliceAgreement.encapsulate(bobAgreement.getKeypair().getEncapsulationKey());

byte[] decapsSecretKey = bobAgreement.decapsulate(encapsResult.getCipherText());

System.out.println(Arrays.toString(encapsResult.getSecretKey()));
System.out.println(Arrays.toString(decapsSecretKey));

Output:
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.4.0")
}
KyberKotlin - v0.3.1-standard

Published by ronhombre 9 months ago

UNOPTIMIZED/STANDARD VERSION

Changelog:

  • Branchless code where it mattered.

Platforms:

  • JVM

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Usage:

JVM

Kotlin

val aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)
val bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)

val aliceAgreement = KyberAgreement(aliceKeys)
val bobAgreement = KyberAgreement(bobKeys)

val encapsResult = aliceAgreement.encapsulate(bobAgreement.keypair.encapsulationKey)

val decapsSecretKey = bobAgreement.decapsulate(encapsResult.cipherText)

println(encapsResult.secretKey.contentToString())
println(decapsSecretKey.contentToString())

Java

KyberKEMKeyPair aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);
KyberKEMKeyPair bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);

KyberAgreement aliceAgreement = new KyberAgreement(aliceKeys);
KyberAgreement bobAgreement = new KyberAgreement(bobKeys);

KyberEncapsulationResult encapsResult = aliceAgreement.encapsulate(bobAgreement.getKeypair().getEncapsulationKey());

byte[] decapsSecretKey = bobAgreement.decapsulate(encapsResult.getCipherText());

System.out.println(Arrays.toString(encapsResult.getSecretKey()));
System.out.println(Arrays.toString(decapsSecretKey));

Output:
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.3.1-standard")
}
KyberKotlin - v0.3.0-standard

Published by ronhombre 9 months ago

UNOPTIMIZED/STANDARD VERSION

Changelog:

  • Convert KyberEncryptionKey, KyberDecryptionKey, KyberEncapsulationKey, KyberDecapsulationKey, and KyberCipherText to HEX, BASE64, and BYTES vice-versa.
  • Reverted SecureRandom update. #4d08b5f4
  • Added tests for conversions.
  • KyberEncryptionKey, KyberDecryptionKey, KyberEncapsulationKey, KyberDecapsulationKey, and KyberCipherText all have the fullbytes attribute or getFullBytes() for Java.
  • Moved interfaces to their own folder to clean up src directory.
  • New KyberParameter fields.
  • The standard branch is now a version.

Platforms:

  • JVM

Features:

  • ML-KEM Key Generation(512, 768, 1024)
  • ML-KEM Encapsulation(512, 768, 1024)
  • ML-KEM Decapsulation(512, 768, 1024)
  • Convert to or from HEX, BASE64, and BYTES.

Usage:

JVM

Kotlin

val aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)
val bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512)

val aliceAgreement = KyberAgreement(aliceKeys)
val bobAgreement = KyberAgreement(bobKeys)

val encapsResult = aliceAgreement.encapsulate(bobAgreement.keypair.encapsulationKey)

val decapsSecretKey = bobAgreement.decapsulate(encapsResult.cipherText)

println(encapsResult.secretKey.contentToString())
println(decapsSecretKey.contentToString())

Java

KyberKEMKeyPair aliceKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);
KyberKEMKeyPair bobKeys = KyberKeyGenerator.generate(KyberParameter.ML_KEM_512);

KyberAgreement aliceAgreement = new KyberAgreement(aliceKeys);
KyberAgreement bobAgreement = new KyberAgreement(bobKeys);

KyberEncapsulationResult encapsResult = aliceAgreement.encapsulate(bobAgreement.getKeypair().getEncapsulationKey());

byte[] decapsSecretKey = bobAgreement.decapsulate(encapsResult.getCipherText());

System.out.println(Arrays.toString(encapsResult.getSecretKey()));
System.out.println(Arrays.toString(decapsSecretKey));

Output:
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]
[1, -123, 89, 94, -70, -97, -54, -58, -82, -10, -92, 10, -85, 115, -61, 85, 33, -109, 66, 71, -76, 86, -19, -37, 28, 66, 56, 72, -101, -56, -58, 22]

Import as Dependency:

JAR JVM

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
}

Add to libs/ folder

Maven JVM

dependencies {
    implementation("asia.hombre:kyber:0.3.0-standard")
}
Badges
Extracted from project README
CodeQL master Maven Central GitHub license