<PackageReference Include="BouncyCastle.Cryptography" Version="2.5.1" />

BcTlsMLKemDomain

using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Crypto.Generators; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Security; using System; namespace Org.BouncyCastle.Tls.Crypto.Impl.BC { public class BcTlsMLKemDomain : TlsKemDomain { protected readonly BcTlsCrypto m_crypto; protected readonly TlsKemConfig m_config; protected readonly MLKemParameters m_domainParameters; protected readonly bool m_isServer; public virtual bool IsServer => m_isServer; public static MLKemParameters GetDomainParameters(TlsKemConfig kemConfig) { switch (kemConfig.NamedGroup) { case 1298: return MLKemParameters.ml_kem_512; case 1896: return MLKemParameters.ml_kem_768; case 4132: return MLKemParameters.ml_kem_1024; default: throw new ArgumentException("No ML-KEM configuration provided", "kemConfig"); } } public BcTlsMLKemDomain(BcTlsCrypto crypto, TlsKemConfig kemConfig) { m_crypto = crypto; m_config = kemConfig; m_domainParameters = GetDomainParameters(kemConfig); m_isServer = kemConfig.IsServer; } public virtual TlsAgreement CreateKem() { return new BcTlsMLKem(this); } public virtual BcTlsSecret Decapsulate(MLKemPrivateKeyParameters privateKey, byte[] ciphertext) { IKemDecapsulator decapsulator = KemUtilities.GetDecapsulator(m_domainParameters.Oid); decapsulator.Init(privateKey); byte[] data = KemUtilities.Decapsulate(decapsulator, ciphertext, 0, ciphertext.Length); return m_crypto.AdoptLocalSecret(data); } public virtual MLKemPublicKeyParameters DecodePublicKey(byte[] encoding) { return MLKemPublicKeyParameters.FromEncoding(m_domainParameters, encoding); } public virtual byte[] Encapsulate(MLKemPublicKeyParameters publicKey, out TlsSecret secret) { IKemEncapsulator encapsulator = KemUtilities.GetEncapsulator(m_domainParameters.Oid); encapsulator.Init(new ParametersWithRandom(publicKey, m_crypto.SecureRandom)); Tuple<byte[], byte[]> tuple = KemUtilities.Encapsulate(encapsulator); secret = m_crypto.AdoptLocalSecret(tuple.Item2); return tuple.Item1; } public virtual byte[] EncodePublicKey(MLKemPublicKeyParameters publicKey) { return publicKey.GetEncoded(); } public virtual AsymmetricCipherKeyPair GenerateKeyPair() { MLKemKeyPairGenerator mLKemKeyPairGenerator = new MLKemKeyPairGenerator(); mLKemKeyPairGenerator.Init(new MLKemKeyGenerationParameters(m_crypto.SecureRandom, m_domainParameters)); return mLKemKeyPairGenerator.GenerateKeyPair(); } } }