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.
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.
-
SignedByteBlock() = default