Package-level declarations

Types

Link copied to clipboard

Nonces of accepted authenticated requests, per device, for replay protection (docs/server-authentication.md). Entries only need to live as long as their request timestamp is inside the server's validity window.

Link copied to clipboard
interface ClientStorage

Client storage boundary.

Link copied to clipboard

The local device's authentication key pair (docs/server-authentication.md), separate from the messaging identity. There is at most one active key. It is replaced only by promoting a pending key after the server accepted it: the pending recovery key of a device recovery (docs/device-recovery.md), the pending rotation key of a routine rotation (docs/device-authentication-rotation.md) or the pending last-device recovery key of a last-device recovery (docs/last-device-recovery.md). The three pending slots are separate, and at most one of them is filled at a time.

Link copied to clipboard

A rejected device registration. Nothing was stored. Messages never contain key bytes.

Link copied to clipboard

Device authentication public keys, one per DeviceAddress (docs/server-authentication.md). A registration is added by register and replaced only by replaceForRecovery (docs/device-recovery.md) or replaceForRotation (docs/device-authentication-rotation.md); it is never removed. Atomic; byte arrays are copied at the boundary.

Link copied to clipboard
class DeviceRegistrationState(val registration: DeviceRegistration, val authEpoch: Long, val authKeyInstalledAt: Instant, val recoveryId: DeviceRecoveryId?, val rotationId: DeviceAuthenticationRotationId? = null, val lastDeviceRecoveryId: LastDeviceRecoveryId? = null)

A stored registration: registration with its authEpoch, the server time authKeyInstalledAt its key was installed at, and the transition that installed the key: recoveryId for a device recovery, rotationId for a routine rotation, lastDeviceRecoveryId for a last-device recovery, none for a key from first registration. At most one of them is set.

Link copied to clipboard
interface IdentityStore

The local device's long-term identity key pair. There is at most one.

Link copied to clipboard
class LastDeviceRecoveryChallengeRequest(val target: DeviceAddress, val candidateId: LastDeviceRecoveryChallengeId, candidateNonce: ByteArray, val now: Instant, val expiresAt: Instant)

A request for a challenge for target: the server-chosen random candidateId and candidateNonce (used only if a new challenge is stored), the server time now and the new challenge's expiresAt.

Link copied to clipboard

A rejected recovery key registration. Nothing was stored. Messages never contain key bytes.

Link copied to clipboard
class LastDeviceRecoveryReplacement(val expected: DeviceRegistrationState, expectedRecoveryPublicKey: ByteArray, val challengeId: LastDeviceRecoveryChallengeId, challengeNonce: ByteArray, replacementPublicKey: ByteArray, val recoveryId: LastDeviceRecoveryId, val now: Instant)

A verified last-device recovery for DeviceRegistrationRepository.replaceForLastDeviceRecovery: replace the key of expected with replacementPublicKey, authorized by the recovery key expectedRecoveryPublicKey over the challenge challengeId / challengeNonce. expected is the state the signatures were verified against. now is the server time: the challenge must not have expired before it, and it becomes the new key's installation time.

Link copied to clipboard

Last-device recovery state (docs/last-device-recovery.md, docs/recovery-key-lifecycle.md): per user the state of its offline recovery key (public key, recovery key epoch, transition metadata), and per device at most one outstanding server-issued challenge. Shares its atomicity with DeviceRegistrationRepository and AuthenticationNonceRepository: DeviceRegistrationRepository.replaceForLastDeviceRecovery consumes a challenge in the same step as it replaces the key, and a recovery key rotation or revocation claims its nonce, compares the authorizing device's registration and removes every challenge of the user in the same step as it changes the recovery key. Never holds private key material.

Link copied to clipboard

Queues opaque envelopes per recipient device. See docs/transport-ordering.md for why the order matters.

Link copied to clipboard
class PendingInboundMessage(val sender: DeviceAddress, val id: LogicalMessageId, val sequence: Long, val receivedAt: Instant, val frame: ByteArray)

A received application message the application has not finalized (committed or discarded) yet (docs/application-delivery.md).

Link copied to clipboard

Received application messages kept until the application commits or discards them, so they can be delivered again, also after a restart. Keyed by (sender, logical ID).

Link copied to clipboard
class PendingOutboundMessage(val recipient: DeviceAddress, val id: LogicalMessageId, val sequence: Long, val frame: ByteArray)

A sent application message the recipient has not acknowledged yet (docs/message-reliability.md).

Link copied to clipboard

Sent application messages kept until the recipient acknowledges them, so they can be encrypted and sent again. Keyed by (recipient, logical ID).

Link copied to clipboard

A rejected publication. The repository state is unchanged. Messages never contain key bytes.

Link copied to clipboard

Public prekey material of each device, as published by the devices. Holds public keys only; the server never sees private keys. State is kept per DeviceAddress: one identity key, one current signed prekey, an inventory of available one-time prekeys and the IDs of consumed one-time prekeys.

Link copied to clipboard
interface PreKeyStore

The local device's private prekeys.

Link copied to clipboard
class ProcessedInboundMessage(val sender: DeviceAddress, val id: LogicalMessageId, val finalization: InboundFinalization, val digest: ByteArray?, val finalizedAt: Instant?, val discardReason: MessageDiscardReason?)

A finalized received message: its terminal tombstone (docs/application-delivery.md, docs/message-discard.md).

Link copied to clipboard

Terminal tombstones of the logical messages the application committed or discarded, for duplicate suppression (docs/message-reliability.md, docs/application-delivery.md, docs/message-discard.md). Keyed by (sender, logical ID): the same ID from another sender is a different message. An entry is never replaced, so its outcome never changes; entries are removed only by pruneFinalizedAtOrBefore.

Link copied to clipboard

A verified cancellation of userId's pending reset resetId by authority.

Link copied to clipboard

Who cancels a pending reset: see RecoveryKeyResetCancellation.

Link copied to clipboard
class RecoveryKeyResetCompletionTransition(val userId: UserId, val resetId: RecoveryKeyResetId, expectedPublicKey: ByteArray, val expectedEpoch: Long, val requestedAt: Instant, val eligibleAt: Instant, newPublicKey: ByteArray, val expectedCompleter: DeviceRegistrationState, val completionId: RecoveryKeyResetCompletionId, val now: Instant)

A verified reset completion for LastDeviceRecoveryRepository.completeRecoveryKeyReset: the pending reset resetId of userId's key expectedPublicKey at expectedEpoch (requested at requestedAt, eligible from eligibleAt) is completed with newPublicKey by expectedCompleter (the registration the ServerAuth request was verified with). now is the server time, compared with the eligibility time and stored as installation time.

Link copied to clipboard
class RecoveryKeyResetRequest(val requester: DeviceRegistrationState, val candidateId: RecoveryKeyResetId, val now: Instant, val eligibleAt: Instant)

A reset request for LastDeviceRecoveryRepository.requestRecoveryKeyReset by requester (the registration the ServerAuth request was verified with): the server-chosen random candidateId (used only if a new reset is stored), the server time now and the policy's eligibleAt. The key and epoch the reset binds are read by the repository in the same step, never supplied.

Link copied to clipboard
class RecoveryKeyRevocationTransition(val userId: UserId, expectedPublicKey: ByteArray, val expectedEpoch: Long, val expectedAuthorizer: DeviceRegistrationState, val revocationId: RecoveryKeyRevocationId, val nonce: RequestNonce, val timestamp: Instant, val pruneBefore: Instant, val now: Instant)

A verified recovery key revocation for LastDeviceRecoveryRepository.revokeRecoveryKey: revoke userId's key expectedPublicKey at expectedEpoch. The other fields as in RecoveryKeyRotationTransition; now becomes the revocation time.

Link copied to clipboard
class RecoveryKeyRotationTransition(val userId: UserId, expectedPublicKey: ByteArray, val expectedEpoch: Long, newPublicKey: ByteArray, val expectedAuthorizer: DeviceRegistrationState, val rotationId: RecoveryKeyRotationId, val nonce: RequestNonce, val timestamp: Instant, val pruneBefore: Instant, val now: Instant)

A verified recovery key rotation for LastDeviceRecoveryRepository.rotateRecoveryKey: replace userId's key expectedPublicKey at expectedEpoch with newPublicKey. expectedAuthorizer is the authorizing device's registration the ServerAuth request was verified with; the rotation only happens while it is still current. nonce / timestamp are the statement's (client-supplied, used for replay protection only); now is the server time stored as installation time.

Link copied to clipboard
class RecoveryKeyState(val epoch: Long, val status: RecoveryKeyStatus, publicKey: ByteArray?, val installedAt: Instant?, val transitionedAt: Instant, val rotationId: RecoveryKeyRotationId? = null, val revocationId: RecoveryKeyRevocationId? = null, val resetCompletionId: RecoveryKeyResetCompletionId? = null)

A user's stored recovery key state (docs/recovery-key-lifecycle.md): epoch, the publicKey and its server installation time installedAt (both only while status is RecoveryKeyStatus.ACTIVE), the server time of the last transition transitionedAt (registration, rotation, reset completion or revocation; for a revoked key the revocation time), and the transition that produced this state: rotationId for a rotation, revocationId for a revocation, resetCompletionId for a completed delayed reset, none for a registration. At most one of them is set.

Link copied to clipboard

Whether a user's recovery key is ACTIVE or REVOKED. A user that never registered one has no RecoveryKeyState.

Link copied to clipboard
class RecoveryReplacement(val expectedTarget: DeviceRegistrationState, val expectedAuthorizer: DeviceRegistrationState, replacementPublicKey: ByteArray, val recoveryId: DeviceRecoveryId, val nonce: RequestNonce, val timestamp: Instant, val pruneBefore: Instant, val installedAt: Instant)

A verified recovery for DeviceRegistrationRepository.replaceForRecovery: replace expectedTarget's key with replacementPublicKey, authorized by expectedAuthorizer. Both expected states are what the signatures were verified against; the replacement only happens if they are still current. timestamp is the request's (client-supplied) time, used for the nonce; installedAt is the server time stored as the new key's installation time.

Link copied to clipboard
class RemoteIdentityRecord(val identityKey: ByteArray, val verification: VerificationState)

A pinned remote identity key and whether the user verified exactly this key (docs/identity-verification.md). identityKey is a copy.

Link copied to clipboard

Remote identity keys pinned on first contact (trust on first use, see docs/identity-trust.md). One public identity key per remote DeviceAddress; two devices of the same user have separate entries.

Link copied to clipboard
class RotationReplacement(val expected: DeviceRegistrationState, replacementPublicKey: ByteArray, val rotationId: DeviceAuthenticationRotationId, val nonce: RequestNonce, val timestamp: Instant, val pruneBefore: Instant, val installedAt: Instant)

A verified routine rotation for DeviceRegistrationRepository.replaceForRotation: replace the key of expected with replacementPublicKey. expected is the state the signatures were verified against; the replacement only happens if it is still current. timestamp is the statement's (client-supplied) time, used for the nonce; installedAt is the server time stored as the new key's installation time.

Link copied to clipboard
interface ServerStorage
Link copied to clipboard

Session initiations from a remote device that must never become the current session again (see docs/session-lifecycle.md): initiations whose session was replaced, and initiations that lost a simultaneous-initiation collision. Kept per remote DeviceAddress. IDs are public values.

Link copied to clipboard
interface SessionStore
Link copied to clipboard
data class SignedPreKeyInfo(val id: SignedPreKeyId, val isCurrent: Boolean, val createdAt: Instant?, val replacedAt: Instant?)

Lifecycle metadata of one stored signed prekey. Holds no key material.

Link copied to clipboard
class StoredLastDeviceRecoveryChallenge(val challenge: LastDeviceRecoveryChallenge, authPublicKey: ByteArray, val recoveryKeyEpoch: Long)

A stored challenge: the public challenge, the registered key it was issued for (authPublicKey, server-side only, never returned to clients) and the recovery key epoch it was issued under (recoveryKeyEpoch; a rotation or revocation of the recovery key invalidates it).