Comment on page
Concat
Sometimes it is necessary to concatenate data together to form an input or output. This is represented via the
||
symbol in pseudocode.For example, an AEAD ciphertext is usually a ciphertext concatenated with a tag.
Concatenation is often not as simple as it sounds. You MUST be careful to avoid canonicalization attacks.
This is important for hashing, message authentication (e.g. Encrypt-then-MAC), associated data in AEADs, and info in key derivation.
Two solutions are:
- 1.Only ever concatenate fixed-length inputs. With two inputs, only one needs to be fixed-length. With three inputs, only two need to be fixed-length.
- 2.For variable-length inputs, also concatenate the length of each input as a 64-bit unsigned integer (ulong) converted to bytes in little-endian. See this C# code example. This is done internally in AEADs like ChaCha20-Poly1305.
Fills a span with the concatenation of two spans.
Spans.Concat(Span<byte> buffer, ReadOnlySpan<byte> a, ReadOnlySpan<byte> b)
buffer
has a length not equal to a.Length + b.Length
.a
has a length not equal to buffer.Length - b.Length
.b
has a length not equal to buffer.Length - a.Length
.Fills a span with the concatenation of three spans.
Spans.Concat(Span<byte> buffer, ReadOnlySpan<byte> a, ReadOnlySpan<byte> b, ReadOnlySpan<byte> c)
buffer
has a length not equal to a.Length + b.Length + c.Length
.a
has a length not equal to buffer.Length - b.Length - c.Length
.b
has a length not equal to buffer.Length - a.Length - c.Length
.c
has a length not equal to buffer.Length - a.Length - b.Length
.Fills a span with the concatenation of four spans.
Spans.Concat(Span<byte> buffer, ReadOnlySpan<byte> a, ReadOnlySpan<byte> b, ReadOnlySpan<byte> c, ReadOnlySpan<byte> d)
buffer
has a length not equal to a.Length + b.Length + c.Length + d.Length
.a
has a length not equal to buffer.Length - b.Length - c.Length - d.Length
.b
has a length not equal to buffer.Length - a.Length - c.Length - d.Length
.c
has a length not equal to buffer.Length - a.Length - b.Length - d.Length
.d
has a length not equal to buffer.Length - a.Length - b.Length - c.Length
.Fills a span with the concatenation of five spans.
Spans.Concat(Span<byte> buffer, ReadOnlySpan<byte> a, ReadOnlySpan<byte> b, ReadOnlySpan<byte> c, ReadOnlySpan<byte> d, ReadOnlySpan<byte> e)
buffer
has a length not equal to a.Length + b.Length + c.Length + d.Length + e.Length
.a
has a length not equal to buffer.Length - b.Length - c.Length - d.Length - e.Length
.b
has a length not equal to buffer.Length - a.Length - c.Length - d.Length - e.Length
.c
has a length not equal to buffer.Length - a.Length - b.Length - d.Length - e.Length
.d
has a length not equal to buffer.Length - a.Length - b.Length - c.Length - e.Length
.e
has a length not equal to buffer.Length - a.Length - b.Length - c.Length - d.Length
.Fills a span with the concatenation of six spans.
Spans.Concat(Span<byte> buffer, ReadOnlySpan<byte> a, ReadOnlySpan<byte> b, ReadOnlySpan<byte> c, ReadOnlySpan<byte> d, ReadOnlySpan<byte> e, ReadOnlySpan<byte> f)
buffer
has a length not equal to a.Length + b.Length + c.Length + d.Length + e.Length + f.Length
.a
has a length not equal to buffer.Length - b.Length - c.Length - d.Length - e.Length - f.Length
.b
has a length not equal to buffer.Length - a.Length - c.Length - d.Length - e.Length - f.Length
.c
has a length not equal to buffer.Length - a.Length - b.Length - d.Length - e.Length - f.Length
.d
has a length not equal to buffer.Length - a.Length - b.Length - c.Length - e.Length - f.Length
.e
has a length not equal to buffer.Length - a.Length - b.Length - c.Length - d.Length - f.Length
.f
has a length not equal to buffer.Length - a.Length - b.Length - c.Length - d.Length - e.Length
.There is unfortunately no
Concat()
function for arrays or spans in .NET, and there is not even a Span<T>.CopyTo(Span<T> destination, int index)
. This class fills that gap.Last modified 1yr ago