/// <summary>
        /// Default constructor for Symmetric key algorithm
        /// </summary>
        /// <param name="algorithm">Algorithm to use</param>
        /// <param name="keySizeInBits">Key size in bits, e.g. 256</param>
        /// <param name="settings">Settings for chosen algorithm</param>
        public SymmetricKeyAlgorithm(SymmetricEncryptionAlgorithm algorithm, int keySizeInBits, object settings)
        {
            this.algorithm = algorithm.ToString();

            if (algorithm == SymmetricEncryptionAlgorithm.AES_CTR)
            {
                if (!Array.Exists(AES_CTR.allowedKeyLengths, allowed => allowed * 8 == keySizeInBits))
                {
                    throw new ArgumentException($"{keySizeInBits} is not valid AES-CTR key size!");
                }

                this.settingsAES_CTR = (SettingsAES_CTR)settings;
            }
            else if (algorithm == SymmetricEncryptionAlgorithm.ChaCha20)
            {
                if (ChaCha20.allowedKeyLength * 8 != keySizeInBits)
                {
                    throw new ArgumentException($"{keySizeInBits} is not valid ChaCha20 key size!");
                }

                this.settingsChaCha20 = (SettingsChaCha20)settings;
            }
            else
            {
                throw new NotImplementedException($"{algorithm} constructor not implemented yet!");
            }

            this.keySizeInBits = keySizeInBits;
        }
        /// <summary>
        /// Deep copy constructor
        /// </summary>
        /// <param name="copyThis">SymmetricKeyAlgorithm to copy</param>
        public SymmetricKeyAlgorithm(SymmetricKeyAlgorithm copyThis)
        {
            this.algorithm     = copyThis.algorithm;
            this.keySizeInBits = copyThis.keySizeInBits;

            if (copyThis.settingsAES_CTR != null)
            {
                this.settingsAES_CTR = new SettingsAES_CTR(copyThis.settingsAES_CTR.initialCounter);
            }

            if (copyThis.settingsChaCha20 != null)
            {
                this.settingsChaCha20 = new SettingsChaCha20(copyThis.settingsChaCha20.nonce, copyThis.settingsChaCha20.counter);
            }
        }
 /// <summary>
 /// Generate new SymmetricKeyAlgorithm, you should use this instead of constructor
 /// </summary>
 /// <param name="symmetricEncryptionAlgorithm">Wanted Symmetric encryption algorithm</param>
 /// <returns>SymmetricKeyAlgorithm</returns>
 public static SymmetricKeyAlgorithm GenerateNew(SymmetricEncryptionAlgorithm symmetricEncryptionAlgorithm)
 {
     return(new SymmetricKeyAlgorithm(symmetricEncryptionAlgorithm, 256, (symmetricEncryptionAlgorithm == SymmetricEncryptionAlgorithm.AES_CTR) ? (object)SettingsAES_CTR.CreateWithCryptographicRandomNumbers() : (object)SettingsChaCha20.CreateWithCryptographicRandomNumbers()));
 }