├── README.md ├── Tamarin-Tutorial-afternoon.odp ├── Tamarin-Tutorial-afternoon.pdf ├── Tamarin-Tutorial-morning.odp ├── Tamarin-Tutorial-morning.pdf ├── handouts ├── Handout-Exercise-I-II.pdf ├── Handout-Naxos.pdf └── Tamarin-basics-dependency-graphs.pdf ├── img └── by.svg └── tutorial-models ├── 1_morning ├── NAXOS_01_simple.spthy ├── NAXOS_08_eCK.spthy ├── NAXOS_15_eCK_PFS.spthy └── solutions │ ├── NAXOS_02_simple_excl1.spthy │ ├── NAXOS_03_simple_excl2.spthy │ ├── NAXOS_04_simple_excl3.spthy │ ├── NAXOS_05_simple_excl4.spthy │ ├── NAXOS_06_simple_excl5.spthy │ ├── NAXOS_07_simple_excl_h_ltk.spthy │ ├── NAXOS_09_eCK_excl1.spthy │ ├── NAXOS_10_eCK_excl2.spthy │ ├── NAXOS_11_eCK_excl3.spthy │ ├── NAXOS_12_eCK_excl4.spthy │ ├── NAXOS_13_eCK_excl5.spthy │ └── NAXOS_14_eCK_excl_h_ltk.spthy ├── 2_afternoon ├── NSLPK3.spthy ├── NSPK3.spthy ├── partial │ ├── NSLPK3-initiatorrules.txt │ ├── NSLPK3-lemmas.txt │ ├── NSLPK3-responderrules.txt │ ├── NSLPK3-setuprules.txt │ ├── NSLPK3-sourceslemma.txt │ ├── NSPK3-initiatorrules.txt │ ├── NSPK3-lemmas.txt │ ├── NSPK3-responderrules.txt │ ├── NSPK3-setuprules.txt │ └── NSPK3-sourceslemma.txt └── project.spthy ├── 3_from_slides ├── NAXOS_eCK.spthy ├── NAXOS_eCK_PFS.spthy ├── foo_eligibility.spthy ├── loop.spthy ├── sources-nolemma-load.spthy └── sources.spthy ├── 4_observational_equivalence ├── SignedDH.spthy ├── SignedDH_partiallysolved.spthy └── probEnc.spthy └── tutorial-models.zip /README.md: -------------------------------------------------------------------------------- 1 | # Teaching Materials for the Tamarin Prover 2 | 3 | This repository contains teaching materials related to the [Tamarin Prover](http://tamarin-prover.github.io/). 4 | These materials complement the official [Tamarin manual](https://tamarin-prover.github.io/manual/). 5 | 6 | ## General support 7 | 8 | ### Understanding dependency graphs (handout) 9 | 10 | The following PDF can be used as a reference handout for understanding dependency graphs. 11 | 12 | * [Handout: dependency graphs](handouts/Tamarin-basics-dependency-graphs.pdf) 13 | 14 | (Update coming with more explanation of specific adversary nodes) 15 | 16 | ## Tutorials 17 | 18 | The core Tamarin team and other contributors have developed different tutorials over time. 19 | Below you can find four tutorials. 20 | 21 | ### 1. One-day tutorial 22 | 23 | (Originally given at EuroSnP/Eurocrypt 2017) 24 | 25 | * [Morning slides PDF](Tamarin-Tutorial-morning.pdf) 26 | [(Libreoffice source file)](Tamarin-Tutorial-morning.odp) 27 | 28 | * [Afternoon slides PDF](Tamarin-Tutorial-afternoon.pdf) 29 | [(Libreoffice source file)](Tamarin-Tutorial-afternoon.odp) 30 | 31 | * [Tamarin model files](tutorial-models) 32 | [(ZIP archive version)](tutorial-models/tutorial-models.zip) 33 | 34 | * Handouts to print: 35 | * [Exercises](handouts/Handout-Exercise-I-II.pdf) 36 | * [Naxos protocol description](handouts/Handout-Naxos.pdf) 37 | * [Dependency graphs](handouts/Tamarin-basics-dependency-graphs.pdf) 38 | 39 | **Authors:** David Basin, [Cas Cremers](https://cispa.saarland/group/cremers/index.html), Jannik Dreier, and Ralf Sasse. 40 | 41 | ### 2. Toy protocol exercise 42 | 43 | - [Tamarin toy protocol exercise](https://github.com/benjaminkiesl/tamarin_toy_protocol). 44 | 45 | **Author:** Benjamin Kiesl 46 | 47 | ### 3. Tamarin workshop 48 | 49 | - [Tamarin workshop (2-4 hours)](https://github.com/felixlinker/tamarin-workshop). 50 | 51 | **Author:** Felix Linker 52 | 53 | ### 4. One-day Tamarin workshop 54 | 55 | - [Tamarin workshop](https://github.com/sgiampietro/tamarin-tutorial) given at Croatia Summer School on real-world crypto and privacy 2024. 56 | 57 | **Authors:** Alexander Dax, Sofia Giampietro, Xenia Hofmeier, Niklas Medinger, and Aurora Naska 58 | 59 | 60 | 61 | ## License 62 | 63 | All the materials in the `tamarin-prover/teaching` repository are provided under a [Creative Commons Attribution license](https://creativecommons.org/licenses/by/4.0/) (CC-BY). 64 | 65 | [CC-BY](https://creativecommons.org/licenses/by/4.0/) 66 | -------------------------------------------------------------------------------- /Tamarin-Tutorial-afternoon.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamarin-prover/teaching/e5ee58948c019e89224f5481d4720c7b30dc8387/Tamarin-Tutorial-afternoon.odp -------------------------------------------------------------------------------- /Tamarin-Tutorial-afternoon.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamarin-prover/teaching/e5ee58948c019e89224f5481d4720c7b30dc8387/Tamarin-Tutorial-afternoon.pdf -------------------------------------------------------------------------------- /Tamarin-Tutorial-morning.odp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamarin-prover/teaching/e5ee58948c019e89224f5481d4720c7b30dc8387/Tamarin-Tutorial-morning.odp -------------------------------------------------------------------------------- /Tamarin-Tutorial-morning.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamarin-prover/teaching/e5ee58948c019e89224f5481d4720c7b30dc8387/Tamarin-Tutorial-morning.pdf -------------------------------------------------------------------------------- /handouts/Handout-Exercise-I-II.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamarin-prover/teaching/e5ee58948c019e89224f5481d4720c7b30dc8387/handouts/Handout-Exercise-I-II.pdf -------------------------------------------------------------------------------- /handouts/Handout-Naxos.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamarin-prover/teaching/e5ee58948c019e89224f5481d4720c7b30dc8387/handouts/Handout-Naxos.pdf -------------------------------------------------------------------------------- /handouts/Tamarin-basics-dependency-graphs.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamarin-prover/teaching/e5ee58948c019e89224f5481d4720c7b30dc8387/handouts/Tamarin-basics-dependency-graphs.pdf -------------------------------------------------------------------------------- /img/by.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 19 | 21 | 43 | 45 | 46 | 48 | image/svg+xml 49 | 51 | 52 | 53 | 54 | 58 | 64 | 69 | 70 | 73 | 74 | 77 | 81 | 82 | 86 | 87 | 88 | 89 | 92 | 93 | 102 | 103 | 106 | 109 | 110 | 111 | 112 | 113 | 114 | 116 | 126 | 127 | 129 | 132 | 133 | 142 | 143 | 144 | 145 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/NAXOS_01_simple.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_01_simple 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: secrecy wrt adversary who can compromise other long-term keys 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* Generate long-term keypair */ 25 | rule generate_ltk: 26 | let pkA = 'g'^~lkA 27 | in 28 | [ Fr(~lkA) ] 29 | --> 30 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 31 | 32 | /* Initiator */ 33 | rule Init_1: 34 | let exI = h1(<~eskI, ~lkI >) 35 | hkI = 'g'^exI 36 | in 37 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 38 | --> 39 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 40 | , Out( hkI ) ] 41 | 42 | rule Init_2: 43 | let pkR = 'g'^~lkR 44 | exI = h1(< ~eskI, ~lkI >) 45 | kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 46 | // kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 47 | in 48 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 49 | --[ Accept( ~eskI, $I, $R, kI) ]-> 50 | [ ] 51 | 52 | /* Responder */ 53 | rule Resp_1: 54 | let pkI = 'g'^~lkI 55 | exR = h1(< ~eskR, ~lkR >) 56 | hkr = 'g'^exR 57 | kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 58 | // kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 59 | in 60 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 61 | --[ Accept( ~eskR, $R, $I, kR ) ]-> 62 | [ Out( hkr ) ] 63 | 64 | /* Key Reveals */ 65 | rule Ltk_reveal: 66 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 67 | 68 | lemma key_secrecy: 69 | /* 70 | * If A and B are honest, the adversary doesn't learn the session key 71 | */ 72 | "(All #i1 Test A B k. 73 | ( 74 | Accept(Test, A, B, k) @ i1 75 | & 76 | not ( (Ex #ia . LtkRev ( A ) @ ia ) 77 | | (Ex #ib . LtkRev ( B ) @ ib ) 78 | ) 79 | ) 80 | ==> not (Ex #i2. K( k ) @ i2 ) 81 | )" 82 | 83 | end 84 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/NAXOS_08_eCK.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_08_eCK 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: eCK security 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* In the description in the paper, we omitted the sorts. 25 | * In this description they are made explicit. 26 | * '$A' is equivalent to 'A:pub' 27 | * '~x' is equivalent to 'x:fresh' 28 | */ 29 | 30 | /* Generate long-term keypair */ 31 | rule generate_ltk: 32 | let pkA = 'g'^~lkA 33 | in 34 | [ Fr(~lkA) ] 35 | --[ RegKey($A) ]-> 36 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 37 | 38 | /* Initiator */ 39 | rule Init_1: 40 | let exI = h1(<~eskI, ~lkI >) 41 | hkI = 'g'^exI 42 | in 43 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 44 | --> 45 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 46 | , !Ephk(~eskI, ~eskI) 47 | , Out( hkI ) ] 48 | 49 | rule Init_2: 50 | let pkR = 'g'^~lkR 51 | exI = h1(< ~eskI, ~lkI >) 52 | kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 53 | in 54 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 55 | --[ Accept( ~eskI, $I, $R, kI) 56 | , Sid( ~eskI, < 'Init', $I, $R, hkI, Y >) 57 | , Match( ~eskI, < 'Resp', $R, $I, hkI, Y >) 58 | ]-> 59 | [ !Sessk( ~eskI, kI) ] 60 | 61 | /* Responder */ 62 | rule Resp_1: 63 | let pkI = 'g'^~lkI 64 | exR = h1(< ~eskR, ~lkR >) 65 | hkr = 'g'^exR 66 | kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 67 | in 68 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 69 | --[ Accept( ~eskR, $R, $I, kR ) 70 | , Sid( ~eskR, <'Resp', $R, $I, X, hkr >) 71 | , Match( ~eskR, <'Init', $I, $R, X, hkr> ) 72 | ]-> 73 | [ Out( hkr ), 74 | !Ephk(~eskR, ~eskR), 75 | !Sessk( ~eskR, kR) ] 76 | 77 | /* Key Reveals for the eCK model */ 78 | rule Sessk_reveal: 79 | [ !Sessk(~tid, k) ] --[ SesskRev(~tid) ]-> [ Out(k) ] 80 | 81 | rule Ltk_reveal: 82 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 83 | 84 | rule Ephk_reveal: 85 | [ !Ephk(~s, ~ek) ] --[ EphkRev(~s) ]-> [ Out(~ek) ] 86 | 87 | 88 | /* Security properties */ 89 | /* 90 | lemma eCK_same_key: 91 | " // If every agent registered at most one public key 92 | (All A #i #j. RegKey(A)@i & RegKey(A)@j ==> (#i = #j)) 93 | ==> // then matching sessions accept the same key 94 | (not (Ex #i1 #i2 #i3 #i4 s ss k kk A B minfo . 95 | Accept(s, A, B, k ) @ i1 96 | & Accept(ss, B, A, kk) @ i2 97 | & Sid(s, minfo) @ i3 98 | & Match(ss, minfo) @i4 99 | & not( k = kk ) 100 | ) )" 101 | */ 102 | 103 | lemma eCK_key_secrecy: 104 | /* 105 | * The property specification very closely follows the original eCK 106 | * (ProvSec) paper: 107 | * 108 | * If there exists a Test session whose key k is known to the 109 | * Adversary, then... 110 | */ 111 | "(All #i1 #i2 Test A B k. 112 | Accept(Test, A, B, k) @ i1 & K( k ) @ i2 113 | ==> ( 114 | /* ... the Test session must be "not clean". 115 | * Test is not clean if one of the following has happened: 116 | */ 117 | /* 1a. session-key-reveal of test thread. */ 118 | (Ex #i3. SesskRev( Test ) @ i3 ) 119 | 120 | /* 1b. session-key-reveal of matching session */ 121 | | (Ex MatchingSession #i3 #i4 ms. 122 | /* ( MatchingSession's 'ms' info matches with Test ) */ 123 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 124 | & ( 125 | (Ex #i5. SesskRev( MatchingSession ) @ i5 ) 126 | ) 127 | ) 128 | /* 2. If matching session exists and ... */ 129 | | (Ex MatchingSession #i3 #i4 ms. 130 | /* ( MatchingSession's 'ms' info matches with Test ) */ 131 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 132 | & ( 133 | /* 2a. reveal either both sk_A and esk_A, or */ 134 | (Ex #i5 #i6. LtkRev ( A ) @ i5 & EphkRev ( Test ) @ i6 ) 135 | /* 2b. both sk_B and esk_B */ 136 | | (Ex #i5 #i6. LtkRev ( B ) @ i5 & EphkRev ( MatchingSession ) @ i6 ) 137 | ) 138 | ) 139 | /* 3. No matching session exists and ... */ 140 | | ( ( not(Ex MatchingSession #i3 #i4 ms. 141 | /* ( MatchingSession's 'ms' info matches with Test ) */ 142 | Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4 ) ) 143 | & ( 144 | /* 3a. reveal either sk_B, or */ 145 | (Ex #i5 . LtkRev (B) @ i5 ) 146 | /* 3b. both sk_A and esk_A */ 147 | | (Ex #i5 #i6. LtkRev (A) @ i5 & EphkRev ( Test ) @ i6 ) 148 | ) 149 | ) 150 | ) 151 | )" 152 | 153 | end 154 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/NAXOS_15_eCK_PFS.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_15_eCK_PFS 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: eCK security with PFS 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* In the description in the paper, we omitted the sorts. 25 | * In this description they are made explicit. 26 | * '$A' is equivalent to 'A:pub' 27 | * '~x' is equivalent to 'x:fresh' 28 | */ 29 | 30 | /* Generate long-term keypair */ 31 | rule generate_ltk: 32 | let pkA = 'g'^~lkA 33 | in 34 | [ Fr(~lkA) ] 35 | --[ RegKey($A) ]-> 36 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 37 | 38 | /* Initiator */ 39 | rule Init_1: 40 | let exI = h1(<~eskI, ~lkI >) 41 | hkI = 'g'^exI 42 | in 43 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 44 | --> 45 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 46 | , !Ephk(~eskI, ~eskI) 47 | , Out( hkI ) ] 48 | 49 | rule Init_2: 50 | let pkR = 'g'^~lkR 51 | exI = h1(< ~eskI, ~lkI >) 52 | kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 53 | in 54 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 55 | --[ Accept( ~eskI, $I, $R, kI) 56 | , Sid( ~eskI, < 'Init', $I, $R, hkI, Y >) 57 | , Match( ~eskI, < 'Resp', $R, $I, hkI, Y >) 58 | ]-> 59 | [ !Sessk( ~eskI, kI) ] 60 | 61 | /* Responder */ 62 | rule Resp_1: 63 | let pkI = 'g'^~lkI 64 | exR = h1(< ~eskR, ~lkR >) 65 | hkr = 'g'^exR 66 | kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 67 | in 68 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 69 | --[ Accept( ~eskR, $R, $I, kR ) 70 | , Sid( ~eskR, <'Resp', $R, $I, X, hkr >) 71 | , Match( ~eskR, <'Init', $I, $R, X, hkr> ) 72 | ]-> 73 | [ Out( hkr ), 74 | !Ephk(~eskR, ~eskR), 75 | !Sessk( ~eskR, kR) ] 76 | 77 | /* Key Reveals for the eCK model */ 78 | rule Sessk_reveal: 79 | [ !Sessk(~tid, k) ] --[ SesskRev(~tid) ]-> [ Out(k) ] 80 | 81 | rule Ltk_reveal: 82 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 83 | 84 | rule Ephk_reveal: 85 | [ !Ephk(~s, ~ek) ] --[ EphkRev(~s) ]-> [ Out(~ek) ] 86 | 87 | 88 | /* Security properties */ 89 | /* 90 | lemma eCK_same_key: 91 | " // If every agent registered at most one public key 92 | (All A #i #j. RegKey(A)@i & RegKey(A)@j ==> (#i = #j)) 93 | ==> // then matching sessions accept the same key 94 | (not (Ex #i1 #i2 #i3 #i4 s ss k kk A B minfo . 95 | Accept(s, A, B, k ) @ i1 96 | & Accept(ss, B, A, kk) @ i2 97 | & Sid(s, minfo) @ i3 98 | & Match(ss, minfo) @i4 99 | & not( k = kk ) 100 | ) )" 101 | */ 102 | 103 | lemma eCK_PFS_key_secrecy: 104 | /* 105 | * The property specification very closely follows the original eCK 106 | * (ProvSec) paper: 107 | * 108 | * If there exists a Test session whose key k is known to the 109 | * Adversary, then... 110 | */ 111 | "(All #i1 #i2 Test A B k. 112 | Accept(Test, A, B, k) @ i1 & K( k ) @ i2 113 | ==> ( 114 | /* ... the Test session must be "not clean". 115 | * Test is not clean if one of the following has happened: 116 | */ 117 | /* 1a. session-key-reveal of test thread. */ 118 | (Ex #i3. SesskRev( Test ) @ i3 ) 119 | 120 | /* 1b. session-key-reveal of matching session */ 121 | | (Ex MatchingSession #i3 #i4 ms. 122 | /* ( MatchingSession's 'ms' info matches with Test ) */ 123 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 124 | & ( 125 | (Ex #i5. SesskRev( MatchingSession ) @ i5 ) 126 | ) 127 | ) 128 | /* 2. If matching session exists and ... */ 129 | | (Ex MatchingSession #i3 #i4 ms. 130 | /* ( MatchingSession's 'ms' info matches with Test ) */ 131 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 132 | & ( 133 | /* 2a. reveal either both sk_A and esk_A, or */ 134 | (Ex #i5 #i6. LtkRev ( A ) @ i5 & EphkRev ( Test ) @ i6 ) 135 | /* 2b. both sk_B and esk_B */ 136 | | (Ex #i5 #i6. LtkRev ( B ) @ i5 & EphkRev ( MatchingSession ) @ i6 ) 137 | ) 138 | ) 139 | /* 3. No matching session exists and ... */ 140 | | ( ( not(Ex MatchingSession #i3 #i4 ms. 141 | /* ( MatchingSession's 'ms' info matches with Test ) */ 142 | Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4 ) ) 143 | & ( 144 | /* 3a. reveal either sk_B, or */ 145 | (Ex #i5 . LtkRev (B) @ i5 & i5 < i1 ) /* Perfect Forward Secrecy (PFS) modification */ 146 | /* 3b. both sk_A and esk_A */ 147 | | (Ex #i5 #i6. LtkRev (A) @ i5 & EphkRev ( Test ) @ i6 ) 148 | ) 149 | ) 150 | ) 151 | )" 152 | 153 | end 154 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/solutions/NAXOS_02_simple_excl1.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_02_simple_excl1 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: secrecy wrt adversary who can compromise other long-term keys 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* Generate long-term keypair */ 25 | rule generate_ltk: 26 | let pkA = 'g'^~lkA 27 | in 28 | [ Fr(~lkA) ] 29 | --> 30 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 31 | 32 | /* Initiator */ 33 | rule Init_1: 34 | let exI = h1(<~eskI, ~lkI >) 35 | hkI = 'g'^exI 36 | in 37 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 38 | --> 39 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 40 | , Out( hkI ) ] 41 | 42 | rule Init_2: 43 | let pkR = 'g'^~lkR 44 | exI = h1(< ~eskI, ~lkI >) 45 | kI = h2(< pkR^exI, Y^exI, $I, $R >) 46 | // kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 47 | in 48 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 49 | --[ Accept( ~eskI, $I, $R, kI) ]-> 50 | [ ] 51 | 52 | /* Responder */ 53 | rule Resp_1: 54 | let pkI = 'g'^~lkI 55 | exR = h1(< ~eskR, ~lkR >) 56 | hkr = 'g'^exR 57 | kR = h2(< X^~lkR, X^exR, $I, $R >) 58 | // kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 59 | in 60 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 61 | --[ Accept( ~eskR, $R, $I, kR ) ]-> 62 | [ Out( hkr ) ] 63 | 64 | /* Key Reveals */ 65 | rule Ltk_reveal: 66 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 67 | 68 | lemma key_secrecy: 69 | /* 70 | * If A and B are honest, the adversary doesn't learn the session key 71 | */ 72 | "(All #i1 Test A B k. 73 | ( 74 | Accept(Test, A, B, k) @ i1 75 | & 76 | not ( (Ex #ia . LtkRev ( A ) @ ia ) 77 | | (Ex #ib . LtkRev ( B ) @ ib ) 78 | ) 79 | ) 80 | ==> not (Ex #i2. K( k ) @ i2 ) 81 | )" 82 | 83 | end 84 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/solutions/NAXOS_03_simple_excl2.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_03_simple_excl2 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: secrecy wrt adversary who can compromise other long-term keys 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* Generate long-term keypair */ 25 | rule generate_ltk: 26 | let pkA = 'g'^~lkA 27 | in 28 | [ Fr(~lkA) ] 29 | --> 30 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 31 | 32 | /* Initiator */ 33 | rule Init_1: 34 | let exI = h1(<~eskI, ~lkI >) 35 | hkI = 'g'^exI 36 | in 37 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 38 | --> 39 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 40 | , Out( hkI ) ] 41 | 42 | rule Init_2: 43 | let pkR = 'g'^~lkR 44 | exI = h1(< ~eskI, ~lkI >) 45 | kI = h2(< Y^~lkI, Y^exI, $I, $R >) 46 | // kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 47 | in 48 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 49 | --[ Accept( ~eskI, $I, $R, kI) ]-> 50 | [ ] 51 | 52 | /* Responder */ 53 | rule Resp_1: 54 | let pkI = 'g'^~lkI 55 | exR = h1(< ~eskR, ~lkR >) 56 | hkr = 'g'^exR 57 | kR = h2(< pkI^exR, X^exR, $I, $R >) 58 | // kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 59 | in 60 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 61 | --[ Accept( ~eskR, $R, $I, kR ) ]-> 62 | [ Out( hkr ) ] 63 | 64 | /* Key Reveals */ 65 | rule Ltk_reveal: 66 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 67 | 68 | lemma key_secrecy: 69 | /* 70 | * If A and B are honest, the adversary doesn't learn the session key 71 | */ 72 | "(All #i1 Test A B k. 73 | ( 74 | Accept(Test, A, B, k) @ i1 75 | & 76 | not ( (Ex #ia . LtkRev ( A ) @ ia ) 77 | | (Ex #ib . LtkRev ( B ) @ ib ) 78 | ) 79 | ) 80 | ==> not (Ex #i2. K( k ) @ i2 ) 81 | )" 82 | 83 | end 84 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/solutions/NAXOS_04_simple_excl3.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_04_simple_excl3 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: secrecy wrt adversary who can compromise other long-term keys 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* Generate long-term keypair */ 25 | rule generate_ltk: 26 | let pkA = 'g'^~lkA 27 | in 28 | [ Fr(~lkA) ] 29 | --> 30 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 31 | 32 | /* Initiator */ 33 | rule Init_1: 34 | let exI = h1(<~eskI, ~lkI >) 35 | hkI = 'g'^exI 36 | in 37 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 38 | --> 39 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 40 | , Out( hkI ) ] 41 | 42 | rule Init_2: 43 | let pkR = 'g'^~lkR 44 | exI = h1(< ~eskI, ~lkI >) 45 | kI = h2(< Y^~lkI, pkR^exI, $I, $R >) 46 | // kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 47 | in 48 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 49 | --[ Accept( ~eskI, $I, $R, kI) ]-> 50 | [ ] 51 | 52 | /* Responder */ 53 | rule Resp_1: 54 | let pkI = 'g'^~lkI 55 | exR = h1(< ~eskR, ~lkR >) 56 | hkr = 'g'^exR 57 | kR = h2(< pkI^exR, X^~lkR, $I, $R >) 58 | // kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 59 | in 60 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 61 | --[ Accept( ~eskR, $R, $I, kR ) ]-> 62 | [ Out( hkr ) ] 63 | 64 | /* Key Reveals */ 65 | rule Ltk_reveal: 66 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 67 | 68 | lemma key_secrecy: 69 | /* 70 | * If A and B are honest, the adversary doesn't learn the session key 71 | */ 72 | "(All #i1 Test A B k. 73 | ( 74 | Accept(Test, A, B, k) @ i1 75 | & 76 | not ( (Ex #ia . LtkRev ( A ) @ ia ) 77 | | (Ex #ib . LtkRev ( B ) @ ib ) 78 | ) 79 | ) 80 | ==> not (Ex #i2. K( k ) @ i2 ) 81 | )" 82 | 83 | end 84 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/solutions/NAXOS_05_simple_excl4.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_05_simple_excl4 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: secrecy wrt adversary who can compromise other long-term keys 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* Generate long-term keypair */ 25 | rule generate_ltk: 26 | let pkA = 'g'^~lkA 27 | in 28 | [ Fr(~lkA) ] 29 | --> 30 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 31 | 32 | /* Initiator */ 33 | rule Init_1: 34 | let exI = h1(<~eskI, ~lkI >) 35 | hkI = 'g'^exI 36 | in 37 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 38 | --> 39 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 40 | , Out( hkI ) ] 41 | 42 | rule Init_2: 43 | let pkR = 'g'^~lkR 44 | exI = h1(< ~eskI, ~lkI >) 45 | kI = h2(< Y^~lkI, pkR^exI, Y^exI, $R >) 46 | // kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 47 | in 48 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 49 | --[ Accept( ~eskI, $I, $R, kI) ]-> 50 | [ ] 51 | 52 | /* Responder */ 53 | rule Resp_1: 54 | let pkI = 'g'^~lkI 55 | exR = h1(< ~eskR, ~lkR >) 56 | hkr = 'g'^exR 57 | kR = h2(< pkI^exR, X^~lkR, X^exR, $R >) 58 | // kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 59 | in 60 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 61 | --[ Accept( ~eskR, $R, $I, kR ) ]-> 62 | [ Out( hkr ) ] 63 | 64 | /* Key Reveals */ 65 | rule Ltk_reveal: 66 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 67 | 68 | lemma key_secrecy: 69 | /* 70 | * If A and B are honest, the adversary doesn't learn the session key 71 | */ 72 | "(All #i1 Test A B k. 73 | ( 74 | Accept(Test, A, B, k) @ i1 75 | & 76 | not ( (Ex #ia . LtkRev ( A ) @ ia ) 77 | | (Ex #ib . LtkRev ( B ) @ ib ) 78 | ) 79 | ) 80 | ==> not (Ex #i2. K( k ) @ i2 ) 81 | )" 82 | 83 | end 84 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/solutions/NAXOS_06_simple_excl5.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_06_simple_excl5 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: secrecy wrt adversary who can compromise other long-term keys 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* Generate long-term keypair */ 25 | rule generate_ltk: 26 | let pkA = 'g'^~lkA 27 | in 28 | [ Fr(~lkA) ] 29 | --> 30 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 31 | 32 | /* Initiator */ 33 | rule Init_1: 34 | let exI = h1(<~eskI, ~lkI >) 35 | hkI = 'g'^exI 36 | in 37 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 38 | --> 39 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 40 | , Out( hkI ) ] 41 | 42 | rule Init_2: 43 | let pkR = 'g'^~lkR 44 | exI = h1(< ~eskI, ~lkI >) 45 | kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I >) 46 | // kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 47 | in 48 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 49 | --[ Accept( ~eskI, $I, $R, kI) ]-> 50 | [ ] 51 | 52 | /* Responder */ 53 | rule Resp_1: 54 | let pkI = 'g'^~lkI 55 | exR = h1(< ~eskR, ~lkR >) 56 | hkr = 'g'^exR 57 | kR = h2(< pkI^exR, X^~lkR, X^exR, $I >) 58 | // kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 59 | in 60 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 61 | --[ Accept( ~eskR, $R, $I, kR ) ]-> 62 | [ Out( hkr ) ] 63 | 64 | /* Key Reveals */ 65 | rule Ltk_reveal: 66 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 67 | 68 | lemma key_secrecy: 69 | /* 70 | * If A and B are honest, the adversary doesn't learn the session key 71 | */ 72 | "(All #i1 Test A B k. 73 | ( 74 | Accept(Test, A, B, k) @ i1 75 | & 76 | not ( (Ex #ia . LtkRev ( A ) @ ia ) 77 | | (Ex #ib . LtkRev ( B ) @ ib ) 78 | ) 79 | ) 80 | ==> not (Ex #i2. K( k ) @ i2 ) 81 | )" 82 | 83 | end 84 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/solutions/NAXOS_07_simple_excl_h_ltk.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_07_simple_excluding_ltk_in_h1 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: secrecy wrt adversary who can compromise other long-term keys 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* Generate long-term keypair */ 25 | rule generate_ltk: 26 | let pkA = 'g'^~lkA 27 | in 28 | [ Fr(~lkA) ] 29 | --> 30 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 31 | 32 | /* Initiator */ 33 | rule Init_1: 34 | let exI = h1( ~eskI ) 35 | hkI = 'g'^exI 36 | in 37 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 38 | --> 39 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 40 | , Out( hkI ) ] 41 | 42 | rule Init_2: 43 | let pkR = 'g'^~lkR 44 | exI = h1( ~eskI ) 45 | kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 46 | // kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 47 | in 48 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 49 | --[ Accept( ~eskI, $I, $R, kI) ]-> 50 | [ ] 51 | 52 | /* Responder */ 53 | rule Resp_1: 54 | let pkI = 'g'^~lkI 55 | exR = h1( ~eskR ) 56 | hkr = 'g'^exR 57 | kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 58 | // kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 59 | in 60 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 61 | --[ Accept( ~eskR, $R, $I, kR ) ]-> 62 | [ Out( hkr ) ] 63 | 64 | /* Key Reveals */ 65 | rule Ltk_reveal: 66 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 67 | 68 | lemma key_secrecy: 69 | /* 70 | * If A and B are honest, the adversary doesn't learn the session key 71 | */ 72 | "(All #i1 Test A B k. 73 | ( 74 | Accept(Test, A, B, k) @ i1 75 | & 76 | not ( (Ex #ia . LtkRev ( A ) @ ia ) 77 | | (Ex #ib . LtkRev ( B ) @ ib ) 78 | ) 79 | ) 80 | ==> not (Ex #i2. K( k ) @ i2 ) 81 | )" 82 | 83 | end 84 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/solutions/NAXOS_09_eCK_excl1.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_09_eCK_excl1 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: eCK security 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* In the description in the paper, we omitted the sorts. 25 | * In this description they are made explicit. 26 | * '$A' is equivalent to 'A:pub' 27 | * '~x' is equivalent to 'x:fresh' 28 | */ 29 | 30 | /* Generate long-term keypair */ 31 | rule generate_ltk: 32 | let pkA = 'g'^~lkA 33 | in 34 | [ Fr(~lkA) ] 35 | --[ RegKey($A) ]-> 36 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 37 | 38 | /* Initiator */ 39 | rule Init_1: 40 | let exI = h1(<~eskI, ~lkI >) 41 | hkI = 'g'^exI 42 | in 43 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 44 | --> 45 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 46 | , !Ephk(~eskI, ~eskI) 47 | , Out( hkI ) ] 48 | 49 | rule Init_2: 50 | let pkR = 'g'^~lkR 51 | exI = h1(< ~eskI, ~lkI >) 52 | kI = h2(< pkR^exI, Y^exI, $I, $R >) 53 | // kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 54 | in 55 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 56 | --[ Accept( ~eskI, $I, $R, kI) 57 | , Sid( ~eskI, < 'Init', $I, $R, hkI, Y >) 58 | , Match( ~eskI, < 'Resp', $R, $I, hkI, Y >) 59 | ]-> 60 | [ !Sessk( ~eskI, kI) ] 61 | 62 | /* Responder */ 63 | rule Resp_1: 64 | let pkI = 'g'^~lkI 65 | exR = h1(< ~eskR, ~lkR >) 66 | hkr = 'g'^exR 67 | kR = h2(< X^~lkR, X^exR, $I, $R >) 68 | // kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 69 | in 70 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 71 | --[ Accept( ~eskR, $R, $I, kR ) 72 | , Sid( ~eskR, <'Resp', $R, $I, X, hkr >) 73 | , Match( ~eskR, <'Init', $I, $R, X, hkr> ) 74 | ]-> 75 | [ Out( hkr ), 76 | !Ephk(~eskR, ~eskR), 77 | !Sessk( ~eskR, kR) ] 78 | 79 | /* Key Reveals for the eCK model */ 80 | rule Sessk_reveal: 81 | [ !Sessk(~tid, k) ] --[ SesskRev(~tid) ]-> [ Out(k) ] 82 | 83 | rule Ltk_reveal: 84 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 85 | 86 | rule Ephk_reveal: 87 | [ !Ephk(~s, ~ek) ] --[ EphkRev(~s) ]-> [ Out(~ek) ] 88 | 89 | 90 | /* Security properties */ 91 | /* 92 | lemma eCK_same_key: 93 | " // If every agent registered at most one public key 94 | (All A #i #j. RegKey(A)@i & RegKey(A)@j ==> (#i = #j)) 95 | ==> // then matching sessions accept the same key 96 | (not (Ex #i1 #i2 #i3 #i4 s ss k kk A B minfo . 97 | Accept(s, A, B, k ) @ i1 98 | & Accept(ss, B, A, kk) @ i2 99 | & Sid(s, minfo) @ i3 100 | & Match(ss, minfo) @i4 101 | & not( k = kk ) 102 | ) )" 103 | */ 104 | 105 | lemma eCK_key_secrecy: 106 | /* 107 | * The property specification very closely follows the original eCK 108 | * (ProvSec) paper: 109 | * 110 | * If there exists a Test session whose key k is known to the 111 | * Adversary, then... 112 | */ 113 | "(All #i1 #i2 Test A B k. 114 | Accept(Test, A, B, k) @ i1 & K( k ) @ i2 115 | ==> ( 116 | /* ... the Test session must be "not clean". 117 | * Test is not clean if one of the following has happened: 118 | */ 119 | /* 1a. session-key-reveal of test thread. */ 120 | (Ex #i3. SesskRev( Test ) @ i3 ) 121 | 122 | /* 1b. session-key-reveal of matching session */ 123 | | (Ex MatchingSession #i3 #i4 ms. 124 | /* ( MatchingSession's 'ms' info matches with Test ) */ 125 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 126 | & ( 127 | (Ex #i5. SesskRev( MatchingSession ) @ i5 ) 128 | ) 129 | ) 130 | /* 2. If matching session exists and ... */ 131 | | (Ex MatchingSession #i3 #i4 ms. 132 | /* ( MatchingSession's 'ms' info matches with Test ) */ 133 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 134 | & ( 135 | /* 2a. reveal either both sk_A and esk_A, or */ 136 | (Ex #i5 #i6. LtkRev ( A ) @ i5 & EphkRev ( Test ) @ i6 ) 137 | /* 2b. both sk_B and esk_B */ 138 | | (Ex #i5 #i6. LtkRev ( B ) @ i5 & EphkRev ( MatchingSession ) @ i6 ) 139 | ) 140 | ) 141 | /* 3. No matching session exists and ... */ 142 | | ( ( not(Ex MatchingSession #i3 #i4 ms. 143 | /* ( MatchingSession's 'ms' info matches with Test ) */ 144 | Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4 ) ) 145 | & ( 146 | /* 3a. reveal either sk_B, or */ 147 | (Ex #i5 . LtkRev (B) @ i5 ) 148 | /* 3b. both sk_A and esk_A */ 149 | | (Ex #i5 #i6. LtkRev (A) @ i5 & EphkRev ( Test ) @ i6 ) 150 | ) 151 | ) 152 | ) 153 | )" 154 | 155 | end 156 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/solutions/NAXOS_10_eCK_excl2.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_10_eCK_excl2 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: eCK security 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* In the description in the paper, we omitted the sorts. 25 | * In this description they are made explicit. 26 | * '$A' is equivalent to 'A:pub' 27 | * '~x' is equivalent to 'x:fresh' 28 | */ 29 | 30 | /* Generate long-term keypair */ 31 | rule generate_ltk: 32 | let pkA = 'g'^~lkA 33 | in 34 | [ Fr(~lkA) ] 35 | --[ RegKey($A) ]-> 36 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 37 | 38 | /* Initiator */ 39 | rule Init_1: 40 | let exI = h1(<~eskI, ~lkI >) 41 | hkI = 'g'^exI 42 | in 43 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 44 | --> 45 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 46 | , !Ephk(~eskI, ~eskI) 47 | , Out( hkI ) ] 48 | 49 | rule Init_2: 50 | let pkR = 'g'^~lkR 51 | exI = h1(< ~eskI, ~lkI >) 52 | kI = h2(< Y^~lkI, Y^exI, $I, $R >) 53 | // kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 54 | in 55 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 56 | --[ Accept( ~eskI, $I, $R, kI) 57 | , Sid( ~eskI, < 'Init', $I, $R, hkI, Y >) 58 | , Match( ~eskI, < 'Resp', $R, $I, hkI, Y >) 59 | ]-> 60 | [ !Sessk( ~eskI, kI) ] 61 | 62 | /* Responder */ 63 | rule Resp_1: 64 | let pkI = 'g'^~lkI 65 | exR = h1(< ~eskR, ~lkR >) 66 | hkr = 'g'^exR 67 | kR = h2(< pkI^exR, X^exR, $I, $R >) 68 | // kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 69 | in 70 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 71 | --[ Accept( ~eskR, $R, $I, kR ) 72 | , Sid( ~eskR, <'Resp', $R, $I, X, hkr >) 73 | , Match( ~eskR, <'Init', $I, $R, X, hkr> ) 74 | ]-> 75 | [ Out( hkr ), 76 | !Ephk(~eskR, ~eskR), 77 | !Sessk( ~eskR, kR) ] 78 | 79 | /* Key Reveals for the eCK model */ 80 | rule Sessk_reveal: 81 | [ !Sessk(~tid, k) ] --[ SesskRev(~tid) ]-> [ Out(k) ] 82 | 83 | rule Ltk_reveal: 84 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 85 | 86 | rule Ephk_reveal: 87 | [ !Ephk(~s, ~ek) ] --[ EphkRev(~s) ]-> [ Out(~ek) ] 88 | 89 | 90 | /* Security properties */ 91 | /* 92 | lemma eCK_same_key: 93 | " // If every agent registered at most one public key 94 | (All A #i #j. RegKey(A)@i & RegKey(A)@j ==> (#i = #j)) 95 | ==> // then matching sessions accept the same key 96 | (not (Ex #i1 #i2 #i3 #i4 s ss k kk A B minfo . 97 | Accept(s, A, B, k ) @ i1 98 | & Accept(ss, B, A, kk) @ i2 99 | & Sid(s, minfo) @ i3 100 | & Match(ss, minfo) @i4 101 | & not( k = kk ) 102 | ) )" 103 | */ 104 | 105 | lemma eCK_key_secrecy: 106 | /* 107 | * The property specification very closely follows the original eCK 108 | * (ProvSec) paper: 109 | * 110 | * If there exists a Test session whose key k is known to the 111 | * Adversary, then... 112 | */ 113 | "(All #i1 #i2 Test A B k. 114 | Accept(Test, A, B, k) @ i1 & K( k ) @ i2 115 | ==> ( 116 | /* ... the Test session must be "not clean". 117 | * Test is not clean if one of the following has happened: 118 | */ 119 | /* 1a. session-key-reveal of test thread. */ 120 | (Ex #i3. SesskRev( Test ) @ i3 ) 121 | 122 | /* 1b. session-key-reveal of matching session */ 123 | | (Ex MatchingSession #i3 #i4 ms. 124 | /* ( MatchingSession's 'ms' info matches with Test ) */ 125 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 126 | & ( 127 | (Ex #i5. SesskRev( MatchingSession ) @ i5 ) 128 | ) 129 | ) 130 | /* 2. If matching session exists and ... */ 131 | | (Ex MatchingSession #i3 #i4 ms. 132 | /* ( MatchingSession's 'ms' info matches with Test ) */ 133 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 134 | & ( 135 | /* 2a. reveal either both sk_A and esk_A, or */ 136 | (Ex #i5 #i6. LtkRev ( A ) @ i5 & EphkRev ( Test ) @ i6 ) 137 | /* 2b. both sk_B and esk_B */ 138 | | (Ex #i5 #i6. LtkRev ( B ) @ i5 & EphkRev ( MatchingSession ) @ i6 ) 139 | ) 140 | ) 141 | /* 3. No matching session exists and ... */ 142 | | ( ( not(Ex MatchingSession #i3 #i4 ms. 143 | /* ( MatchingSession's 'ms' info matches with Test ) */ 144 | Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4 ) ) 145 | & ( 146 | /* 3a. reveal either sk_B, or */ 147 | (Ex #i5 . LtkRev (B) @ i5 ) 148 | /* 3b. both sk_A and esk_A */ 149 | | (Ex #i5 #i6. LtkRev (A) @ i5 & EphkRev ( Test ) @ i6 ) 150 | ) 151 | ) 152 | ) 153 | )" 154 | 155 | end 156 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/solutions/NAXOS_11_eCK_excl3.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_11_eCK_excl3 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: eCK security 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* In the description in the paper, we omitted the sorts. 25 | * In this description they are made explicit. 26 | * '$A' is equivalent to 'A:pub' 27 | * '~x' is equivalent to 'x:fresh' 28 | */ 29 | 30 | /* Generate long-term keypair */ 31 | rule generate_ltk: 32 | let pkA = 'g'^~lkA 33 | in 34 | [ Fr(~lkA) ] 35 | --[ RegKey($A) ]-> 36 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 37 | 38 | /* Initiator */ 39 | rule Init_1: 40 | let exI = h1(<~eskI, ~lkI >) 41 | hkI = 'g'^exI 42 | in 43 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 44 | --> 45 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 46 | , !Ephk(~eskI, ~eskI) 47 | , Out( hkI ) ] 48 | 49 | rule Init_2: 50 | let pkR = 'g'^~lkR 51 | exI = h1(< ~eskI, ~lkI >) 52 | kI = h2(< Y^~lkI, pkR^exI, $I, $R >) 53 | // kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 54 | in 55 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 56 | --[ Accept( ~eskI, $I, $R, kI) 57 | , Sid( ~eskI, < 'Init', $I, $R, hkI, Y >) 58 | , Match( ~eskI, < 'Resp', $R, $I, hkI, Y >) 59 | ]-> 60 | [ !Sessk( ~eskI, kI) ] 61 | 62 | /* Responder */ 63 | rule Resp_1: 64 | let pkI = 'g'^~lkI 65 | exR = h1(< ~eskR, ~lkR >) 66 | hkr = 'g'^exR 67 | kR = h2(< pkI^exR, X^~lkR, $I, $R >) 68 | // kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 69 | in 70 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 71 | --[ Accept( ~eskR, $R, $I, kR ) 72 | , Sid( ~eskR, <'Resp', $R, $I, X, hkr >) 73 | , Match( ~eskR, <'Init', $I, $R, X, hkr> ) 74 | ]-> 75 | [ Out( hkr ), 76 | !Ephk(~eskR, ~eskR), 77 | !Sessk( ~eskR, kR) ] 78 | 79 | /* Key Reveals for the eCK model */ 80 | rule Sessk_reveal: 81 | [ !Sessk(~tid, k) ] --[ SesskRev(~tid) ]-> [ Out(k) ] 82 | 83 | rule Ltk_reveal: 84 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 85 | 86 | rule Ephk_reveal: 87 | [ !Ephk(~s, ~ek) ] --[ EphkRev(~s) ]-> [ Out(~ek) ] 88 | 89 | 90 | /* Security properties */ 91 | /* 92 | lemma eCK_same_key: 93 | " // If every agent registered at most one public key 94 | (All A #i #j. RegKey(A)@i & RegKey(A)@j ==> (#i = #j)) 95 | ==> // then matching sessions accept the same key 96 | (not (Ex #i1 #i2 #i3 #i4 s ss k kk A B minfo . 97 | Accept(s, A, B, k ) @ i1 98 | & Accept(ss, B, A, kk) @ i2 99 | & Sid(s, minfo) @ i3 100 | & Match(ss, minfo) @i4 101 | & not( k = kk ) 102 | ) )" 103 | */ 104 | 105 | lemma eCK_key_secrecy: 106 | /* 107 | * The property specification very closely follows the original eCK 108 | * (ProvSec) paper: 109 | * 110 | * If there exists a Test session whose key k is known to the 111 | * Adversary, then... 112 | */ 113 | "(All #i1 #i2 Test A B k. 114 | Accept(Test, A, B, k) @ i1 & K( k ) @ i2 115 | ==> ( 116 | /* ... the Test session must be "not clean". 117 | * Test is not clean if one of the following has happened: 118 | */ 119 | /* 1a. session-key-reveal of test thread. */ 120 | (Ex #i3. SesskRev( Test ) @ i3 ) 121 | 122 | /* 1b. session-key-reveal of matching session */ 123 | | (Ex MatchingSession #i3 #i4 ms. 124 | /* ( MatchingSession's 'ms' info matches with Test ) */ 125 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 126 | & ( 127 | (Ex #i5. SesskRev( MatchingSession ) @ i5 ) 128 | ) 129 | ) 130 | /* 2. If matching session exists and ... */ 131 | | (Ex MatchingSession #i3 #i4 ms. 132 | /* ( MatchingSession's 'ms' info matches with Test ) */ 133 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 134 | & ( 135 | /* 2a. reveal either both sk_A and esk_A, or */ 136 | (Ex #i5 #i6. LtkRev ( A ) @ i5 & EphkRev ( Test ) @ i6 ) 137 | /* 2b. both sk_B and esk_B */ 138 | | (Ex #i5 #i6. LtkRev ( B ) @ i5 & EphkRev ( MatchingSession ) @ i6 ) 139 | ) 140 | ) 141 | /* 3. No matching session exists and ... */ 142 | | ( ( not(Ex MatchingSession #i3 #i4 ms. 143 | /* ( MatchingSession's 'ms' info matches with Test ) */ 144 | Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4 ) ) 145 | & ( 146 | /* 3a. reveal either sk_B, or */ 147 | (Ex #i5 . LtkRev (B) @ i5 ) 148 | /* 3b. both sk_A and esk_A */ 149 | | (Ex #i5 #i6. LtkRev (A) @ i5 & EphkRev ( Test ) @ i6 ) 150 | ) 151 | ) 152 | ) 153 | )" 154 | 155 | end 156 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/solutions/NAXOS_12_eCK_excl4.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_12_eCK_excl4 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: eCK security 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* In the description in the paper, we omitted the sorts. 25 | * In this description they are made explicit. 26 | * '$A' is equivalent to 'A:pub' 27 | * '~x' is equivalent to 'x:fresh' 28 | */ 29 | 30 | /* Generate long-term keypair */ 31 | rule generate_ltk: 32 | let pkA = 'g'^~lkA 33 | in 34 | [ Fr(~lkA) ] 35 | --[ RegKey($A) ]-> 36 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 37 | 38 | /* Initiator */ 39 | rule Init_1: 40 | let exI = h1(<~eskI, ~lkI >) 41 | hkI = 'g'^exI 42 | in 43 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 44 | --> 45 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 46 | , !Ephk(~eskI, ~eskI) 47 | , Out( hkI ) ] 48 | 49 | rule Init_2: 50 | let pkR = 'g'^~lkR 51 | exI = h1(< ~eskI, ~lkI >) 52 | kI = h2(< Y^~lkI, pkR^exI, Y^exI, $R >) 53 | // kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 54 | in 55 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 56 | --[ Accept( ~eskI, $I, $R, kI) 57 | , Sid( ~eskI, < 'Init', $I, $R, hkI, Y >) 58 | , Match( ~eskI, < 'Resp', $R, $I, hkI, Y >) 59 | ]-> 60 | [ !Sessk( ~eskI, kI) ] 61 | 62 | /* Responder */ 63 | rule Resp_1: 64 | let pkI = 'g'^~lkI 65 | exR = h1(< ~eskR, ~lkR >) 66 | hkr = 'g'^exR 67 | kR = h2(< pkI^exR, X^~lkR, X^exR, $R >) 68 | // kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 69 | in 70 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 71 | --[ Accept( ~eskR, $R, $I, kR ) 72 | , Sid( ~eskR, <'Resp', $R, $I, X, hkr >) 73 | , Match( ~eskR, <'Init', $I, $R, X, hkr> ) 74 | ]-> 75 | [ Out( hkr ), 76 | !Ephk(~eskR, ~eskR), 77 | !Sessk( ~eskR, kR) ] 78 | 79 | /* Key Reveals for the eCK model */ 80 | rule Sessk_reveal: 81 | [ !Sessk(~tid, k) ] --[ SesskRev(~tid) ]-> [ Out(k) ] 82 | 83 | rule Ltk_reveal: 84 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 85 | 86 | rule Ephk_reveal: 87 | [ !Ephk(~s, ~ek) ] --[ EphkRev(~s) ]-> [ Out(~ek) ] 88 | 89 | 90 | /* Security properties */ 91 | /* 92 | lemma eCK_same_key: 93 | " // If every agent registered at most one public key 94 | (All A #i #j. RegKey(A)@i & RegKey(A)@j ==> (#i = #j)) 95 | ==> // then matching sessions accept the same key 96 | (not (Ex #i1 #i2 #i3 #i4 s ss k kk A B minfo . 97 | Accept(s, A, B, k ) @ i1 98 | & Accept(ss, B, A, kk) @ i2 99 | & Sid(s, minfo) @ i3 100 | & Match(ss, minfo) @i4 101 | & not( k = kk ) 102 | ) )" 103 | */ 104 | 105 | lemma eCK_key_secrecy: 106 | /* 107 | * The property specification very closely follows the original eCK 108 | * (ProvSec) paper: 109 | * 110 | * If there exists a Test session whose key k is known to the 111 | * Adversary, then... 112 | */ 113 | "(All #i1 #i2 Test A B k. 114 | Accept(Test, A, B, k) @ i1 & K( k ) @ i2 115 | ==> ( 116 | /* ... the Test session must be "not clean". 117 | * Test is not clean if one of the following has happened: 118 | */ 119 | /* 1a. session-key-reveal of test thread. */ 120 | (Ex #i3. SesskRev( Test ) @ i3 ) 121 | 122 | /* 1b. session-key-reveal of matching session */ 123 | | (Ex MatchingSession #i3 #i4 ms. 124 | /* ( MatchingSession's 'ms' info matches with Test ) */ 125 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 126 | & ( 127 | (Ex #i5. SesskRev( MatchingSession ) @ i5 ) 128 | ) 129 | ) 130 | /* 2. If matching session exists and ... */ 131 | | (Ex MatchingSession #i3 #i4 ms. 132 | /* ( MatchingSession's 'ms' info matches with Test ) */ 133 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 134 | & ( 135 | /* 2a. reveal either both sk_A and esk_A, or */ 136 | (Ex #i5 #i6. LtkRev ( A ) @ i5 & EphkRev ( Test ) @ i6 ) 137 | /* 2b. both sk_B and esk_B */ 138 | | (Ex #i5 #i6. LtkRev ( B ) @ i5 & EphkRev ( MatchingSession ) @ i6 ) 139 | ) 140 | ) 141 | /* 3. No matching session exists and ... */ 142 | | ( ( not(Ex MatchingSession #i3 #i4 ms. 143 | /* ( MatchingSession's 'ms' info matches with Test ) */ 144 | Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4 ) ) 145 | & ( 146 | /* 3a. reveal either sk_B, or */ 147 | (Ex #i5 . LtkRev (B) @ i5 ) 148 | /* 3b. both sk_A and esk_A */ 149 | | (Ex #i5 #i6. LtkRev (A) @ i5 & EphkRev ( Test ) @ i6 ) 150 | ) 151 | ) 152 | ) 153 | )" 154 | 155 | end 156 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/solutions/NAXOS_13_eCK_excl5.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_13_eCK_excl5 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: eCK security 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* In the description in the paper, we omitted the sorts. 25 | * In this description they are made explicit. 26 | * '$A' is equivalent to 'A:pub' 27 | * '~x' is equivalent to 'x:fresh' 28 | */ 29 | 30 | /* Generate long-term keypair */ 31 | rule generate_ltk: 32 | let pkA = 'g'^~lkA 33 | in 34 | [ Fr(~lkA) ] 35 | --[ RegKey($A) ]-> 36 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 37 | 38 | /* Initiator */ 39 | rule Init_1: 40 | let exI = h1(<~eskI, ~lkI >) 41 | hkI = 'g'^exI 42 | in 43 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 44 | --> 45 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 46 | , !Ephk(~eskI, ~eskI) 47 | , Out( hkI ) ] 48 | 49 | rule Init_2: 50 | let pkR = 'g'^~lkR 51 | exI = h1(< ~eskI, ~lkI >) 52 | kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I >) 53 | // kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 54 | in 55 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 56 | --[ Accept( ~eskI, $I, $R, kI) 57 | , Sid( ~eskI, < 'Init', $I, $R, hkI, Y >) 58 | , Match( ~eskI, < 'Resp', $R, $I, hkI, Y >) 59 | ]-> 60 | [ !Sessk( ~eskI, kI) ] 61 | 62 | /* Responder */ 63 | rule Resp_1: 64 | let pkI = 'g'^~lkI 65 | exR = h1(< ~eskR, ~lkR >) 66 | hkr = 'g'^exR 67 | kR = h2(< pkI^exR, X^~lkR, X^exR, $I >) 68 | // kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 69 | in 70 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 71 | --[ Accept( ~eskR, $R, $I, kR ) 72 | , Sid( ~eskR, <'Resp', $R, $I, X, hkr >) 73 | , Match( ~eskR, <'Init', $I, $R, X, hkr> ) 74 | ]-> 75 | [ Out( hkr ), 76 | !Ephk(~eskR, ~eskR), 77 | !Sessk( ~eskR, kR) ] 78 | 79 | /* Key Reveals for the eCK model */ 80 | rule Sessk_reveal: 81 | [ !Sessk(~tid, k) ] --[ SesskRev(~tid) ]-> [ Out(k) ] 82 | 83 | rule Ltk_reveal: 84 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 85 | 86 | rule Ephk_reveal: 87 | [ !Ephk(~s, ~ek) ] --[ EphkRev(~s) ]-> [ Out(~ek) ] 88 | 89 | 90 | /* Security properties */ 91 | /* 92 | lemma eCK_same_key: 93 | " // If every agent registered at most one public key 94 | (All A #i #j. RegKey(A)@i & RegKey(A)@j ==> (#i = #j)) 95 | ==> // then matching sessions accept the same key 96 | (not (Ex #i1 #i2 #i3 #i4 s ss k kk A B minfo . 97 | Accept(s, A, B, k ) @ i1 98 | & Accept(ss, B, A, kk) @ i2 99 | & Sid(s, minfo) @ i3 100 | & Match(ss, minfo) @i4 101 | & not( k = kk ) 102 | ) )" 103 | */ 104 | 105 | lemma eCK_key_secrecy: 106 | /* 107 | * The property specification very closely follows the original eCK 108 | * (ProvSec) paper: 109 | * 110 | * If there exists a Test session whose key k is known to the 111 | * Adversary, then... 112 | */ 113 | "(All #i1 #i2 Test A B k. 114 | Accept(Test, A, B, k) @ i1 & K( k ) @ i2 115 | ==> ( 116 | /* ... the Test session must be "not clean". 117 | * Test is not clean if one of the following has happened: 118 | */ 119 | /* 1a. session-key-reveal of test thread. */ 120 | (Ex #i3. SesskRev( Test ) @ i3 ) 121 | 122 | /* 1b. session-key-reveal of matching session */ 123 | | (Ex MatchingSession #i3 #i4 ms. 124 | /* ( MatchingSession's 'ms' info matches with Test ) */ 125 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 126 | & ( 127 | (Ex #i5. SesskRev( MatchingSession ) @ i5 ) 128 | ) 129 | ) 130 | /* 2. If matching session exists and ... */ 131 | | (Ex MatchingSession #i3 #i4 ms. 132 | /* ( MatchingSession's 'ms' info matches with Test ) */ 133 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 134 | & ( 135 | /* 2a. reveal either both sk_A and esk_A, or */ 136 | (Ex #i5 #i6. LtkRev ( A ) @ i5 & EphkRev ( Test ) @ i6 ) 137 | /* 2b. both sk_B and esk_B */ 138 | | (Ex #i5 #i6. LtkRev ( B ) @ i5 & EphkRev ( MatchingSession ) @ i6 ) 139 | ) 140 | ) 141 | /* 3. No matching session exists and ... */ 142 | | ( ( not(Ex MatchingSession #i3 #i4 ms. 143 | /* ( MatchingSession's 'ms' info matches with Test ) */ 144 | Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4 ) ) 145 | & ( 146 | /* 3a. reveal either sk_B, or */ 147 | (Ex #i5 . LtkRev (B) @ i5 ) 148 | /* 3b. both sk_A and esk_A */ 149 | | (Ex #i5 #i6. LtkRev (A) @ i5 & EphkRev ( Test ) @ i6 ) 150 | ) 151 | ) 152 | ) 153 | )" 154 | 155 | end 156 | -------------------------------------------------------------------------------- /tutorial-models/1_morning/solutions/NAXOS_14_eCK_excl_h_ltk.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_14_eCK_excluding_ltk_in_h1 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | /* 9 | * Protocol: NAXOS 10 | * Modeler: Cas Cremers, Benedikt Schmidt 11 | * Date: January 2012/April 2012 12 | * Source: "Stronger Security of Authenticated Key Exchange" 13 | * LaMacchia, Lauter, Mityagin, 2007 14 | * Property: eCK security 15 | * 16 | * Status: Working 17 | */ 18 | 19 | functions: h1/1 20 | functions: h2/1 21 | 22 | /* Protocol rules */ 23 | 24 | /* In the description in the paper, we omitted the sorts. 25 | * In this description they are made explicit. 26 | * '$A' is equivalent to 'A:pub' 27 | * '~x' is equivalent to 'x:fresh' 28 | */ 29 | 30 | /* Generate long-term keypair */ 31 | rule generate_ltk: 32 | let pkA = 'g'^~lkA 33 | in 34 | [ Fr(~lkA) ] 35 | --[ RegKey($A) ]-> 36 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 37 | 38 | /* Initiator */ 39 | rule Init_1: 40 | let 41 | exI = ~eskI 42 | // exI = h1(<~eskI, ~lkI >) 43 | hkI = 'g'^exI 44 | in 45 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 46 | --> 47 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 48 | , !Ephk(~eskI, ~eskI) 49 | , Out( hkI ) ] 50 | 51 | rule Init_2: 52 | let pkR = 'g'^~lkR 53 | exI = ~eskI 54 | //exI = h1(< ~eskI, ~lkI >) 55 | kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 56 | in 57 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 58 | --[ Accept( ~eskI, $I, $R, kI) 59 | , Sid( ~eskI, < 'Init', $I, $R, hkI, Y >) 60 | , Match( ~eskI, < 'Resp', $R, $I, hkI, Y >) 61 | ]-> 62 | [ !Sessk( ~eskI, kI) ] 63 | 64 | /* Responder */ 65 | rule Resp_1: 66 | let pkI = 'g'^~lkI 67 | exR = ~eskR 68 | // exR = h1(< ~eskR, ~lkR >) 69 | hkr = 'g'^exR 70 | kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 71 | in 72 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 73 | --[ Accept( ~eskR, $R, $I, kR ) 74 | , Sid( ~eskR, <'Resp', $R, $I, X, hkr >) 75 | , Match( ~eskR, <'Init', $I, $R, X, hkr> ) 76 | ]-> 77 | [ Out( hkr ), 78 | !Ephk(~eskR, ~eskR), 79 | !Sessk( ~eskR, kR) ] 80 | 81 | /* Key Reveals for the eCK model */ 82 | rule Sessk_reveal: 83 | [ !Sessk(~tid, k) ] --[ SesskRev(~tid) ]-> [ Out(k) ] 84 | 85 | rule Ltk_reveal: 86 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 87 | 88 | rule Ephk_reveal: 89 | [ !Ephk(~s, ~ek) ] --[ EphkRev(~s) ]-> [ Out(~ek) ] 90 | 91 | 92 | /* Security properties */ 93 | /* 94 | lemma eCK_same_key: 95 | " // If every agent registered at most one public key 96 | (All A #i #j. RegKey(A)@i & RegKey(A)@j ==> (#i = #j)) 97 | ==> // then matching sessions accept the same key 98 | (not (Ex #i1 #i2 #i3 #i4 s ss k kk A B minfo . 99 | Accept(s, A, B, k ) @ i1 100 | & Accept(ss, B, A, kk) @ i2 101 | & Sid(s, minfo) @ i3 102 | & Match(ss, minfo) @i4 103 | & not( k = kk ) 104 | ) )" 105 | */ 106 | 107 | lemma eCK_key_secrecy: 108 | /* 109 | * The property specification very closely follows the original eCK 110 | * (ProvSec) paper: 111 | * 112 | * If there exists a Test session whose key k is known to the 113 | * Adversary, then... 114 | */ 115 | "(All #i1 #i2 Test A B k. 116 | Accept(Test, A, B, k) @ i1 & K( k ) @ i2 117 | ==> ( 118 | /* ... the Test session must be "not clean". 119 | * Test is not clean if one of the following has happened: 120 | */ 121 | /* 1a. session-key-reveal of test thread. */ 122 | (Ex #i3. SesskRev( Test ) @ i3 ) 123 | 124 | /* 1b. session-key-reveal of matching session */ 125 | | (Ex MatchingSession #i3 #i4 ms. 126 | /* ( MatchingSession's 'ms' info matches with Test ) */ 127 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 128 | & ( 129 | (Ex #i5. SesskRev( MatchingSession ) @ i5 ) 130 | ) 131 | ) 132 | /* 2. If matching session exists and ... */ 133 | | (Ex MatchingSession #i3 #i4 ms. 134 | /* ( MatchingSession's 'ms' info matches with Test ) */ 135 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 136 | & ( 137 | /* 2a. reveal either both sk_A and esk_A, or */ 138 | (Ex #i5 #i6. LtkRev ( A ) @ i5 & EphkRev ( Test ) @ i6 ) 139 | /* 2b. both sk_B and esk_B */ 140 | | (Ex #i5 #i6. LtkRev ( B ) @ i5 & EphkRev ( MatchingSession ) @ i6 ) 141 | ) 142 | ) 143 | /* 3. No matching session exists and ... */ 144 | | ( ( not(Ex MatchingSession #i3 #i4 ms. 145 | /* ( MatchingSession's 'ms' info matches with Test ) */ 146 | Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4 ) ) 147 | & ( 148 | /* 3a. reveal either sk_B, or */ 149 | (Ex #i5 . LtkRev (B) @ i5 ) 150 | /* 3b. both sk_A and esk_A */ 151 | | (Ex #i5 #i6. LtkRev (A) @ i5 & EphkRev ( Test ) @ i6 ) 152 | ) 153 | ) 154 | ) 155 | )" 156 | 157 | end 158 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/NSLPK3.spthy: -------------------------------------------------------------------------------- 1 | theory NSLPK3 2 | begin 3 | 4 | builtins: asymmetric-encryption 5 | 6 | // Public key infrastructure 7 | rule Register_pk: 8 | [ Fr(~ltkA) ] 9 | --> 10 | [ !Ltk($A, ~ltkA), !Pk($A, pk(~ltkA)), Out(pk(~ltkA)) ] 11 | 12 | rule Reveal_ltk: 13 | [ !Ltk(A, ltkA) ] --[ RevLtk(A) ]-> [ Out(ltkA) ] 14 | 15 | 16 | /* We formalize the following protocol 17 | 18 | protocol NSLPK3 { 19 | 1. I -> R: {'1',ni,I}pk(R) 20 | 2. I <- R: {'2',ni,nr,R}pk(I) 21 | 3. I -> R: {'3',nr}pk(R) 22 | } 23 | */ 24 | 25 | rule I_1: 26 | let m1 = aenc{'1', ~ni, $I}pkR 27 | in 28 | [ Fr(~ni) 29 | , !Pk($R, pkR) 30 | ] 31 | --[ OUT_I_1(m1) 32 | ]-> 33 | [ Out( m1 ) 34 | , St_I_1($I, $R, ~ni) 35 | ] 36 | 37 | rule R_1: 38 | let m1 = aenc{'1', ni, I}pk(ltkR) 39 | m2 = aenc{'2', ni, ~nr, $R}pkI 40 | in 41 | [ !Ltk($R, ltkR) 42 | , In( m1 ) 43 | , !Pk(I, pkI) 44 | , Fr(~nr) 45 | ] 46 | --[ IN_R_1_ni( ni, m1 ) 47 | , OUT_R_1( m2 ) 48 | , Running(I, $R, <'init',ni,~nr>) 49 | ]-> 50 | [ Out( m2 ) 51 | , St_R_1($R, I, ni, ~nr) 52 | ] 53 | 54 | rule I_2: 55 | let m2 = aenc{'2', ni, nr, R}pk(ltkI) 56 | m3 = aenc{'3', nr}pkR 57 | in 58 | [ St_I_1(I, R, ni) 59 | , !Ltk(I, ltkI) 60 | , In( m2 ) 61 | , !Pk(R, pkR) 62 | ] 63 | --[ IN_I_2_nr( nr, m2) 64 | , Commit (I, R, <'init',ni,nr>) // need to log identities explicitely to 65 | , Running(R, I, <'resp',ni,nr>) // specify that they must not be 66 | // compromised in the property. 67 | ]-> 68 | [ Out( m3 ) 69 | , Secret(I,R,nr) 70 | , Secret(I,R,ni) 71 | ] 72 | 73 | rule R_2: 74 | [ St_R_1(R, I, ni, nr) 75 | , !Ltk(R, ltkR) 76 | , In( aenc{'3', nr}pk(ltkR) ) 77 | ] 78 | --[ Commit (R, I, <'resp',ni,nr>) 79 | ]-> 80 | [ Secret(R,I,nr) 81 | , Secret(R,I,ni) 82 | ] 83 | 84 | rule Secrecy_claim: 85 | [ Secret(A, B, m) ] --[ Secret(A, B, m) ]-> [] 86 | 87 | 88 | 89 | /* Note that we are using an untyped protocol model. 90 | The contents of the 'ni' variable in rule R_1 may therefore in general be any 91 | message. This leads to unsolved chain constraints when checking what message 92 | can be extracted from the message sent by rule R_1. In order to get rid of 93 | these constraints, we require the following sources invariant that relates the 94 | point of instantiation to the point of sending by either the adversary or the 95 | initiator. 96 | 97 | In order to understand the use of this sources invariant you might try the 98 | follwing experiment. Comment out this sources invariant and then check the 99 | precomputed case distinctions in the GUI. Try to complete the proof of the 100 | 'nonce_secrecy' lemma. 101 | */ 102 | lemma types [sources]: 103 | " (All ni m1 #i. 104 | IN_R_1_ni( ni, m1) @ i 105 | ==> 106 | ( (Ex #j. KU(ni) @ j & j < i) 107 | | (Ex #j. OUT_I_1( m1 ) @ j) 108 | ) 109 | ) 110 | & (All nr m2 #i. 111 | IN_I_2_nr( nr, m2) @ i 112 | ==> 113 | ( (Ex #j. KU(nr) @ j & j < i) 114 | | (Ex #j. OUT_R_1( m2 ) @ j) 115 | ) 116 | ) 117 | " 118 | 119 | // Nonce secrecy from the perspective of both the initiator and the responder. 120 | lemma nonce_secrecy: 121 | " /* It cannot be that */ 122 | not( 123 | Ex A B s #i. 124 | /* somebody claims to have setup a shared secret, */ 125 | Secret(A, B, s) @ i 126 | /* but the adversary knows it */ 127 | & (Ex #j. K(s) @ j) 128 | /* without having performed a long-term key reveal. */ 129 | & not (Ex #r. RevLtk(A) @ r) 130 | & not (Ex #r. RevLtk(B) @ r) 131 | )" 132 | 133 | // Injective agreement from the perspective of both the initiator and the responder. 134 | lemma injective_agree: 135 | " /* Whenever somebody commits to running a session, then*/ 136 | All actor peer params #i. 137 | Commit(actor, peer, params) @ i 138 | ==> 139 | /* there is somebody running a session with the same parameters */ 140 | (Ex #j. Running(actor, peer, params) @ j & j < i 141 | /* and there is no other commit on the same parameters */ 142 | & not(Ex actor2 peer2 #i2. 143 | Commit(actor2, peer2, params) @ i2 & not(#i = #i2) 144 | ) 145 | ) 146 | /* or the adversary perform a long-term key reveal on actor or peer */ 147 | | (Ex #r. RevLtk(actor) @ r) 148 | | (Ex #r. RevLtk(peer) @ r) 149 | " 150 | 151 | // Consistency check: ensure that secrets can be shared between honest agents. 152 | lemma session_key_setup_possible: 153 | exists-trace 154 | " /* It is possible that */ 155 | Ex A B s #i. 156 | /* somebody claims to have setup a shared secret, */ 157 | Secret(A, B, s) @ i 158 | /* without the adversary having performed a long-term key reveal. */ 159 | & not (Ex #r. RevLtk(A) @ r) 160 | & not (Ex #r. RevLtk(B) @ r) 161 | " 162 | 163 | end 164 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/NSPK3.spthy: -------------------------------------------------------------------------------- 1 | theory NSPK3 2 | begin 3 | 4 | builtins: asymmetric-encryption 5 | 6 | // Public key infrastructure 7 | rule Register_pk: 8 | [ Fr(~ltkA) ] 9 | --> 10 | [ !Ltk($A, ~ltkA), !Pk($A, pk(~ltkA)), Out(pk(~ltkA)) ] 11 | 12 | rule Reveal_ltk: 13 | [ !Ltk(A, ltkA) ] --[ RevLtk(A) ]-> [ Out(ltkA) ] 14 | 15 | 16 | /* We formalize the following protocol 17 | 18 | protocol NSPK3 { 19 | 1. I -> R: {'1',ni,I}pk(R) 20 | 2. I <- R: {'2',ni,nr}pk(I) 21 | 3. I -> R: {'3',nr}pk(R) 22 | } 23 | */ 24 | 25 | rule I_1: 26 | let m1 = aenc{'1', ~ni, $I}pkR 27 | in 28 | [ Fr(~ni) 29 | , !Pk($R, pkR) 30 | ] 31 | --[ OUT_I_1(m1) 32 | ]-> 33 | [ Out( m1 ) 34 | , St_I_1($I, $R, ~ni) 35 | ] 36 | 37 | rule R_1: 38 | let m1 = aenc{'1', ni, I}pk(ltkR) 39 | m2 = aenc{'2', ni, ~nr}pkI 40 | in 41 | [ !Ltk($R, ltkR) 42 | , In( m1 ) 43 | , !Pk(I, pkI) 44 | , Fr(~nr) 45 | ] 46 | --[ IN_R_1_ni( ni, m1 ) 47 | , OUT_R_1( m2 ) 48 | , Running(I, $R, <'init',ni,~nr>) 49 | ]-> 50 | [ Out( m2 ) 51 | , St_R_1($R, I, ni, ~nr) 52 | ] 53 | 54 | rule I_2: 55 | let m2 = aenc{'2', ni, nr}pk(ltkI) 56 | m3 = aenc{'3', nr}pkR 57 | in 58 | [ St_I_1(I, R, ni) 59 | , !Ltk(I, ltkI) 60 | , In( m2 ) 61 | , !Pk(R, pkR) 62 | ] 63 | --[ IN_I_2_nr( nr, m2) 64 | , Commit (I, R, <'init',ni,nr>) // need to log identities explicitely to 65 | , Running(R, I, <'resp',ni,nr>) // specify that they must not be 66 | // compromised in the property. 67 | ]-> 68 | [ Out( m3 ) 69 | , Secret(I,R,nr) 70 | , Secret(I,R,ni) 71 | ] 72 | 73 | rule R_2: 74 | [ St_R_1(R, I, ni, nr) 75 | , !Ltk(R, ltkR) 76 | , In( aenc{'3', nr}pk(ltkR) ) 77 | ] 78 | --[ Commit (R, I, <'resp',ni,nr>) 79 | ]-> 80 | [ Secret(R,I,nr) 81 | , Secret(R,I,ni) 82 | ] 83 | 84 | rule Secrecy_claim: 85 | [ Secret(A, B, m) ] --[ Secret(A, B, m) ]-> [] 86 | 87 | 88 | 89 | /* Note that we are using an untyped protocol model. For proofs, we therefore 90 | require a protocol specific type invariant for proof construction. In 91 | principle, such an invariant is not required for attack search, but does help 92 | a lot. 93 | 94 | See 'NSLPK3.spthy' for a detailed explanation of the construction of this 95 | invariant. 96 | */ 97 | lemma types [sources]: 98 | " (All ni m1 #i. 99 | IN_R_1_ni( ni, m1) @ i 100 | ==> 101 | ( (Ex #j. KU(ni) @ j & j < i) 102 | | (Ex #j. OUT_I_1( m1 ) @ j) 103 | ) 104 | ) 105 | & (All nr m2 #i. 106 | IN_I_2_nr( nr, m2) @ i 107 | ==> 108 | ( (Ex #j. KU(nr) @ j & j < i) 109 | | (Ex #j. OUT_R_1( m2 ) @ j) 110 | ) 111 | ) 112 | " 113 | 114 | // Nonce secrecy from the perspective of both the initiator and the responder. 115 | lemma nonce_secrecy: 116 | " /* It cannot be that */ 117 | not( 118 | Ex A B s #i. 119 | /* somebody claims to have setup a shared secret, */ 120 | Secret(A, B, s) @ i 121 | /* but the adversary knows it */ 122 | & (Ex #j. K(s) @ j) 123 | /* without having performed a long-term key reveal. */ 124 | & not (Ex #r. RevLtk(A) @ r) 125 | & not (Ex #r. RevLtk(B) @ r) 126 | )" 127 | 128 | // Injective agreement from the perspective of both the initiator and the responder. 129 | lemma injective_agree: 130 | " /* Whenever somebody commits to running a session, then*/ 131 | All actor peer params #i. 132 | Commit(actor, peer, params) @ i 133 | ==> 134 | /* there is somebody running a session with the same parameters */ 135 | (Ex #j. Running(actor, peer, params) @ j & j < i 136 | /* and there is no other commit on the same parameters */ 137 | & not(Ex actor2 peer2 #i2. 138 | Commit(actor2, peer2, params) @ i2 & not(#i = #i2) 139 | ) 140 | ) 141 | /* or the adversary perform a long-term key reveal on actor or peer */ 142 | | (Ex #r. RevLtk(actor) @ r) 143 | | (Ex #r. RevLtk(peer) @ r) 144 | " 145 | 146 | // Consistency check: ensure that secrets can be shared between honest agents. 147 | lemma session_key_setup_possible: 148 | exists-trace 149 | " /* It is possible that */ 150 | Ex A B s #i. 151 | /* somebody claims to have setup a shared secret, */ 152 | Secret(A, B, s) @ i 153 | /* without the adversary having performed a long-term key reveal. */ 154 | & not (Ex #r. RevLtk(A) @ r) 155 | & not (Ex #r. RevLtk(B) @ r) 156 | " 157 | 158 | end 159 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/partial/NSLPK3-initiatorrules.txt: -------------------------------------------------------------------------------- 1 | rule I_1: 2 | let m1 = aenc{'1', ~ni, $I}pkR 3 | in 4 | [ Fr(~ni) 5 | , !Pk($R, pkR) 6 | ] 7 | --[ OUT_I_1(m1) 8 | ]-> 9 | [ Out( m1 ) 10 | , St_I_1($I, $R, ~ni) 11 | ] 12 | 13 | rule I_2: 14 | let m2 = aenc{'2', ni, nr, R}pk(ltkI) 15 | m3 = aenc{'3', nr}pkR 16 | in 17 | [ St_I_1(I, R, ni) 18 | , !Ltk(I, ltkI) 19 | , In( m2 ) 20 | , !Pk(R, pkR) 21 | ] 22 | --[ IN_I_2_nr( nr, m2) 23 | , Commit (I, R, <'init',ni,nr>) // need to log identities explicitely to 24 | , Running(R, I, <'resp',ni,nr>) // specify that they must not be 25 | // compromised in the property. 26 | ]-> 27 | [ Out( m3 ) 28 | , Secret(I,R,nr) 29 | , Secret(I,R,ni) 30 | ] 31 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/partial/NSLPK3-lemmas.txt: -------------------------------------------------------------------------------- 1 | lemma types [sources]: 2 | " (All ni m1 #i. 3 | IN_R_1_ni( ni, m1) @ i 4 | ==> 5 | ( (Ex #j. KU(ni) @ j & j < i) 6 | | (Ex #j. OUT_I_1( m1 ) @ j) 7 | ) 8 | ) 9 | & (All nr m2 #i. 10 | IN_I_2_nr( nr, m2) @ i 11 | ==> 12 | ( (Ex #j. KU(nr) @ j & j < i) 13 | | (Ex #j. OUT_R_1( m2 ) @ j) 14 | ) 15 | ) 16 | " 17 | 18 | // Nonce secrecy from the perspective of both the initiator and the responder. 19 | lemma nonce_secrecy: 20 | " /* It cannot be that */ 21 | not( 22 | Ex A B s #i. 23 | /* somebody claims to have setup a shared secret, */ 24 | Secret(A, B, s) @ i 25 | /* but the adversary knows it */ 26 | & (Ex #j. K(s) @ j) 27 | /* without having performed a long-term key reveal. */ 28 | & not (Ex #r. RevLtk(A) @ r) 29 | & not (Ex #r. RevLtk(B) @ r) 30 | )" 31 | 32 | // Injective agreement from the perspective of both the initiator and the responder. 33 | lemma injective_agree: 34 | " /* Whenever somebody commits to running a session, then*/ 35 | All actor peer params #i. 36 | Commit(actor, peer, params) @ i 37 | ==> 38 | /* there is somebody running a session with the same parameters */ 39 | (Ex #j. Running(actor, peer, params) @ j & j < i 40 | /* and there is no other commit on the same parameters */ 41 | & not(Ex actor2 peer2 #i2. 42 | Commit(actor2, peer2, params) @ i2 & not(#i = #i2) 43 | ) 44 | ) 45 | /* or the adversary perform a long-term key reveal on actor or peer */ 46 | | (Ex #r. RevLtk(actor) @ r) 47 | | (Ex #r. RevLtk(peer) @ r) 48 | " 49 | 50 | // Consistency check: ensure that secrets can be shared between honest agents. 51 | lemma session_key_setup_possible: 52 | exists-trace 53 | " /* It is possible that */ 54 | Ex A B s #i. 55 | /* somebody claims to have setup a shared secret, */ 56 | Secret(A, B, s) @ i 57 | /* without the adversary having performed a long-term key reveal. */ 58 | & not (Ex #r. RevLtk(A) @ r) 59 | & not (Ex #r. RevLtk(B) @ r) 60 | " 61 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/partial/NSLPK3-responderrules.txt: -------------------------------------------------------------------------------- 1 | rule R_1: 2 | let m1 = aenc{'1', ni, I}pk(ltkR) 3 | m2 = aenc{'2', ni, ~nr, $R}pkI 4 | in 5 | [ !Ltk($R, ltkR) 6 | , In( m1 ) 7 | , !Pk(I, pkI) 8 | , Fr(~nr) 9 | ] 10 | --[ IN_R_1_ni( ni, m1 ) 11 | , OUT_R_1( m2 ) 12 | , Running(I, $R, <'init',ni,~nr>) 13 | ]-> 14 | [ Out( m2 ) 15 | , St_R_1($R, I, ni, ~nr) 16 | ] 17 | 18 | rule R_2: 19 | [ St_R_1(R, I, ni, nr) 20 | , !Ltk(R, ltkR) 21 | , In( aenc{'3', nr}pk(ltkR) ) 22 | ] 23 | --[ Commit (R, I, <'resp',ni,nr>) 24 | ]-> 25 | [ Secret(R,I,nr) 26 | , Secret(R,I,ni) 27 | ] 28 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/partial/NSLPK3-setuprules.txt: -------------------------------------------------------------------------------- 1 | rule Register_pk: 2 | [ Fr(~ltkA) ] 3 | --> 4 | [ !Ltk($A, ~ltkA), !Pk($A, pk(~ltkA)), Out(pk(~ltkA)) ] 5 | 6 | rule Reveal_ltk: 7 | [ !Ltk(A, ltkA) ] --[ RevLtk(A) ]-> [ Out(ltkA) ] 8 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/partial/NSLPK3-sourceslemma.txt: -------------------------------------------------------------------------------- 1 | lemma types [sources]: 2 | " (All ni m1 #i. 3 | IN_R_1_ni( ni, m1) @ i 4 | ==> 5 | ( (Ex #j. KU(ni) @ j & j < i) 6 | | (Ex #j. OUT_I_1( m1 ) @ j) 7 | ) 8 | ) 9 | & (All nr m2 #i. 10 | IN_I_2_nr( nr, m2) @ i 11 | ==> 12 | ( (Ex #j. KU(nr) @ j & j < i) 13 | | (Ex #j. OUT_R_1( m2 ) @ j) 14 | ) 15 | ) 16 | " 17 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/partial/NSPK3-initiatorrules.txt: -------------------------------------------------------------------------------- 1 | rule I_1: 2 | let m1 = aenc{'1', ~ni, $I}pkR 3 | in 4 | [ Fr(~ni) 5 | , !Pk($R, pkR) 6 | ] 7 | --[ OUT_I_1(m1) 8 | ]-> 9 | [ Out( m1 ) 10 | , St_I_1($I, $R, ~ni) 11 | ] 12 | 13 | rule I_2: 14 | let m2 = aenc{'2', ni, nr}pk(ltkI) 15 | m3 = aenc{'3', nr}pkR 16 | in 17 | [ St_I_1(I, R, ni) 18 | , !Ltk(I, ltkI) 19 | , In( m2 ) 20 | , !Pk(R, pkR) 21 | ] 22 | --[ IN_I_2_nr( nr, m2) 23 | , Commit (I, R, <'init',ni,nr>) // need to log identities explicitly to 24 | , Running(R, I, <'resp',ni,nr>) // specify that they must not be 25 | // compromised in the property. 26 | ]-> 27 | [ Out( m3 ) 28 | , Secret(I,R,nr) 29 | , Secret(I,R,ni) 30 | ] 31 | 32 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/partial/NSPK3-lemmas.txt: -------------------------------------------------------------------------------- 1 | lemma types [sources]: 2 | " (All ni m1 #i. 3 | IN_R_1_ni( ni, m1) @ i 4 | ==> 5 | ( (Ex #j. KU(ni) @ j & j < i) 6 | | (Ex #j. OUT_I_1( m1 ) @ j) 7 | ) 8 | ) 9 | & (All nr m2 #i. 10 | IN_I_2_nr( nr, m2) @ i 11 | ==> 12 | ( (Ex #j. KU(nr) @ j & j < i) 13 | | (Ex #j. OUT_R_1( m2 ) @ j) 14 | ) 15 | ) 16 | " 17 | 18 | // Nonce secrecy from the perspective of both the initiator and the responder. 19 | lemma nonce_secrecy: 20 | " /* It cannot be that */ 21 | not( 22 | Ex A B s #i. 23 | /* somebody claims to have setup a shared secret, */ 24 | Secret(A, B, s) @ i 25 | /* but the adversary knows it */ 26 | & (Ex #j. K(s) @ j) 27 | /* without having performed a long-term key reveal. */ 28 | & not (Ex #r. RevLtk(A) @ r) 29 | & not (Ex #r. RevLtk(B) @ r) 30 | )" 31 | 32 | // Injective agreement from the perspective of both the initiator and the responder. 33 | lemma injective_agree: 34 | " /* Whenever somebody commits to running a session, then*/ 35 | All actor peer params #i. 36 | Commit(actor, peer, params) @ i 37 | ==> 38 | /* there is somebody running a session with the same parameters */ 39 | (Ex #j. Running(actor, peer, params) @ j & j < i 40 | /* and there is no other commit on the same parameters */ 41 | & not(Ex actor2 peer2 #i2. 42 | Commit(actor2, peer2, params) @ i2 & not(#i = #i2) 43 | ) 44 | ) 45 | /* or the adversary perform a long-term key reveal on actor or peer */ 46 | | (Ex #r. RevLtk(actor) @ r) 47 | | (Ex #r. RevLtk(peer) @ r) 48 | " 49 | 50 | // Consistency check: ensure that secrets can be shared between honest agents. 51 | lemma session_key_setup_possible: 52 | exists-trace 53 | " /* It is possible that */ 54 | Ex A B s #i. 55 | /* somebody claims to have setup a shared secret, */ 56 | Secret(A, B, s) @ i 57 | /* without the adversary having performed a long-term key reveal. */ 58 | & not (Ex #r. RevLtk(A) @ r) 59 | & not (Ex #r. RevLtk(B) @ r) 60 | " 61 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/partial/NSPK3-responderrules.txt: -------------------------------------------------------------------------------- 1 | rule R_1: 2 | let m1 = aenc{'1', ni, I}pk(ltkR) 3 | m2 = aenc{'2', ni, ~nr}pkI 4 | in 5 | [ !Ltk($R, ltkR) 6 | , In( m1 ) 7 | , !Pk(I, pkI) 8 | , Fr(~nr) 9 | ] 10 | --[ IN_R_1_ni( ni, m1 ) 11 | , OUT_R_1( m2 ) 12 | , Running(I, $R, <'init',ni,~nr>) 13 | ]-> 14 | [ Out( m2 ) 15 | , St_R_1($R, I, ni, ~nr) 16 | ] 17 | 18 | rule R_2: 19 | [ St_R_1(R, I, ni, nr) 20 | , !Ltk(R, ltkR) 21 | , In( aenc{'3', nr}pk(ltkR) ) 22 | ] 23 | --[ Commit (R, I, <'resp',ni,nr>) 24 | ]-> 25 | [ Secret(R,I,nr) 26 | , Secret(R,I,ni) 27 | ] 28 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/partial/NSPK3-setuprules.txt: -------------------------------------------------------------------------------- 1 | rule Register_pk: 2 | [ Fr(~ltkA) ] 3 | --> 4 | [ !Ltk($A, ~ltkA), !Pk($A, pk(~ltkA)), Out(pk(~ltkA)) ] 5 | 6 | rule Reveal_ltk: 7 | [ !Ltk(A, ltkA) ] --[ RevLtk(A) ]-> [ Out(ltkA) ] 8 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/partial/NSPK3-sourceslemma.txt: -------------------------------------------------------------------------------- 1 | lemma types [sources]: 2 | " (All ni m1 #i. 3 | IN_R_1_ni( ni, m1) @ i 4 | ==> 5 | ( (Ex #j. KU(ni) @ j & j < i) 6 | | (Ex #j. OUT_I_1( m1 ) @ j) 7 | ) 8 | ) 9 | & (All nr m2 #i. 10 | IN_I_2_nr( nr, m2) @ i 11 | ==> 12 | ( (Ex #j. KU(nr) @ j & j < i) 13 | | (Ex #j. OUT_R_1( m2 ) @ j) 14 | ) 15 | ) 16 | " 17 | -------------------------------------------------------------------------------- /tutorial-models/2_afternoon/project.spthy: -------------------------------------------------------------------------------- 1 | theory project 2 | begin 3 | 4 | /* For this hands-on session we ask you to specify and analyze the 5 | Needham-Schroeder protocol. Then, model the fix by Lowe and verify the 6 | resulting protocol. Start with NSPK3: 7 | 8 | protocol NSPK3 { 9 | 1. I -> R: {'1',ni,I}pk(R) 10 | 2. I <- R: {'2',ni,nr}pk(I) 11 | 3. I -> R: {'3',nr}pk(R) 12 | } 13 | 14 | Lowe's fix for message 2: 15 | 2. I <- R: {'2',ni,nr,R}pk(I) 16 | 17 | */ 18 | 19 | /* Equational Theory / Builtins */ 20 | 21 | 22 | /* Setup Rules */ 23 | 24 | 25 | /* Initiator Rules */ 26 | 27 | 28 | /* Responder Rules */ 29 | 30 | 31 | /* Sources Lemma */ 32 | 33 | 34 | /* Property Lemmas */ 35 | 36 | 37 | end 38 | -------------------------------------------------------------------------------- /tutorial-models/3_from_slides/NAXOS_eCK.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_eCK 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | functions: h1/1 9 | functions: h2/1 10 | 11 | /* Protocol rules */ 12 | 13 | /* In the description in the slides, we omitted the sorts. 14 | * In this description they are made explicit. 15 | * '$A' is equivalent to 'A:pub' 16 | * '~x' is equivalent to 'x:fresh' 17 | */ 18 | 19 | /* Generate long-term keypair */ 20 | rule generate_ltk: 21 | let pkA = 'g'^~lkA 22 | in 23 | [ Fr(~lkA) ] 24 | --[ RegKey($A) ]-> 25 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 26 | 27 | /* Initiator */ 28 | rule Init_1: 29 | let exI = h1(<~eskI, ~lkI >) 30 | hkI = 'g'^exI 31 | in 32 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 33 | --> 34 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 35 | , !Ephk(~eskI, ~eskI) 36 | , Out( hkI ) ] 37 | 38 | rule Init_2: 39 | let pkR = 'g'^~lkR 40 | exI = h1(< ~eskI, ~lkI >) 41 | kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 42 | in 43 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 44 | --[ Accept( ~eskI, $I, $R, kI) 45 | , Sid( ~eskI, < 'Init', $I, $R, hkI, Y >) 46 | , Match( ~eskI, < 'Resp', $R, $I, hkI, Y >) 47 | ]-> 48 | [ !Sessk( ~eskI, kI) ] 49 | 50 | /* Responder */ 51 | rule Resp_1: 52 | let pkI = 'g'^~lkI 53 | exR = h1(< ~eskR, ~lkR >) 54 | hkr = 'g'^exR 55 | kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 56 | in 57 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 58 | --[ Accept( ~eskR, $R, $I, kR ) 59 | , Sid( ~eskR, <'Resp', $R, $I, X, hkr >) 60 | , Match( ~eskR, <'Init', $I, $R, X, hkr> ) 61 | ]-> 62 | [ Out( hkr ), 63 | !Ephk(~eskR, ~eskR), 64 | !Sessk( ~eskR, kR) ] 65 | 66 | /* Key Reveals for the eCK model */ 67 | rule Sessk_reveal: 68 | [ !Sessk(~tid, k) ] --[ SesskRev(~tid) ]-> [ Out(k) ] 69 | 70 | rule Ltk_reveal: 71 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 72 | 73 | rule Ephk_reveal: 74 | [ !Ephk(~s, ~ek) ] --[ EphkRev(~s) ]-> [ Out(~ek) ] 75 | 76 | 77 | /* Security properties */ 78 | 79 | lemma eCK_key_secrecy: 80 | /* 81 | * The property specification very closely follows the original eCK 82 | * (ProvSec) paper: 83 | * 84 | * If there exists a Test session whose key k is known to the 85 | * Adversary, then... 86 | */ 87 | "(All #i1 #i2 Test A B k. 88 | Accept(Test, A, B, k) @ i1 & K( k ) @ i2 89 | ==> ( 90 | /* ... the Test session must be "not clean". 91 | * Test is not clean if one of the following has happened: 92 | */ 93 | /* 1a. session-key-reveal of test thread. */ 94 | (Ex #i3. SesskRev( Test ) @ i3 ) 95 | 96 | /* 1b. session-key-reveal of matching session */ 97 | | (Ex MatchingSession #i3 #i4 ms. 98 | /* ( MatchingSession's 'ms' info matches with Test ) */ 99 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 100 | & ( 101 | (Ex #i5. SesskRev( MatchingSession ) @ i5 ) 102 | ) 103 | ) 104 | /* 2. If matching session exists and ... */ 105 | | (Ex MatchingSession #i3 #i4 ms. 106 | /* ( MatchingSession's 'ms' info matches with Test ) */ 107 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 108 | & ( 109 | /* 2a. reveal either both sk_A and esk_A, or */ 110 | (Ex #i5 #i6. LtkRev ( A ) @ i5 & EphkRev ( Test ) @ i6 ) 111 | /* 2b. both sk_B and esk_B */ 112 | | (Ex #i5 #i6. LtkRev ( B ) @ i5 & EphkRev ( MatchingSession ) @ i6 ) 113 | ) 114 | ) 115 | /* 3. No matching session exists and ... */ 116 | | ( ( not(Ex MatchingSession #i3 #i4 ms. 117 | /* ( MatchingSession's 'ms' info matches with Test ) */ 118 | Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4 ) ) 119 | & ( 120 | /* 3a. reveal either sk_B, or */ 121 | (Ex #i5 . LtkRev (B) @ i5 ) 122 | /* 3b. both sk_A and esk_A */ 123 | | (Ex #i5 #i6. LtkRev (A) @ i5 & EphkRev ( Test ) @ i6 ) 124 | ) 125 | ) 126 | ) 127 | )" 128 | 129 | lemma executable: 130 | exists-trace 131 | "Ex id1 id2 I R k #i #j. Accept(id1, I, R, k) @ #i & Accept(id2, R, I, k) @ #j & not (#i = #j)" 132 | 133 | end 134 | -------------------------------------------------------------------------------- /tutorial-models/3_from_slides/NAXOS_eCK_PFS.spthy: -------------------------------------------------------------------------------- 1 | theory NAXOS_eCK_PFS 2 | begin 3 | 4 | builtins: diffie-hellman 5 | 6 | section{* NAXOS *} 7 | 8 | functions: h1/1 9 | functions: h2/1 10 | 11 | /* Protocol rules */ 12 | 13 | /* In the description in the slides, we omitted the sorts. 14 | * In this description they are made explicit. 15 | * '$A' is equivalent to 'A:pub' 16 | * '~x' is equivalent to 'x:fresh' 17 | */ 18 | 19 | /* Generate long-term keypair */ 20 | rule generate_ltk: 21 | let pkA = 'g'^~lkA 22 | in 23 | [ Fr(~lkA) ] 24 | --[ RegKey($A) ]-> 25 | [ !Ltk( $A, ~lkA ), !Pk( $A, pkA ), Out( pkA ) ] 26 | 27 | /* Initiator */ 28 | rule Init_1: 29 | let exI = h1(<~eskI, ~lkI >) 30 | hkI = 'g'^exI 31 | in 32 | [ Fr( ~eskI ), !Ltk( $I, ~lkI ) ] 33 | --> 34 | [ Init_1( ~eskI, $I, $R, ~lkI, hkI ) 35 | , !Ephk(~eskI, ~eskI) 36 | , Out( hkI ) ] 37 | 38 | rule Init_2: 39 | let pkR = 'g'^~lkR 40 | exI = h1(< ~eskI, ~lkI >) 41 | kI = h2(< Y^~lkI, pkR^exI, Y^exI, $I, $R >) 42 | in 43 | [ Init_1( ~eskI, $I, $R, ~lkI , hkI), !Pk( $R, pkR ), In( Y ) ] 44 | --[ Accept( ~eskI, $I, $R, kI) 45 | , Sid( ~eskI, < 'Init', $I, $R, hkI, Y >) 46 | , Match( ~eskI, < 'Resp', $R, $I, hkI, Y >) 47 | ]-> 48 | [ !Sessk( ~eskI, kI) ] 49 | 50 | /* Responder */ 51 | rule Resp_1: 52 | let pkI = 'g'^~lkI 53 | exR = h1(< ~eskR, ~lkR >) 54 | hkr = 'g'^exR 55 | kR = h2(< pkI^exR, X^~lkR, X^exR, $I, $R >) 56 | in 57 | [ Fr( ~eskR ), !Ltk($R, ~lkR), !Pk($I, pkI), In( X ) ] 58 | --[ Accept( ~eskR, $R, $I, kR ) 59 | , Sid( ~eskR, <'Resp', $R, $I, X, hkr >) 60 | , Match( ~eskR, <'Init', $I, $R, X, hkr> ) 61 | ]-> 62 | [ Out( hkr ), 63 | !Ephk(~eskR, ~eskR), 64 | !Sessk( ~eskR, kR) ] 65 | 66 | /* Key Reveals for the eCK model */ 67 | rule Sessk_reveal: 68 | [ !Sessk(~tid, k) ] --[ SesskRev(~tid) ]-> [ Out(k) ] 69 | 70 | rule Ltk_reveal: 71 | [ !Ltk($A, lkA) ] --[ LtkRev($A) ]-> [ Out(lkA) ] 72 | 73 | rule Ephk_reveal: 74 | [ !Ephk(~s, ~ek) ] --[ EphkRev(~s) ]-> [ Out(~ek) ] 75 | 76 | 77 | /* Security properties */ 78 | 79 | // Note that the protocol is NOT supposed to have this property, and indeed it does not 80 | lemma eCK_PFS_key_secrecy: 81 | /* 82 | * The property specification very closely follows the original eCK 83 | * (ProvSec) paper: 84 | * 85 | * If there exists a Test session whose key k is known to the 86 | * Adversary, then... 87 | */ 88 | "(All #i1 #i2 Test A B k. 89 | Accept(Test, A, B, k) @ i1 & K( k ) @ i2 90 | ==> ( 91 | /* ... the Test session must be "not clean". 92 | * Test is not clean if one of the following has happened: 93 | */ 94 | /* 1a. session-key-reveal of test thread. */ 95 | (Ex #i3. SesskRev( Test ) @ i3 ) 96 | 97 | /* 1b. session-key-reveal of matching session */ 98 | | (Ex MatchingSession #i3 #i4 ms. 99 | /* ( MatchingSession's 'ms' info matches with Test ) */ 100 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 101 | & ( 102 | (Ex #i5. SesskRev( MatchingSession ) @ i5 ) 103 | ) 104 | ) 105 | /* 2. If matching session exists and ... */ 106 | | (Ex MatchingSession #i3 #i4 ms. 107 | /* ( MatchingSession's 'ms' info matches with Test ) */ 108 | ( Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4) 109 | & ( 110 | /* 2a. reveal either both sk_A and esk_A, or */ 111 | (Ex #i5 #i6. LtkRev ( A ) @ i5 & EphkRev ( Test ) @ i6 ) 112 | /* 2b. both sk_B and esk_B */ 113 | | (Ex #i5 #i6. LtkRev ( B ) @ i5 & EphkRev ( MatchingSession ) @ i6 ) 114 | ) 115 | ) 116 | /* 3. No matching session exists and ... */ 117 | | ( ( not(Ex MatchingSession #i3 #i4 ms. 118 | /* ( MatchingSession's 'ms' info matches with Test ) */ 119 | Sid ( MatchingSession, ms ) @ i3 & Match( Test, ms ) @ i4 ) ) 120 | & ( 121 | /* 3a. reveal either sk_B, or */ 122 | (Ex #i5 . LtkRev (B) @ i5 & i5 < i1 ) /* Perfect Forward Secrecy (PFS) modification */ 123 | /* 3b. both sk_A and esk_A */ 124 | | (Ex #i5 #i6. LtkRev (A) @ i5 & EphkRev ( Test ) @ i6 ) 125 | ) 126 | ) 127 | ) 128 | )" 129 | 130 | lemma executable: 131 | exists-trace 132 | "Ex id1 id2 I R k #i #j. Accept(id1, I, R, k) @ #i & Accept(id2, R, I, k) @ #j & not (#i = #j)" 133 | 134 | end 135 | -------------------------------------------------------------------------------- /tutorial-models/3_from_slides/foo_eligibility.spthy: -------------------------------------------------------------------------------- 1 | theory FOO_Eligibility 2 | begin 3 | 4 | 5 | /* 6 | * Protocol: Protocol by Fujioka, Okamoto and Ohta (FOO) 7 | * Modeler: Charles Duménil 8 | * Date: July 2016 9 | * Source: Formal verification of voting and auction protocols by Jannik Dreier 10 | * Status: Working 11 | */ 12 | 13 | 14 | /* 15 | Protocol FOO { 16 | Phase 1: 17 | V -> A: < blind(commit(v,r),b), sign(blind(commit(v,r),b),skV) > 18 | A -> V: < blind(commit(v,r),b), sign(blind(commit(v,r),b),skA) > "Registered" + "Check signature Voter" 19 | Phase 2: 20 | V -> C: < commit(vote,r), sign(commit(vote,r),ltkA) > "Check signature Admin" + "Check commitment" 21 | Phase 3: 22 | C -> Pub: < commit(vote,r), sign(commit(vote,r),ltkA) > "Check signature Admin" 23 | V -> C: r "Check commitment" 24 | C -> Pub: v "VotePublished" + "Check r" 25 | } 26 | */ 27 | 28 | 29 | functions: pk/1, sign/2, checksign/2, blind/2, unblind/2, open/2, commit/2 30 | equations: open(commit(m,r),r) = m, 31 | unblind(blind(m,r),r) = m, 32 | unblind(sign(blind(m,r),sk),r) = sign(m,sk), 33 | checksign(sign(m,k),pk(k)) = m 34 | 35 | 36 | // Public key infrastructure 37 | 38 | rule Register_Voter_pk: 39 | [ Fr(~ltkV) ] --[ ]-> [ !Ltk($V, ~ltkV), !Pk($V, pk(~ltkV)), Out(pk(~ltkV)) ] 40 | 41 | rule Register_Admin_pk: 42 | [ Fr(~ltkA) ] --[ ]-> [ !AdminLtk($A, ~ltkA), !AdminPk($A, pk(~ltkA)), Out(pk(~ltkA)) ] 43 | 44 | // Rules 45 | 46 | rule V_1: 47 | let x = commit( $vote , ~r ) 48 | e = blind( x, ~b ) 49 | s = sign ( e , ~ltkV ) 50 | in 51 | [ Fr( ~r ), Fr( ~b ), !Ltk( V, ~ltkV ) ] 52 | --[ Created_vote_V_1(x), Created_commit_V_1(e) ]-> 53 | [ Out( ), St_V_1( V, $vote, ~r, ~b ) ] 54 | 55 | rule A_1: 56 | let d = sign( e, ~ltkA ) 57 | in 58 | [ In( ), !AdminLtk( A, ~ltkA ), !Ltk( V, ~ltkV ) ] 59 | --[ Registered(e), In_A_1(e) ]-> 60 | [ Out( ) ] 61 | 62 | rule V_2: // Check Admin_Signature & Check the commit 63 | let e = blind(commit(vote,~r),~b) 64 | d = sign(blind(commit(vote,~r),~b),~ltkA) 65 | y = sign(commit(vote,~r),~ltkA) 66 | x = commit(vote,~r) 67 | in 68 | [ In( ), St_V_1( V, vote, ~r, ~b), !AdminLtk(A, ~ltkA) ] 69 | --[ ]-> 70 | [ Out( ), St_V_2( V, A, vote, ~r ) ] 71 | 72 | rule C_1: 73 | let y = sign(x,~ltkA) 74 | in 75 | [ In( ), !AdminLtk(A, ~ltkA)] 76 | --[ ]-> 77 | [ St_C_1( A, x), Out() ] 78 | 79 | rule V_3: 80 | let x = commit(vote,~r) 81 | in 82 | [ In( x ), St_V_2(V, A, vote, ~r )] 83 | --[ ]-> 84 | [ Out( ~r ) ] 85 | 86 | rule C_2: 87 | let v = open(x, r) 88 | x = commit(open(x,r),r) 89 | in 90 | [ In( r ), St_C_1( A, x ) ] 91 | --[ VotePublished( v ), Out_C_2(x) ]-> 92 | [ Out( v ) ] 93 | 94 | 95 | 96 | // sources lemma 97 | 98 | lemma types [sources]: 99 | " ( All e #i. In_A_1(e) @ i 100 | ==> 101 | (Ex #j . Created_commit_V_1(e) @ j& j 105 | (Ex #j. Created_vote_V_1(v)@j & j 122 | ( Ex r b #i. Registered(blind(commit(vote,r),b)) @ i & #i < #j )" 123 | 124 | /* 125 | 126 | ============================================================================== 127 | summary of summaries: 128 | 129 | analyzed: examples/features/equational_theories/foo_eligibility.spthy 130 | 131 | types (all-traces): verified (32 steps) 132 | exec (exists-trace): verified (9 steps) 133 | eligibility (all-traces): verified (9 steps) 134 | 135 | ============================================================================== 136 | 137 | real 0m10.292s 138 | user 0m22.792s 139 | sys 0m10.180s 140 | 141 | */ 142 | 143 | end 144 | 145 | -------------------------------------------------------------------------------- /tutorial-models/3_from_slides/loop.spthy: -------------------------------------------------------------------------------- 1 | theory loop 2 | begin 3 | 4 | rule starting: 5 | [ Fr(x) ] 6 | --[ Start(x) ]-> 7 | [ A(x) ] 8 | 9 | rule looping: 10 | [ A(x) ] 11 | --[ Loop(x) ]-> 12 | [ A(x) ] 13 | 14 | lemma initalize: 15 | "All x #i. Loop(x)@i ==> Ex #j. Start(x)@j" 16 | 17 | end 18 | -------------------------------------------------------------------------------- /tutorial-models/3_from_slides/sources-nolemma-load.spthy: -------------------------------------------------------------------------------- 1 | theory sourcesNoLemmaLoad 2 | begin 3 | 4 | builtins: asymmetric-encryption 5 | 6 | // Public key infrastructure 7 | rule Register_pk: 8 | [ Fr(~ltkA) ] 9 | --> 10 | [ !Ltk($A, ~ltkA), !Pk($A, pk(~ltkA)), Out(pk(~ltkA)) ] 11 | 12 | 13 | /* We formalize the following protocol 14 | protocol { 15 | 1. I -> R: {ni,I}pk(R) 16 | 2. I <- R: {ni}pk(I) 17 | } 18 | */ 19 | 20 | rule I_1: 21 | let m1 = aenc{~ni, $I}pkR 22 | in 23 | [ Fr(~ni) , !Pk($R, pkR) ] 24 | --[ OUT_I_1(m1) ]-> 25 | [ Out( m1 ) ] 26 | 27 | rule R_1: 28 | let m1 = aenc{ni, I}pk(ltkR) 29 | m2 = aenc{ni}pkI 30 | in 31 | [ !Ltk($R, ltkR) , In( m1 ), !Pk(I, pkI) ] 32 | --[ IN_R_1_ni( ni, m1 ) , Finish() ]-> 33 | [ Out( m2 ) ] 34 | 35 | lemma show: 36 | exists-trace "Ex #i. Finish()@i" 37 | simplify 38 | solve( !Ltk( $R, ltkR ) ▶₀ #i ) 39 | case Register_pk 40 | solve( !Pk( I, pkI ) ▶₂ #i ) 41 | case Register_pk 42 | solve( !KU( aenc(, pk(~ltkA)) ) @ #vk ) 43 | case I_1 44 | by sorry /* removed */ 45 | next 46 | case R_1_case_1 47 | solve( !KU( aenc(<, $R>, pk(~ltkA.2)) ) @ #vk.1 ) 48 | case R_1_case_1 49 | solve( !KU( aenc(<<, $R>, $R.1>, pk(~ltkA.3)) ) @ #vk.2 ) 50 | case R_1_case_1 51 | solve( !KU( aenc(<<<, $R>, $R.1>, $R.2>, pk(~ltkA.4)) 52 | ) @ #vk.3 ) 53 | case R_1_case_1 54 | by sorry 55 | next 56 | case R_1_case_2 57 | by sorry 58 | next 59 | case c_aenc 60 | by sorry 61 | qed 62 | next 63 | case R_1_case_2 64 | by sorry 65 | next 66 | case c_aenc 67 | by sorry 68 | qed 69 | next 70 | case R_1_case_2 71 | by sorry 72 | next 73 | case c_aenc 74 | by sorry 75 | qed 76 | next 77 | case R_1_case_2 78 | by sorry 79 | next 80 | case c_aenc 81 | solve( !KU( pk(~ltkA) ) @ #vk.2 ) 82 | case R_1 83 | by sorry 84 | next 85 | case Register_pk 86 | by sorry /* removed */ 87 | next 88 | case c_pk 89 | solve( !KU( ~ltkA ) @ #vk.5 ) 90 | case R_1 91 | solve( !KU( ~ltkA.2 ) @ #vk.7 ) 92 | case R_1 93 | by sorry /* removed */ 94 | qed 95 | qed 96 | qed 97 | qed 98 | qed 99 | qed 100 | 101 | end 102 | -------------------------------------------------------------------------------- /tutorial-models/3_from_slides/sources.spthy: -------------------------------------------------------------------------------- 1 | theory sources 2 | begin 3 | 4 | builtins: asymmetric-encryption 5 | 6 | // Public key infrastructure 7 | rule Register_pk: 8 | [ Fr(~ltkA) ] 9 | --> 10 | [ !Ltk($A, ~ltkA), !Pk($A, pk(~ltkA)), Out(pk(~ltkA)) ] 11 | 12 | 13 | /* We formalize the following protocol 14 | protocol { 15 | 1. I -> R: {ni,I}pk(R) 16 | 2. I <- R: {ni}pk(I) 17 | } 18 | */ 19 | 20 | rule I_1: 21 | let m1 = aenc{~ni, $I}pkR 22 | in 23 | [ Fr(~ni) , !Pk($R, pkR) ] 24 | --[ OUT_I_1(m1) ]-> 25 | [ Out( m1 ) ] 26 | 27 | rule R_1: 28 | let m1 = aenc{ni, I}pk(ltkR) 29 | m2 = aenc{ni}pkI 30 | in 31 | [ !Ltk($R, ltkR) , In( m1 ), !Pk(I, pkI) ] 32 | --[ IN_R_1_ni( ni, m1 ) ]-> 33 | [ Out( m2 ) ] 34 | 35 | 36 | lemma types [sources]: 37 | " 38 | (All ni m1 #i. 39 | IN_R_1_ni( ni, m1) @ i 40 | ==> 41 | ( (Ex #j. KU(ni) @ j & j < i) 42 | | (Ex #j. OUT_I_1( m1 ) @ j) 43 | ) 44 | ) 45 | " 46 | 47 | 48 | end 49 | -------------------------------------------------------------------------------- /tutorial-models/4_observational_equivalence/SignedDH.spthy: -------------------------------------------------------------------------------- 1 | theory SignedDH 2 | begin 3 | 4 | section{* The Signed Diffie-Hellman Protocol for Observational Equivalence - for real-or-random strong secrecy *} 5 | 6 | builtins: diffie-hellman, signing 7 | functions: h/1 8 | 9 | // Public key infrastructure 10 | rule Register_pk: 11 | [ Fr(~ltk) ] 12 | --[ Register($A) ]-> 13 | [ !Ltk($A, ~ltk), !Pk($A, pk(~ltk)) ] 14 | 15 | rule Get_pk: 16 | [ !Pk(A, pk) ] 17 | --> 18 | [ Out(pk) ] 19 | 20 | // Protocol 21 | rule Init_1: 22 | [ Fr(~ekI), !Ltk($I, ltkI) ] 23 | --> 24 | [ Init_1( $I, $R, ~ekI ) 25 | , Out( <$I, $R, 'g' ^ ~ekI, sign{'1', $I, $R,'g' ^ ~ekI }ltkI> ) ] 26 | 27 | rule Init_2: 28 | let Y = 'g' ^ z // think of this as a group element check 29 | in 30 | [ Init_1( $I, $R, ~ekI ) 31 | , !Pk($R, pk(ltkR)) 32 | , In( <$R, $I, Y, sign{'2', $R, $I, Y }ltkR> ) 33 | ] 34 | --[ SessionKey($I,$R, Y ^ ~ekI) 35 | , ExpR(z) 36 | ]-> 37 | [ InitiatorKey($I,$R, Y ^ ~ekI) ] 38 | 39 | rule Resp: 40 | let X = 'g' ^ z // think of this as a group element check 41 | in 42 | [ !Pk($I, pk(ltkI)) 43 | , !Ltk($R, ltkR) 44 | , Fr(~ekR) 45 | , In( <$I, $R, X, sign{'1', $I, $R, X }ltkI> ) 46 | ] 47 | --[ SessionKey($I,$R, X ^ ~ekR) 48 | , ExpR(z) ]-> 49 | [ 50 | ResponderKey($I,$R, X ^ ~ekR) 51 | , Out( <$R, $I, 'g' ^ ~ekR, sign{'2', $R, $I, 'g' ^ ~ekR }ltkR> ) 52 | ] 53 | 54 | 55 | rule ChallengeInitiator: 56 | [ InitiatorKey(I,R, k) , Fr(~z)] 57 | --[ Challenge(I,R,diff(k, ~z)) 58 | , SafeChallenge() 59 | ]-> 60 | [ Out(diff(k,'g'^~z)) ] 61 | // [ Out(diff(k,~z)) ] 62 | // the other output must be a 'g'^~z or even 'g'^~z^~f (for another fresh ~f) 63 | 64 | rule ChallengeResponder: 65 | [ ResponderKey(I,R, k) , Fr(~z)] 66 | --[ Challenge(I,R,diff(k, ~z)) 67 | , SafeChallenge() 68 | ]-> 69 | [ Out(diff(k,'g'^~z)) ] 70 | // [ Out(diff(k,~z)) ] 71 | // the other output must be a 'g'^~z or even 'g'^~z^~f (for another fresh ~f) 72 | 73 | 74 | //restriction singleChallenge: 75 | // "All I R k I2 R2 k2 #j #j2. Challenge(I, R, k)@j & Challenge(I2, R2, k2)@ j2 ==> #j = #j2" 76 | 77 | restriction safeSingleChallenge: 78 | " All #i1 #i2. SafeChallenge() @i1 & SafeChallenge() @i2 ==> #i1 = #i2" 79 | 80 | end 81 | -------------------------------------------------------------------------------- /tutorial-models/4_observational_equivalence/probEnc.spthy: -------------------------------------------------------------------------------- 1 | theory probEnc 2 | begin 3 | 4 | /* 5 | * Protocol: Probabilistic encryption 6 | * Modeler: Jannik Dreier and Ralf Sasse 7 | * Described in: Automated Symbolic Proofs of Observational Equivalence [CCS'15] 8 | * Date: April 2015 9 | * 10 | * Status: working 11 | // Observational equivalence is proven automatically in less than 0.4 seconds. 12 | */ 13 | 14 | functions: penc/3, pdec/2, pk/1 15 | 16 | equations: pdec(penc(m,pk(k),r), k) = m 17 | 18 | rule gen: 19 | [ Fr(~k) ] 20 | --[ ]-> 21 | [ !Key(~k), Out(pk(~k)) ] 22 | 23 | rule enc: 24 | [ !Key(k), Fr(~r1), Fr(~r2), In(x) ] 25 | --[ ]-> 26 | [ Out(diff(~r1, penc(x, pk(k), ~r2))) ] 27 | 28 | end 29 | -------------------------------------------------------------------------------- /tutorial-models/tutorial-models.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tamarin-prover/teaching/e5ee58948c019e89224f5481d4720c7b30dc8387/tutorial-models/tutorial-models.zip --------------------------------------------------------------------------------