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