8298387: Implement JEP 497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm

Reviewed-by: jnimeh
This commit is contained in:
Ben Perez 2024-11-22 17:48:08 +00:00
parent 21e0fb8648
commit 8b98f958dc
10 changed files with 3789 additions and 12 deletions

View File

@ -69,28 +69,28 @@ public class NamedParameterSpec implements AlgorithmParameterSpec {
= new NamedParameterSpec("Ed448");
/**
* The ML-KEM-512 parameters
* The ML-DSA-44 parameters
*
* @since 24
*/
public static final NamedParameterSpec ML_KEM_512
= new NamedParameterSpec("ML-KEM-512");
public static final NamedParameterSpec ML_DSA_44
= new NamedParameterSpec("ML-DSA-44");
/**
* The ML-KEM-768 parameters
* The ML-DSA-65 parameters
*
* @since 24
*/
public static final NamedParameterSpec ML_KEM_768
= new NamedParameterSpec("ML-KEM-768");
public static final NamedParameterSpec ML_DSA_65
= new NamedParameterSpec("ML-DSA-65");
/**
* The ML-KEM-1024 parameters
* The ML-DSA-87 parameters
*
* @since 24
*/
public static final NamedParameterSpec ML_KEM_1024
= new NamedParameterSpec("ML-KEM-1024");
public static final NamedParameterSpec ML_DSA_87
= new NamedParameterSpec("ML-DSA-87");
private final String name;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,212 @@
/*
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.provider;
import sun.security.jca.JCAUtil;
import java.security.*;
import java.security.SecureRandom;
import java.util.Arrays;
public class ML_DSA_Impls {
public enum Version {
DRAFT, FINAL
}
// This implementation works in FIPS 204 final. If for some reason
// (for example, interop with an old version, or running an old test),
// set the version to an older one. The following VM option is required:
//
// --add-exports java.base/sun.security.provider=ALL-UNNAMED
public static Version version = Version.DRAFT;
static int name2int(String name) {
if (name.endsWith("44")) {
return 2;
} else if (name.endsWith("65")) {
return 3;
} else if (name.endsWith("87")) {
return 5;
} else {
// should not happen
throw new ProviderException("Unknown name " + name);
}
}
public sealed static class KPG
extends NamedKeyPairGenerator permits KPG2, KPG3, KPG5 {
public KPG() {
// ML-DSA-65 is default
super("ML-DSA", "ML-DSA-65", "ML-DSA-44", "ML-DSA-87");
}
public KPG(String pname) {
super("ML-DSA", pname);
}
@Override
protected byte[][] implGenerateKeyPair(String name, SecureRandom sr) {
byte[] seed = new byte[32];
var r = sr != null ? sr : JCAUtil.getDefSecureRandom();
r.nextBytes(seed);
ML_DSA mlDsa = new ML_DSA(name2int(name));
ML_DSA.ML_DSA_KeyPair kp = mlDsa.generateKeyPairInternal(seed);
try {
return new byte[][]{
mlDsa.pkEncode(kp.publicKey()),
mlDsa.skEncode(kp.privateKey())
};
} finally {
kp.privateKey().destroy();
Arrays.fill(seed, (byte)0);
}
}
}
public final static class KPG2 extends KPG {
public KPG2() {
super("ML-DSA-44");
}
}
public final static class KPG3 extends KPG {
public KPG3() {
super("ML-DSA-65");
}
}
public final static class KPG5 extends KPG {
public KPG5() {
super("ML-DSA-87");
}
}
public sealed static class KF extends NamedKeyFactory permits KF2, KF3, KF5 {
public KF() {
super("ML-DSA", "ML-DSA-44", "ML-DSA-65", "ML-DSA-87");
}
public KF(String name) {
super("ML-DSA", name);
}
}
public final static class KF2 extends KF {
public KF2() {
super("ML-DSA-44");
}
}
public final static class KF3 extends KF {
public KF3() {
super("ML-DSA-65");
}
}
public final static class KF5 extends KF {
public KF5() {
super("ML-DSA-87");
}
}
public sealed static class SIG extends NamedSignature permits SIG2, SIG3, SIG5 {
public SIG() {
super("ML-DSA", "ML-DSA-44", "ML-DSA-65", "ML-DSA-87");
}
public SIG(String name) {
super("ML-DSA", name);
}
@Override
protected byte[] implSign(String name, byte[] skBytes,
Object sk2, byte[] msg, SecureRandom sr) {
var size = name2int(name);
var r = sr != null ? sr : JCAUtil.getDefSecureRandom();
byte[] rnd = new byte[32];
r.nextBytes(rnd);
var mlDsa = new ML_DSA(size);
if (version == Version.FINAL) {
// FIPS 204 Algorithm 2 ML-DSA.Sign prepend {0, len(ctx)}
// to message before passing it to Sign_internal.
var m = new byte[msg.length + 2];
System.arraycopy(msg, 0, m, 2, msg.length); // len(ctx) = 0
msg = m;
}
ML_DSA.ML_DSA_Signature sig = mlDsa.signInternal(msg, rnd, skBytes);
return mlDsa.sigEncode(sig);
}
@Override
protected boolean implVerify(String name, byte[] pkBytes,
Object pk2, byte[] msg, byte[] sigBytes)
throws SignatureException {
var size = name2int(name);
var mlDsa = new ML_DSA(size);
if (version == Version.FINAL) {
// FIPS 204 Algorithm 3 ML-DSA.Verify prepend {0, len(ctx)}
// to message before passing it to Verify_internal.
var m = new byte[msg.length + 2];
System.arraycopy(msg, 0, m, 2, msg.length); // len(ctx) = 0
msg = m;
}
return mlDsa.verifyInternal(pkBytes, msg, sigBytes);
}
@Override
protected Object implCheckPublicKey(String name, byte[] pk)
throws InvalidKeyException {
ML_DSA mlDsa = new ML_DSA(name2int(name));
return mlDsa.checkPublicKey(pk);
}
@Override
protected Object implCheckPrivateKey(String name, byte[] sk)
throws InvalidKeyException {
ML_DSA mlDsa = new ML_DSA(name2int(name));
return mlDsa.checkPrivateKey(sk);
}
}
public final static class SIG2 extends SIG {
public SIG2() {
super("ML-DSA-44");
}
}
public final static class SIG3 extends SIG {
public SIG3() {
super("ML-DSA-65");
}
}
public final static class SIG5 extends SIG {
public SIG5() {
super("ML-DSA-87");
}
}
}

View File

@ -187,20 +187,33 @@ public final class SunEntries {
attrs.clear();
attrs.put("ImplementedIn", "Software");
addWithAlias(p, "Signature", "HSS/LMS", "sun.security.provider.HSS", attrs);
add(p, "Signature", "ML-DSA", "sun.security.provider.ML_DSA_Impls$SIG", attrs);
addWithAlias(p, "Signature", "ML-DSA-44", "sun.security.provider.ML_DSA_Impls$SIG2", attrs);
addWithAlias(p, "Signature", "ML-DSA-65", "sun.security.provider.ML_DSA_Impls$SIG3", attrs);
addWithAlias(p, "Signature", "ML-DSA-87", "sun.security.provider.ML_DSA_Impls$SIG5", attrs);
/*
* Key Pair Generator engines
*/
attrs.clear();
attrs.put("ImplementedIn", "Software");
attrs.put("KeySize", "2048"); // for DSA KPG and APG only
String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$";
dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current");
attrs.put("KeySize", "2048");
addWithAlias(p, "KeyPairGenerator", "DSA", dsaKPGImplClass, attrs);
attrs.remove("KeySize");
add(p, "KeyPairGenerator", "ML-DSA", "sun.security.provider.ML_DSA_Impls$KPG", attrs);
addWithAlias(p, "KeyPairGenerator", "ML-DSA-44", "sun.security.provider.ML_DSA_Impls$KPG2", attrs);
addWithAlias(p, "KeyPairGenerator", "ML-DSA-65", "sun.security.provider.ML_DSA_Impls$KPG3", attrs);
addWithAlias(p, "KeyPairGenerator", "ML-DSA-87", "sun.security.provider.ML_DSA_Impls$KPG5", attrs);
/*
* Algorithm Parameter Generator engines
*/
attrs.put("KeySize", "2048");
addWithAlias(p, "AlgorithmParameterGenerator", "DSA",
"sun.security.provider.DSAParameterGenerator", attrs);
attrs.remove("KeySize");
@ -219,6 +232,11 @@ public final class SunEntries {
addWithAlias(p, "KeyFactory", "HSS/LMS",
"sun.security.provider.HSS$KeyFactoryImpl", attrs);
add(p, "KeyFactory", "ML-DSA", "sun.security.provider.ML_DSA_Impls$KF", attrs);
addWithAlias(p, "KeyFactory", "ML-DSA-44", "sun.security.provider.ML_DSA_Impls$KF2", attrs);
addWithAlias(p, "KeyFactory", "ML-DSA-65", "sun.security.provider.ML_DSA_Impls$KF3", attrs);
addWithAlias(p, "KeyFactory", "ML-DSA-87", "sun.security.provider.ML_DSA_Impls$KF5", attrs);
/*
* Digest engines
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -178,6 +178,9 @@ public enum KnownOIDs {
SHA3_256withRSA("2.16.840.1.101.3.4.3.14", "SHA3-256withRSA"),
SHA3_384withRSA("2.16.840.1.101.3.4.3.15", "SHA3-384withRSA"),
SHA3_512withRSA("2.16.840.1.101.3.4.3.16", "SHA3-512withRSA"),
ML_DSA_44("2.16.840.1.101.3.4.3.17", "ML-DSA-44"),
ML_DSA_65("2.16.840.1.101.3.4.3.18", "ML-DSA-65"),
ML_DSA_87("2.16.840.1.101.3.4.3.19", "ML-DSA-87"),
// kems 2.16.840.1.101.3.4.4.*
ML_KEM_512("2.16.840.1.101.3.4.4.1", "ML-KEM-512"),

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -205,7 +205,8 @@ public class Deterministic {
case "EC" -> 256;
case "EdDSA", "Ed25519", "XDH", "X25519" -> 255;
case "Ed448", "X448" -> 448;
case "ML-KEM", "ML-KEM-768", "ML-KEM-512", "ML-KEM-1024" -> -1;
case "ML-KEM", "ML-KEM-768", "ML-KEM-512", "ML-KEM-1024",
"ML-DSA", "ML-DSA-44", "ML-DSA-65", "ML-DSA-87" -> -1;
default -> throw new UnsupportedOperationException(alg);
};
g.initialize(size, new SeededSecureRandom(SEED + offset));

File diff suppressed because one or more lines are too long