Skip to content

Commit e22daf9

Browse files
authored
Merge pull request #12 from henriman/sif-pkg-slayers-path-onehop
Verify `pkg/slayers/path/onehop`
2 parents 7eaabb1 + bb19940 commit e22daf9

File tree

8 files changed

+110
-31
lines changed

8 files changed

+110
-31
lines changed

pkg/slayers/path/empty/empty_spec.gobra

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,5 @@ Path implements path.Path
5858
// Definitions to allow *Path to be treated as a path.Path
5959
pred (e *Path) Mem(buf []byte) { acc(e) && len(buf) == 0 }
6060
pred (e *Path) NonInitMem() { true }
61+
6162
(*Path) implements path.Path

pkg/slayers/path/hopfield.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,15 +110,15 @@ func (h *HopField) DecodeFromBytes(raw []byte) (err error) {
110110
// SerializeTo writes the fields into the provided buffer. The buffer must be of length >=
111111
// path.HopLen.
112112
// @ requires len(b) >= HopLen
113-
// @ requires acc(h.Mem(), R10)
114-
// @ requires low(h.GetEgressRouterAlert()) && low(h.GetIngressRouterAlert())
113+
// @ requires acc(h.Mem(), R10) && h.IsLow()
115114
// @ preserves sl.Bytes(b, 0, HopLen)
116115
// @ ensures acc(h.Mem(), R10)
117116
// @ ensures err == nil
118117
// @ ensures BytesToIO_HF(b, 0, 0, HopLen) ==
119118
// @ unfolding acc(h.Mem(), R10) in h.Abs()
120119
// @ decreases
121120
func (h *HopField) SerializeTo(b []byte) (err error) {
121+
//@ h.RevealIsLow(R10)
122122
if len(b) < HopLen {
123123
return serrors.New("buffer for HopField too short", "expected", MacLen, "actual", len(b))
124124
}

pkg/slayers/path/hopfield_spec.gobra

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,37 @@ pred (h *HopField) Mem() {
2727
acc(h) && h.ConsIngress >= 0 && h.ConsEgress >= 0
2828
}
2929

30+
ghost
31+
requires h.Mem()
32+
decreases
33+
pure func (h *HopField) GetEgressRouterAlert() bool {
34+
return unfolding h.Mem() in h.EgressRouterAlert
35+
}
36+
37+
ghost
38+
requires h.Mem()
39+
decreases
40+
pure func (h *HopField) GetIngressRouterAlert() bool {
41+
return unfolding h.Mem() in h.IngressRouterAlert
42+
}
43+
44+
// TODO: Once Gobra issue #846 is resolved, implement this.
45+
ghost
46+
trusted
47+
requires h.Mem()
48+
decreases
49+
pure func (h *HopField) IsLow() bool
50+
51+
// "Reveal the body" of `h.IsLow` (necessary bc. we can't implement `h.IsLow` yet).
52+
// TODO: Once Gobra issue #846 is resolved, implement this.
53+
ghost
54+
trusted
55+
requires p > 0
56+
requires acc(h.Mem(), p) && h.IsLow()
57+
ensures acc(h.Mem(), p)
58+
ensures low(h.GetEgressRouterAlert()) && low(h.GetIngressRouterAlert())
59+
decreases
60+
func (h *HopField) RevealIsLow(p perm)
3061

3162
ghost
3263
decreases
@@ -115,17 +146,3 @@ pure func (h HopField) Abs() (io.HF) {
115146
HVF: AbsMac(h.Mac),
116147
}
117148
}
118-
119-
ghost
120-
requires h.Mem()
121-
decreases
122-
pure func (h *HopField) GetEgressRouterAlert() bool {
123-
return unfolding h.Mem() in h.EgressRouterAlert
124-
}
125-
126-
ghost
127-
requires h.Mem()
128-
decreases
129-
pure func (h *HopField) GetIngressRouterAlert() bool {
130-
return unfolding h.Mem() in h.IngressRouterAlert
131-
}

pkg/slayers/path/onehop/onehop.go

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ type Path struct {
6464
}
6565

6666
// @ requires o.NonInitMem()
67+
// @ requires low(len(data))
6768
// @ preserves acc(sl.Bytes(data, 0, len(data)), R42)
6869
// @ ensures (len(data) >= PathLen) == (r == nil)
6970
// @ ensures r == nil ==> o.Mem(data)
@@ -98,20 +99,25 @@ func (o *Path) DecodeFromBytes(data []byte) (r error) {
9899
return r
99100
}
100101

101-
// @ preserves acc(o.Mem(ubuf), R1)
102+
// @ requires low(len(b))
103+
// @ requires acc(o.Mem(ubuf), R1) && o.IsLow(ubuf)
102104
// @ preserves acc(sl.Bytes(ubuf, 0, len(ubuf)), R1)
103105
// @ preserves sl.Bytes(b, 0, len(b))
106+
// @ ensures acc(o.Mem(ubuf), R1)
104107
// @ ensures (len(b) >= PathLen) == (err == nil)
105108
// @ ensures err != nil ==> err.ErrorMem()
106109
// @ ensures err == nil ==> o.LenSpec(ubuf) <= len(b)
107110
// @ decreases
108111
func (o *Path) SerializeTo(b []byte /*@, ubuf []byte @*/) (err error) {
112+
//@ o.RevealIsLow(ubuf, R1)
109113
if len(b) < PathLen {
110114
return serrors.New("buffer too short for OneHop path", "expected", int(PathLen), "actual",
111115
int(len(b)))
112116
}
113117
offset := 0
114118
//@ unfold acc(o.Mem(ubuf), R1)
119+
//@ o.FirstHop.RevealIsLow(R2)
120+
//@ o.SecondHop.RevealIsLow(R2)
115121
//@ sl.SplitRange_Bytes(b, 0, offset+path.InfoLen, writePerm)
116122
if err := o.Info.SerializeTo(b[:offset+path.InfoLen]); err != nil {
117123
//@ sl.CombineRange_Bytes(b, 0, offset+path.InfoLen, writePerm)
@@ -135,10 +141,13 @@ func (o *Path) SerializeTo(b []byte /*@, ubuf []byte @*/) (err error) {
135141

136142
// ToSCIONDecoded converts the one hop path in to a normal SCION path in the
137143
// decoded format.
138-
// @ preserves o.Mem(ubuf)
144+
// @ requires o.Mem(ubuf)
145+
// @ requires low(o.GetSecondHopConsIngress(ubuf))
139146
// @ preserves sl.Bytes(ubuf, 0, len(ubuf))
147+
// @ ensures o.Mem(ubuf)
140148
// @ ensures err == nil ==> (sd != nil && sd.Mem(ubuf))
141149
// @ ensures err != nil ==> err.ErrorMem()
150+
// @ ensures low(err != nil)
142151
// @ decreases
143152
func (o *Path) ToSCIONDecoded( /*@ ghost ubuf []byte @*/ ) (sd *scion.Decoded, err error) {
144153
//@ unfold acc(o.Mem(ubuf), R1)
@@ -198,14 +207,15 @@ func (o *Path) ToSCIONDecoded( /*@ ghost ubuf []byte @*/ ) (sd *scion.Decoded, e
198207
}
199208

200209
// Reverse a OneHop path that returns a reversed SCION path.
201-
// @ requires o.Mem(ubuf)
210+
// @ requires o.Mem(ubuf) && o.IsLow(ubuf)
202211
// @ preserves sl.Bytes(ubuf, 0, len(ubuf))
203-
// @ ensures err == nil ==> p != nil
204-
// @ ensures err == nil ==> p.Mem(ubuf)
205-
// @ ensures err == nil ==> typeOf(p) == type[*scion.Decoded]
206-
// @ ensures err != nil ==> err.ErrorMem()
212+
// @ ensures err == nil ==> p != nil
213+
// @ ensures err == nil ==> p.Mem(ubuf)
214+
// @ ensures err == nil ==> typeOf(p) == type[*scion.Decoded]
215+
// @ ensures err != nil ==> err.ErrorMem()
207216
// @ decreases
208217
func (o *Path) Reverse( /*@ ghost ubuf []byte @*/ ) (p path.Path, err error) {
218+
//@ o.RevealIsLow(ubuf, writePerm)
209219
sp, err := o.ToSCIONDecoded( /*@ ubuf @*/ )
210220
if err != nil {
211221
return nil, serrors.WrapStr("converting to scion path", err)

pkg/slayers/path/onehop/onehop_spec.gobra

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,55 @@ pred (o *Path) Mem(ubuf []byte) {
3232
PathLen <= len(ubuf)
3333
}
3434

35+
ghost
36+
requires o.Mem(ub)
37+
decreases
38+
pure func (o *Path) GetSecondHopConsIngress(ghost ub []byte) uint16 {
39+
return unfolding o.Mem(ub) in
40+
unfolding o.SecondHop.Mem() in o.SecondHop.ConsIngress
41+
}
42+
43+
ghost
44+
requires o.Mem(ub)
45+
decreases
46+
pure func (o *Path) GetInfo(ghost ub []byte) path.InfoField {
47+
return unfolding o.Mem(ub) in o.Info
48+
}
49+
50+
ghost
51+
requires o.Mem(ub)
52+
decreases
53+
pure func (o *Path) FirstHopIsLow(ghost ub []byte) bool {
54+
return unfolding o.Mem(ub) in o.FirstHop.IsLow()
55+
}
56+
57+
ghost
58+
requires o.Mem(ub)
59+
decreases
60+
pure func (o *Path) SecondHopIsLow(ghost ub []byte) bool {
61+
return unfolding o.Mem(ub) in o.SecondHop.IsLow()
62+
}
63+
64+
// TODO: Once Gobra issue #846 is resolved, implement `IsLow`.
65+
ghost
66+
trusted
67+
requires o.Mem(ub)
68+
decreases
69+
pure func (o *Path) IsLow(ub []byte) bool
70+
71+
// "Reveal the body" of `o.IsLow` (necessary bc. we can't implement `o.IsLow` yet).
72+
// TODO: Once Gobra issue #846 is resolved, implement this.
73+
ghost
74+
trusted
75+
requires p > 0
76+
requires acc(o.Mem(ub), p) && o.IsLow(ub)
77+
ensures acc(o.Mem(ub), p)
78+
ensures low(o.GetSecondHopConsIngress(ub)) &&
79+
low(o.GetInfo(ub).ConsDir) && low(o.GetInfo(ub).Peer) &&
80+
o.FirstHopIsLow(ub) && o.SecondHopIsLow(ub)
81+
decreases
82+
func (o *Path) RevealIsLow(ub []byte, p perm)
83+
3584
ghost
3685
requires p.Mem(buf)
3786
ensures p.NonInitMem()
@@ -64,4 +113,4 @@ pure func (p *Path) LenSpec(ghost ub []byte) int {
64113
return PathLen
65114
}
66115

67-
(*Path) implements path.Path
116+
(*Path) implements path.Path

pkg/slayers/path/path.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ type Path interface {
113113
//@ IsValidResultOfDecoding(b []byte) bool
114114
// Reverse reverses a path such that it can be used in the reversed direction.
115115
// XXX(shitz): This method should possibly be moved to a higher-level path manipulation package.
116-
//@ requires Mem(ub)
116+
//@ requires Mem(ub) && IsLow(ub)
117117
//@ preserves sl.Bytes(ub, 0, len(ub))
118118
//@ ensures e == nil ==> p != nil
119119
//@ ensures e == nil ==> p.Mem(ub)

pkg/slayers/path/scion/decoded_spec.gobra

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ pred (d *Decoded) Mem(ubuf []byte) {
4747
(forall i int :: { &d.HopFields[i] } 0 <= i && i < len(d.HopFields) ==> d.HopFields[i].Mem())
4848
}
4949

50-
// TODO: Once Gobra issue #846 is resolved, actually implement `IsLow`.
5150
ghost
52-
trusted
5351
requires d.Mem(ub)
5452
decreases
55-
pure func (d *Decoded) IsLow(ub []byte) bool
53+
pure func (d *Decoded) IsLow(ub []byte) bool {
54+
return true
55+
}
5656

5757
/**** End of Predicates ****/
5858

@@ -119,6 +119,7 @@ ensures e == nil ==> (
119119
d.LenSpec(ubuf) == old(d.LenSpec(ubuf)) &&
120120
(old(d.GetBase(ubuf).Valid()) ==> d.GetBase(ubuf).Valid()))
121121
ensures e != nil ==> d.NonInitMem() && e.ErrorMem()
122+
ensures low(e != nil)
122123
decreases
123124
func (d *Decoded) IncPath(ghost ubuf []byte) (e error) {
124125
unfold d.Mem(ubuf)

pkg/slayers/path/scion/raw_spec.gobra

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,13 @@ pred (s *Raw) Mem(buf []byte) {
3838
len(s.Raw) == s.Base.Len()
3939
}
4040

41-
// TODO: Once Gobra issue #846 is resolved, actually implement `IsLow`.
4241
ghost
43-
trusted
4442
requires s.Mem(ub)
4543
decreases
46-
pure func (s *Raw) IsLow(ub []byte) bool
44+
pure func (s *Raw) IsLow(ub []byte) bool {
45+
return true
46+
}
47+
4748
/**** End of Predicates ****/
4849

4950
(*Raw) implements path.Path

0 commit comments

Comments
 (0)