private static void Test4(IBlockCrypto crypto, string hex1, string hex2) { Assert.AreEqual(@"AES-CBC", crypto.Name); Assert.AreEqual(16, crypto.BlockSize); Span <byte> h1 = hex1.FromHex(); Span <byte> h2 = hex2.FromHex(); Span <byte> o1 = stackalloc byte[64]; crypto.Encrypt4(h1, o1); Assert.IsTrue(o1.SequenceEqual(h2)); crypto.Reset(); crypto.Encrypt4(h1, o1); Assert.IsTrue(o1.SequenceEqual(h2)); crypto.Reset(); crypto.Decrypt(h2, o1); crypto.Decrypt(h2.Slice(16), o1.Slice(16)); crypto.Decrypt(h2.Slice(32), o1.Slice(32)); crypto.Decrypt(h2.Slice(48), o1.Slice(48)); Assert.IsTrue(o1.SequenceEqual(h1)); crypto.Dispose(); }
private static void Test4(IBlockCrypto crypto, string hex1, string hex2) { Assert.AreEqual(@"AES", crypto.Name); Assert.AreEqual(16, crypto.BlockSize); Span <byte> h1 = hex1.FromHex(); Span <byte> h2 = hex2.FromHex(); Span <byte> o1 = stackalloc byte[crypto.BlockSize * 4]; crypto.Encrypt4(h1, o1); Assert.IsTrue(o1.SequenceEqual(h2)); crypto.Encrypt4(h1, o1); Assert.IsTrue(o1.SequenceEqual(h2)); crypto.Dispose(); }
private void TestEncrypt4(IBlockCrypto crypto, Span <byte> origin) { Span <byte> o = stackalloc byte[origin.Length]; for (var i = 0; i < Max; ++i) { crypto.Encrypt4(origin, o); } crypto.Dispose(); }
public unsafe void Encrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> source, Span <byte> destination, Span <byte> tag, ReadOnlySpan <byte> associatedData = default) { if (nonce.Length != NonceSize) { throw new ArgumentException(@"Nonce size must be 12 bytes", nameof(nonce)); } if (destination.Length != source.Length) { throw new ArgumentException(string.Empty, nameof(destination)); } var length = (ulong)source.Length << 3; var counterBlock = _counterBlock.AsSpan(0, BlockSize4); var counter0 = counterBlock.Slice(12, 4); var counter1 = counterBlock.Slice(28, 4); var counter2 = counterBlock.Slice(44, 4); var counter3 = counterBlock.Slice(60, 4); nonce.CopyTo(counterBlock); nonce.CopyTo(counterBlock.Slice(16)); nonce.CopyTo(counterBlock.Slice(32)); nonce.CopyTo(counterBlock.Slice(48)); counter0[0] = 0; counter0[1] = 0; counter0[2] = 0; counter0[3] = 1; counter1[0] = 0; counter1[1] = 0; counter1[2] = 0; counter1[3] = 3; counter2[0] = 0; counter2[1] = 0; counter2[2] = 0; counter2[3] = 4; counter3[0] = 0; counter3[1] = 0; counter3[2] = 0; counter3[3] = 5; _crypto.Encrypt(counterBlock, tag); counter0[3] = 2; _gHash.Update(associatedData); while (!source.IsEmpty) { _crypto.Encrypt4(counterBlock, _buffer); counter0.IncrementBe4(); counter1.IncrementBe4(); counter2.IncrementBe4(); counter3.IncrementBe4(); var n = Math.Min(source.Length, BlockSize4); fixed(byte *pOut = destination) fixed(byte *pSource = source) fixed(byte *pBuffer = _buffer) { IntrinsicsUtils.Xor(pSource, pBuffer, pOut, n); } _gHash.Update(destination.Slice(0, n)); source = source.Slice(n); destination = destination.Slice(n); } BinaryPrimitives.WriteUInt64BigEndian(_buffer, (ulong)associatedData.Length << 3); BinaryPrimitives.WriteUInt64BigEndian(_buffer.AsSpan(8), length); _gHash.Update(_buffer.AsSpan(0, TagSize)); _gHash.GetMac(_buffer); fixed(byte *pTag = tag) fixed(byte *pBuffer = _buffer) { IntrinsicsUtils.Xor16(pTag, pBuffer, pTag); } }