Hi! This is the first of a few (more) questions I'm going to be posting about SAPIC+, SAPIC+ translation to ProVerif, and how constructs like channels, state, etc. are meant to be understood.
I wrote a fairly simple example that uses a private channel, and some lemmas that I thought would be straightforward to prove:
theory test_private_channels begin
let reader(sc: channel) = (
in(sc, x);
event Read(x);
out(sc, 'newstate')
)
process:(
new sc: channel;
(
out(sc, 'oldstate') ||
!reader(sc)
)
)
lemma ExOld:
exists-trace
"Ex #i. Read('oldstate')@i"
lemma ExNew:
exists-trace
"Ex #i. Read('newstate')@i"
lemma AlwaysOldOrNew:
"All x #i. Read(x)@i ==> x = 'oldstate' | x = 'newstate'"
lemma OldThenNew:
"All #i #j.
Read('newstate')@i & Read('oldstate')@j ==> j < i"
end
Tamarin quickly proves the first 3 lemmas, but gets stuck forever (and eventually runs out of memory) proving OldThenNew. But if I replace my process definition with:
process:(
new sc: channel;
(
out(sc, 'oldstate') ||
reader(sc) || reader(sc) || reader(sc) || ...
)
)
for any finite number of reader(sc) processes I choose to put there, it proves OldThenNew (though it takes longer and longer with each additional reader(sc) process, and rapidly becomes impractical).
My assumption about the semantics of private channels is that, if a process calls out(p,X) on a private channel p, X can be received one time by any number of concurrent executions of in(p) (so that it is possible for an arbitrary number of processes to "simultaneously" receive 'oldstate' in my example, and thus an arbitrary number of "Read('oldstate')" events to occur), but that once X has been received in a particular process, an additional in(p) in that process would block until some other process called out(p); also, once another out(p, Y) is called, all subsequent (concurrent) executions of in(p) would receive Y. With that semantics, it seems to me that I should be able to prove "OldThenNew", and the fact that Tamarin can prove it automatically for an arbitrary finite number of instantiations of reader (modulo available memory and time) also points in that direction... but I don't have any idea how, or if it's possible, to prove it in the infinite process replication case; I've tried doing it manually, and when I do that, no matter what I try, I end up in an infinite regress of steps that are proven by contradiction and marked "/* cyclic */" in the Tamarin UI.
Any suggestions, or help with my potential lack of understanding of the SAPIC+ channel semantics, would be greatly appreciated. Thanks!
-Dan Zimmerman