From ed1cc00b02fd51495068210a78fa2eee4e51cfca Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 14 May 2026 04:49:36 -0400 Subject: [PATCH 1/2] BAEL-9111 Add code for ML-KEM and ML-DSA in Java 24 --- .../ModuleLatticeBasedDigitalSignature.java | 41 +++++++++++++++++ .../ModuleLatticeBasedKeyEncapsulation.java | 45 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignature.java create mode 100644 core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulation.java diff --git a/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignature.java b/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignature.java new file mode 100644 index 000000000000..6ac2fb15e6c4 --- /dev/null +++ b/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignature.java @@ -0,0 +1,41 @@ +package com.baeldung.javafeatures.mlkemdsa; + +import java.security.spec.NamedParameterSpec; +import javax.crypto.KEM; +import javax.crypto.SecretKey; +import java.security.*; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ModuleLatticeBasedDigitalSignature { + + public static void main(String[] args) throws Exception { + Logger logger = LoggerFactory.getLogger(ModuleLatticeBasedDigitalSignature.class); + + // Signer: Generate an ML-DSA key pair + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-DSA"); + kpg.initialize(NamedParameterSpec.ML_DSA_65); + + KeyPair kp = kpg.generateKeyPair(); + PrivateKey privateKey = kp.getPrivate(); + PublicKey publicKey = kp.getPublic(); + + // Signer: Sign the message using the private key + Signature signature = Signature.getInstance("ML-DSA"); + String message = "This is a test message signed"; + byte[] messageBytes = message.getBytes(); + + signature.initSign(privateKey); + signature.update(messageBytes); + byte[] sigBytes = signature.sign(); + + // Verifier: Verify the signature using the public key + signature.initVerify(publicKey); + signature.update(messageBytes); + boolean isValid = signature.verify(sigBytes); + + logger.info("Is the signature valid? " + isValid); + + } +} diff --git a/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulation.java b/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulation.java new file mode 100644 index 000000000000..7de889b1f2a7 --- /dev/null +++ b/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulation.java @@ -0,0 +1,45 @@ +package com.baeldung.javafeatures.mlkemdsa; + +import java.security.spec.NamedParameterSpec; +import javax.crypto.KEM; +import javax.crypto.SecretKey; +import java.security.*; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ModuleLatticeBasedKeyEncapsulation { + + public static void main(String[] args) throws Exception { + Logger logger = LoggerFactory.getLogger(ModuleLatticeBasedKeyEncapsulation.class); + + // Receiver: Generate an ML-KEM key pair + KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM"); + kpg.initialize(NamedParameterSpec.ML_KEM_768); + + KeyPair receiverKeyPair = kpg.generateKeyPair(); + PrivateKey privateKey = receiverKeyPair.getPrivate(); + PublicKey publicKey = receiverKeyPair.getPublic(); + + // Simulated transmission of the public key to the sender + + // Sender: Encapsulate a shared secret key using the receiver's public key + KEM senderKem = KEM.getInstance("ML-KEM"); + KEM.Encapsulator encapsulator = senderKem.newEncapsulator(publicKey); + KEM.Encapsulated encapsulated = encapsulator.encapsulate(); + SecretKey senderSharedSecret = encapsulated.key(); + byte[] ciphertext = encapsulated.encapsulation(); + + // Simulated transmission of the secret key to the receiver + + // Receiver: Decapsulate the secret key using the private key + KEM receiverKem = KEM.getInstance("ML-KEM"); + KEM.Decapsulator decapsulator = receiverKem.newDecapsulator(privateKey); + SecretKey receiverSharedSecret = decapsulator.decapsulate(ciphertext); + + // Verify that both parties have the same secret key + boolean match = Arrays.equals(senderSharedSecret.getEncoded(), receiverSharedSecret.getEncoded()); + logger.info("Do the shared secret keys match? " + match); + + } +} From 99beaeab5c0b88a4627ad59ee4104f41d9d29a2d Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 25 May 2026 16:32:48 -0400 Subject: [PATCH 2/2] BAEL-9111 Add unit tests --- core-java-modules/core-java-24/pom.xml | 21 +++++++++++++++++++ .../ModuleLatticeBasedDigitalSignature.java | 10 +++++---- .../ModuleLatticeBasedKeyEncapsulation.java | 13 +++++++----- ...eLatticeBasedDigitalSignatureUnitTest.java | 13 ++++++++++++ ...eLatticeBasedKeyEncapsulationUnitTest.java | 13 ++++++++++++ 5 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 core-java-modules/core-java-24/src/test/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignatureUnitTest.java create mode 100644 core-java-modules/core-java-24/src/test/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulationUnitTest.java diff --git a/core-java-modules/core-java-24/pom.xml b/core-java-modules/core-java-24/pom.xml index f90e661520f2..1de61372899c 100644 --- a/core-java-modules/core-java-24/pom.xml +++ b/core-java-modules/core-java-24/pom.xml @@ -22,7 +22,28 @@ --enable-preview + + org.apache.maven.plugins + maven-pmd-plugin + 3.26.0 + + 24 + + + + net.sourceforge.pmd + pmd-core + 7.10.0 + + + net.sourceforge.pmd + pmd-java + 7.10.0 + + + + diff --git a/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignature.java b/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignature.java index 6ac2fb15e6c4..0690e5b25e6f 100644 --- a/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignature.java +++ b/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignature.java @@ -10,9 +10,7 @@ public class ModuleLatticeBasedDigitalSignature { - public static void main(String[] args) throws Exception { - Logger logger = LoggerFactory.getLogger(ModuleLatticeBasedDigitalSignature.class); - + public static boolean verifyDigitalSignature() throws Exception { // Signer: Generate an ML-DSA key pair KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-DSA"); kpg.initialize(NamedParameterSpec.ML_DSA_65); @@ -35,7 +33,11 @@ public static void main(String[] args) throws Exception { signature.update(messageBytes); boolean isValid = signature.verify(sigBytes); - logger.info("Is the signature valid? " + isValid); + return isValid; + } + public static void main(String[] args) throws Exception { + Logger logger = LoggerFactory.getLogger(ModuleLatticeBasedDigitalSignature.class); + logger.info("Is the signature valid? " + verifyDigitalSignature()); } } diff --git a/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulation.java b/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulation.java index 7de889b1f2a7..91ef5eec4000 100644 --- a/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulation.java +++ b/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulation.java @@ -10,8 +10,7 @@ public class ModuleLatticeBasedKeyEncapsulation { - public static void main(String[] args) throws Exception { - Logger logger = LoggerFactory.getLogger(ModuleLatticeBasedKeyEncapsulation.class); + public static boolean performKeyExchange() throws Exception { // Receiver: Generate an ML-KEM key pair KeyPairGenerator kpg = KeyPairGenerator.getInstance("ML-KEM"); @@ -37,9 +36,13 @@ public static void main(String[] args) throws Exception { KEM.Decapsulator decapsulator = receiverKem.newDecapsulator(privateKey); SecretKey receiverSharedSecret = decapsulator.decapsulate(ciphertext); - // Verify that both parties have the same secret key boolean match = Arrays.equals(senderSharedSecret.getEncoded(), receiverSharedSecret.getEncoded()); - logger.info("Do the shared secret keys match? " + match); + return match; + } + + public static void main(String[] args) throws Exception { + Logger logger = LoggerFactory.getLogger(ModuleLatticeBasedKeyEncapsulation.class); + logger.info("Do the shared secret keys match? " + performKeyExchange()); } -} +} \ No newline at end of file diff --git a/core-java-modules/core-java-24/src/test/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignatureUnitTest.java b/core-java-modules/core-java-24/src/test/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignatureUnitTest.java new file mode 100644 index 000000000000..8e18d13a6855 --- /dev/null +++ b/core-java-modules/core-java-24/src/test/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignatureUnitTest.java @@ -0,0 +1,13 @@ +package com.baeldung.javafeatures.mlkemdsa; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class ModuleLatticeBasedDigitalSignatureUnitTest { + + @Test + void givenMLDSA_whenSigningMessage_thenSignatureVerifiedSuccessfully() throws Exception { + assertTrue(ModuleLatticeBasedDigitalSignature.verifyDigitalSignature()); + } +} \ No newline at end of file diff --git a/core-java-modules/core-java-24/src/test/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulationUnitTest.java b/core-java-modules/core-java-24/src/test/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulationUnitTest.java new file mode 100644 index 000000000000..517d01dbac82 --- /dev/null +++ b/core-java-modules/core-java-24/src/test/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulationUnitTest.java @@ -0,0 +1,13 @@ +package com.baeldung.javafeatures.mlkemdsa; + +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +class ModuleLatticeBasedKeyEncapsulationUnitTest { + + @Test + void givenMLKEM_whenSharingSecretKeys_thenSharedSecretKeysMatchedSuccessfully() throws Exception { + assertTrue(ModuleLatticeBasedKeyEncapsulation.performKeyExchange()); + } +} \ No newline at end of file