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))); }
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)); }
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)); }
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)); } }
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)); } }
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)); } }
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)); } }
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)); } }
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); } }
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); } }
public byte[] Decrypt(Tests.Vectors.XChaCha20TestVector test) { var cipher = new XChaCha20(test.Key, 0); return(cipher.Decrypt(CryptoBytes.Combine(test.Nonce, test.CipherText))); }
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)); }
public byte[] Decrypt(Tests.Vectors.Rfc8439TestVector test) { var cipher = new ChaCha20(test.Key, test.InitialCounter); return(cipher.Decrypt(CryptoBytes.Combine(test.Nonce, test.CipherText))); }
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)); }