Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Component Communication

Which component communicates with what?

flowchart TD
    subgraph A[Attestant]
        B[/<a href="https://codeberg.org/reachable-systems/reach/src/branch/main/attestant">Reach Attestant</a>/]
    end

    subgraph C[Local Peer]
        E{{<a href="https://codeberg.org/reachable-systems/reach/src/branch/main/node#peer-node">Reachable Peer Node</a>}}
        D[<a href="https://codeberg.org/reachable-systems/reach/src/branch/main/reachable-app">Reachable Application</a>]
        F([<a href="https://codeberg.org/reachable-systems/reach/src/branch/main/secrets">Reachable Secrets</a>])
        F -.->|encrypts/decrypts & signs/verifies messages for| D
        E -.->|provides long-term storage for| D
    end

    subgraph G[Remote Peer]
        H{{<a href="https://codeberg.org/reachable-systems/reach/src/branch/main/node#peer-node">Reachable Peer Node</a>}}
    end

    subgraph Reaching Party
        I[<a href="https://codeberg.org/reachable-systems/reach/src/branch/main/reaching-app">Reaching Application</a>]
        J([<a href="https://codeberg.org/reachable-systems/reach/src/branch/main/reaching-app/src-wasm">Reaching Link</a>])
        J -.->|encrypts/decrypts & signs/verifies messages for| I
    end

    K{{<a href="https://codeberg.org/reachable-systems/reach/src/branch/main/node#server-node">Reachable Server Node</a>}}

    K -->|hosts| I

    A -->|signs verifying keys of| C
    A -->|signs verifying keys of| G
    A -->|provides prerequisites to| K

    I ==>|collects messages from| K
    E ==>|collects messages from| K
    H ==>|collects messages from| K
    B ==>|uploads signed verifying keys to| K
    E <==>|opportunistically syncs with| H

All local connections use WebSocket based binary protocols via Unix domain sockets.

Deployment Bootstrap

sequenceDiagram
    participant at as Attestant
    participant sn as Server Node
    participant pub as Public Resource

    at-->>at: generates AttestantSigningKeys/AttestantVerifyingKeys
    at-->>at: generates Params
    at-->>at: generates ServerNodeSecretKey
    at-->>at: generates SharedSecretKeys/SharedPublicKeys
    at-->>at: generates SharedSigningKeys/SharedVerifyingKeys
    at-->>at: signs all generated keys with AttestantSigningKeys
    at->>sn: AttestantVerifyingKeys, Params, ServerNodeSecretKey,<br>SharedSecretKeys, SharedPublicKeys,<br>SharedSigningKeys, SharedVerifyingKeys
    note over sn: Server Node is now ready to accept connections
    at->>pub: AttestantVerifyingKeys Visual Key Identity

Reachable Peer

Onboarding

sequenceDiagram
    participant at as Attestant
    participant rs as Reachable Secrets
    participant rc as Reachable Application
    participant rn as Reachable Peer Node
    participant sn as Server Node

    rc->>rs: SecretsHello
    rs->>rc: Uninitialized
    rc->>rn: Init
    rn->>sn: Init
    sn->>rn: Reach
    note over sn,rn: Reach contains AttestantVerifyingKeys, Params,<br>empty ReachableSignedKeys, decoy EnvelopeIdHints
    rn->>rc: Reach
    rc->>rs: Initialize (AttestantVerifyingKeys, Params)
    rs-->>rs: generates passphrase
    rs-->>rs: generates ReachableSigningKeys/UnsignedReachableVerifyingKeys
    rs->>rc: Initialized (passphrase, UnsignedReachableVerifyingKeys)
    note over rc: user accepts and saves passphrase
    rc->>rs: GetReachablePublicKeyRing
    rs-->>rs: generates ReachableSecretKeys/UnsignedReachablePublicKeys
    rs-->>rs: signs with ReachableSigningKeys
    rs->>rc: ReachablePublicKeyRing
    note over rc: saves for OOB exchange with Attestant
    rc-->>at: UnsignedReachableVerifyingKeys, ReachablePublicKeyRing (OOB)
    at-->>at: signs UnsignedReachableVerifyingKeys
    at->>sn: InitAuthenticatedSession
    sn->>at: AuthenticationChallenge
    at-->>at: signs challenge with AttestantSigningKeys
    at->>sn: AuthenticationAssurance
    sn-->>sn: verifies with AttestantVerifyingKeys
    sn->>at: Ok
    at->>sn: ReachableVerifyingKeys, ReachablePublicKeyRing
    sn-->>sn: stores in database
    sn->>at: Ok
    note over rc: Reachable Peer now authenticates to Server
    rc->>rn: InitAuthenticatedSession
    rn->>sn: InitAuthenticatedSession
    sn->>rn: AuthenticationChallenge
    rn->>rc: AuthenticationChallenge
    rc->>rs: AuthenticationChallenge
    rs-->>rs: signs with ReachableSigningKeys
    rs->>rc: AuthenticationAssurance
    rc->>rn: AuthenticationAssurance
    rn->>sn: AuthenticationAssurance
    sn-->>sn: verifies with stored ReachableVerifyingKeys
    sn->>rn: Ok
    rn->>rc: Ok
    rc->>rn: GetSharedEncryptionKeys, GetSharedIdentityKeys
    rn->>sn: GetSharedEncryptionKeys, GetSharedIdentityKeys
    sn->>rn: SharedSecretKeys/SharedPublicKeys,<br>SharedSigningKeys/SharedVerifyingKeys
    rn->>rc: SharedSecretKeys/SharedPublicKeys,<br>SharedSigningKeys/SharedVerifyingKeys
    rc->>rs: SharedEncryptionKeys, SharedIdentityKeys
    rs-->>rs: stores shared keys
    rs->>rc: Ok
    note over rc: Peer is now fully onboarded and can poll for messages

Polling for Messages

sequenceDiagram
    participant rs as Reachable Secrets
    participant rc as Reachable Application
    participant rn as Reachable Peer Node
    participant sn as Server Node

    rc->>rn: Init
    rn->>sn: Init
    sn->>rn: Reach
    note over sn,rn: Reach contains AttestantVerifyingKeys, Params,<br>ReachableSignedKeys, and EnvelopeIdHints
    rn->>rc: Reach
    rc->>rs: Reach
    rs-->>rs: verifies AttestantVerifyingKeys
    rs-->>rs: identifies own ReachablePublicKeys in ReachableSignedKeys
    rs-->>rs: attempts to "take all the" EnvelopeIdHints<br>using ReachableSecretKeys
    note over rs: for each successful hint decryption, saves the<br>relationship between the ReachableSecretKey and EnvelopeId
    rs->>rc: HintedEnvelopeIds
    note over rc: for each HintedEnvelopeId:
    rc->>rn: EnvelopeId
    note over rn,sn: Peers are queried before Server
    rn->>sn: EnvelopeId
    sn->>rn: Envelope
    note over rn: stores Envelope with EnvelopeId as key
    rn->>rc: Envelope
    rc->>rs: Envelope
    rs-->>rs: opens Envelope with ReachableSecretKeys
    rs-->>rs: verifies signatures binding Key, MessageVaultPassport, MessageVault
    rs-->>rs: verifies ReachingVerifyingKeys from MessageVaultPassport
    alt MessageVaultLink contains SealedMessageVaultId
        rs-->>rs: unseals SealedMessageVaultId with SharedSecretKeys
    end
    note over rs: saves relationship between MessageVaultId and<br>the recovered symmetric Key
    rs->>rc: MessageVaultId
    rc->>rn: MessageVaultId
    note over rn,sn: Peers are queried before Server
    rn->>sn: MessageVaultId
    sn->>rn: MessageVault
    note over rn: stores MessageVault with MessageVaultId as key
    rn->>rc: MessageVault
    rc->>rs: MessageVault
    rs-->>rs: authenticates MessageVault using MessageVaultProvenance
    rs-->>rs: decrypts MessageVault with Key
    rs->>rc: Message
    note over rc: displays Message contents<br>recovers and stores ReachingPublicKeys for replies

Replying to Messages

sequenceDiagram
    participant rs as Reachable Secrets
    participant rc as Reachable Application
    participant rn as Reachable Peer Node
    participant sn as Server Node

    note over rc: user writes reply Message
    rc->>rs: Message
    rs-->>rs: generates symmetric encryption Key
    rs-->>rs: encrypts Message with Key
    note over rs: stores Key along with MessageVaultSeed digest
    rs->>rc: MessageVaultSeed
    note over rc: computes and caches MessageVaultSeed digest
    rc->>rn: MessageVaultSeed
    rn->>sn: MessageVaultSeed
    sn-->>sn: generates MessageVaultId
    sn-->>sn: stores MessageVault in database
    sn-->>sn: seals MessageVaultId with SharedPublicKeys
    sn->>rn: SealedMessageVaultId
    rn->>rc: SealedMessageVaultId
    rc->>rs: SealedMessageVaultId
    rs-->>rs: unseals with SharedSecretKeys
    rs->>rc: MessageVaultId
    rc->>rn: AssignMessageVaultId (digest + MessageVaultId)
    note over rn: binds MessageVaultSeed with matching digest<br>to MessageVaultId, stores as MessageVault
    rn->>rc: MessageVault
    note over rc: creates EnvelopeConsignment with MessageVault<br>and ReachingPublicKeys from original message
    rc->>rs: EnvelopeConsignment
    rs-->>rs: looks up Key for this MessageVault
    rs-->>rs: builds MessageVaultPassport with SharedVerifyingKeys
    rs-->>rs: encrypts MessageVaultPassport with Key
    rs-->>rs: signs Key with SharedSigningKeys (for Reaching User)<br>and ReachableSigningKeys (for Reachable Peers)
    rs-->>rs: encrypts Credentials for all ReachablePublicKeys<br>and ReachingPublicKeys
    rs->>rc: EnvelopeSeed
    note over rc: computes and caches EnvelopeSeed digest
    rc->>rn: EnvelopeSeed
    rn->>sn: EnvelopeSeed
    sn-->>sn: generates EnvelopeId
    sn-->>sn: stores Envelope in database
    sn-->>sn: creates EnvelopeIdHints for each BlindedPublicKey
    sn-->>sn: seals EnvelopeId with SharedPublicKeys
    sn->>rn: SealedEnvelopeId
    rn->>rc: SealedEnvelopeId
    rc->>rs: SealedEnvelopeId
    rs-->>rs: unseals with SharedSecretKeys
    rs->>rc: EnvelopeId
    rc->>rn: AssignEnvelopeId (digest + EnvelopeId)
    note over rn: binds EnvelopeSeed with matching digest<br>to EnvelopeId, stores as Envelope
    rn->>rc: Ok

Reaching User

Initial Contact

How does an anonymous Reaching User send their first message?

sequenceDiagram
    participant ru as Reaching User
    participant rl as Reaching Link
    participant sn as Server Node

    ru->>sn: Init
    sn->>ru: Reach
    note over sn,ru: Reach contains AttestantVerifyingKeys, Params,<br>ReachableSignedKeys, EnvelopeIdHints (all decoys for new user)
    ru->>rl: Reach
    rl-->>rl: verifies ReachableVerifyingKeys with AttestantVerifyingKeys
    rl-->>rl: verifies ReachablePublicKeys with ReachableVerifyingKeys
    rl-->>rl: caches EnvelopeIdHints for later
    rl->>ru: verified Reach data
    note over ru: manually verifies AttestantVerifyingKeys Visual Key Identity
    ru-->>ru: generates passphrase
    ru->>rl: passphrase + Params
    rl-->>rl: derives ReachingSigningKeys/ReachingVerifyingKeys
    rl-->>rl: derives ReachingSecretKeys/ReachingPublicKeys (current + previous)
    rl-->>rl: attempts to "take all the" EnvelopeIdHints
    note over rl: finds nothing (first contact)
    rl->>ru: ready to compose
    note over ru: writes Message
    ru->>rl: Message
    rl-->>rl: generates symmetric Key
    rl-->>rl: encrypts Message with Key
    rl->>ru: MessageVaultSeed
    ru->>sn: MessageVaultSeed
    sn-->>sn: generates MessageVaultId
    sn-->>sn: stores MessageVault
    sn-->>sn: seals MessageVaultId with SharedPublicKeys + ServerNodeSecretKey
    sn->>ru: SealedMessageVaultId
    ru->>rl: SealedMessageVaultId
    rl-->>rl: builds MessageVaultPassport with ReachingVerifyingKeys + MessageVaultLink
    rl-->>rl: encrypts MessageVaultPassport with Key
    rl-->>rl: signs Key with ReachingSigningKeys
    rl-->>rl: encrypts Credentials for all ReachablePublicKeys
    rl->>ru: EnvelopeSeed
    ru->>sn: EnvelopeSeed
    sn-->>sn: generates EnvelopeId
    sn-->>sn: stores Envelope
    sn-->>sn: for each BlindedPublicKey, creates EnvelopeIdHint
    sn-->>sn: seals EnvelopeId with SharedPublicKeys + ServerNodeSecretKey
    sn->>ru: SealedEnvelopeId
    note over ru: message sent successfully

Receiving Reply

sequenceDiagram
    participant ru as Reaching User
    participant rl as Reaching Link
    participant sn as Server Node

    ru->>sn: Init
    sn->>ru: Reach
    note over sn,ru: Reach contains AttestantVerifyingKeys, Params,<br>ReachableSignedKeys, EnvelopeIdHints (includes reply)
    ru->>rl: Reach
    rl-->>rl: verifies all keys as before
    rl-->>rl: caches EnvelopeIdHints
    rl->>ru: verified Reach data
    note over ru: verifies AttestantVerifyingKeys Visual Key Identity
    ru->>rl: remembered passphrase
    rl-->>rl: derives ReachingSigningKeys/ReachingVerifyingKeys
    rl-->>rl: derives ReachingSecretKeys/ReachingPublicKeys (current + previous epochs)
    rl-->>rl: attempts to "take all the" EnvelopeIdHints
    note over rl: successfully "takes" 1 EnvelopeId
    rl->>ru: HintedEnvelopeIds
    ru->>sn: EnvelopeId
    sn->>ru: Envelope
    ru->>rl: Envelope
    rl-->>rl: opens Envelope with ReachingSecretKeys
    rl-->>rl: verifies signatures storied in Credentials binding Key, MessageVaultPassport
    rl-->>rl: verifies SharedVerifyingKeys from MessageVaultPassport
    rl-->>rl: recovers MessageVaultId from MessageVaultLink
    rl->>ru: MessageVaultId
    ru->>sn: MessageVaultId
    sn->>ru: MessageVault
    ru->>rl: MessageVault
    rl-->>rl: verifies signatures stored in MessageVaultProvenance binding MessageVault, Key
    rl-->>rl: decrypts MessageVault with Key
    rl->>ru: Message
    note over ru: displays reply Message