tamarin-prover-0.8.2.0: data/examples/loops/Minimal_HashChain.spthy
theory Minimal_HashChain begin
/*
Protocol: A minimal HashChain example (inspired by TESLA 2)
Modeler: Simon Meier
Date: August 2012
Status: note yet working
(requires multiset or repeated exponentiation reasoning)
This models the key difficulty in the proof of the TESLA 2 protocol with
re-authentication: the verification that the key checking process is
sufficient to guarantee that the key is a key of the hash-chain.
*/
functions: f/1
// Chain setup phase
////////////////////
// Hash chain generation
rule Gen_Start:
[ Fr(seed) ] --> [ Gen(seed, seed), Out(seed) ]
// The NextKey-facts are used by the sender rules to store the link between
// the keys in the chain.
rule Gen_Step:
[ Gen(seed, chain) ]
--[ ChainKey(chain)
]->
[ Gen(seed, f(chain) ) ]
// At some point the sender decides to stop the hash-chain precomputation.
rule Gen_Stop:
[ Gen(seed, kZero) ]
--[ ChainKey(kZero) ]->
[ !Final(kZero) ]
// Key checking
///////////////
// Start checking an arbitrary key. Use a loop-id to allow connecting
// different statements about the same loop.
rule Check0:
[ In(kOrig)
, Fr(loopId)
]
--[ Start(loopId, kOrig)
]->
[ Loop(loopId, kOrig, kOrig) ]
rule Check:
[ Loop(loopId, k, kOrig) ]
--[ Loop(loopId, k, kOrig) ]->
[ Loop(loopId, f(k), kOrig) ]
rule Success:
[ Loop(loopId, kZero, kOrig), !Final(kZero) ]
--[ Success(loopId, kOrig)
]-> []
// Provable: restricts the search space
lemma Loop_Start [use_induction, reuse]:
"All lid k kOrig #i. Loop(lid, k, kOrig) @ i ==>
Ex #j. Start(lid, kOrig) @ j & j < i"
// Provable: restricts the search space
lemma Loop_Success_ord [use_induction, reuse]:
"All lid k kOrig1 kOrig2 #i #j.
Loop(lid, k, kOrig1) @ i
& Success(lid, kOrig2) @ j
==>
( i < j)
"
// Provable: connects an arbitrary loop step with its start.
lemma Loop_charn [use_induction]:
"All lid k kOrig #i. Loop(lid, k, kOrig) @ i ==>
Ex #j. Loop(lid, kOrig, kOrig) @ j"
// Not yet provable: the problem is that we cannot express the relation
// between the keys on two different segments of the same loop.
// @BS: Do you have an idea on how we could use multisets to formulate a
// strong enough invariant?
lemma Loop_and_success [use_induction]:
"All lid k kOrig1 kOrig2 #i #j.
Loop(lid, k, kOrig1) @ i
& Success(lid, kOrig2) @ j
==>
(Ex #j. ChainKey(k) @ j)
"
// The ultimate goal! A successful check implies that the starting key is a
// key of the chain.
lemma Success_charn:
"All lid k #i. Success(lid, k) @ i ==>
Ex #j. ChainKey(k) @ j"
/* A try on building the required 'smaller' relation in an axiomatic fashion.
This interacts too strongly with
Does not really work! We need a better way to express this stuff.
rule Succ_to_Smaller:
[ !Succ(x, y) ] --[ IsSmaller(x, y) ]-> [!Smaller(x, y)]
rule Smaller_Extend:
[ !Succ(x, y), !Smaller(y, z) ]
--[ IsSmaller(x, z) ]->
[ !Smaller(x, z) ]
axiom force_succ_smaller:
"All #t1 2 a b c. IsSucc(a,b)@t1
==> Ex #t2 . IsSmaller(a,b)@t2 "
axiom transitivity:
"All #t1 #t2 a b c. IsSmaller(a,b)@t1 & IsSmaller(b,c)@t2
==> Ex #t3 . IsSmaller(a,c)@t3 "
*/
end