Table of Contents

XSalsa20Poly1305 Class

Definition

Namespace
Bodu.Security.Cryptography
Assembly
Bodu.Security.Cryptography.dll
Package
Bodu.Security.Cryptography 1.2.0
Source
XSalsa20Poly1305.cs

Provides authenticated encryption using the XSalsa20-Poly1305 construction of NaCl / libsodium crypto_secretbox, with the Bodu AEAD combined layout ciphertext ‖ tag. Accepts a 256-bit key and a 192-bit nonce and produces a 128-bit authentication tag. This class cannot be inherited.

public sealed class XSalsa20Poly1305 : Poly1305AeadTransform, IStreamAeadTransform, IAeadTransform, IDisposable
Inheritance
XSalsa20Poly1305
Implements
Inherited Members
Extension Methods

Examples

using Bodu.Security.Cryptography;
using Bodu.Security.Cryptography.Extensions;

using var enc = new XSalsa20Poly1305(key, nonce);
byte[] sealed_ = enc.Encrypt(plaintext); // ciphertext || tag, no associated data
using var dec = new XSalsa20Poly1305(key, nonce);
byte[] recovered = dec.Decrypt(sealed_);

Remarks

The cryptographic body matches secretbox: a 256-bit subkey is derived from the key and the first 128 bits of the nonce via HSalsa20, Salsa20 runs under that subkey with the trailing 64 bits of the nonce, the leading 32 bytes of the counter-0 keystream block form the one-time Poly1305 key, the message is encrypted with the keystream from byte 32 onward, and the tag is computed over the ciphertext alone.

Wire format is not libsodium combined-mode. libsodium crypto_secretbox_easy emits tag ‖ ciphertext; this type emits ciphertext ‖ tag to match the rest of the Bodu AEAD surface. The ciphertext and tag bytes are identical - only the order differs. Use ToLibsodiumCombined(ReadOnlySpan<byte>, Span<byte>) / FromLibsodiumCombined(ReadOnlySpan<byte>, Span<byte>) at the interop boundary to convert between the two layouts.

No associated data. The secretbox construction does not authenticate associated data; supplying non-empty associated data to Encrypt(ReadOnlySpan<byte>, Span<byte>, ReadOnlySpan<byte>) or Decrypt(ReadOnlySpan<byte>, Span<byte>, ReadOnlySpan<byte>) throws ArgumentException. When associated-data support is required, use XSalsa20Poly1305Aead (XSalsa20 with RFC 8439 framing) or XChaCha20Poly1305.

Each instance is single-use. A new instance must be created for every message. Reusing a nonce under the same key destroys confidentiality and authenticity.

Key separation. Do not reuse a key across this construction, the raw XSalsa20 stream cipher, or any other AEAD construction unless an external key-separation scheme derives an independent key for each use.

Constructors

XSalsa20Poly1305(byte[], byte[])

Initializes a new instance of the XSalsa20Poly1305 class with the specified key and nonce.

public XSalsa20Poly1305(byte[] key, byte[] nonce)

Parameters

key byte[]

The 256-bit (32-byte) secret key. Must not be null.

nonce byte[]

The 192-bit (24-byte) nonce. Must be unique for every message encrypted under the same key. Must not be null.

Exceptions

ArgumentNullException

key or nonce is null.

ArgumentException

key is not exactly 32 bytes, or nonce is not exactly 24 bytes.

XSalsa20Poly1305(ReadOnlySpan<byte>, ReadOnlySpan<byte>)

Initializes a new instance of the XSalsa20Poly1305 class with the specified key and nonce spans.

public XSalsa20Poly1305(ReadOnlySpan<byte> key, ReadOnlySpan<byte> nonce)

Parameters

key ReadOnlySpan<byte>

The 256-bit (32-byte) secret key.

nonce ReadOnlySpan<byte>

The 192-bit (24-byte) nonce. Must be unique for every message encrypted under the same key.

Exceptions

ArgumentException

key is not exactly 32 bytes, or nonce is not exactly 24 bytes.

Fields

KeySize

Length of the XSalsa20-Poly1305 key is 256 bits (32 bytes).

public const int KeySize = 256

Field Value

int

NonceSize

Length of the XSalsa20-Poly1305 nonce is 192 bits (24 bytes).

public const int NonceSize = 192

Field Value

int

Properties

SupportsAssociatedData

Gets a value indicating whether this construction authenticates associated data.

protected override bool SupportsAssociatedData { get; }

Property Value

bool

true for the RFC 8439-framed constructions; false for the secretbox construction, which has no associated-data input.

Methods

CreateEngine()

Creates the keystream engine for a single message, positioned at block counter 0.

protected override IStreamCipher CreateEngine()

Returns

IStreamCipher

A freshly constructed IStreamCipher bound to Key and Nonce.

Remarks

The caller owns the returned engine and disposes it after the message completes.

FromLibsodiumCombined(ReadOnlySpan<byte>, Span<byte>)

Converts a libsodium combined output tag ‖ ciphertext into the Bodu combined layout ciphertext ‖ tag.

public static void FromLibsodiumCombined(ReadOnlySpan<byte> tagThenCiphertext, Span<byte> ciphertextThenTag)

Parameters

tagThenCiphertext ReadOnlySpan<byte>

The libsodium output: the 16-byte tag followed by the ciphertext.

ciphertextThenTag Span<byte>

Receives the Bodu layout: the ciphertext followed by the 16-byte tag. May alias tagThenCiphertext for an in-place conversion.

Exceptions

ArgumentException

tagThenCiphertext is shorter than the tag, or ciphertextThenTag is too small.

OpenCore(IStreamCipher, ReadOnlySpan<byte>, ReadOnlySpan<byte>, Span<byte>)

Verifies and decrypts a message. The default implementation applies the RFC 8439 framing.

protected override int OpenCore(IStreamCipher engine, ReadOnlySpan<byte> associatedData, ReadOnlySpan<byte> ciphertextWithTag, Span<byte> output)

Parameters

engine IStreamCipher

The keystream engine, positioned at block counter 0.

associatedData ReadOnlySpan<byte>

The associated data that must match the value used at encryption time.

ciphertextWithTag ReadOnlySpan<byte>

The ciphertext followed by its authentication tag.

output Span<byte>

Receives the recovered plaintext.

Returns

int

The number of plaintext bytes written.

Exceptions

CryptographicException

The authentication tag did not match.

SealCore(IStreamCipher, ReadOnlySpan<byte>, ReadOnlySpan<byte>, Span<byte>)

Encrypts and authenticates a message. The default implementation applies the RFC 8439 framing.

protected override int SealCore(IStreamCipher engine, ReadOnlySpan<byte> associatedData, ReadOnlySpan<byte> plaintext, Span<byte> output)

Parameters

engine IStreamCipher

The keystream engine, positioned at block counter 0.

associatedData ReadOnlySpan<byte>

The associated data to authenticate.

plaintext ReadOnlySpan<byte>

The data to encrypt.

output Span<byte>

Receives the ciphertext followed by the authentication tag.

Returns

int

The number of bytes written.

ToLibsodiumCombined(ReadOnlySpan<byte>, Span<byte>)

Converts a Bodu combined output ciphertext ‖ tag into the libsodium combined layout tag ‖ ciphertext.

public static void ToLibsodiumCombined(ReadOnlySpan<byte> ciphertextThenTag, Span<byte> tagThenCiphertext)

Parameters

ciphertextThenTag ReadOnlySpan<byte>

The Bodu output: ciphertext followed by the 16-byte tag.

tagThenCiphertext Span<byte>

Receives the libsodium layout: the 16-byte tag followed by the ciphertext. May alias ciphertextThenTag for an in-place conversion.

Exceptions

ArgumentException

ciphertextThenTag is shorter than the tag, or tagThenCiphertext is too small.

Applies to

ProductVersions
.NET8, 10

See Also