/// <summary>
        /// Creates a new instance of a <see cref="CascadingSymmetricKey" /> using the specified buffer.
        /// </summary>
        /// <param name="buffer">
        /// A binary representation of a <see cref="CascadingSymmetricKey" />.
        /// </param>
        /// <returns>
        /// A new instance of a <see cref="CascadingSymmetricKey" />.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// <paramref name="buffer" /> is invalid.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="buffer" /> is <see langword="null" />.
        /// </exception>
        public static CascadingSymmetricKey FromBuffer(SecureBuffer buffer)
        {
            buffer.RejectIf().IsNull(nameof(buffer)).OrIf(argument => argument.Length != SerializedLength, nameof(buffer), "The specified buffer is invalid.");

            try
            {
                var keys = (SecureSymmetricKey[])null;

                buffer.Access(pinnedBuffer =>
                {
                    // Interrogate the final 16 bits to determine the depth.
                    var keyLength = SecureSymmetricKey.SerializedLength;
                    var depth     = BitConverter.ToUInt16(pinnedBuffer, (SerializedLength - sizeof(UInt16)));
                    keys          = new SecureSymmetricKey[depth];

                    for (var i = 0; i < depth; i++)
                    {
                        using (var secureBuffer = new SecureBuffer(keyLength))
                        {
                            secureBuffer.Access(keyBuffer =>
                            {
                                // Copy out the key buffers.
                                Array.Copy(pinnedBuffer, (keyLength * i), keyBuffer, 0, keyLength);
                            });

                            keys[i] = SecureSymmetricKey.FromBuffer(secureBuffer);
                        }
                    }
                });

                return(new CascadingSymmetricKey(keys));
            }
            catch
            {
                throw new ArgumentException("The specified buffer is invalid.", nameof(buffer));
            }
        }
        /// <summary>
        /// Creates a new instance of a <see cref="SecureSymmetricKey" /> using the specified buffer.
        /// </summary>
        /// <param name="buffer">
        /// A binary representation of a <see cref="SecureSymmetricKey" />.
        /// </param>
        /// <returns>
        /// A new instance of a <see cref="SecureSymmetricKey" />.
        /// </returns>
        /// <exception cref="ArgumentException">
        /// <paramref name="buffer" /> is invalid.
        /// </exception>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="buffer" /> is <see langword="null" />.
        /// </exception>
        public static SecureSymmetricKey FromBuffer(SecureBuffer buffer)
        {
            buffer.RejectIf().IsNull(nameof(buffer)).OrIf(argument => argument.Length != SerializedLength, nameof(buffer), "The specified buffer is invalid.");

            try
            {
                var result = (SecureSymmetricKey)null;

                buffer.Access(pinnedCiphertext =>
                {
                    using (var plaintextBuffer = new PinnedBuffer(SerializedPlaintextLength, true))
                    {
                        using (var cipher = BufferEncryptionAlgorithm.ToCipher(RandomnessProvider))
                        {
                            using (var plaintext = cipher.Decrypt(pinnedCiphertext, BufferEncryptionKey))
                            {
                                Array.Copy(plaintext, 0, plaintextBuffer, 0, SerializedPlaintextLength);
                            }
                        }

                        using (var keySource = new PinnedBuffer(KeySourceLengthInBytes, true))
                        {
                            Array.Copy(plaintextBuffer, KeySourceBufferIndex, keySource, 0, KeySourceLengthInBytes);
                            var algorithm      = (SymmetricAlgorithmSpecification)plaintextBuffer[AlgorithmBufferIndex];
                            var derivationMode = (SecureSymmetricKeyDerivationMode)plaintextBuffer[DerivationModeBufferIndex];
                            result             = new SecureSymmetricKey(algorithm, derivationMode, keySource);
                        }
                    }
                });

                return(result);
            }
            catch
            {
                throw new ArgumentException("The specified buffer is invalid.", nameof(buffer));
            }
        }