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); } } } }
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); } }
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); } } }
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)); } } }
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); } } }
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); } } }
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); } }
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); } }
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); }
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); } }
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); } }
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); } }
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); } }
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(); }