Skip to content

Commit aec306e

Browse files
committed
fixes a weird incompleteness in Gobra where a 1/16 seems smaller than wildcard permission amount
1 parent b7cc7be commit aec306e

File tree

4 files changed

+13
-16
lines changed

4 files changed

+13
-16
lines changed

dh/implementation/initiator/initiator.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -370,13 +370,11 @@ func (i *Initiator) ProduceHsMsg3() (signedMsg3 []byte, success bool) {
370370
}
371371

372372
//@ requires acc(i, 1/2) && acc(i.l.Mem(), 1/2)
373-
//@ requires acc(Mem(signedMsg3), 1/2) && Abs(signedMsg3) == by.signB(ay.tuple5B(ay.integer32B(Msg3Tag), ay.integer32B(i.idA), ay.integer32B(i.idB), by.gamma(i.YT), by.expB(ay.generatorB(), by.gamma(i.xT))), by.gamma(i.skAT))
373+
//@ requires Mem(signedMsg3) && signedMsg3 != nil && Abs(signedMsg3) == by.signB(ay.tuple5B(ay.integer32B(Msg3Tag), ay.integer32B(i.idA), ay.integer32B(i.idB), by.gamma(i.YT), by.expB(ay.generatorB(), by.gamma(i.xT))), by.gamma(i.skAT))
374374
//@ requires pl.token(t0) && io.P_Alice(t0, ridT, s0)
375375
//@ requires HasHsMsg3OutFact(ridT, i.idA, i.idB, i.YT, i.xT, i.skAT, s0)
376376
//@ requires ProcessedHsMsg2Pred(ridT, i.idA, i.idB, i.skAT, i.skBT, i.xT, i.YT, s0)
377377
//@ ensures acc(i, 1/2) && acc(i.l.Mem(), 1/2)
378-
// due to the workaround for sanitization, we obtain a different slice to which `signedMsg3` points:
379-
// ensures acc(Mem(signedMsg3), 1/2) && signedMsg3 != nil
380378
//@ ensures Mem(signedMsg3) && signedMsg3 != nil && Abs(signedMsg3) == before(Abs(signedMsg3))
381379
//@ ensures pl.token(t1) && io.P_Alice(t1, ridT, s1)
382380
//@ ensures ProcessedHsMsg2Pred(ridT, i.idA, i.idB, i.skAT, i.skBT, i.xT, i.YT, s1)
@@ -408,8 +406,7 @@ func (i *Initiator) ProduceHsMsg3() (signedMsg3 []byte, success bool) {
408406
sharedSecret, err /*@, sharedSecretB @*/ = i.l.DhSharedSecret(i.x, i.Y)
409407
if err == nil { //argot:ignore diodon-dh-io-independence
410408
i.irKey, i.riKey = NewBytes(32), NewBytes(32)
411-
//@ ghost var t0Abs, t1Abs by.Bytes
412-
err /*@, t0Abs, t1Abs @*/ = KDF2Slice(i.irKey, i.riKey, sharedSecret /*@, sharedSecretB @*/)
409+
err = KDF2Slice(i.irKey, i.riKey, sharedSecret)
413410
if err == nil {
414411
i.l.PrintKeys(i.irKey, i.riKey)
415412
//@ fold HandshakeCompletedPred(i.irKey, i.riKey, i.xT, i.YT)

dh/implementation/library/crypto.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -221,12 +221,10 @@ func Equals(s1, s2 []byte) (res bool) {
221221
// which is a bug.
222222
// @ trusted
223223
// @ decreases
224-
// @ requires Mem(t0) && Mem(t1)
225-
// @ requires acc(Mem(key), 1/16) && keyAbs == Abs(key)
226-
// @ ensures Mem(t0) && t0Abs == Abs(t0) && Mem(t1) && t1Abs == Abs(t1)
227-
// @ ensures err == nil ==> kdf1B(keyAbs) == t0Abs
228-
// @ ensures err == nil ==> kdf2B(keyAbs) == t1Abs
229-
func KDF2Slice(t0, t1 []byte, key []byte /*@, ghost keyAbs Bytes @*/) (err error /*@, ghost t0Abs Bytes, ghost t1Abs Bytes @*/) {
224+
// @ preserves Mem(t0) && Mem(t1) && acc(Mem(key), 1/16)
225+
// @ ensures err == nil ==> kdf1B(Abs(key)) == Abs(t0)
226+
// @ ensures err == nil ==> kdf2B(Abs(key)) == Abs(t1)
227+
func KDF2Slice(t0, t1 []byte, key []byte) (err error) {
230228
if len(t0) != 32 || len(t1) != 32 {
231229
err = errors.New("invalid argument length")
232230
return
@@ -240,7 +238,7 @@ func KDF2Slice(t0, t1 []byte, key []byte /*@, ghost keyAbs Bytes @*/) (err error
240238
}
241239

242240
// @ trusted
243-
// @ preserves Mem(sum) && Mem(key) && Mem(in0)
241+
// @ preserves Mem(sum) && acc(Mem(key), 1/32) && acc(Mem(in0), 1/32)
244242
func HMAC1Slice(sum []byte, key, in0 []byte) {
245243
mac := hmac.New(func() hash.Hash {
246244
h, _ := blake2s.New256(nil)

dh/implementation/library/io.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ import fmt "fmt"
1010
// calling this function results in a proof obligations that the necessary I/O permission
1111
// for performing an output operation are present. Thus, we can treat this function as
1212
// sanitizing `data`
13+
// technically, fractional permissions for `data` is sufficient. However, we express the specification
14+
// in a way that it does not matter for callers whether this function copies the slice of bytes or returns
15+
// the same one.
1316
// @ trusted
14-
// @ requires acc(Mem(data), 1/16)
17+
// @ requires Mem(data) && data != nil
1518
// @ requires token(t) && e_OutFact(t, rid, m) && gamma(m) == Abs(data)
16-
// @ ensures acc(Mem(data), 1/16)
1719
// @ ensures token(t1) && t1 == old(get_e_OutFact_placeDst(t, rid, m))
18-
// @ ensures Mem(res) && Abs(data) == Abs(res) && res != nil // added due to the workaround for the data flow analysis' imprecision
20+
// @ ensures Mem(res) && Abs(res) == old(Abs(data)) && res != nil
1921
func PerformVirtualOutputOperation(data []byte /*@, ghost t Place, ghost rid tm.Term, ghost m tm.Term @*/) (res []byte /*@, ghost t1 Place @*/) {
2022
// due to an imprecision in the data flow analysis, we have to copy the slice instead of directly returning `data`
2123
// otherwise, the data flow analysis considers the result tainted despite configuring this function as a sanitizer

dh/implementation/library/state.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pred Mem(data []byte)
1717
1818
ghost
1919
decreases
20-
requires acc(Mem(b), _)
20+
requires acc(Mem(b), 1/32)
2121
pure func Abs(b []byte) (res by.Bytes)
2222
@*/
2323

0 commit comments

Comments
 (0)