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

            rnd.NextBytes(key);

            var aead = new ChaCha20Poly1305(key);

            for (var i = 0; i < 100; i++)
            {
                var message = new byte[100];
                rnd.NextBytes(message);

                var aad = new byte[16];
                rnd.NextBytes(aad);

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

                var ciphertext = aead.Encrypt(message, aad, nonce);
                var decrypted  = aead.Decrypt(ciphertext, aad, nonce);

                //Assert.AreEqual(message, decrypted);
                Assert.IsTrue(CryptoBytes.ConstantTimeEquals(message, decrypted));
            }
        }
Beispiel #2
0
        public void EncryptDecryptLongMessagesWithNonceTest()
        {
            var rnd = new Random();

            var dataSize = 16;

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

                var aad = new byte[dataSize / 3];
                rnd.NextBytes(aad);

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

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

                var aead       = new ChaCha20Poly1305(key);
                var ciphertext = aead.Encrypt(plaintext, aad, nonce);
                var decrypted  = aead.Decrypt(ciphertext, aad, nonce);

                //Assert.AreEqual(plaintext, decrypted);
                Assert.IsTrue(CryptoBytes.ConstantTimeEquals(plaintext, decrypted));
                dataSize += 5 * dataSize / 11;
            }
        }
Beispiel #3
0
        /// <summary>Method which encrypts a string using ChaCha20.</summary>
        private void Encrypt()
        {
            var enc = new ChaCha20Poly1305(Encoding.ASCII.GetBytes(Key));

            EncryptedPassword    = enc.Encrypt(Encoding.ASCII.GetBytes(HashedPassword));
            EncryptedPasswordb64 = Convert.ToBase64String(EncryptedPassword);
        }
Beispiel #4
0
        public void EncryptWhenNonceLengthIsInvalidFails()
        {
            // Arrange, Act & Assert
            var aead = new ChaCha20Poly1305(new byte[Snuffle.KEY_SIZE_IN_BYTES]);

            Assert.Throws <CryptographicException>(() => aead.Encrypt(new byte[0], new byte[0], new byte[12 + TestHelpers.ReturnRandomPositiveNegative()]), EXCEPTION_MESSAGE_NONCE_LENGTH);
        }
Beispiel #5
0
        public void RandomNonceTest()
        {
            var rnd = new Random();
            var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];

            rnd.NextBytes(key);

            var aead = new ChaCha20Poly1305(key);

            var message     = new byte[0];
            var aad         = new byte[0];
            var ciphertexts = new HashSet <string>();
            var samples     = 1 << 17;

            for (var i = 0; i < samples; i++)
            {
                var ct    = aead.Encrypt(message, aad);
                var ctHex = CryptoBytes.ToHexStringLower(ct);

                Assert.IsFalse(ciphertexts.Contains(ctHex));
                ciphertexts.Add(ctHex);
            }

            Assert.AreEqual(samples, ciphertexts.Count);
        }
Beispiel #6
0
        public void EncryptWhenNonceIsEmptyFails()
        {
            // Arrange, Act & Assert
            var aead = new ChaCha20Poly1305(new byte[Snuffle.KEY_SIZE_IN_BYTES]);

            Assert.Throws <CryptographicException>(() => aead.Encrypt(new byte[0], new byte[0], new byte[0]), EXCEPTION_MESSAGE_NONCE_LENGTH);
        }
Beispiel #7
0
        //Can we change the ChaCha20Poly1305 input to some kind of ICrypto interface or action with 'Encrypt' and 'Decrypt'?
        private void Pack(IBufferWriter <byte> output, CryptoDtoHeaderDto header, ChaCha20Poly1305 crypto, ReadOnlySpan <byte> dtoNameBuffer, ReadOnlySpan <byte> dtoBuffer)
        {
            lock (bufferLock)
            {
                headerBuffer.Clear();
                MessagePackSerializer.Serialize(headerBuffer, header);
                ReadOnlySpan <byte> headerBytes = headerBuffer.WrittenSpan;

                ushort headerLength = (ushort)headerBytes.Length;
                BinaryPrimitives.WriteUInt16LittleEndian(headerLengthBytes, headerLength);
                ushort dtoNameLength = (ushort)dtoNameBuffer.Length;
                BinaryPrimitives.WriteUInt16LittleEndian(dtoNameLengthBytes, dtoNameLength);
                ushort dtoLength = (ushort)dtoBuffer.Length;
                BinaryPrimitives.WriteUInt16LittleEndian(dtoLengthBytes, dtoLength);

                switch (header.Mode)
                {
                case CryptoDtoMode.ChaCha20Poly1305:
                {
                    int adLength = 2 + headerLength;
                    int aeLength = 2 + dtoNameLength + 2 + dtoLength;

                    // Copy data into associated data buffer
                    adBuffer.Clear();
                    adBuffer.Write(headerLengthBytes);
                    adBuffer.Write(headerBytes);

                    // Copy data into authenticated encryption buffer
                    aeBuffer.Clear();
                    aeBuffer.Write(dtoNameLengthBytes);
                    aeBuffer.Write(dtoNameBuffer);
                    aeBuffer.Write(dtoLengthBytes);
                    aeBuffer.Write(dtoBuffer);

                    Span <byte> nonceSpan = new Span <byte>(nonceBytes);
                    BinaryPrimitives.WriteUInt64LittleEndian(nonceSpan.Slice(4), header.Sequence);

                    var adSpan         = adBuffer.WrittenSpan;
                    var aeSpan         = aeBuffer.WrittenSpan;
                    var cipherTextSpan = cipherText.Span.Slice(0, aeLength);
                    cipherTextSpan.Clear();
                    Span <byte> tagSpan = tagBuffer;
                    tagSpan.Clear();
                    crypto.Encrypt(nonceSpan, aeSpan, cipherTextSpan, tagSpan, adSpan);

                    output.Write(adSpan);
                    output.Write(cipherTextSpan);
                    output.Write(tagSpan);
                    break;
                }

                default:
                    throw new CryptographicException("Mode not recognised");
                }
            }
        }
Beispiel #8
0
        public void ModifiedCiphertextFails()
        {
            var rnd = new Random();
            var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];

            rnd.NextBytes(key);

            var aad = new byte[16];

            rnd.NextBytes(aad);

            var message = new byte[32];

            rnd.NextBytes(message);

            var aead       = new ChaCha20Poly1305(key);
            var ciphertext = aead.Encrypt(message, aad);

            // Flipping bits
            for (var b = 0; b < ciphertext.Length; b++)
            {
                for (var bit = 0; bit < 8; bit++)
                {
                    var modified = new byte[ciphertext.Length];
                    Array.Copy(ciphertext, modified, ciphertext.Length);

                    modified[b] ^= (byte)(1 << bit);

                    Assert.Throws <CryptographicException>(() => aead.Decrypt(modified, aad), SnufflePoly1305.AEAD_EXCEPTION_INVALID_TAG);
                }
            }

            // Truncate the message
            for (var length = 0; length < ciphertext.Length; length++)
            {
                var modified = new byte[length];
                Array.Copy(ciphertext, modified, length);

                Assert.Throws <CryptographicException>(() => aead.Decrypt(modified, aad), SnufflePoly1305.AEAD_EXCEPTION_INVALID_TAG);
            }

            // Modify AAD
            for (var b = 0; b < aad.Length; b++)
            {
                for (var bit = 0; bit < 8; bit++)
                {
                    var modified = new byte[aad.Length];
                    Array.Copy(aad, modified, aad.Length);

                    modified[b] ^= (byte)(1 << bit);

                    Assert.Throws <CryptographicException>(() => aead.Decrypt(modified, aad), SnufflePoly1305.AEAD_EXCEPTION_INVALID_TAG);
                }
            }
        }
Beispiel #9
0
        public static void TwoEncryptionsAndDecryptionsUsingOneInstance()
        {
            byte[] key             = "fde37f01fe9ca260f432e0ed98b3e0bb23895ca1ca1ce2cfcaaca2ccc98889d7".HexToByteArray();
            byte[] originalData1   = Enumerable.Range(1, 15).Select((x) => (byte)x).ToArray();
            byte[] originalData2   = Enumerable.Range(14, 97).Select((x) => (byte)x).ToArray();
            byte[] associatedData2 = Enumerable.Range(100, 109).Select((x) => (byte)x).ToArray();
            byte[] nonce1          = "b41329dd64af2c3036661b46".HexToByteArray();
            byte[] nonce2          = "8ba10892e8b87d031196bf99".HexToByteArray();

            byte[] expectedCiphertext1 = "75f5aafbbabab80a3cfa2ecfd1bc58".HexToByteArray();
            byte[] expectedTag1        = "1ed70acc454fba01f0354e93eba9b428".HexToByteArray();

            byte[] expectedCiphertext2 = (
                "f95cc19929463ba96a2cfc21fac5345ec308e2748995ba285af6b21ca3d665bc" +
                "00144604b38e9645fb2d5f5893fc78871bd8f5fc91caaa013eac5f80397fd65c" +
                "358c239f013f3c75da17ddbd14de01eb67f5204dfa787986fb27a098fe21b2c5" +
                "07").HexToByteArray();
            byte[] expectedTag2 = "9877f87f29f68b5f9efb071c1351ccf6".HexToByteArray();

            using (var chaChaPoly = new ChaCha20Poly1305(key))
            {
                byte[] ciphertext1 = new byte[originalData1.Length];
                byte[] tag1        = new byte[expectedTag1.Length];
                chaChaPoly.Encrypt(nonce1, originalData1, ciphertext1, tag1);
                Assert.Equal(expectedCiphertext1, ciphertext1);
                Assert.Equal(expectedTag1, tag1);

                byte[] ciphertext2 = new byte[originalData2.Length];
                byte[] tag2        = new byte[expectedTag2.Length];
                chaChaPoly.Encrypt(nonce2, originalData2, ciphertext2, tag2, associatedData2);
                Assert.Equal(expectedCiphertext2, ciphertext2);
                Assert.Equal(expectedTag2, tag2);

                byte[] plaintext1 = new byte[originalData1.Length];
                chaChaPoly.Decrypt(nonce1, ciphertext1, tag1, plaintext1);
                Assert.Equal(originalData1, plaintext1);

                byte[] plaintext2 = new byte[originalData2.Length];
                chaChaPoly.Decrypt(nonce2, ciphertext2, tag2, plaintext2, associatedData2);
                Assert.Equal(originalData2, plaintext2);
            }
        }
Beispiel #10
0
        public void ModifiedAssociatedDataFails()
        {
            var rnd = new Random();
            var key = new byte[Snuffle.KEY_SIZE_IN_BYTES];

            rnd.NextBytes(key);

            var aead = new ChaCha20Poly1305(key);
            var aad  = new byte[0];

            for (var msgSize = 0; msgSize < 75; msgSize++)
            {
                var message = new byte[msgSize];
                rnd.NextBytes(message);

                // encrypting with aad as a 0-length array
                var ciphertext = aead.Encrypt(message, aad);
                var decrypted  = aead.Decrypt(ciphertext, aad);
                //Assert.AreEqual(message, decrypted);
                Assert.IsTrue(CryptoBytes.ConstantTimeEquals(message, decrypted));

                var decrypted2 = aead.Decrypt(ciphertext, null);
                //Assert.AreEqual(message, decrypted2);
                Assert.IsTrue(CryptoBytes.ConstantTimeEquals(message, decrypted2));

                var badAad = new byte[] { 1, 2, 3 };
                Assert.Throws <CryptographicException>(() => aead.Decrypt(ciphertext, badAad), SnufflePoly1305.AEAD_EXCEPTION_INVALID_TAG);

                // encrypting with aad equal to null
                ciphertext = aead.Encrypt(message, null);
                decrypted  = aead.Decrypt(ciphertext, aad);
                //Assert.AreEqual(message, decrypted);
                Assert.IsTrue(CryptoBytes.ConstantTimeEquals(message, decrypted));

                decrypted2 = aead.Decrypt(ciphertext, null);
                //Assert.AreEqual(message, decrypted2);
                Assert.IsTrue(CryptoBytes.ConstantTimeEquals(message, decrypted2));

                Assert.Throws <CryptographicException>(() => aead.Decrypt(ciphertext, badAad), SnufflePoly1305.AEAD_EXCEPTION_INVALID_TAG);
            }
        }
        private static byte[] Pack(string channelTag, CryptoDtoMode mode, ReadOnlySpan <byte> transmitKey, ulong sequenceToBeSent, byte[] dtoNameBuffer, byte[] dtoBuffer)
        {
            CryptoDtoHeaderDto header = new CryptoDtoHeaderDto
            {
                ChannelTag = channelTag,
                Sequence   = sequenceToBeSent,
                Mode       = mode
            };

            var    headerBuffer  = MessagePackSerializer.Serialize(header);
            ushort headerLength  = (ushort)headerBuffer.Length;
            ushort dtoNameLength = (ushort)dtoNameBuffer.Length;
            ushort dtoLength     = (ushort)dtoBuffer.Length;

            switch (header.Mode)
            {
            case CryptoDtoMode.ChaCha20Poly1305:
            {
                int aePayloadLength = 2 + dtoNameLength + 2 + dtoLength;
                var aePayloadBuffer = new byte[aePayloadLength];

                Array.Copy(BitConverter.GetBytes(dtoNameLength), 0, aePayloadBuffer, 0, 2);
                Array.Copy(dtoNameBuffer, 0, aePayloadBuffer, 2, dtoNameLength);

                Array.Copy(BitConverter.GetBytes(dtoLength), 0, aePayloadBuffer, 2 + dtoNameLength, 2);
                Array.Copy(dtoBuffer, 0, aePayloadBuffer, 2 + dtoNameLength + 2, dtoLength);

                int adPayloadLength = 2 + headerLength;
                var adPayloadBuffer = new byte[adPayloadLength];

                Array.Copy(BitConverter.GetBytes(headerLength), 0, adPayloadBuffer, 0, 2);
                Array.Copy(headerBuffer, 0, adPayloadBuffer, 2, headerLength);

                Span <byte> nonceBuffer = stackalloc byte[Aead.NonceSize];
                BinaryPrimitives.WriteUInt64LittleEndian(nonceBuffer.Slice(4), header.Sequence);

                var    aead              = new ChaCha20Poly1305(transmitKey.ToArray());
                byte[] aeadPayload       = aead.Encrypt(aePayloadBuffer, adPayloadBuffer, nonceBuffer);
                int    aeadPayloadLength = aeadPayload.Length;

                byte[] packetBuffer = new byte[2 + headerLength + aeadPayloadLength];

                Array.Copy(BitConverter.GetBytes(headerLength), 0, packetBuffer, 0, 2);
                Array.Copy(headerBuffer, 0, packetBuffer, 2, headerLength);
                Array.Copy(aeadPayload, 0, packetBuffer, 2 + headerLength, aeadPayloadLength);
                return(packetBuffer);
            }

            default:
                throw new CryptographicException("Mode not recognised");
            }
        }
Beispiel #12
0
        public static void EncryptDecryptNullTag()
        {
            byte[] key        = "fde37f01fe9ca260f432e0ed98b3e0bb23895ca1ca1ce2cfcaaca2ccc98889d7".HexToByteArray();
            byte[] nonce      = new byte[NonceSizeInBytes];
            byte[] plaintext  = new byte[0];
            byte[] ciphertext = new byte[0];

            using (var chaChaPoly = new ChaCha20Poly1305(key))
            {
                Assert.Throws <ArgumentNullException>(() => chaChaPoly.Encrypt(nonce, plaintext, ciphertext, (byte[])null));
                Assert.Throws <ArgumentNullException>(() => chaChaPoly.Decrypt(nonce, ciphertext, (byte[])null, plaintext));
            }
        }
Beispiel #13
0
        public static void PlaintextAndCiphertextSizeDiffer(int ptLen, int ctLen)
        {
            byte[] key        = new byte[KeySizeInBytes];
            byte[] nonce      = new byte[NonceSizeInBytes];
            byte[] plaintext  = new byte[ptLen];
            byte[] ciphertext = new byte[ctLen];
            byte[] tag        = new byte[TagSizeInBytes];

            using (var chaChaPoly = new ChaCha20Poly1305(key))
            {
                Assert.Throws <ArgumentException>(() => chaChaPoly.Encrypt(nonce, plaintext, ciphertext, tag));
                Assert.Throws <ArgumentException>(() => chaChaPoly.Decrypt(nonce, ciphertext, tag, plaintext));
            }
        }
Beispiel #14
0
        public static void Rfc8439Tests(AEADTest testCase)
        {
            using (var chaChaPoly = new ChaCha20Poly1305(testCase.Key))
            {
                byte[] ciphertext = new byte[testCase.Plaintext.Length];
                byte[] tag        = new byte[testCase.Tag.Length];
                chaChaPoly.Encrypt(testCase.Nonce, testCase.Plaintext, ciphertext, tag, testCase.AssociatedData);
                Assert.Equal(testCase.Ciphertext, ciphertext);
                Assert.Equal(testCase.Tag, tag);

                byte[] plaintext = new byte[testCase.Plaintext.Length];
                chaChaPoly.Decrypt(testCase.Nonce, ciphertext, tag, plaintext, testCase.AssociatedData);
                Assert.Equal(testCase.Plaintext, plaintext);
            }
        }
Beispiel #15
0
        public static void InvalidTagSize(int tagSize)
        {
            int dataLength = 30;

            byte[] plaintext  = Enumerable.Range(1, dataLength).Select((x) => (byte)x).ToArray();
            byte[] ciphertext = new byte[dataLength];
            byte[] key        = RandomNumberGenerator.GetBytes(KeySizeInBytes);
            byte[] nonce      = RandomNumberGenerator.GetBytes(NonceSizeInBytes);
            byte[] tag        = new byte[tagSize];

            using (var chaChaPoly = new ChaCha20Poly1305(key))
            {
                Assert.Throws <ArgumentException>("tag", () => chaChaPoly.Encrypt(nonce, plaintext, ciphertext, tag));
            }
        }
Beispiel #16
0
        public static void InplaceEncryptDecrypt()
        {
            byte[] key               = "fde37f01fe9ca260f432e0ed98b3e0bb23895ca1ca1ce2cfcaaca2ccc98889d7".HexToByteArray();
            byte[] nonce             = RandomNumberGenerator.GetBytes(NonceSizeInBytes);
            byte[] originalPlaintext = new byte[] { 1, 2, 8, 12, 16, 99, 0 };
            byte[] data              = (byte[])originalPlaintext.Clone();
            byte[] tag               = new byte[TagSizeInBytes];

            using (var chaChaPoly = new ChaCha20Poly1305(key))
            {
                chaChaPoly.Encrypt(nonce, data, data, tag);
                Assert.NotEqual(originalPlaintext, data);

                chaChaPoly.Decrypt(nonce, data, tag, data);
                Assert.Equal(originalPlaintext, data);
            }
        }
Beispiel #17
0
        public static void Rfc8439TestsTamperTag(AEADTest testCase)
        {
            using (var chaChaPoly = new ChaCha20Poly1305(testCase.Key))
            {
                byte[] ciphertext = new byte[testCase.Plaintext.Length];
                byte[] tag        = new byte[testCase.Tag.Length];
                chaChaPoly.Encrypt(testCase.Nonce, testCase.Plaintext, ciphertext, tag, testCase.AssociatedData);
                Assert.Equal(testCase.Ciphertext, ciphertext);
                Assert.Equal(testCase.Tag, tag);

                tag[0] ^= 1;

                byte[] plaintext = RandomNumberGenerator.GetBytes(testCase.Plaintext.Length);
                Assert.Throws <CryptographicException>(
                    () => chaChaPoly.Decrypt(testCase.Nonce, ciphertext, tag, plaintext, testCase.AssociatedData));
                Assert.Equal(new byte[plaintext.Length], plaintext);
            }
        }
Beispiel #18
0
        public string Encode(string payload, int?timestamp = null)
        {
            if (!timestamp.HasValue)
            {
                timestamp = (int)DateTime.UtcNow.Ticks;
            }

            var versionByte = new byte[VersionByte];

            Buffer.BlockCopy(Version.ToCharArray(), 0, versionByte, 0, VersionByte);

            var nonceBytes = new byte[NonceBytes];
            var rng        = new RNGCryptoServiceProvider();

            rng.GetBytes(nonceBytes);

            var timestampBytes = new byte[TimestampBytes];

            Buffer.BlockCopy(timestamp.ToString().ToCharArray(), 0, timestampBytes, 0, timestampBytes.Length);

            var headerBytes = new byte[HeaderBytes];

            Buffer.BlockCopy(versionByte, 0, headerBytes, 0, VersionByte);
            Buffer.BlockCopy(timestampBytes, 0, headerBytes, VersionByte, TimestampBytes);
            Buffer.BlockCopy(nonceBytes, 0, headerBytes, VersionByte + TimestampBytes, NonceBytes);

            var plainTextBytes = new byte[payload.GetBytes().Length];

            Buffer.BlockCopy(payload.GetBytes(), 0, plainTextBytes, 0, plainTextBytes.Length);

            var keyBytes = new byte[Snuffle.KEY_SIZE_IN_BYTES];

            Buffer.BlockCopy(_key.ToCharArray(), 0, keyBytes, 0, _key.ToCharArray().Length);

            var aead            = new ChaCha20Poly1305(keyBytes);
            var cipherTextBytes = aead.Encrypt(plainTextBytes, null, nonceBytes);

            var tokenBytes = new byte[headerBytes.Length + cipherTextBytes.Length];

            Buffer.BlockCopy(headerBytes, 0, tokenBytes, 0, headerBytes.Length);
            Buffer.BlockCopy(cipherTextBytes, 0, tokenBytes, headerBytes.Length, cipherTextBytes.Length);

            return(tokenBytes.ToBase62());
        }
Beispiel #19
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));
            }
        }
Beispiel #20
0
        public static void ValidNonceAndTagSize()
        {
            const int dataLength = 35;

            byte[] plaintext  = Enumerable.Range(1, dataLength).Select((x) => (byte)x).ToArray();
            byte[] ciphertext = new byte[dataLength];
            byte[] key        = RandomNumberGenerator.GetBytes(KeySizeInBytes);
            byte[] nonce      = RandomNumberGenerator.GetBytes(NonceSizeInBytes);
            byte[] tag        = new byte[TagSizeInBytes];

            using (var chaChaPoly = new ChaCha20Poly1305(key))
            {
                chaChaPoly.Encrypt(nonce, plaintext, ciphertext, tag);

                byte[] decrypted = new byte[dataLength];
                chaChaPoly.Decrypt(nonce, ciphertext, tag, decrypted);
                Assert.Equal(plaintext, decrypted);
            }
        }
Beispiel #21
0
        public static void Test(string[] testVector)
        {
            var plaintext  = testVector[0];
            var aad        = testVector[1];
            var key        = testVector[2];
            var nonce      = testVector[3];
            var ciphertext = testVector[4];
            var tag        = testVector[5];

            var a = new ChaCha20Poly1305();

            using (var k = Key.Import(a, key.DecodeHex(), KeyBlobFormat.RawSymmetricKey))
            {
                var b = a.Encrypt(k, new Nonce(nonce.DecodeHex(), 0), aad.DecodeHex(), plaintext.DecodeHex());
                Assert.Equal((ciphertext + tag).DecodeHex(), b);

                var r = a.Decrypt(k, new Nonce(nonce.DecodeHex(), 0), aad.DecodeHex(), b);
                Assert.Equal(plaintext.DecodeHex(), r);
            }
        }
        public int EncryptWithAd(ReadOnlySpan <byte> ad, ReadOnlySpan <byte> plaintext, Span <byte> ciphertext)
        {
            Debug.Assert(_key.Length == Aead.KEY_SIZE);
            Debug.Assert(ciphertext.Length >= plaintext.Length + Aead.TAG_SIZE);

            Span <byte> nonce = stackalloc byte[Aead.NONCE_SIZE];

            BinaryPrimitives.WriteUInt64LittleEndian(nonce.Slice(4), _nonce);

            var cipher = new ChaCha20Poly1305(_key);

            var cipherTextOutput = ciphertext.Slice(0, plaintext.Length);
            var tag = ciphertext.Slice(plaintext.Length, Aead.TAG_SIZE);

            _logger.LogDebug($"Encrypting text length - {plaintext.Length} with nonce - {_nonce}");

            cipher.Encrypt(nonce, plaintext.ToArray(), cipherTextOutput, tag, ad.ToArray());

            _nonce++;

            return(cipherTextOutput.Length + tag.Length);
        }
Beispiel #23
0
        public static void EncryptTamperAADDecrypt(int dataLength, int additionalDataLength)
        {
            byte[] additionalData = new byte[additionalDataLength];
            RandomNumberGenerator.Fill(additionalData);

            byte[] plaintext  = Enumerable.Range(1, dataLength).Select((x) => (byte)x).ToArray();
            byte[] ciphertext = new byte[dataLength];
            byte[] key        = RandomNumberGenerator.GetBytes(KeySizeInBytes);
            byte[] nonce      = RandomNumberGenerator.GetBytes(NonceSizeInBytes);
            byte[] tag        = new byte[TagSizeInBytes];

            using (var chaChaPoly = new ChaCha20Poly1305(key))
            {
                chaChaPoly.Encrypt(nonce, plaintext, ciphertext, tag, additionalData);

                additionalData[0] ^= 1;

                byte[] decrypted = new byte[dataLength];
                Assert.Throws <CryptographicException>(
                    () => chaChaPoly.Decrypt(nonce, ciphertext, tag, decrypted, additionalData));
            }
        }
Beispiel #24
0
 public byte[] Encrypt() => aead.Encrypt(message, aad);
Beispiel #25
0
        public void Encrypt()
        {
            var ciphertext = new byte[message.Length];

            aead.Encrypt(nonce, message, ciphertext, tag, aad);
        }
Beispiel #26
0
 public void Encrypt() => aead.Encrypt(nonce.Span, message.Span, ciphertext.Span, tag.Span, aad.Span);
Beispiel #27
0
        public bool Poly1305Match(string msg, byte[] shortPoly1305)
        {
            var msgPoly1305 = cipherPoly1305.Encrypt(Encoding.ASCII.GetBytes(msg), null, iv);

            return(msgPoly1305.Skip(msgPoly1305.Length - 4).SequenceEqual(shortPoly1305));
        }