public override byte[] DeriveKeyFromHmac(
            ECDiffieHellmanPublicKey otherPartyPublicKey,
            HashAlgorithmName hashAlgorithm,
            byte[]?hmacKey,
            byte[]?secretPrepend,
            byte[]?secretAppend)
        {
            if (otherPartyPublicKey == null)
            {
                throw new ArgumentNullException(nameof(otherPartyPublicKey));
            }
            if (string.IsNullOrEmpty(hashAlgorithm.Name))
            {
                throw new ArgumentException(SR.Cryptography_HashAlgorithmNameNullOrEmpty, nameof(hashAlgorithm));
            }

            using (SafeNCryptSecretHandle secretAgreement = DeriveSecretAgreementHandle(otherPartyPublicKey))
            {
                Interop.NCrypt.SecretAgreementFlags flags = hmacKey == null ?
                                                            Interop.NCrypt.SecretAgreementFlags.UseSecretAsHmacKey :
                                                            Interop.NCrypt.SecretAgreementFlags.None;

                return(Interop.NCrypt.DeriveKeyMaterialHmac(
                           secretAgreement,
                           hashAlgorithm.Name,
                           hmacKey,
                           secretPrepend,
                           secretAppend,
                           flags));
            }
        }
        public byte[] DeriveKeyMaterial(CngKey otherPartyPublicKey)
        {
            ArgumentNullException.ThrowIfNull(otherPartyPublicKey);

            if (otherPartyPublicKey.AlgorithmGroup != CngAlgorithmGroup.ECDiffieHellman)
            {
                throw new ArgumentException(SR.Cryptography_ArgECDHRequiresECDHKey, nameof(otherPartyPublicKey));
            }
            if (otherPartyPublicKey.KeySize != KeySize)
            {
                throw new ArgumentException(SR.Cryptography_ArgECDHKeySizeMismatch, nameof(otherPartyPublicKey));
            }

            // Setting the flag to UseSecretAsHmacKey even when the KDF isn't HMAC, because that's what .NET Framework does.
            Interop.NCrypt.SecretAgreementFlags flags =
                UseSecretAgreementAsHmacKey
                    ? Interop.NCrypt.SecretAgreementFlags.UseSecretAsHmacKey
                    : Interop.NCrypt.SecretAgreementFlags.None;

            using (SafeNCryptSecretHandle handle = DeriveSecretAgreementHandle(otherPartyPublicKey))
            {
                switch (KeyDerivationFunction)
                {
                case ECDiffieHellmanKeyDerivationFunction.Hash:
                    return(Interop.NCrypt.DeriveKeyMaterialHash(
                               handle,
                               HashAlgorithm.Algorithm,
                               _secretPrepend,
                               _secretAppend,
                               flags));

                case ECDiffieHellmanKeyDerivationFunction.Hmac:
                    return(Interop.NCrypt.DeriveKeyMaterialHmac(
                               handle,
                               HashAlgorithm.Algorithm,
                               _hmacKey,
                               _secretPrepend,
                               _secretAppend,
                               flags));

                case ECDiffieHellmanKeyDerivationFunction.Tls:
                    if (_label == null || _seed == null)
                    {
                        throw new InvalidOperationException(SR.Cryptography_TlsRequiresLabelAndSeed);
                    }

                    return(Interop.NCrypt.DeriveKeyMaterialTls(
                               handle,
                               _label,
                               _seed,
                               flags));

                default:
                    Debug.Fail($"Unknown KDF ({KeyDerivationFunction})");
                    // Match .NET Framework behavior
                    goto case ECDiffieHellmanKeyDerivationFunction.Tls;
                }
            }
        }