# Poly1305

## Purpose

[Poly1305](https://datatracker.ietf.org/doc/html/rfc8439#section-2.5) is a fast **one-time** message authentication code (MAC). It takes a 256-bit key **that can only be used once** and produces a 128-bit tag.

{% hint style="danger" %}
You almost definitely want [BLAKE2b](/message-authentication.md) instead. **Poly1305 is easy to misuse and less secure due to the short tag length**.
{% endhint %}

## Usage

### ComputeTag

Fills a span with a tag computed from a message and a **one-time** key.

```csharp
Poly1305.ComputeTag(Span<byte> tag, ReadOnlySpan<byte> message, ReadOnlySpan<byte> oneTimeKey)
```

#### Exceptions

[ArgumentOutOfRangeException](https://docs.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception)

`tag` has a length not equal to `TagSize`.

[ArgumentOutOfRangeException](https://docs.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception)

`oneTimeKey` has a length not equal to `KeySize`.

[CryptographicException](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.cryptographicexception)

The tag could not be computed.

### VerifyTag

Verifies that a tag is correct in constant time for a given message and **one-time** key. It returns `true` if the tag is valid and `false` otherwise.

```csharp
Poly1305.VerifyTag(ReadOnlySpan<byte> tag, ReadOnlySpan<byte> message, ReadOnlySpan<byte> oneTimeKey)
```

#### Exceptions

[ArgumentOutOfRangeException](https://docs.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception)

`tag` has a length not equal to `TagSize`.

[ArgumentOutOfRangeException](https://docs.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception)

`oneTimeKey` has a length not equal to `KeySize`.

### IncrementalPoly1305

Provides support for computing a tag from several messages and a **one-time** key.

```csharp
using var poly1305 = new IncrementalPoly1305(ReadOnlySpan<byte> oneTimeKey);
poly1305.Update(ReadOnlySpan<byte> message1);
poly1305.Update(ReadOnlySpan<byte> message2);
// Compute
poly1305.Finalize(Span<byte> tag);
// Or verify
bool valid = poly1305.FinalizeAndVerify(ReadOnlySpan<byte> tag);

// Avoid another using statement
// WARNING: Do NOT reuse the same key
poly1305.Reinitialize(ReadOnlySpan<byte> differentOneTimeKey);
poly1305.Update(ReadOnlySpan<byte> message3);
poly1305.Finalize(Span<byte> tag);
```

#### Exceptions

[ArgumentOutOfRangeException](https://docs.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception)

`oneTimeKey` has a length not equal to `KeySize`.

[ArgumentOutOfRangeException](https://docs.microsoft.com/en-us/dotnet/api/system.argumentoutofrangeexception)

`tag` has a length not equal to `TagSize`.

[CryptographicException](https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.cryptographicexception)

The tag could not be computed.

[InvalidOperationException](https://learn.microsoft.com/en-us/dotnet/api/system.invalidoperationexception)

Cannot update after finalizing or finalize twice (without reinitializing).

[ObjectDisposedException](https://learn.microsoft.com/en-us/dotnet/api/system.objectdisposedexception)

The object has been disposed.

## Constants

These are used for validation and/or save you defining your own constants.

```csharp
public const int KeySize = 32;
public const int TagSize = 16;
public const int BlockSize = 16;
```

## Notes

{% hint style="danger" %}
Each key **MUST** be uniformly random, unpredictable, and unique. You **MUST NOT** reuse a key or use the same key for multiple purposes (e.g., encryption and Poly1305).
{% endhint %}

{% hint style="danger" %}
Do **NOT** use Poly1305 as a hash function or key derivation function (KDF). Use [BLAKE2b](/key-derivation.md).
{% endhint %}

{% hint style="danger" %}
Tags **MUST** be compared in constant time to avoid leaking information, so use the `VerifyTag()` or `FinalizeAndVerify()` function.​
{% endhint %}

{% hint style="danger" %}
Tags **MUST NOT** be truncated to minimise the opportunity for forgery.
{% endhint %}

{% hint style="warning" %}
[BLAKE2b](/message-authentication.md) is **strongly recommended** over Poly1305 as a MAC because it has better security guarantees. Due to the 128-bit tag length, Poly1305 should only ever be used for online protocols and small messages.
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://www.geralt.xyz/advanced/poly1305.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
