<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="../../../unit.xsl"?>
<KIVSPEC name="security"><SPECBODY>enrich <a href="../../../specs/CINDY/export/unit.xml">CINDY</a> with
   
   predicates 
      only-issued-tickets-are-accepted : (agent → documentlist) × (agent → noncelist);
      user-secret-known-by-owner : (agent → documentset);
      issued-tickets-received-or-unprocessed-if-not-full : (agent → documentlist) × (agent → documentlist) × (agent → nat → documentlist);
      nonces-unknown-to-user : (agent → documentset) × (agent → nat → documentlist);
      if-accepted-then-presented : (agent → documentlist) × (agent → noncelist) × (agent → noncelist);
      tickets-from-cinema-unique-if-not-fwd : (agent → documentlist) × (agent → documentlist) × (agent → nat → documentlist) × documentset × 
                                              (agent → documentset) × (agent → noncelist) × (agent → documentlist);
      state-invariant : (agent → noncelist) × (agent → documentlist) × (nat → nonce) × documentset × connections × (agent → documentlist) × 
                        (agent → nat → documentlist) × nat × (agent → documentlist) × (agent → noncelist) × (agent → documentlist) × 
                        (agent → documentset);
      accepted-with-presenter-wellformed : (agent → documentlist);
      cell-phone-tickets-are-real-issued : (agent → documentlist) × (agent → nat → documentlist) × (agent → documentlist);
      cinema-tickets-are-issued : (agent → documentlist) × (agent → nat → documentlist) × (agent → documentlist);
      only-known-nonces-are-presented : (agent → noncelist) × (agent → nat → documentlist) × documentset × (agent → documentlist);
      unused-nonces-unknown : (nat → nonce) × nat × (agent → nat → documentlist) × documentset × (agent → documentset) × (agent → documentlist);
      issued-tickets-are-accepted : (agent → documentlist) × (agent → noncelist) × (agent → noncelist);
      no-negative-sender-ID : (agent → nat → documentlist);
      accepted-and-presenter-consistent : (agent → noncelist) × (agent → documentlist);
      user-secret-remains-secret : (agent → documentset) × (agent → nat → documentlist) × documentset;
      connections-wellformed : connections;
      tickets-wellformed : (agent → documentlist);
      ticket-is-accepted-only-once : (agent → noncelist);
      issued-wellformed : (agent → documentlist);
      msgs-wellformed : (agent → nat → documentlist);
      attacker-secrets-unknown-to-user : documentset × (agent → documentset) × (agent → nat → documentlist);
      ticket-forwarded : nonce × agent × (agent → documentlist);
      forwarded-only-if-in-tickets : (agent → documentlist) × (agent → documentlist);
      already-presented : nonce × (agent → noncelist) × (agent → nat → documentlist);
      cinema-ticket-inputs : nonce × document;
      cinema-ticket-tickets : nonce × document;
      tickets-from-cinema-unique-if-not-fwd : (agent → documentlist) × (agent → documentlist) × documentset × (agent → noncelist) × 
                                              (agent → documentlist) × (agent → nat → documentlist);
      first-presented-by-owner : nonce × nat × nat × (agent → documentlist) × (agent → documentlist) × (agent → noncelist) × 
                                 (agent → nat → documentlist);
      not-fwd-not-known-by-others : nonce × nat × nat × (agent → documentlist) × (agent → documentlist) × documentset × (agent → noncelist) × 
                                    (agent → nat → documentlist);
      fresh-ticket-unique : nonce × nat × nat × (agent → documentlist) × (agent → documentlist) × documentset × (agent → noncelist) × 
                            (agent → nat → documentlist);
      owner-accepted : nonce × nat × nat × (agent → documentlist) × (agent → documentlist) × (agent → noncelist) × (agent → documentlist) × 
                       (agent → nat → documentlist);
      issued-list-wellformed : documentlist;
      bad-cell-phone-ports-empty : (agent → nat → documentlist);
   variables 
      i1 : int; 
   
   axioms 
      only-issued-tickets-are-accepted
      :  ⊦ only-issued-tickets-are-accepted(issued, accepted) ↔ (∀ nonce. nonce ∈ accepted(cinema) → nonce ∈ issued(cinema))
      ;
      user-secret-known-by-owner
      :  ⊦ user-secret-known-by-owner(user-known) ↔ (∀ agent. user?(agent) ∧ ∃agent(agent) → secretdoc(agent-secret(agent)) ∈ user-known(agent))
      ;
      issued-tickets-received-or-unprocessed-if-not-full
      : ⊦ 
          issued-tickets-received-or-unprocessed-if-not-full(issued, tickets, inputs)
        ↔ (∀ doc, j0. 
                (∃ i, nonce. doc = doclist(intdoc(i) ' + noncedoc(nonce) '))
              ∧ (∃ i, j. doclist(intdoc(i) ' + intdoc(j) ' + intdoc(j0) ' + doc ') ∈ issued(cinema)) ∧ cell-phone?(phone-number2agent(j0))
              ∧ ∃agent(phone-number2agent(j0)) ∧ # tickets(phone-number2agent(j0)) &lt; MAX-NO-TICKETS
            →   doclist(intdoc(n→i(cinema .no)) ' + comdoc(loadTicket, doc) ') ∈ inputs(phone-number2agent(j0))(2)
              ∨ doclist(intdoc(n→i(cinema .no)) ' + doc ') ∈ tickets(phone-number2agent(j0)))
      ;
      nonces-unknown-to-user
      : ⊦ 
          nonces-unknown-to-user(user-known, inputs)
        ↔ (∀ nonce, n. ¬ noncedoc(nonce) ∈∫ user-known(user(n)) ∧ (∀ m. ¬ noncedoc(nonce) ∈∫ inputs(user(n))(m)))
      ;
      if-accepted-then-presented
      : ⊦ 
          if-accepted-then-presented(issued, accepted, presented)
        ↔ (∀ nonce. nonce ∈ accepted(cinema) → nonce ∈ presented(cinema) ∧ nonce ∈ issued(cinema))
      ;
      bad-cell-phone-ports-empty :  ⊦ bad-cell-phone-ports-empty(inputs) ↔ (∀ m, n. n ≠ 1 ∧ n ≠ 2 → inputs(cell-phone(m))(n) = []);
      cinema-ticket-inputs
      : ⊦ 
          cinema-ticket-inputs(nonce, doc)
        ↔ (∃ i. doc = doclist(intdoc(n→i(cinema .no)) ' + comdoc(loadTicket, doclist(intdoc(i) ' + noncedoc(nonce) ')) '))
      ;
      cinema-ticket-tickets
      :  ⊦ cinema-ticket-tickets(nonce, doc) ↔ (∃ i. doc = doclist(intdoc(n→i(cinema .no)) ' + doclist(intdoc(i) ' + noncedoc(nonce) ')))
      ;
      owner-accepted
      : ⊦ 
          owner-accepted(nonce, n, m, tickets, passedOn, presented, accepted-with-presenter, inputs)
        ↔     n &lt; # tickets(cell-phone(m)) ∧ cinema-ticket-tickets(nonce, tickets(cell-phone(m))[n])
            ∧ ¬ ticket-forwarded(nonce, cell-phone(m), passedOn) ∧ already-presented(nonce, presented, inputs) ∧ nonce ∈ presented(cinema)
          → doclist(intdoc(n→i(m)) ' + noncedoc(nonce) ') ∈ accepted-with-presenter(cinema)
      ;
      fresh-ticket-unique
      : ⊦ 
          fresh-ticket-unique(nonce, n, m, tickets, passedOn, attacker-known, presented, inputs)
        ↔   n &lt; # inputs(cell-phone(m))(2) ∧ cinema-ticket-inputs(nonce, inputs(cell-phone(m))(2)[n])
          →   (∀ agent, n. agent ≠ cell-phone(m) → ¬ noncedoc(nonce) ∈∫ inputs(agent)(n)) ∧ (∀ agent. ¬ noncedoc(nonce) ∈∫ tickets(agent))
            ∧ ¬ noncedoc(nonce) ∈∫ attacker-known
            ∧ (∀ n0. n0 ≠ n ∧ n0 &lt; # inputs(cell-phone(m))(2) → ¬ noncedoc(nonce) ∈∫ (inputs(cell-phone(m))(2)[n0]))
            ∧ ¬ already-presented(nonce, presented, inputs) ∧ ¬ ticket-forwarded(nonce, cell-phone(m), passedOn)
            ∧ (∀ n0. n0 ≠ 2 → ¬ noncedoc(nonce) ∈∫ inputs(cell-phone(m))(n0))
      ;
      not-fwd-not-known-by-others
      : ⊦ 
          not-fwd-not-known-by-others(nonce, n, m, tickets, passedOn, attacker-known, presented, inputs)
        ↔     n &lt; # tickets(cell-phone(m)) ∧ cinema-ticket-tickets(nonce, tickets(cell-phone(m))[n])
            ∧ ¬ ticket-forwarded(nonce, cell-phone(m), passedOn) ∧ ¬ already-presented(nonce, presented, inputs)
          →   (∀ agent, n. ¬ (agent = cinema ∧ n = 3) → ¬ noncedoc(nonce) ∈∫ inputs(agent)(n)) ∧ ¬ noncedoc(nonce) ∈∫ attacker-known
            ∧ (∀ n0. n0 ≠ n ∧ n0 &lt; # tickets(cell-phone(m)) → ¬ noncedoc(nonce) ∈∫ (tickets(cell-phone(m))[n0]))
            ∧ (∀ agent. agent ≠ cell-phone(m) → ¬ noncedoc(nonce) ∈∫ tickets(agent))
      ;
      first-presented-by-owner
      : ⊦ 
          first-presented-by-owner(nonce, n, m, tickets, passedOn, presented, inputs)
        ↔     n &lt; # tickets(cell-phone(m)) ∧ cinema-ticket-tickets(nonce, tickets(cell-phone(m))[n])
            ∧ ¬ ticket-forwarded(nonce, cell-phone(m), passedOn) ∧ already-presented(nonce, presented, inputs) ∧ ¬ nonce ∈ presented(cinema)
          → (∀ n0. 
                n0 &lt; # inputs(cinema)(3) ∧ noncedoc(nonce) ∈∫ (inputs(cinema)(3)[n0]) ∧ (∀ n1. n1 &lt; n0 → ¬ noncedoc(nonce) ∈∫ (inputs(cinema)(3)[n1]))
              → (inputs(cinema)(3)[n0]) = doclist(intdoc(n→i(m)) ' + noncedoc(nonce) '))
      ;
      tickets-from-cinema-unique-if-not-fwd
      : ⊦ 
          tickets-from-cinema-unique-if-not-fwd(tickets, passedOn, attacker-known, presented, accepted-with-presenter, inputs)
        ↔ (∀ nonce, m, n. 
              fresh-ticket-unique(nonce, n, m, tickets, passedOn, attacker-known, presented, inputs)
            ∧ not-fwd-not-known-by-others(nonce, n, m, tickets, passedOn, attacker-known, presented, inputs)
            ∧ first-presented-by-owner(nonce, n, m, tickets, passedOn, presented, inputs)
            ∧ owner-accepted(nonce, n, m, tickets, passedOn, presented, accepted-with-presenter, inputs))
      ;
      already-presented :  ⊦ already-presented(nonce, presented, inputs) ↔ noncedoc(nonce) ∈∫ inputs(cinema)(3) ∨ nonce ∈ presented(cinema);
      ticket-forwarded :  ⊦ ticket-forwarded(nonce, agent, passedOn) ↔ noncedoc(nonce) ∈∫ passedOn(agent);
      forwarded-only-if-in-tickets
      :  ⊦ forwarded-only-if-in-tickets(tickets, passedOn) ↔ (∀ agent, nonce. noncedoc(nonce) ∈∫ passedOn(agent) → noncedoc(nonce) ∈∫ tickets(agent))
      ;
      state-invariant
      : ⊦ 
          state-invariant
          (accepted, accepted-with-presenter, all-nonces, attacker-known, connections, issued, inputs, next-nonce, passedOn, presented, tickets, 
           user-known)
        ↔   cell-phone-tickets-are-real-issued(tickets, inputs, issued) ∧ accepted-with-presenter-wellformed(accepted-with-presenter)
          ∧ cinema-tickets-are-issued(issued, inputs, tickets) ∧ only-known-nonces-are-presented(presented, inputs, attacker-known, tickets)
          ∧ unused-nonces-unknown(all-nonces, next-nonce, inputs, attacker-known, user-known, tickets)
          ∧ issued-tickets-are-accepted(issued, presented, accepted) ∧ no-negative-sender-ID(inputs)
          ∧ accepted-and-presenter-consistent(accepted, accepted-with-presenter)
          ∧ attacker-secrets-unknown-to-user(attacker-known, user-known, inputs) ∧ user-secret-remains-secret(user-known, inputs, attacker-known)
          ∧ connections-wellformed(connections) ∧ tickets-wellformed(tickets) ∧ msgs-wellformed(inputs) ∧ issued-wellformed(issued)
          ∧ max∫ attacker-known ∧ (∀ agent. max∫ user-known(agent)) ∧ ¬ dups(all-nonces) ∧ user-secret-known-by-owner(user-known)
          ∧ issued-tickets-received-or-unprocessed-if-not-full(issued, tickets, inputs) ∧ nonces-unknown-to-user(user-known, inputs)
          ∧ if-accepted-then-presented(issued, accepted, presented)
          ∧ tickets-from-cinema-unique-if-not-fwd(tickets, passedOn, attacker-known, presented, accepted-with-presenter, inputs)
          ∧ ticket-is-accepted-only-once(accepted) ∧ forwarded-only-if-in-tickets(tickets, passedOn)
      ;
      cell-phone-tickets-are-real-issued
      : ⊦ 
          cell-phone-tickets-are-real-issued(tickets, inputs, issued)
        ↔ (∀ nonce, m, n. 
                n &lt; # tickets(cell-phone(m)) ∧ cinema-ticket-tickets(nonce, tickets(cell-phone(m))[n])
              ∨ n &lt; # inputs(cell-phone(m))(2) ∧ cinema-ticket-inputs(nonce, inputs(cell-phone(m))(2)[n])
            → nonce ∈ real-issued(issued(cinema)))
      ;
      accepted-with-presenter-wellformed
      : ⊦ 
          accepted-with-presenter-wellformed(accepted-with-presenter)
        ↔ (∀ doc. 
              doc ∈ accepted-with-presenter(cinema)
            → is-doclist(doc) ∧ is-intdoc(get-part(doc, 1)) ∧ is-noncedoc(get-part(doc, 2)) ∧ get-int(get-part(doc, 1)) ≥ 0)
      ;
      cinema-tickets-are-issued
      : ⊦ 
          cinema-tickets-are-issued(issued, inputs, tickets)
        ↔ (∀ nonce, i, m. 
                doclist(intdoc(n→i(cinema .no)) ' + comdoc(loadTicket, doclist(intdoc(i) ' + noncedoc(nonce) '))) ∈ inputs(cell-phone(m))(2)
              ∨ doclist(intdoc(n→i(cinema .no)) ' + doclist(intdoc(i) ' + noncedoc(nonce) ')) ∈ tickets(cell-phone(m))
            → (∃ i0, j. 
                  (i0 = buyCell-Phone ∨ i0 = buyInternet)
                ∧ doclist(intdoc(i0) ' + intdoc(j) ' + intdoc(n→i(m)) ' + doclist(intdoc(i) ' + noncedoc(nonce) ') ') ∈ issued(cinema)))
      ;
      only-known-nonces-are-presented
      : ⊦ 
          only-known-nonces-are-presented(presented, inputs, attacker-known, tickets)
        ↔ (∀ nonce. 
              nonce ∈ presented(cinema) ∨ noncedoc(nonce) ∈∫ inputs(cinema)(3)
            → noncedoc(nonce) ∈∫ attacker-known ∨ (∃ agent. cell-phone?(agent) ∧ noncedoc(nonce) ∈∫ tickets(agent)))
      ;
      unused-nonces-unknown
      : ⊦ 
          unused-nonces-unknown(all-nonces, next-nonce, inputs, attacker-known, user-known, tickets)
        ↔ (∀ n. 
              n ≥ next-nonce
            →   ¬ noncedoc(all-nonces(n)) ∈∫ attacker-known ∧ (∀ agent. ¬ noncedoc(all-nonces(n)) ∈∫ user-known(agent))
              ∧ (∀ agent, n0. ¬ noncedoc(all-nonces(n)) ∈∫ inputs(agent)(n0)) ∧ (∀ agent. ¬ noncedoc(all-nonces(n)) ∈∫ tickets(agent)))
      ;
      issued-tickets-are-accepted
      : ⊦ 
          issued-tickets-are-accepted(issued, presented, accepted)
        ↔ (∀ nonce. nonce ∈ issued(cinema) ∧ nonce ∈ presented(cinema) → nonce ∈ accepted(cinema))
      ;
      no-negative-sender-ID
      : ⊦ 
        no-negative-sender-ID(inputs) ↔ (∀ agent, n. is-direct-endpoint(agent ⊙ n) → (∀ doc. doc ∈ inputs(agent)(n) → get-int(get-part(doc, 1)) ≥ 0))
      ;
      accepted-and-presenter-consistent
      : ⊦ 
          accepted-and-presenter-consistent(accepted, accepted-with-presenter)
        ↔ (∀ nonce. nonce ∈ accepted(cinema) ↔ (∃ i. doclist(intdoc(i) ' + noncedoc(nonce) ') ∈ accepted-with-presenter(cinema)))
      ;
      attacker-secrets-unknown-to-user
      : ⊦ 
          attacker-secrets-unknown-to-user(attacker-known, user-known, inputs)
        ↔ (∀ secret. 
              secretdoc(secret) ∈∫ attacker-known
            → (∀ agent. ¬ secretdoc(secret) ∈∫ user-known(agent)) ∧ (∀ agent, n. user?(agent) → ¬ secretdoc(secret) ∈∫ inputs(agent)(n)))
      ;
      user-secret-remains-secret
      : ⊦ 
          user-secret-remains-secret(user-known, inputs, attacker-known)
        ↔   (∀ secret, agent, n. user?(agent) → ¬ secretdoc(secret) ∈∫ inputs(agent)(n))
          ∧ (∀ secret, n. 
                secretdoc(secret) ∈∫ user-known(user(n))
              →   (∀ agent, n. attacker?(agent) → ¬ secretdoc(secret) ∈∫ inputs(agent)(n)) ∧ ¬ secretdoc(secret) ∈∫ attacker-known
                ∧ (∀ agent0. agent0 ≠ user(n) → ¬ secretdoc(secret) ∈∫ user-known(agent0)))
      ;
      connections-wellformed :  ⊦ connections-wellformed(connections) ↔ (∀ conn. conn ∈ connections → conn-ok(conn));
      tickets-wellformed
      : ⊦ 
          tickets-wellformed(tickets)
        ↔ (∀ agent, doc. doc ∈ tickets(agent) → (∃ i, i0, nonce. doc = doclist(intdoc(i) ' + doclist(intdoc(i0) ' + noncedoc(nonce) ') ')))
      ;
      msgs-wellformed
      :  ⊦ msgs-wellformed(inputs) ↔ (∀ agent, n, doc. doc ∈ inputs(agent)(n) → is-doclist(doc) ∧ # doc .list = 2 ∧ is-intdoc(get-part(doc, 1)))
      ;
      issued-wellformed :  ⊦ issued-wellformed(issued) ↔ issued-list-wellformed(issued(cinema));
      issued-list-wellformed
      : ⊦ 
          issued-list-wellformed(docs)
        ↔ (∀ doc. 
              doc ∈ docs
            → (∃ i, i0, j, j0, nonce. 
                  (i = buyInternet ∨ i = buyCell-Phone)
                ∧ doc = doclist(intdoc(i) ' + intdoc(i0) ' + (intdoc(j) ' + doclist(intdoc(j0) ' + noncedoc(nonce) ')))))
      ;
      ticket-is-accepted-only-once :  ⊦ ticket-is-accepted-only-once(accepted) ↔ ¬ dups(accepted(cinema));
   
end enrich</SPECBODY></KIVSPEC>