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