Beispiel #1
0
        public void EncryptDecryptNBlocksTest()
        {
            // Arrange
            var rnd = new Random();
            var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];

            for (var i = 0; i < 64; i++)
            {
                RandomNumberGenerator.Fill(key);

                var cipher = new XChaCha20(key, 0);

                for (var j = 0; j < 64; j++)
                {
                    var expected = new byte[rnd.Next(300)];
                    rnd.NextBytes(expected);

                    // Act
                    var output    = cipher.Encrypt(expected);
                    var plaintext = cipher.Decrypt(output);

                    // Assert
                    plaintext.Should().Equal(expected);
                }
            }
        }
Beispiel #2
0
        public void Decrypt(Tests.Vectors.XChaCha20TestVector test)
        {
            var plaintext = new byte[test.CipherText.Length];
            var cipher    = new XChaCha20(test.Key, 0);

            cipher.Decrypt(test.CipherText, test.Nonce, plaintext);
        }
Beispiel #3
0
        public void EncryptDecryptNBlocksWithDestinationBufferTest()
        {
            // Arrange
            var rnd = new Random();
            var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];

            for (var i = 0; i < 64; i++)
            {
                RandomNumberGenerator.Fill(key);

                var nonce = new byte[XChaCha20.NONCE_SIZE_IN_BYTES];
                RandomNumberGenerator.Fill(nonce);

                var cipher = new XChaCha20(key, 0);

                for (var j = 0; j < 64; j++)
                {
                    var expected = new byte[rnd.Next(300)];
                    rnd.NextBytes(expected);

                    // Act
                    var ciphertext = new byte[expected.Length];
                    cipher.Encrypt(expected, nonce, ciphertext);

                    var plaintext = new byte[expected.Length];
                    cipher.Decrypt(ciphertext, nonce, plaintext);

                    // Assert
                    plaintext.Should().Equal(expected);
                }
            }
        }
Beispiel #4
0
        public void EncryptDecryptLongMessagesWithNonceTest()
        {
            var rnd = new Random();

            var dataSize = 16;

            while (dataSize <= (1 << 24))
            {
                var plaintext = new byte[dataSize];
                rnd.NextBytes(plaintext);

                var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];
                rnd.NextBytes(key);

                var cipher = new XChaCha20(key, 0);

                var nonce = new byte[cipher.NonceSizeInBytes()];
                rnd.NextBytes(nonce);

                var ciphertext = cipher.Encrypt(plaintext, nonce);
                var decrypted  = cipher.Decrypt(ciphertext, nonce);

                //Assert.AreEqual(plaintext, decrypted);
                Assert.IsTrue(CryptoBytes.ConstantTimeEquals(plaintext, decrypted));
                dataSize += 5 * dataSize / 11;
            }
        }
Beispiel #5
0
        public void HChaCha20BlockTestVector()
        {
            // https://tools.ietf.org/html/draft-irtf-cfrg-xchacha-03#section-2.2.1

            // Arrange
            var key    = CryptoBytes.FromHexString("00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f".Replace(":", string.Empty));
            var nonce  = CryptoBytes.FromHexString("00:00:00:09:00:00:00:4a:00:00:00:00:31:41:59:27".Replace(":", string.Empty));
            var cipher = new XChaCha20(key, 0);

            // Act
            var subKey = new byte[32];

            cipher.HChaCha20(subKey, nonce);
            var state = subKey.ToUInt16Array();
            //var stateHex = CryptoBytes.ToHexStringLower(subKey.ToArray());

            // Assert
            // HChaCha20 returns only the first and last rows
            var expectedState = new uint[]
            {
                0x423b4182, 0xfe7bb227, 0x50420ed3, 0x737d878a,
                //0x0aa76448, 0x7954cdf3, 0x846acd37, 0x7b3c58ad,
                //0x77e35583, 0x83e77c12, 0xe0076a2d, 0xbc6cd0e5,
                0xd5e4f9a0, 0x53a8748a, 0x13c42ec1, 0xdcecd326
            };

            // Same as above but in HEX
            //var expectedStateHex = "82413b4" + "227b27bfe" + "d30e4250" + "8a877d73"
            //                     + "a0f9e4d" + "58a74a853" + "c12ec413" + "26d3ecdc";

            state.Should().BeEquivalentTo(expectedState);
            //stateHex.Should().Be(expectedStateHex);
        }
Beispiel #6
0
        public void EncryptDecryptLongMessagesWithDestinationBufferTest()
        {
            var rnd = new Random();

            var dataSize = 16;

            while (dataSize <= (1 << 24))
            {
                var plaintext = new byte[dataSize];
                rnd.NextBytes(plaintext);

                var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];
                RandomNumberGenerator.Fill(key);

                var nonce = new byte[XChaCha20.NONCE_SIZE_IN_BYTES];
                RandomNumberGenerator.Fill(nonce);

                var cipher = new XChaCha20(key, 0);

                var ciphertext = new byte[plaintext.Length];
                cipher.Encrypt(plaintext, nonce, ciphertext);

                var decrypted = new byte[plaintext.Length];
                cipher.Decrypt(ciphertext, nonce, decrypted);

                decrypted.Should().Equal(plaintext);
                dataSize += 5 * dataSize / 11;
            }
        }
Beispiel #7
0
        public void HChaCha20StateTestVector()
        {
            // https://tools.ietf.org/html/draft-irtf-cfrg-xchacha-03#section-2.2.1

            // Arrange
            var key    = CryptoBytes.FromHexString("00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d:0e:0f:10:11:12:13:14:15:16:17:18:19:1a:1b:1c:1d:1e:1f".Replace(":", string.Empty));
            var nonce  = CryptoBytes.FromHexString("00:00:00:09:00:00:00:4a:00:00:00:00:31:41:59:27".Replace(":", string.Empty));
            var cipher = new XChaCha20(key, 0);

            // Act
            var initialState = new uint[16];

            cipher.HChaCha20InitialState(initialState, nonce);

            // Assert
            var expectedInitialState = new uint[]
            {
                0x61707865, 0x3320646e, 0x79622d32, 0x6b206574,
                0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c,
                0x13121110, 0x17161514, 0x1b1a1918, 0x1f1e1d1c,
                0x09000000, 0x4a000000, 0x00000000, 0x27594131
            };

            initialState.Should().BeEquivalentTo(expectedInitialState);
        }
Beispiel #8
0
        public void EncryptDecryptNBlocksTest()
        {
            // Arrange
            var rnd = new Random();
            var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];

            for (var i = 0; i < 64; i++)
            {
                rnd.NextBytes(key);

                var cipher = new XChaCha20(key, 0);

                for (var j = 0; j < 64; j++)
                {
                    var expectedInput = new byte[rnd.Next(300)];
                    rnd.NextBytes(expectedInput);

                    // Act
                    var output      = cipher.Encrypt(expectedInput);
                    var actualInput = cipher.Decrypt(output);

                    // Assert
                    //Assert.AreEqual(expectedInput, actualInput);
                    Assert.IsTrue(CryptoBytes.ConstantTimeEquals(expectedInput, actualInput));
                }
            }
        }
Beispiel #9
0
        public void DecryptWhenNonceIsEmptyFails()
        {
            // Arrange
            var cipher = new XChaCha20(new byte[Snuffle.KEY_SIZE_IN_BYTES], 0);

            // Act & Assert
            Assert.Throws <CryptographicException>(() => cipher.Decrypt(new byte[0], new byte[0]), EXCEPTION_MESSAGE_NONCE_LENGTH);
        }
Beispiel #10
0
        public void DecryptWhenNonceLengthIsInvalidFails()
        {
            // Arrange
            var cipher = new XChaCha20(new byte[Snuffle.KEY_SIZE_IN_BYTES], 0);

            // Act & Assert
            Assert.Throws <CryptographicException>(() => cipher.Decrypt(new byte[0], new byte[cipher.NonceSizeInBytes() + TestHelpers.ReturnRandomPositiveNegative()]), EXCEPTION_MESSAGE_NONCE_LENGTH);
        }
Beispiel #11
0
        public void EncryptWhenPlaintextIsNotEqualToCiphertextFails(int plaintextLen, int ciphertextLen)
        {
            // Arrange
            var cipher = new XChaCha20(new byte[Snuffle.KEY_SIZE_IN_BYTES], 0);

            // Act
            var act = () => cipher.Encrypt(new byte[plaintextLen], new byte[cipher.NonceSizeInBytes], new byte[ciphertextLen]);

            // Assert
            act.Should().Throw <ArgumentException>().WithMessage("The plaintext parameter and the ciphertext do not have the same length.");
        }
Beispiel #12
0
        public void DecryptWhenCiphertextIsTooShortFails()
        {
            // Arrange
            var rnd = new Random();
            var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];

            // Act
            var cipher = new XChaCha20(key, 0);

            // Assert
            Assert.Throws <CryptographicException>(() => cipher.Decrypt(new byte[2]));
        }
Beispiel #13
0
        public void XChaCha20BlockWhenNonceLengthIsEmptyFails()
        {
            // Arrange
            var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];

            var cipher = new XChaCha20(key, 0);
            var nonce  = new byte[0];
            var block  = new byte[Snuffle.BLOCK_SIZE_IN_BYTES];

            // Act & Assert
            Assert.Throws <CryptographicException>(() => cipher.ProcessKeyStreamBlock(nonce, 0, block));
        }
Beispiel #14
0
        public void XChaCha20BlockWhenLengthIsInvalidFails()
        {
            // Arrange
            var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];

            var cipher = new XChaCha20(key, 0);
            var nonce  = new byte[cipher.NonceSizeInBytes() + TestHelpers.ReturnRandomPositiveNegative()];
            var block  = new byte[0];

            // Act & Assert
            Assert.Throws <CryptographicException>(() => cipher.ProcessKeyStreamBlock(nonce, 0, block));
        }
Beispiel #15
0
        public void HChaCha20_computes_key()
        {
            // From https://trac.tools.ietf.org/html/draft-irtf-cfrg-xchacha-01#section-2.2.1
            var key      = "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f".DecodeHex();
            var nonce    = "000000090000004a0000000031415927".DecodeHex();
            var expected = "82413b4227b27bfed30e42508a877d73a0f9e4d58a74a853c12ec41326d3ecdc".DecodeHex();
            var result   = new byte[32];

            XChaCha20.HChaCha20(key, nonce, result);

            Assert.Equal(expected, result);
        }
Beispiel #16
0
        public void Setup()
        {
            key = new byte[Snuffle.KEY_SIZE_IN_BYTES];
            rnd.NextBytes(key.Span);

            nonce = new byte[24];
            rnd.NextBytes(nonce.Span);

            message = new byte[Size];
            rnd.NextBytes(message.Span);

            cipher = new XChaCha20(key, 0);
        }
Beispiel #17
0
        public void DecryptWhenNonceIsEmptyFails()
        {
            // Arrange
            var nonce      = new byte[0];
            var plaintext  = new byte[0];
            var ciphertext = new byte[0];

            var cipher = new XChaCha20(new byte[Snuffle.KEY_SIZE_IN_BYTES], 0);

            // Act & Assert
            Action act = () => cipher.Decrypt(ciphertext, nonce, plaintext);

            act.Should().Throw <ArgumentException>().WithMessage(EXCEPTION_MESSAGE_NONCE_LENGTH);
        }
Beispiel #18
0
        public void DecryptWhenNonceLengthIsInvalidFails()
        {
            // Arrange
            var nonce      = new byte[XChaCha20.NONCE_SIZE_IN_BYTES + TestHelpers.ReturnRandomPositiveNegative()];
            var plaintext  = new byte[0];
            var ciphertext = new byte[0];

            var cipher = new XChaCha20(new byte[Snuffle.KEY_SIZE_IN_BYTES], 0);

            // Act & Assert
            Action act = () => cipher.Decrypt(ciphertext, nonce, plaintext);

            act.Should().Throw <ArgumentException>().WithMessage(EXCEPTION_MESSAGE_NONCE_LENGTH);
        }
Beispiel #19
0
        public void XChaCha20BlockWhenLengthIsInvalidFails()
        {
            // Arrange
            var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];

            var cipher = new XChaCha20(key, 0);
            var nonce  = new byte[XChaCha20.NONCE_SIZE_IN_BYTES + TestHelpers.ReturnRandomPositiveNegative()];
            var block  = new byte[0];

            // Act & Assert
            Action act = () => cipher.ProcessKeyStreamBlock(nonce, 0, block);

            act.Should().Throw <CryptographicException>();
        }
Beispiel #20
0
        public void DecryptWhenCiphertextIsTooShortFails()
        {
            // Arrange
            var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];

            RandomNumberGenerator.Fill(key);

            // Act
            var    cipher = new XChaCha20(key, 0);
            Action act    = () => cipher.Decrypt(new byte[2]);

            // Assert
            act.Should().Throw <ArgumentException>();
        }
Beispiel #21
0
        public void HChaCha20TestVectors()
        {
            // Arrange
            foreach (var test in HChaCha20TestVector.HChaCha20TestVectors)
            {
                var cipher = new XChaCha20(test.Key, 0);

                // Act
                var output = new byte[Snuffle.KEY_SIZE_IN_BYTES];
                cipher.HChaCha20(output, test.Input);

                // Assert
                output.Should().Equal(test.Output);
            }
        }
Beispiel #22
0
        public void HChaCha20TestVectors()
        {
            // Arrange
            foreach (var test in HChaCha20TestVector.HChaCha20TestVectors)
            {
                var cipher = new XChaCha20(test.Key, 0);

                // Act
                var output = cipher.HChaCha20(test.Input);

                // Assert
                //Assert.That(output, Is.EqualTo(test.Output));
                Assert.IsTrue(CryptoBytes.ConstantTimeEquals(test.Output, output));
            }
        }
Beispiel #23
0
        public void XChaCha20TestVectors()
        {
            // From libsodium's test/default/xchacha20.c (tv_stream_xchacha20) and https://tools.ietf.org/html/draft-arciszewski-xchacha-00.

            // Arrange
            foreach (var test in XChaCha20TestVector.XChaCha20TestVectors)
            {
                // Act
                var cipher = new XChaCha20(test.Key, 0);
                var output = cipher.Decrypt(CryptoBytes.Combine(test.Nonce, test.CipherText));

                // Assert
                //Assert.That(output, Is.EqualTo(test.Output));
                Assert.IsTrue(CryptoBytes.ConstantTimeEquals(test.PlainText, output));
            }
        }
Beispiel #24
0
        public void XChaCha20TestVectors()
        {
            // From libsodium's test/default/xchacha20.c (tv_stream_xchacha20) and https://tools.ietf.org/html/draft-arciszewski-xchacha-00.

            // Arrange
            foreach (var test in XChaCha20TestVector.XChaCha20TestVectors)
            {
                // Act
                var cipher = new XChaCha20(test.Key, 0);

                var output = new byte[test.CipherText.Length];
                cipher.Decrypt(test.CipherText, test.Nonce, output);

                // Assert
                output.Should().Equal(test.PlainText);
            }
        }
Beispiel #25
0
        public void XChaCha20TestVectors()
        {
            // From libsodium's test/default/xchacha20.c (tv_stream_xchacha20) and https://tools.ietf.org/html/draft-arciszewski-xchacha-00.

            // Arrange
            foreach (var test in XChaCha20TestVector.XChaCha20TestVectors)
            {
                // Act
                var cipher = new XChaCha20(test.Key, 0);

                // We do test all method overloads
                var output1 = cipher.Decrypt(CryptoBytes.Combine(test.Nonce, test.CipherText));
                var output2 = cipher.Decrypt(test.CipherText, test.Nonce);
                var output3 = new byte[test.CipherText.Length];
                cipher.Decrypt(test.CipherText, test.Nonce, output3);

                // Assert
                output1.Should().Equal(test.PlainText);
                output2.Should().Equal(test.PlainText);
                output3.Should().Equal(test.PlainText);
            }
        }
Beispiel #26
0
        public void EncryptDecryptLongMessagesTest()
        {
            var rnd = new Random();

            var dataSize = 16;

            while (dataSize <= (1 << 24))
            {
                var plaintext = new byte[dataSize];
                rnd.NextBytes(plaintext);

                var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];
                RandomNumberGenerator.Fill(key);

                var cipher = new XChaCha20(key, 0);

                var ciphertext = cipher.Encrypt(plaintext);
                var decrypted  = cipher.Decrypt(ciphertext);

                decrypted.Should().Equal(plaintext);
                dataSize += 5 * dataSize / 11;
            }
        }
Beispiel #27
0
        public byte[] Decrypt(Tests.Vectors.XChaCha20TestVector test)
        {
            var cipher = new XChaCha20(test.Key, 0);

            return(cipher.Decrypt(CryptoBytes.Combine(test.Nonce, test.CipherText)));
        }