REPROSEC / dolev-yao-star-extrinsic

DY* with extrinsic proofs
https://reprosec.org/
Mozilla Public License 2.0
8 stars 0 forks source link

ISO-DH Example #36

Open fabian-hk opened 1 week ago

fabian-hk commented 1 week ago

I finally finished porting the ISO-DH example to the extrinsic DY code base, and I am happy to receive your feedback. We should also discuss whether that example is part of the core DY repository or if it should live in its own repo. Right now, there are a lot of comments and debugging statements. I would like to keep it like that to help others understand it better, but I can understand if that is not something we want in the main repo. In this case, I would create a separate repo with a version that has more details in the code. This separate repo could also serve as an example of how to set up a repository to analyze a protocol with DY*.

fabian-hk commented 1 week ago

@TWal, I would like to answer your question about my impression of the extrinsic DY*: I like the approach much better than the intrinsic version because you don't have all the complexity at once. In the extrinsic version, I am able to focus first on the model and then think about the proofs.

One thing I was wondering if it could be improved is the code that combines the invariants, because it seems to me that it is always the same (at least in the NSL and ISO-DH example):

/// List of all local state predicates.

let all_sessions = [
  pki_tag_and_invariant;
  private_keys_tag_and_invariant;
  (local_state_dh_session.tag, local_state_predicate_to_local_bytes_state_predicate dh_session_pred);
]

/// List of all local event predicates.

let all_events = [
  (dh_event_instance.tag, compile_event_pred dh_event_pred)
]

/// Create the global trace invariants.

let dh_trace_invs: trace_invariants (dh_crypto_invs) = {
  state_pred = mk_state_predicate dh_crypto_invs all_sessions;
  event_pred = mk_event_pred all_events;
}

instance dh_protocol_invs: protocol_invariants = {
  crypto_invs = dh_crypto_invs;
  trace_invs = dh_trace_invs;
}

/// Lemmas that the global state predicate contains all the local ones

val all_sessions_has_all_sessions: unit -> Lemma (norm [delta_only [`%all_sessions; `%for_allP]; iota; zeta] (for_allP (has_local_bytes_state_predicate dh_protocol_invs) all_sessions))
let all_sessions_has_all_sessions () =
  assert_norm(List.Tot.no_repeats_p (List.Tot.map fst (all_sessions)));
  mk_global_local_bytes_state_predicate_correct dh_protocol_invs all_sessions;
  norm_spec [delta_only [`%all_sessions; `%for_allP]; iota; zeta] (for_allP (has_local_bytes_state_predicate dh_protocol_invs) all_sessions)

val full_dh_session_pred_has_pki_invariant: squash (has_pki_invariant dh_protocol_invs)
let full_dh_session_pred_has_pki_invariant = all_sessions_has_all_sessions ()

val full_dh_session_pred_has_private_keys_invariant: squash (has_private_keys_invariant dh_protocol_invs)
let full_dh_session_pred_has_private_keys_invariant = all_sessions_has_all_sessions ()

val full_dh_session_pred_has_dh_invariant: squash (has_local_state_predicate dh_protocol_invs dh_session_pred)
let full_dh_session_pred_has_dh_invariant = all_sessions_has_all_sessions ()

/// Lemmas that the global event predicate contains all the local ones

val all_events_has_all_events: unit -> Lemma (norm [delta_only [`%all_events; `%for_allP]; iota; zeta] (for_allP (has_compiled_event_pred dh_protocol_invs) all_events))
let all_events_has_all_events () =
  assert_norm(List.Tot.no_repeats_p (List.Tot.map fst (all_events)));
  mk_event_pred_correct dh_protocol_invs all_events;
  norm_spec [delta_only [`%all_events; `%for_allP]; iota; zeta] (for_allP (has_compiled_event_pred dh_protocol_invs) all_events);
  let dumb_lemma (x:prop) (y:prop): Lemma (requires x /\ x == y) (ensures y) = () in
  dumb_lemma (for_allP (has_compiled_event_pred dh_protocol_invs) all_events) (norm [delta_only [`%all_events; `%for_allP]; iota; zeta] (for_allP (has_compiled_event_pred dh_protocol_invs) all_events))

val full_dh_event_pred_has_dh_invariant: squash (has_event_pred dh_protocol_invs dh_event_pred)
let full_dh_event_pred_has_dh_invariant = all_events_has_all_events ()

Another thing I stumbled over is that is_secret matches labels with ==, which does not take into account the commutativity of labels. For this reason, I got stuck in the proof until I used the equivalent tr function. I was wondering whether we should use the equivalent tr function in the is_secret function?

TWal commented 5 days ago

@fabian-hk to answer your remarks:

TWal commented 20 hours ago

I think this is soon ready to merge, before that the following changes would be great:

I can take care of cleaning the proofs in SecurityProperties (or at least, see how much of it can be cleaned, given that they are already quite good!)