diff --git a/crypto/src/crypto/parameters/MLDsaParameters.cs b/crypto/src/crypto/parameters/MLDsaParameters.cs
index 5cb0f4da8..b4a8975d0 100644
--- a/crypto/src/crypto/parameters/MLDsaParameters.cs
+++ b/crypto/src/crypto/parameters/MLDsaParameters.cs
@@ -7,21 +7,36 @@
namespace Org.BouncyCastle.Crypto.Parameters
{
+ ///
+ /// Algorithm parameter set identifiers for ML-DSA (Module-Lattice-Based Digital Signature Algorithm) as
+ /// specified in FIPS 204.
+ ///
+ ///
+ /// ML-DSA is the NIST-standardized post-quantum signature scheme derived from CRYSTALS-Dilithium. Each
+ /// parameter set fixes lattice dimensions and security category. The _with_sha512 variants wrap the
+ /// pure scheme in the HashML-DSA pre-hash construction from FIPS 204, §5.4.
+ ///
public sealed class MLDsaParameters
{
+ /// Pure ML-DSA-44 (NIST security category 2).
public static readonly MLDsaParameters ml_dsa_44 = new MLDsaParameters("ML-DSA-44", MLDsaParameterSet.ml_dsa_44,
NistObjectIdentifiers.id_ml_dsa_44, null);
+ /// Pure ML-DSA-65 (NIST security category 3).
public static readonly MLDsaParameters ml_dsa_65 = new MLDsaParameters("ML-DSA-65", MLDsaParameterSet.ml_dsa_65,
NistObjectIdentifiers.id_ml_dsa_65, null);
+ /// Pure ML-DSA-87 (NIST security category 5).
public static readonly MLDsaParameters ml_dsa_87 = new MLDsaParameters("ML-DSA-87", MLDsaParameterSet.ml_dsa_87,
NistObjectIdentifiers.id_ml_dsa_87, null);
+ /// HashML-DSA-44 pre-hashed with SHA-512.
public static readonly MLDsaParameters ml_dsa_44_with_sha512 = new MLDsaParameters("ML-DSA-44-WITH-SHA512",
MLDsaParameterSet.ml_dsa_44, NistObjectIdentifiers.id_hash_ml_dsa_44_with_sha512,
NistObjectIdentifiers.IdSha512);
+ /// HashML-DSA-65 pre-hashed with SHA-512.
public static readonly MLDsaParameters ml_dsa_65_with_sha512 = new MLDsaParameters("ML-DSA-65-WITH-SHA512",
MLDsaParameterSet.ml_dsa_65, NistObjectIdentifiers.id_hash_ml_dsa_65_with_sha512,
NistObjectIdentifiers.IdSha512);
+ /// HashML-DSA-87 pre-hashed with SHA-512.
public static readonly MLDsaParameters ml_dsa_87_with_sha512 = new MLDsaParameters("ML-DSA-87-WITH-SHA512",
MLDsaParameterSet.ml_dsa_87, NistObjectIdentifiers.id_hash_ml_dsa_87_with_sha512,
NistObjectIdentifiers.IdSha512);
@@ -62,16 +77,20 @@ private MLDsaParameters(string name, MLDsaParameterSet parameterSet, DerObjectId
m_preHashOid = preHashOid;
}
+ /// true for HashML-DSA variants (pre-hashed input); false for pure ML-DSA.
public bool IsPreHash => m_preHashOid != null;
+ /// The standard algorithm name (e.g. ML-DSA-65 or ML-DSA-65-WITH-SHA512).
public string Name => m_name;
internal DerObjectIdentifier Oid => m_oid;
internal DerObjectIdentifier PreHashOid => m_preHashOid;
+ /// The underlying ML-DSA parameter set (lattice dimensions, number-theoretic constants).
public MLDsaParameterSet ParameterSet => m_parameterSet;
+ /// Returns the algorithm name (see ).
public override string ToString() => Name;
}
}
diff --git a/crypto/src/crypto/parameters/MLDsaPublicKeyParameters.cs b/crypto/src/crypto/parameters/MLDsaPublicKeyParameters.cs
index d82b8d366..bddccff3a 100644
--- a/crypto/src/crypto/parameters/MLDsaPublicKeyParameters.cs
+++ b/crypto/src/crypto/parameters/MLDsaPublicKeyParameters.cs
@@ -5,9 +5,27 @@
namespace Org.BouncyCastle.Crypto.Parameters
{
+ ///
+ /// An ML-DSA public (verification) key, as specified in FIPS 204.
+ ///
+ ///
+ /// Internally the key is kept split into the rho seed and the t1 vector per FIPS 204 §5.2.
+ /// The full public-key hash tr is computed lazily on first use and cached for subsequent verify
+ /// operations.
+ ///
public sealed class MLDsaPublicKeyParameters
: MLDsaKeyParameters
{
+ ///
+ /// Create an from its raw FIPS 204 public key encoding.
+ ///
+ /// The ML-DSA algorithm parameters this key belongs to.
+ /// The raw public key bytes. Length must equal the parameter set's
+ /// PublicKeyLength.
+ /// A new .
+ /// If or
+ /// is null.
+ /// If has the wrong length.
public static MLDsaPublicKeyParameters FromEncoding(MLDsaParameters parameters, byte[] encoding)
{
if (parameters == null)
@@ -34,6 +52,7 @@ internal MLDsaPublicKeyParameters(MLDsaParameters parameters, byte[] rho, byte[]
m_t1 = t1;
}
+ /// Returns a fresh copy of the FIPS 204 public key encoding (rho || t1).
public byte[] GetEncoded() => Arrays.Concatenate(m_rho, m_t1);
internal byte[] GetPublicKeyHash() =>
diff --git a/crypto/src/crypto/parameters/MLKemParameters.cs b/crypto/src/crypto/parameters/MLKemParameters.cs
index 8c44f1ff6..21380c545 100644
--- a/crypto/src/crypto/parameters/MLKemParameters.cs
+++ b/crypto/src/crypto/parameters/MLKemParameters.cs
@@ -7,12 +7,24 @@
namespace Org.BouncyCastle.Crypto.Parameters
{
+ ///
+ /// Algorithm parameter set identifiers for ML-KEM (Module-Lattice-Based Key-Encapsulation Mechanism) as
+ /// specified in FIPS 203.
+ ///
+ ///
+ /// ML-KEM is a post-quantum key-encapsulation mechanism standardized by NIST, derived from CRYSTALS-Kyber.
+ /// Each instance binds a human-readable algorithm name, an internal , and the
+ /// NIST-assigned algorithm OID used in X.509/PKIX encodings.
+ ///
public sealed class MLKemParameters
{
+ /// ML-KEM-512 parameter set (NIST security category 1).
public static readonly MLKemParameters ml_kem_512 = new MLKemParameters("ML-KEM-512",
MLKemParameterSet.ml_kem_512, NistObjectIdentifiers.id_alg_ml_kem_512);
+ /// ML-KEM-768 parameter set (NIST security category 3).
public static readonly MLKemParameters ml_kem_768 = new MLKemParameters("ML-KEM-768",
MLKemParameterSet.ml_kem_768, NistObjectIdentifiers.id_alg_ml_kem_768);
+ /// ML-KEM-1024 parameter set (NIST security category 5).
public static readonly MLKemParameters ml_kem_1024 = new MLKemParameters("ML-KEM-1024",
MLKemParameterSet.ml_kem_1024, NistObjectIdentifiers.id_alg_ml_kem_1024);
@@ -43,12 +55,15 @@ private MLKemParameters(string name, MLKemParameterSet parameterSet, DerObjectId
m_oid = oid ?? throw new ArgumentNullException(nameof(oid));
}
+ /// The standard algorithm name identifying this parameter set (e.g. ML-KEM-768).
public string Name => m_name;
internal DerObjectIdentifier Oid => m_oid;
+ /// The underlying ML-KEM parameter set (lattice dimensions, noise bounds, etc.).
public MLKemParameterSet ParameterSet => m_parameterSet;
+ /// Returns the algorithm name (see ).
public override string ToString() => Name;
}
}
diff --git a/crypto/src/crypto/parameters/MLKemPrivateKeyParameters.cs b/crypto/src/crypto/parameters/MLKemPrivateKeyParameters.cs
index edccae5a5..298c0b920 100644
--- a/crypto/src/crypto/parameters/MLKemPrivateKeyParameters.cs
+++ b/crypto/src/crypto/parameters/MLKemPrivateKeyParameters.cs
@@ -6,11 +6,40 @@
namespace Org.BouncyCastle.Crypto.Parameters
{
+ ///
+ /// An ML-KEM private (decapsulation) key, as specified in FIPS 203.
+ ///
+ ///
+ /// A private key may be stored in one of three equivalent forms, selected by : the
+ /// 32-byte seed only, the expanded byte encoding only, or both. The seed form is the smallest and is
+ /// preferred where the runtime can re-expand it on use; the expanded encoding avoids re-expansion but is
+ /// much larger.
+ ///
public sealed class MLKemPrivateKeyParameters
: MLKemKeyParameters
{
- public enum Format { SeedOnly, EncodingOnly, SeedAndEncoding };
-
+ /// Representation format for an ML-KEM private key.
+ public enum Format
+ {
+ /// Store the 32-byte seed only; the expanded encoding is regenerated on demand.
+ SeedOnly,
+ /// Store the full expanded FIPS 203 private key encoding only (no seed available).
+ EncodingOnly,
+ /// Store both the seed and the expanded encoding.
+ SeedAndEncoding
+ };
+
+ ///
+ /// Create an from its expanded FIPS 203 private key encoding.
+ ///
+ /// The ML-KEM algorithm parameters this key belongs to.
+ /// The raw decapsulation key bytes. Length must equal the parameter set's
+ /// SecretKeyBytes.
+ /// A private key in form (no seed retained).
+ /// If or
+ /// is null.
+ /// If has the wrong length or fails the
+ /// FIPS 203 hash check.
public static MLKemPrivateKeyParameters FromEncoding(MLKemParameters parameters, byte[] encoding)
{
if (parameters == null)
@@ -31,9 +60,30 @@ public static MLKemPrivateKeyParameters FromEncoding(MLKemParameters parameters,
return new MLKemPrivateKeyParameters(parameters, seed: null, encoding, Format.EncodingOnly);
}
+ ///
+ /// Derive a private key from its 32-byte seed, defaulting to the
+ /// representation.
+ ///
+ /// The ML-KEM algorithm parameters.
+ /// The 32-byte FIPS 203 seed (d || z).
+ /// A new private key whose expanded encoding is derived from the seed.
+ /// If any argument is null.
+ /// If has the wrong length.
public static MLKemPrivateKeyParameters FromSeed(MLKemParameters parameters, byte[] seed) =>
FromSeed(parameters, seed, preferredFormat: Format.SeedOnly);
+ ///
+ /// Derive a private key from its 32-byte seed, selecting the preferred on-disk representation.
+ ///
+ /// The ML-KEM algorithm parameters.
+ /// The 32-byte FIPS 203 seed (d || z).
+ /// The format to report via . Must be
+ /// or since a seed is available.
+ /// A new private key whose expanded encoding is derived from the seed.
+ /// If or
+ /// is null.
+ /// If has the wrong length or
+ /// is not valid.
public static MLKemPrivateKeyParameters FromSeed(MLKemParameters parameters, byte[] seed,
Format preferredFormat)
{
@@ -70,19 +120,33 @@ internal MLKemPrivateKeyParameters(MLKemParameters parameters, byte[] seed, byte
internal byte[] Encoding => m_encoding;
+ /// Returns a copy of the expanded FIPS 203 private key encoding.
public byte[] GetEncoded() => Arrays.InternalCopyBuffer(m_encoding);
+ /// Extracts the matching from this private key.
public MLKemPublicKeyParameters GetPublicKey() =>
new MLKemPublicKeyParameters(Parameters, GetPublicKeyEncoded());
+ /// Returns the raw public (encapsulation) key bytes embedded in this private key.
public byte[] GetPublicKeyEncoded() => Parameters.ParameterSet.Engine.CopyEncapKey(decapKey: m_encoding);
+ ///
+ /// Returns a copy of the 32-byte seed, or null if the key was imported without one (i.e. created
+ /// via ).
+ ///
public byte[] GetSeed() => Arrays.Clone(m_seed);
+ /// The caller-preferred encoding format (see ).
public Format PreferredFormat => m_preferredFormat;
internal byte[] Seed => m_seed;
+ ///
+ /// Returns this key with a different , or the same instance if no change
+ /// is needed.
+ ///
+ /// The new format. Requesting a seed-bearing format when no seed is
+ /// available throws .
public MLKemPrivateKeyParameters WithPreferredFormat(Format preferredFormat)
{
if (m_preferredFormat == preferredFormat)
diff --git a/crypto/src/crypto/parameters/MLKemPublicKeyParameters.cs b/crypto/src/crypto/parameters/MLKemPublicKeyParameters.cs
index a97943189..5f677d0fb 100644
--- a/crypto/src/crypto/parameters/MLKemPublicKeyParameters.cs
+++ b/crypto/src/crypto/parameters/MLKemPublicKeyParameters.cs
@@ -5,9 +5,29 @@
namespace Org.BouncyCastle.Crypto.Parameters
{
+ ///
+ /// An ML-KEM public (encapsulation) key, represented by the raw byte encoding defined in FIPS 203.
+ ///
+ ///
+ /// Instances are immutable and can be used to perform key encapsulation. Create instances via
+ /// or by generating a key pair; the constructor is
+ /// internal.
+ ///
public sealed class MLKemPublicKeyParameters
: MLKemKeyParameters
{
+ ///
+ /// Create an from its raw FIPS 203 public key encoding.
+ ///
+ /// The ML-KEM algorithm parameters this key belongs to.
+ /// The raw public key bytes. Length must equal the parameter set's
+ /// PublicKeyBytes.
+ /// A new wrapping a defensive copy of
+ /// .
+ /// If or
+ /// is null.
+ /// If has the wrong length or fails the
+ /// FIPS 203 modulus check.
public static MLKemPublicKeyParameters FromEncoding(MLKemParameters parameters, byte[] encoding)
{
if (parameters == null)
@@ -38,6 +58,7 @@ internal MLKemPublicKeyParameters(MLKemParameters parameters, byte[] encoding)
internal byte[] Encoding => m_encoding;
+ /// Returns a copy of the raw FIPS 203 public key encoding.
public byte[] GetEncoded() => Arrays.InternalCopyBuffer(m_encoding);
// NB: Don't remove - needed by commented-out test cases