Signed Byte Blocks

SignedByteBlock stores a complete binary payload, its purpose, an optional key-lookup hint, and an Ed25519 signature in one canonical record. Generate a SigningPrivateKey with the Ed25519 profile for sign(). Parsing requires a finite maximum payload length; verify() returns the payload only for a valid signature and exact expected purpose. untrustedKeyIdHint() is for selecting a candidate verifier before that check. See Signing and Verifying Byte Blocks for the complete workflow, trust boundary, and illustrated format.

Binary Format

Version 1 is ELSB + 0x01 + Ed25519 algorithm 0x01 + one-byte key-ID length + one-byte purpose length + four-byte big-endian payload length + key ID + UTF-8 purpose + payload + 64-byte Ed25519 signature. The signature covers every preceding byte. The key ID is absent or matches [_a-z0-9]{1,64}; the purpose is one to 255 bytes. Parsing rejects malformed lengths, invalid text, trailing data, and unsupported versions or algorithms. Malformed records and payloads exceeding the configured limit raise ParseError in fromByteBlockOrThrow(). fromByteBlock() returns an empty value for these failures and for an infinite limit.

Interface

class SignedByteBlock

A canonical, self-contained signed data record with purpose separation.

Parsed payload bytes remain unavailable until signature and purpose verification succeeds. The optional key ID is only an untrusted lookup hint before verification.

See: Signed Byte Blocks

Public Functions

SignedByteBlock() = default

Create an empty placeholder.

auto verify(const PublicKey &key, const text::String &expectedPurpose) const -> std::optional<mem::ByteBlock>

Verify the complete signed record and return its payload only on success.

This signed record must not be an empty placeholder.

Parameters:
  • key – The expected Ed25519 public key.

  • expectedPurpose – The exact non-empty purpose chosen by the application.

Throws:

CryptologyError – If cryptographic verification fails internally.

Returns:

The authenticated payload, or no value for a mismatch.

inline bool isEmpty() const noexcept

Test whether this object contains a parsed or freshly signed record.

inline const std::optional<text::String> &untrustedKeyIdHint() const noexcept

Get the untrusted key ID hint for key lookup; verify before trusting it.

inline mem::ByteBlock toByteBlock() const noexcept

Return the exact canonical binary record.

Public Static Functions

static auto fromByteBlock(mem::ConstByteSpan encoded, unit::ByteCount maximumPayload) noexcept -> SignedByteBlock

Parse a binary record within an explicit payload limit.

Parameters:
  • encoded – The encoded signed record.

  • maximumPayload – The maximum accepted payload length.

Returns:

The parsed record, or an empty placeholder if malformed, over the limit, or the limit is infinite.

static auto fromByteBlockOrThrow(mem::ConstByteSpan encoded, unit::ByteCount maximumPayload) -> SignedByteBlock

Parse a binary record within an explicit payload limit.

Parameters:
  • encoded – The encoded signed record.

  • maximumPayload – The maximum accepted payload length. Must be finite.

Throws:
  • err::ParseError – If malformed, noncanonical, over the payload limit, or using an unsupported format.

  • text::EncodingError – If a text field contains invalid UTF-8.

static auto sign(const SigningPrivateKey &key, mem::ConstByteSpan payload, const text::String &purpose, std::optional<text::String> keyId = {}) -> SignedByteBlock

Sign a self-contained record with Ed25519.

Parameters:
  • key – A non-empty Ed25519 signing key.

  • payload – The data to embed and authenticate.

  • purpose – A non-empty, valid UTF-8 purpose of at most 255 bytes.

  • keyId – An optional [_a-z0-9]{1,64} lookup hint.

Returns:

The complete signed record.