public void Test_Decrypt_DecryptsLargeBlock(int bufferLength)
        {
            using (var ciphertextStream = new MemoryStream())
                using (var key = XChaChaKey.Generate())
                {
                    var plaintext = RandomBytesGenerator.NextBytes(1024 * 1024);

                    using (var encryptionStream =
                               new XChaChaBufferedStream(ciphertextStream, key, EncryptionMode.Encrypt, bufferLength, leaveOpen: true))
                    {
                        encryptionStream.Write(plaintext);
                    }

                    ciphertextStream.Position = 0;

                    using (var decryptionStream =
                               new XChaChaBufferedStream(ciphertextStream, key, EncryptionMode.Decrypt, bufferLength))
                    {
                        var decryptedPlainText  = new byte[plaintext.Length];
                        var numberOfBytesOutput = decryptionStream.Read(decryptedPlainText);

                        Assert.Equal(plaintext.Length, numberOfBytesOutput);
                        Assert.Equal(plaintext.ToArray(), decryptedPlainText);
                    }
                }
        }
        public void Test_Decrypt_OverReadDecryptionStream_OutputsCorrectNumberOfBytes()
        {
            using (var ciphertextStream = new MemoryStream())
                using (var key = XChaChaKey.Generate())
                {
                    var plaintext = TestConstants.MessageBytes;

                    using (var encryptionStream =
                               new XChaChaBufferedStream(ciphertextStream, key, EncryptionMode.Encrypt, leaveOpen: true))
                    {
                        encryptionStream.Write(plaintext);
                    }

                    ciphertextStream.Position = 0;

                    using (var decryptionStream = new XChaChaBufferedStream(ciphertextStream, key, EncryptionMode.Decrypt))
                    {
                        var decryptedPlainText  = new byte[plaintext.Length * 2];
                        var numberOfBytesOutput = decryptionStream.Read(decryptedPlainText);

                        Assert.Equal(plaintext.Length, numberOfBytesOutput);
                        Assert.Equal(plaintext, decryptedPlainText.Take(plaintext.Length));
                    }
                }
        }
        public void Test_Decrypt_UsingCompressionStream_DecryptsSmallBlock()
        {
            using (var ciphertextStream = new MemoryStream())
                using (var key = XChaChaKey.Generate())
                {
                    var plaintext = TestConstants.MessageBytes;

                    using (var encryptionStream =
                               new XChaChaBufferedStream(ciphertextStream, key, EncryptionMode.Encrypt, leaveOpen: true))
                    {
                        using (var compressionStream = new BrotliStream(encryptionStream, CompressionMode.Compress))
                        {
                            compressionStream.Write(plaintext);
                        }
                    }

                    ciphertextStream.Position = 0;

                    using (var decryptionStream = new XChaChaBufferedStream(ciphertextStream, key, EncryptionMode.Decrypt))
                    {
                        using (var decompressionStream = new BrotliStream(decryptionStream, CompressionMode.Decompress))
                        {
                            var decryptedPlainText  = new byte[plaintext.Length];
                            var numberOfBytesOutput = decompressionStream.Read(decryptedPlainText);

                            Assert.Equal(plaintext.Length, numberOfBytesOutput);
                            Assert.Equal(plaintext, decryptedPlainText);
                        }
                    }
                }
        }
Esempio n. 4
0
        public void Test_Encrypt_WriteDifferentAmountsToStream()
        {
            var plaintext1 = RandomBytesGenerator.NextBytes(157 * 1024);
            var plaintext2 = RandomBytesGenerator.NextBytes(314 * 1024);
            var plaintext3 = RandomBytesGenerator.NextBytes(273 * 1024);

            var       totalPlainTextLength = plaintext1.Length + plaintext2.Length + plaintext3.Length;
            const int numberOfWrites       = 3;
            var       expectedOutputLength = StreamHeaderLength + totalPlainTextLength + (numberOfWrites * StreamABytes);

            using (var outputStream = new MemoryStream())
            {
                using (var key = XChaChaKey.Generate())
                    using (var encryptionStream = new XChaChaStream(outputStream, key, EncryptionMode.Encrypt))
                    {
                        encryptionStream.Write(plaintext1);
                        encryptionStream.Write(plaintext2);
                        encryptionStream.WriteFinal(plaintext3);
                    }

                var ciphertext = outputStream.ToArray();

                Assert.Equal(expectedOutputLength, ciphertext.Length);
            }
        }
Esempio n. 5
0
        public void Test_Decrypt_VerifyEndOfMessage_FalseWhenPartiallyDecrypted()
        {
            using (var ciphertextStream = new MemoryStream())
                using (var key = XChaChaKey.Generate())
                {
                    var plaintext1 = RandomBytesGenerator.NextBytes(1024);
                    var plaintext2 = RandomBytesGenerator.NextBytes(1024);

                    using (var encryptionStream = new XChaChaStream(ciphertextStream, key, EncryptionMode.Encrypt, leaveOpen: true))
                    {
                        encryptionStream.Write(plaintext1);
                        encryptionStream.WriteFinal(plaintext2);
                    }

                    ciphertextStream.Position = 0;

                    using (var decryptionStream = new XChaChaStream(ciphertextStream, key, EncryptionMode.Decrypt))
                    {
                        var decryptedPlainText = new byte[plaintext1.Length];

                        decryptionStream.Read(decryptedPlainText);
                        Assert.False(decryptionStream.VerifyEndOfMessage());
                    }
                }
        }
        public void Test_Decrypt_MultipleSmallBlocks()
        {
            using (var ciphertextStream = new MemoryStream())
                using (var key = XChaChaKey.Generate())
                {
                    var plaintext1 = RandomBytesGenerator.NextBytes(17);
                    var plaintext2 = RandomBytesGenerator.NextBytes(23);

                    using (var encryptionStream =
                               new XChaChaBufferedStream(ciphertextStream, key, EncryptionMode.Encrypt, leaveOpen: true))
                    {
                        encryptionStream.Write(plaintext1);
                        encryptionStream.Write(plaintext2);
                    }

                    ciphertextStream.Position = 0;

                    using (var decryptionStream = new XChaChaBufferedStream(ciphertextStream, key, EncryptionMode.Decrypt))
                    {
                        var plaintextLength     = plaintext1.Length + plaintext2.Length;
                        var decryptedPlainText  = new byte[plaintextLength];
                        var numberOfBytesOutput = decryptionStream.Read(decryptedPlainText);

                        Assert.Equal(plaintextLength, numberOfBytesOutput);
                        Assert.Equal(plaintext1.Concat(plaintext2), decryptedPlainText);
                    }
                }
        }
Esempio n. 7
0
        public void Test_Decrypt_WithInvalidAdditionalData_Fails()
        {
            using (var ciphertextStream = new MemoryStream())
                using (var key = XChaChaKey.Generate())
                {
                    var plaintext      = TestConstants.MessageBytes;
                    var additionalData = Encoding.UTF8.GetBytes("apple");

                    using (var encryptionStream = new XChaChaStream(ciphertextStream, key, EncryptionMode.Encrypt, leaveOpen: true))
                    {
                        encryptionStream.WriteFinal(plaintext, additionalData);
                    }

                    ciphertextStream.Position = 0;

                    using (var decryptionStream = new XChaChaStream(ciphertextStream, key, EncryptionMode.Decrypt))
                    {
                        var decryptedPlainText    = new byte[plaintext.Length];
                        var invalidAdditionalData = Encoding.UTF8.GetBytes("pear");

                        Action action    = () => decryptionStream.Read(decryptedPlainText, invalidAdditionalData);
                        var    exception = Assert.Throws <CryptographicException>(action);

                        Assert.Equal("block is invalid or corrupt", exception.Message);
                        Assert.True(decryptedPlainText.All((b) => b == 0));
                    }
                }
        }
Esempio n. 8
0
        public void Test_Decrypt_DecryptsTwoBlocks()
        {
            using (var ciphertextStream = new MemoryStream())
                using (var key = XChaChaKey.Generate())
                {
                    const int blockLength = 128 * 1024;
                    var       block1      = RandomBytesGenerator.NextBytes(blockLength);
                    var       block2      = RandomBytesGenerator.NextBytes(blockLength);

                    using (var encryptionStream = new XChaChaStream(ciphertextStream, key, EncryptionMode.Encrypt, leaveOpen: true))
                    {
                        encryptionStream.Write(block1);
                        encryptionStream.WriteFinal(block2);
                    }

                    ciphertextStream.Position = 0;

                    using (var decryptionStream = new XChaChaStream(ciphertextStream, key, EncryptionMode.Decrypt))
                    {
                        var decryptedBlock1      = new byte[blockLength];
                        var decryptedBlock2      = new byte[blockLength];
                        var numberOfBytesOutput1 = decryptionStream.Read(decryptedBlock1);
                        var numberOfBytesOutput2 = decryptionStream.Read(decryptedBlock2);

                        Assert.Equal(blockLength, numberOfBytesOutput1);
                        Assert.Equal(block1, decryptedBlock1);
                        Assert.Equal(blockLength, numberOfBytesOutput2);
                        Assert.Equal(block2, decryptedBlock2);
                    }
                }
        }
Esempio n. 9
0
        public void Test_Decrypt_DecryptsBlock_WithAdditionalData()
        {
            using (var ciphertextStream = new MemoryStream())
                using (var key = XChaChaKey.Generate())
                {
                    var plaintext      = TestConstants.MessageBytes;
                    var additionalData = Encoding.UTF8.GetBytes("apple");

                    using (var encryptionStream = new XChaChaStream(ciphertextStream, key, EncryptionMode.Encrypt, leaveOpen: true))
                    {
                        encryptionStream.WriteFinal(plaintext, additionalData);
                    }

                    ciphertextStream.Position = 0;

                    using (var decryptionStream = new XChaChaStream(ciphertextStream, key, EncryptionMode.Decrypt))
                    {
                        var decryptedPlainText  = new byte[plaintext.Length];
                        var numberOfBytesOutput = decryptionStream.Read(decryptedPlainText, additionalData);

                        Assert.Equal(plaintext.Length, numberOfBytesOutput);
                        Assert.Equal(plaintext, decryptedPlainText);
                    }
                }
        }
Esempio n. 10
0
 public void Test_GenerateKey_GeneratesKeyOfCorrectLength()
 {
     using (var key = XChaChaKey.Generate())
     {
         var keyBytes = key.ToArray();
         Assert.Equal(TestConstants.KeyLength, keyBytes.Length);
     }
 }
 public void Test_CanRead_Encrypt_False(Type streamType)
 {
     using (var key = XChaChaKey.Generate())
         using (var xchachaStream =
                    (XChaChaStreamBase)Activator.CreateInstance(streamType, Stream.Null, key, EncryptionMode.Encrypt, false))
         {
             Assert.False(xchachaStream.CanRead);
         }
 }
 public void Test_Read_OffsetNegative_ExceptionThrown(Type streamType)
 {
     using (var key = XChaChaKey.Generate())
         using (var xchachaStream =
                    (XChaChaStreamBase)Activator.CreateInstance(streamType, Stream.Null, key, EncryptionMode.Encrypt, false))
         {
             Action action = () => xchachaStream.Read(Array.Empty <byte>(), -1, 1);
             Assert.Throws <ArgumentOutOfRangeException>(action);
         }
 }
 public void Test_Write_ParametersInconsistent_ExceptionThrown(Type streamType)
 {
     using (var key = XChaChaKey.Generate())
         using (var xchachaStream =
                    (XChaChaStreamBase)Activator.CreateInstance(streamType, Stream.Null, key, EncryptionMode.Encrypt, false))
         {
             Action action = () => xchachaStream.Write(Array.Empty <byte>(), 3, 1);
             Assert.Throws <ArgumentException>(action);
         }
 }
 public void Test_CanWrite_Decrypt_False(Type streamType)
 {
     using (var key = XChaChaKey.Generate())
         using (var plaintextStream = new MemoryStream(new byte[StreamHeaderLength]))
             using (var xchachaStream =
                        (XChaChaStreamBase)Activator.CreateInstance(streamType, plaintextStream, key, EncryptionMode.Decrypt, false))
             {
                 Assert.False(xchachaStream.CanWrite);
             }
 }
 public void Test_Read_NullBuffer_ExceptionThrown(Type streamType)
 {
     using (var key = XChaChaKey.Generate())
         using (var xchachaStream =
                    (XChaChaStreamBase)Activator.CreateInstance(streamType, Stream.Null, key, EncryptionMode.Encrypt, false))
         {
             Action action = () => xchachaStream.Read(null, 0, 1);
             Assert.Throws <ArgumentNullException>(action);
         }
 }
 public void Test_Read_ParametersInconsistent_ExceptionThrown(Type streamType)
 {
     using (var key = XChaChaKey.Generate())
         using (var xchachaStream =
                    (XChaChaStreamBase)Activator.CreateInstance(streamType, Stream.Null, key, EncryptionMode.Encrypt, false))
         {
             Action action    = () => xchachaStream.Read(Array.Empty <byte>(), 3, 1);
             var    exception = Assert.Throws <ArgumentException>(action);
             Assert.Equal("buffer length, offset, and count are inconsistent", exception.Message);
         }
 }
Esempio n. 17
0
        public void GlobalSetup()
        {
            new Random(31).NextBytes(data);
            this.key = XChaChaKey.Generate();

            using (var bufferedEncryptionStream = new XChaChaBufferedStream(
                       this.bufferedCiphertextStream, this.key, EncryptionMode.Encrypt, leaveOpen: true))
            {
                bufferedEncryptionStream.Write(data);
            }
        }
Esempio n. 18
0
        public void GlobalSetup()
        {
            this.data = new byte[this.DataLengthKb * 1024];
            new Random(31).NextBytes(data);
            this.key   = XChaChaKey.Generate();
            this.nonce = XChaChaNonce.Generate();
            var aeadCipher = new XChaChaAeadCipher();

            this.encryptedData       = new byte[aeadCipher.GetCipherTextLength(this.data.Length)];
            this.decryptOutputBuffer = new byte[aeadCipher.GetCipherTextLength(this.data.Length)];
            aeadCipher.Encrypt(data, this.encryptedData, this.key, this.nonce);
        }
Esempio n. 19
0
        public void Test_Flush_FlushesHeader()
        {
            using (var outputStream = new MemoryStream())
                using (var key = XChaChaKey.Generate())
                    using (var encryptionStream = new XChaChaStream(outputStream, key, EncryptionMode.Encrypt))
                    {
                        var plaintext = Array.Empty <byte>();

                        encryptionStream.WriteFinal(plaintext);
                        encryptionStream.Flush();

                        var ciphertext = outputStream.ToArray();
                        Assert.Equal(StreamHeaderLength, ciphertext.Length);
                    }
        }
        public void Test_Initialize_Decrypt_WrongHeaderLength_ThrowsCryptographicException(Type streamType)
        {
            var invalidHeader = new byte[3];

            using (var key = XChaChaKey.Generate())
                using (var ciphertextStream = new MemoryStream(invalidHeader))
                {
                    Action action    = () => Activator.CreateInstance(streamType, ciphertextStream, key, EncryptionMode.Decrypt, false);
                    var    exception = Assert.ThrowsAny <Exception>(action);
                    // The action throws a System.Reflection.TargetInvocationException. The inner exception contains
                    // the actual exception thrown in the class constructor
                    var innerException = exception.InnerException;
                    Assert.IsType <CryptographicException>(innerException);
                    Assert.Equal("invalid or corrupt header", innerException.Message);
                }
        }
Esempio n. 21
0
        public void Test_Encrypt_ProducesCorrectOutputLength()
        {
            var plaintext = TestConstants.MessageBytes;

            using (var outputStream = new MemoryStream())
            {
                using (var key = XChaChaKey.Generate())
                    using (var encryptionStream = new XChaChaStream(outputStream, key, EncryptionMode.Encrypt))
                    {
                        encryptionStream.WriteFinal(plaintext);
                    }

                var ciphertext = outputStream.ToArray();

                var expectedCipherTextLength = StreamHeaderLength + plaintext.Length + StreamABytes;
                Assert.Equal(expectedCipherTextLength, ciphertext.Length);
            }
        }
        public void Test_Encrypt_WithLargeData_ProducesCorrectOutputLength(int bufferLength)
        {
            var plaintext = RandomBytesGenerator.NextBytes(1024 * 1024);

            using (var outputStream = new MemoryStream())
            {
                using (var key = XChaChaKey.Generate())
                    using (var encryptionStream = new XChaChaBufferedStream(outputStream, key, EncryptionMode.Encrypt, bufferLength))
                    {
                        encryptionStream.Write(plaintext);
                    }

                var ciphertext = outputStream.ToArray();

                var numberOfBlocks           = Math.Ceiling((decimal)plaintext.Length / bufferLength);
                var expectedCipherTextLength = plaintext.Length + StreamHeaderLength + (StreamABytes * numberOfBlocks);
                Assert.Equal(expectedCipherTextLength, ciphertext.Length);
            }
        }
Esempio n. 23
0
        public void Test_Encrypt_WithAdditionalData()
        {
            var plaintext      = TestConstants.MessageBytes;
            var additionalData = Encoding.UTF8.GetBytes("apple");

            using (var outputStream = new MemoryStream())
            {
                using (var key = XChaChaKey.Generate())
                    using (var encryptionStream = new XChaChaStream(outputStream, key, EncryptionMode.Encrypt))
                    {
                        encryptionStream.WriteFinal(plaintext, additionalData);
                    }

                var ciphertext = outputStream.ToArray();

                var expectedCipherTextLength = StreamHeaderLength + plaintext.Length + StreamABytes;
                Assert.Equal(expectedCipherTextLength, ciphertext.Length);
            }
        }
        public void Test_Encrypt_ProducesCorrectOutputLength()
        {
            var plaintext = TestConstants.MessageBytes;

            using (var outputStream = new MemoryStream())
            {
                using (var key = XChaChaKey.Generate())
                    using (var encryptionStream = new XChaChaBufferedStream(outputStream, key, EncryptionMode.Encrypt))
                    {
                        encryptionStream.Write(plaintext);
                    }

                var ciphertext = outputStream.ToArray();

                // The encryption stream encrypts in 128KB blocks
                const int numberOfBlocks           = 1;
                var       expectedCipherTextLength = plaintext.Length + StreamHeaderLength + (StreamABytes * numberOfBlocks);
                Assert.Equal(expectedCipherTextLength, ciphertext.Length);
            }
        }
Esempio n. 25
0
        public void GlobalSetup()
        {
            var data = new byte[this.DataLengthKb * 1024];

            new Random(31).NextBytes(data);
            this.nonBufferedCiphertextStream = new MemoryStream();
            this.bufferedCiphertextStream    = new MemoryStream();
            this.key = XChaChaKey.Generate();

            using (var bufferedEncryptionStream = new XChaChaBufferedStream(
                       this.bufferedCiphertextStream, this.key, EncryptionMode.Encrypt, leaveOpen: true))
            {
                bufferedEncryptionStream.Write(data);
            }

            using (var encryptionStream = new XChaChaStream(
                       this.nonBufferedCiphertextStream, this.key, EncryptionMode.Encrypt, leaveOpen: true))
            {
                encryptionStream.WriteFinal(data);
            }
        }
Esempio n. 26
0
        public void Test_Encrypt_EncryptsTwoBlocks()
        {
            using (var ciphertextStream = new MemoryStream())
                using (var key = XChaChaKey.Generate())
                {
                    const int blockLength = 128 * 1024;
                    var       block1      = RandomBytesGenerator.NextBytes(blockLength);
                    var       block2      = RandomBytesGenerator.NextBytes(blockLength);

                    using (var encryptionStream = new XChaChaStream(ciphertextStream, key, EncryptionMode.Encrypt))
                    {
                        encryptionStream.Write(block1);
                        encryptionStream.WriteFinal(block2);
                    }

                    var ciphertext = ciphertextStream.ToArray();

                    const int numberOfWrites           = 2;
                    const int expectedCiphertextLength = StreamHeaderLength + 2 * blockLength + (numberOfWrites * StreamABytes);

                    Assert.Equal(expectedCiphertextLength, ciphertext.Length);
                }
        }
        public void Test_Decrypt_VerifyEndOfMessage_TrueWhenFullyDecrypted()
        {
            using (var ciphertextStream = new MemoryStream())
                using (var key = XChaChaKey.Generate())
                {
                    var plaintext = RandomBytesGenerator.NextBytes(1024 * 1024);

                    using (var encryptionStream =
                               new XChaChaBufferedStream(ciphertextStream, key, EncryptionMode.Encrypt, leaveOpen: true))
                    {
                        encryptionStream.Write(plaintext);
                    }

                    ciphertextStream.Position = 0;

                    using (var decryptionStream = new XChaChaBufferedStream(ciphertextStream, key, EncryptionMode.Decrypt))
                    {
                        var decryptedPlainText = new byte[plaintext.Length];

                        decryptionStream.Read(decryptedPlainText);
                        Assert.True(decryptionStream.VerifyEndOfMessage());
                    }
                }
        }
 public void GlobalSetup()
 {
     this.data = new byte[this.DataLengthKb * 1024];
     new Random(31).NextBytes(data);
     this.key = XChaChaKey.Generate();
 }