Пример #1
0
        public void ChaCha20TestVectorTC8()
        {
            // TC8: key: 'All your base are belong to us!, IV: 'IETF2013'
            // Test vector TC8 from RFC draft by J. Strombergson
            // https://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-01

            // Arrange
            var key = new byte[32]
            {
                0xC4, 0x6E, 0xC1, 0xB1, 0x8C, 0xE8, 0xA8, 0x78,
                0x72, 0x5A, 0x37, 0xE7, 0x80, 0xDF, 0xB7, 0x35,
                0x1F, 0x68, 0xED, 0x2E, 0x19, 0x4C, 0x79, 0xFB,
                0xC6, 0xAE, 0xBE, 0xE1, 0xA6, 0x67, 0x97, 0x5D
            };

            // The first 4 bytes are set to zero and a large counter
            // is used; this makes the RFC 8439 version of ChaCha20
            // compatible with the original specification by D. J. Bernstein.
            var nonce = new byte[12] {
                0x00, 0x00, 0x00, 0x00,
                0x1A, 0xDA, 0x31, 0xD5, 0xCF, 0x68, 0x82, 0x21
            };

            // Act
            var cipher = new ChaCha20(key, 0);
            var block0 = new byte[Snuffle.BLOCK_SIZE_IN_BYTES];
            var block1 = new byte[Snuffle.BLOCK_SIZE_IN_BYTES];

            cipher.ProcessKeyStreamBlock(nonce, 0, block0);
            cipher.ProcessKeyStreamBlock(nonce, 1, block1);

            // Assert
            var expected = new byte[128]
            {
                0xF6, 0x3A, 0x89, 0xB7, 0x5C, 0x22, 0x71, 0xF9,
                0x36, 0x88, 0x16, 0x54, 0x2B, 0xA5, 0x2F, 0x06,
                0xED, 0x49, 0x24, 0x17, 0x92, 0x30, 0x2B, 0x00,
                0xB5, 0xE8, 0xF8, 0x0A, 0xE9, 0xA4, 0x73, 0xAF,
                0xC2, 0x5B, 0x21, 0x8F, 0x51, 0x9A, 0xF0, 0xFD,
                0xD4, 0x06, 0x36, 0x2E, 0x8D, 0x69, 0xDE, 0x7F,
                0x54, 0xC6, 0x04, 0xA6, 0xE0, 0x0F, 0x35, 0x3F,
                0x11, 0x0F, 0x77, 0x1B, 0xDC, 0xA8, 0xAB, 0x92,

                0xE5, 0xFB, 0xC3, 0x4E, 0x60, 0xA1, 0xD9, 0xA9,
                0xDB, 0x17, 0x34, 0x5B, 0x0A, 0x40, 0x27, 0x36,
                0x85, 0x3B, 0xF9, 0x10, 0xB0, 0x60, 0xBD, 0xF1,
                0xF8, 0x97, 0xB6, 0x29, 0x0F, 0x01, 0xD1, 0x38,
                0xAE, 0x2C, 0x4C, 0x90, 0x22, 0x5B, 0xA9, 0xEA,
                0x14, 0xD5, 0x18, 0xF5, 0x59, 0x29, 0xDE, 0xA0,
                0x98, 0xCA, 0x7A, 0x6C, 0xCF, 0xE6, 0x12, 0x27,
                0x05, 0x3C, 0x84, 0xE4, 0x9A, 0x4A, 0x33, 0x32
            };

            //Assert.AreEqual(expected, Combine(block0, block1));
            Assert.IsTrue(CryptoBytes.ConstantTimeEquals(expected, CryptoBytes.Combine(block0, block1)));
        }
Пример #2
0
        public virtual byte[] Encrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> plaintext, ReadOnlySpan <byte> associatedData = default)
        {
            //if (plaintext.Length > int.MaxValue - _snuffle.NonceSizeInBytes() - Poly1305.MAC_TAG_SIZE_IN_BYTES)
            //    throw new ArgumentException($"The {nameof(plaintext)} is too long.");

            var ciphertext = _snuffle.Encrypt(plaintext, nonce);
            var tag        = Poly1305.ComputeMac(GetMacKey(nonce), GetMacDataRfc8439(associatedData, ciphertext));

            return(CryptoBytes.Combine(ciphertext, tag));
        }
Пример #3
0
        public virtual byte[] Encrypt(ReadOnlySpan <byte> plaintext, ReadOnlySpan <byte> associatedData = default)
        {
            //if (plaintext.Length > int.MaxValue - _snuffle.NonceSizeInBytes() - Poly1305.MAC_TAG_SIZE_IN_BYTES)
            //    throw new ArgumentException($"The {nameof(plaintext)} is too long.");

            var nonce = new byte[_snuffle.NonceSizeInBytes];

            RandomNumberGenerator.Create().GetBytes(nonce);

            var ciphertext = Encrypt(nonce, plaintext, associatedData);

            // return nonce.Concat(ciphertext).ToArray(); // could be inefficient
            return(CryptoBytes.Combine(nonce, ciphertext));
        }
Пример #4
0
        public void ChaCha20TestVector()
        {
            // https://tools.ietf.org/html/rfc8439#section-2.4.2

            // Arrange
            foreach (var test in Rfc8439TestVector.Rfc8439TestVectors)
            {
                // Act
                var cipher = new ChaCha20(test.Key, test.InitialCounter);
                var output = cipher.Decrypt(CryptoBytes.Combine(test.Nonce, test.CipherText));

                // Assert
                //Assert.That(output, Is.EqualTo(test.PlainText));
                Assert.IsTrue(CryptoBytes.ConstantTimeEquals(test.PlainText, output));
            }
        }
Пример #5
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));
            }
        }
Пример #6
0
        public void XChaCha20Poly1305TestVectors()
        {
            // From libsodium's test/default/aead_xchacha20poly1305.c and https://tools.ietf.org/html/draft-arciszewski-xchacha-01.

            // Arrange
            foreach (var test in XChaCha20Poly1305TestVector.TestVectors)
            {
                // Act
                var aead = new XChaCha20Poly1305(test.Key);

                //var message = aead.Decrypt(CryptoBytes.Combine(test.CipherText, test.Tag), test.Aad, test.Nonce); // same as below...
                var output = aead.Decrypt(CryptoBytes.Combine(test.Nonce, test.CipherText, test.Tag), test.Aad);

                // Assert
                //Assert.That(output, Is.EqualTo(test.PlainText));
                Assert.IsTrue(CryptoBytes.ConstantTimeEquals(test.PlainText, output));
            }
        }
Пример #7
0
        public void ChaCha20Poly1305TestVector2()
        {
            // https://tools.ietf.org/html/rfc8439

            // Arrange
            foreach (var test in Rfc8439TestVector.Rfc7634AeadTestVectors)
            {
                // Act
                var aead = new ChaCha20Poly1305(test.Key);
                var ct   = aead.Encrypt(test.PlainText, test.Aad, test.Nonce);
                Assert.That(ct, Is.EqualTo(CryptoBytes.Combine(test.CipherText, test.Tag)));

                var output = aead.Decrypt(ct, test.Aad, test.Nonce);

                // Assert
                //Assert.That(output, Is.EqualTo(test.PlainText));
                Assert.IsTrue(CryptoBytes.ConstantTimeEquals(test.PlainText, output));
            }
        }
Пример #8
0
        public virtual byte[] Encrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> plaintext, ReadOnlySpan <byte> associatedData = default)
        {
            //if (plaintext.Length > int.MaxValue - _snuffle.NonceSizeInBytes() - Poly1305.MAC_TAG_SIZE_IN_BYTES)
            //    throw new ArgumentException($"The {nameof(plaintext)} is too long.");

            var ciphertext = _snuffle.Encrypt(plaintext, nonce);

            using (var macKey = GetMacKey(nonce))
                using (var macData = GetMacDataRfc8439(associatedData, ciphertext))
                {
                    var tag = Poly1305.ComputeMac(macKey.Span, macData.Span);
                    macKey.Span.Clear();
                    macData.Span.Clear();
                    // Array.Resize(ref ciphertext, ciphertext.Length + Poly1305.MAC_TAG_SIZE_IN_BYTES);
                    // Array.Copy(tag, 0, ciphertext, ciphertext.Length - Poly1305.MAC_TAG_SIZE_IN_BYTES, tag.Length);

                    // return ciphertext;
                    // return ciphertext.Concat(tag).ToArray(); // could be inefficient
                    return(CryptoBytes.Combine(ciphertext, tag));
                }
        }
Пример #9
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);
            }
        }
Пример #10
0
        public void ChaCha20TestVector()
        {
            // https://tools.ietf.org/html/rfc8439#section-2.4.2

            // Arrange
            foreach (var test in Rfc8439TestVector.Rfc8439TestVectors)
            {
                // Act
                var cipher = new ChaCha20(test.Key, test.InitialCounter);

                // 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);
            }
        }
Пример #11
0
        public byte[] Decrypt(Tests.Vectors.XChaCha20TestVector test)
        {
            var cipher = new XChaCha20(test.Key, 0);

            return(cipher.Decrypt(CryptoBytes.Combine(test.Nonce, test.CipherText)));
        }
Пример #12
0
        public byte[] Decrypt(Tests.Vectors.XChaCha20Poly1305TestVector test)
        {
            var aead = new XChaCha20Poly1305(test.Key);

            return(aead.Decrypt(CryptoBytes.Combine(test.Nonce, test.CipherText, test.Tag), test.Aad));
        }
Пример #13
0
        public byte[] Decrypt(Tests.Vectors.Rfc8439TestVector test)
        {
            var cipher = new ChaCha20(test.Key, test.InitialCounter);

            return(cipher.Decrypt(CryptoBytes.Combine(test.Nonce, test.CipherText)));
        }
Пример #14
0
        public byte[] DecryptWithNonce(Tests.Vectors.Rfc8439TestVector test)
        {
            var aead = new ChaCha20Poly1305(test.Key);

            return(aead.Decrypt(CryptoBytes.Combine(test.CipherText, test.Tag), test.Aad, test.Nonce));
        }