2017-02-15 20:19:39 +00:00
|
|
|
digraph {
|
|
|
|
|
|
|
|
/* could shave a RTT by committing to the nameplate early, before
|
|
|
|
finishing the rest of the code input. While the user is still
|
|
|
|
typing/completing the code, we claim the nameplate, open the mailbox,
|
|
|
|
and retrieve the peer's PAKE message. Then as soon as the user
|
|
|
|
finishes entering the code, we build our own PAKE message, send PAKE,
|
|
|
|
compute the key, send VERSION. Starting from the Return, this saves
|
|
|
|
two round trips. OTOH it adds consequences to hitting Tab. */
|
|
|
|
|
2017-02-16 01:46:28 +00:00
|
|
|
start [label="Wormhole\nMachine" style="dotted"]
|
|
|
|
|
|
|
|
S0 [label="S0: know\nnothing"]
|
|
|
|
S0 -> P0_queue [label="send" style="dotted"]
|
|
|
|
P0_queue [shape="box" style="dotted" label="queue"]
|
|
|
|
P0_queue -> S0 [style="dotted"]
|
|
|
|
S0 -> P0_build [label="set_code"]
|
|
|
|
|
|
|
|
P0_build [shape="box" label="build_pake\nM.set_nameplate\nM.add_message(pake)"]
|
|
|
|
P0_build -> S1
|
|
|
|
S1 [label="S1: know\ncode"]
|
|
|
|
S1 -> P1_queue [label="send" style="dotted"]
|
|
|
|
P1_queue [shape="box" style="dotted" label="queue"]
|
|
|
|
P1_queue -> S1 [style="dotted"]
|
|
|
|
|
|
|
|
/* the Mailbox will deliver each message exactly once, but doesn't
|
|
|
|
guarantee ordering: if Alice starts the process, then disconnects,
|
|
|
|
then Bob starts (reading PAKE, sending both his PAKE and his VERSION
|
|
|
|
phase), then Alice will see both PAKE and VERSION on her next
|
|
|
|
connect, and might get the VERSION first.
|
|
|
|
|
|
|
|
The Wormhole will queue inbound messages that it isn't ready for. The
|
|
|
|
wormhole shim that lets applications do w.get(phase=) must do
|
|
|
|
something similar, queueing inbound messages until it sees one for
|
|
|
|
the phase it currently cares about.*/
|
|
|
|
|
|
|
|
S1 -> P_mood_scary [label="got_message(pake)\npake bad"]
|
|
|
|
S1 -> P1_compute [label="got_message(pake)\npake good"]
|
|
|
|
S1 -> P1_queue_inbound [label="got_message(other)"]
|
|
|
|
P1_queue_inbound [shape="box" style="dotted" label="queue\ninbound"]
|
|
|
|
P1_queue_inbound -> S1
|
|
|
|
S1 -> P_mood_lonely [label="close"]
|
|
|
|
|
|
|
|
P1_compute [label="compute_key\nM.add_message(version)\nA.got_verifier\nschedule process inbound queue?" shape="box"]
|
|
|
|
P1_compute -> S2
|
|
|
|
|
|
|
|
P_mood_scary [shape="box" label="M.close\nmood=scary"]
|
|
|
|
P_mood_scary -> P_notify_failure
|
|
|
|
|
|
|
|
P_notify_failure [shape="box" label="(record failure)" color="red"]
|
|
|
|
P_notify_failure -> S_closing
|
|
|
|
|
|
|
|
S2 [label="S2: know_key\n(unverified)" color="orange"]
|
|
|
|
S2 -> P_queue3 [label="send" style="dotted"]
|
|
|
|
P_queue3 [shape="box" style="dotted" label="queue"]
|
|
|
|
P_queue3 -> S2 [style="dotted"]
|
|
|
|
S2 -> P_verify [label="got_message"] /* version or phase */
|
|
|
|
S2 -> P_mood_lonely [label="close"] /* more like impatient */
|
|
|
|
|
|
|
|
P_verify [label="verify(msg)" shape="box"]
|
|
|
|
P_verify -> P_accept_msg [label="(good)"]
|
|
|
|
P_verify -> P_mood_scary [label="(bad)"]
|
|
|
|
|
|
|
|
P_accept_msg [label="A.received(msg)\nencrypt queued\nM.add_message(queued)"
|
|
|
|
shape="box"]
|
|
|
|
P_accept_msg -> S3
|
|
|
|
|
|
|
|
S3 [label="S3: know_key\n(verified)" color="green"]
|
|
|
|
S3 -> P_verify [label="got_message"] /* probably phase */
|
|
|
|
S3 -> P_mood_happy [label="close"]
|
|
|
|
S3 -> P_send [label="send"]
|
|
|
|
|
|
|
|
P_mood_happy [shape="box" label="M.close\nmood=happy"]
|
|
|
|
P_mood_happy -> S_closing
|
|
|
|
|
|
|
|
P_mood_lonely [shape="box" label="M.close\nmood=lonely"]
|
|
|
|
P_mood_lonely -> S_closing
|
|
|
|
|
|
|
|
P_send [shape="box" label="encrypt\nM.add_message(msg)"]
|
|
|
|
P_send -> S3
|
|
|
|
|
|
|
|
S_closing [label="closing"]
|
|
|
|
S_closing -> P_closed [label="closed"]
|
|
|
|
S_closing -> S_closing [label="got_message"]
|
|
|
|
|
|
|
|
P_closed [shape="box" label="A.closed"]
|
|
|
|
P_closed -> S_closed
|
|
|
|
S_closed [label="closed"]
|
2017-02-15 20:19:39 +00:00
|
|
|
}
|