public 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)); } _chacha20.SetIV(nonce); _chacha20.SetCounter(1); _chacha20.Update(source, destination); var buffer = _buffer.AsSpan(0, Poly1305Utils.KeySize); _chacha20.SetCounter(0); _chacha20.Update(Init, buffer); using var poly1305 = Poly1305Utils.Create(buffer); poly1305.Update(associatedData); poly1305.Update(destination); Span <byte> block = _buffer.AsSpan(Poly1305Utils.BlockSize); BinaryPrimitives.WriteUInt64LittleEndian(block, (ulong)associatedData.Length); BinaryPrimitives.WriteUInt64LittleEndian(block[8..], (ulong)source.Length);
public void Test(string keyHex, string plainHex, string cipherHex) { var key = keyHex.FromHex(); Test(new Poly1305SF(key), plainHex, cipherHex); Test(new Poly1305X86(key), plainHex, cipherHex); Test(Poly1305Utils.Create(key), plainHex, cipherHex); }
public void Decrypt(ReadOnlySpan <byte> nonce, ReadOnlySpan <byte> source, ReadOnlySpan <byte> tag, Span <byte> destination, ReadOnlySpan <byte> associatedData = default) { if (nonce.Length != NonceSize) { throw new ArgumentException(@"Nonce size must be 24 bytes", nameof(nonce)); } if (destination.Length != source.Length) { throw new ArgumentException(string.Empty, nameof(destination)); } _chacha20.SetIV(nonce); var buffer = _buffer.AsSpan(0, Poly1305Utils.KeySize); _chacha20.SetCounter(0); _chacha20.Update(Init, buffer); using var poly1305 = Poly1305Utils.Create(buffer); poly1305.Update(associatedData); poly1305.Update(source); Span <byte> block = _buffer.AsSpan(TagSize); BinaryPrimitives.WriteUInt64LittleEndian(block, (ulong)associatedData.Length); BinaryPrimitives.WriteUInt64LittleEndian(block.Slice(8), (ulong)source.Length); poly1305.Update(block); poly1305.GetMac(block); if (!block.SequenceEqual(tag)) { throw new ArgumentException(@"Unable to decrypt input with these parameters."); } _chacha20.SetCounter(1); _chacha20.Update(source, destination); }