Skip to content

Commit

Permalink
Add MWE2
Browse files Browse the repository at this point in the history
  • Loading branch information
henriman committed Dec 9, 2024
1 parent d606c27 commit f5603b6
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// 1. We receive a message M over the network.
// 2. We compute a "MAC tag" of M using K.
// 3. We send the computed tag over the network.
package mwe
package mwe1

////////////////////////////// I/O Actions //////////////////////////////
// cf. running-example/policy/actions.gobra
Expand Down
132 changes: 132 additions & 0 deletions verification/scratch/mwe2/mwe2.gobra
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Minimal working example 2.
package mwe2

// Used to track position in protocol.
type Place int
pred token(ghost p Place)

pred RecvPerm(ghost p Place)

// Returns the next place after calling `Recv` from `p`.
// Avoids using an existential quantifier.
ghost
requires RecvPerm(p)
decreases
pure func Recv_T(ghost p Place) Place

// Used to refer to the received message.
ghost
requires RecvPerm(p)
decreases
pure func Recv_R(ghost p Place) int

// This is how the state is/should be updated after receiving message `m`.
decreases
pure func Recv_S(s state, m int) state {
return state { key: s.key, lastMsg1: m, lastMsg2: s.lastMsg1, lastMsg3: s.lastMsg2 }
}

requires token(p) && RecvPerm(p)
ensures token(old(Recv_T(p)))
ensures m == old(Recv_R(p))
ensures low(m)
func Recv(ghost p Place) (m int)

pred SendPerm(ghost p Place, t int)

ghost
requires SendPerm(p, t)
decreases
pure func Send_T(ghost p Place, t int) Place

requires token(p) && SendPerm(p, t)
requires low(t)
ensures token(old(Send_T(p, t)))
func Send(ghost p Place, t int)

pred DeclassifyPerm(ghost p Place, tag int, t int)

ghost
requires DeclassifyPerm(p, tag, t)
decreases
pure func Declassify_T(ghost p Place, tag int, t int) Place

// In order to make permitted declassifications deterministic in low data,
// we add low parameter `p` to "tag" declassifications.
// (Necessary as otherwise IOD spec Protocol2 would not be well-formed.)
ghost
requires token(p) && DeclassifyPerm(p, tag, t)
requires low(tag)
ensures token(old(Declassify_T(p, tag, t)))
ensures low(t)
decreases
func Declassify(ghost p Place, tag int, t int)

// "Linear" protocol.
pred Protocol1(ghost p Place, key int) {
// 1. Receive a message.
RecvPerm(p) &&
// 2. Compute MAC tag and declassify it.
DeclassifyPerm(Recv_T(p), Recv_R(p), MAC(key, Recv_R(p))) &&
// 3. Send MAC tag over network.
SendPerm(Declassify_T(Recv_T(p), Recv_R(p), MAC(key, Recv_R(p))), MAC(key, Recv_R(p))) &&
// 4. Restart.
Protocol1(Send_T(Declassify_T(Recv_T(p), Recv_R(p), MAC(key, Recv_R(p))), MAC(key, Recv_R(p))), key)
}

type state struct {
key int // the private key
lastMsg1 int // 1st most recently received message
lastMsg2 int // 2nd
lastMsg3 int // 3rd
}

pred Protocol2(ghost p Place, s state) {
// Receive a message at any time.
RecvPerm(p) && Protocol2(Recv_T(p), Recv_S(s, Recv_R(p))) &&
// NOTE: at the moment we can declassify things before receiving anything
// Declassify and send either the most or the 2nd most recently received message.
DeclassifyPerm(p, s.lastMsg1, MAC(s.key, s.lastMsg1)) && Protocol2(Declassify_T(p, s.lastMsg1, MAC(s.key, s.lastMsg1)), s) &&
DeclassifyPerm(p, s.lastMsg2, MAC(s.key, s.lastMsg2)) && Protocol2(Declassify_T(p, s.lastMsg2, MAC(s.key, s.lastMsg2)), s) &&
SendPerm(p, MAC(s.key, s.lastMsg1)) && Protocol2(Send_T(p, MAC(s.key, s.lastMsg1)), s) &&
SendPerm(p, MAC(s.key, s.lastMsg2)) && Protocol2(Send_T(p, MAC(s.key, s.lastMsg2)), s)
}

// Abstract function representing the computation of a MAC.
// key x message -> MAC tag
decreases
pure func MAC(int, int) int

requires token(p0) && Protocol2(p0, s)
func authenticate(ghost p0 Place, s state) {

invariant token(p0) && Protocol2(p0, s)
for {
unfold Protocol2(p0, s)
ghost p1 := Recv_T(p0)
m1 := Recv(p0)
s = Recv_S(s, m1)

unfold Protocol2(p1, s)
ghost p2 := Recv_T(p1)
m2 := Recv(p1)
s = Recv_S(s, m2)

unfold Protocol2(p2, s)
ghost p3 := Recv_T(p2)
m3 := Recv(p2)
s = Recv_S(s, m3)

// We can use m2, m3 here. m1 won't work.
t := MAC(s.key, m3)

unfold Protocol2(p3, s)
ghost p4 := Declassify_T(p3, m3, t)
Declassify(p3, m3, t)

unfold Protocol2(p4, s)
ghost p0 = Send_T(p4, t)
Send(p4, t)
}

}

0 comments on commit f5603b6

Please sign in to comment.