Authenticated event
Scope and identity
This shared contract covers the trust transition from untrusted private-event bytes to an authenticated logical event. It applies to the Rust implementation used by Android. Wire details remain owned by the NIP-59 profile and cryptographic policy.
Supported behavior
Layered authentication
shared.authentication.layered — A route parsed from an outer wrapper
selects a candidate account; it does not authenticate the inner message. Rust
must validate the outer event, recipient route, both encrypted layers, seal,
rumor ID and author binding before exposing the inner event. For a chat event,
the authenticated outer recipient must also belong to the inner conversation.
A valid encrypted wrapper addressed to the local account does not grant its sender permission to edit or delete somebody else's message. The owning semantic contract adds that authorization check.
Ciphertext validation
shared.authentication.crypto — NIP-44 payloads must meet the pinned
cryptographic profile and input bounds. Invalid authentication, padding or
encoding must fail through the stable redacted error boundary. Independent
valid and invalid vectors are checked at this shared layer; higher-level
message scenarios reuse it.
Persistence semantics
Authentication is a prerequisite to storing accepted protocol truth. An outer wrapper and its inner logical event have different identities. Their retention and deduplication follow account storage. Rejected input must not create an accepted message merely because bytes arrived. Quarantine is a separate bounded diagnostic/storage outcome.
For the account transport, a valid outer signature with invalid private content must not terminate the account runtime or leave a pending ingestion reservation behind. Live ingestion discards the rejected event and can continue with a valid one. A rejected requested sync event must not advance a successful checkpoint; the transport takes its bounded recovery path.
Observable behavior
A caller receives an authenticated value or a stable failure. Routing metadata is not a decrypted message. An application must not display unauthenticated plaintext, log secret material, or reconstruct authorization from wrapper recipient tags.
Verification and limits
The mapped Rust cases exercise invalid routes, kinds, seal shapes, ciphertext, IDs, author binding, conversation membership, official NIP-44 vectors, extended payloads and size limits. They do not establish interoperability of every released client or every live relay configuration. No new cipher implementation or duplicate per-message vector corpus is introduced by this contract set.
No execution report is bundled with this documentation. Linked test cases describe verification scope; their existence is not a passing result.
| Invariant | Required environments | Execution evidence |
|---|---|---|
shared.authentication.layeredrust-core | rust-host | missing4 mapped test cases
|
shared.authentication.cryptorust-core | rust-host | missing3 mapped test cases
|