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 new file mode 100644 index 000000000000..0690e5b25e6f --- /dev/null +++ b/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedDigitalSignature.java @@ -0,0 +1,43 @@ +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 boolean verifyDigitalSignature() throws Exception { + // 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); + + 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 new file mode 100644 index 000000000000..91ef5eec4000 --- /dev/null +++ b/core-java-modules/core-java-24/src/main/java/com/baeldung/javafeatures/mlkemdsa/ModuleLatticeBasedKeyEncapsulation.java @@ -0,0 +1,48 @@ +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 boolean performKeyExchange() throws Exception { + + // 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); + + boolean match = Arrays.equals(senderSharedSecret.getEncoded(), receiverSharedSecret.getEncoded()); + + 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