Esempio n. 1
0
    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);
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
        }