scyther-proof (empty) → 0.3.0
raw patch · 144 files changed
+63849/−0 lines, 144 filesdep +arraydep +basedep +cmdargssetup-changedbinary-added
Dependencies added: array, base, cmdargs, containers, directory, filepath, json, mtl, parsec, pretty, process, safe, tagsoup, time, uniplate
Files
- .ghci +3/−0
- LICENSE +674/−0
- README +165/−0
- Setup.hs +2/−0
- data/HTML_TEMPLATE +52/−0
- data/css/scyther-proof.css +58/−0
- data/css/ui-lightness/images/ui-anim_basic_16x16.gif binary
- data/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png binary
- data/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png binary
- data/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png binary
- data/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png binary
- data/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png binary
- data/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png binary
- data/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png binary
- data/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png binary
- data/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png binary
- data/css/ui-lightness/images/ui-icons_222222_256x240.png binary
- data/css/ui-lightness/images/ui-icons_228ef1_256x240.png binary
- data/css/ui-lightness/images/ui-icons_ef8c08_256x240.png binary
- data/css/ui-lightness/images/ui-icons_ffd27a_256x240.png binary
- data/css/ui-lightness/images/ui-icons_ffffff_256x240.png binary
- data/css/ui-lightness/jquery-ui-1.8.2.custom.css +489/−0
- data/css/ui-lightness/jquery.ui.accordion.css +12/−0
- data/css/ui-lightness/jquery.ui.all.css +2/−0
- data/css/ui-lightness/jquery.ui.autocomplete.css +39/−0
- data/css/ui-lightness/jquery.ui.base.css +11/−0
- data/css/ui-lightness/jquery.ui.button.css +35/−0
- data/css/ui-lightness/jquery.ui.core.css +37/−0
- data/css/ui-lightness/jquery.ui.datepicker.css +61/−0
- data/css/ui-lightness/jquery.ui.dialog.css +13/−0
- data/css/ui-lightness/jquery.ui.progressbar.css +4/−0
- data/css/ui-lightness/jquery.ui.resizable.css +13/−0
- data/css/ui-lightness/jquery.ui.selectable.css +3/−0
- data/css/ui-lightness/jquery.ui.slider.css +17/−0
- data/css/ui-lightness/jquery.ui.tabs.css +11/−0
- data/css/ui-lightness/jquery.ui.theme.css +249/−0
- data/examples/Makefile +36/−0
- data/examples/OVERVIEW +30/−0
- data/examples/classic/Andrew.spthy +65/−0
- data/examples/classic/BKE.spthy +79/−0
- data/examples/classic/CR_paper.spthy +30/−0
- data/examples/classic/DenningSacco.spthy +89/−0
- data/examples/classic/KerberosV.spthy +208/−0
- data/examples/classic/NS_Public.spthy +70/−0
- data/examples/classic/OtwayRees.spthy +143/−0
- data/examples/classic/TLS.spthy +128/−0
- data/examples/classic/WMF.spthy +76/−0
- data/examples/classic/WooLam.spthy +168/−0
- data/examples/classic/Yahalom2.spthy +79/−0
- data/examples/iso9798/isabelle-parallel-proofs/isoiec-9798-2-bdkey_cert_auto.thy +3214/−0
- data/examples/iso9798/isabelle-parallel-proofs/isoiec-9798-2-udkey_cert_auto.thy +1843/−0
- data/examples/iso9798/isabelle-parallel-proofs/isoiec-9798-3_cert_auto.thy +2773/−0
- data/examples/iso9798/isabelle-parallel-proofs/isoiec-9798-4-bdkey_cert_auto.thy +693/−0
- data/examples/iso9798/isabelle-parallel-proofs/isoiec-9798-4-udkey_cert_auto.thy +668/−0
- data/examples/iso9798/isabelle-proofs/isoiec-9798-2-bdkey_cert_auto.thy +3702/−0
- data/examples/iso9798/isabelle-proofs/isoiec-9798-2-udkey_cert_auto.thy +2190/−0
- data/examples/iso9798/isabelle-proofs/isoiec-9798-3_cert_auto.thy +3320/−0
- data/examples/iso9798/isabelle-proofs/isoiec-9798-4-bdkey_cert_auto.thy +899/−0
- data/examples/iso9798/isabelle-proofs/isoiec-9798-4-udkey_cert_auto.thy +874/−0
- data/examples/iso9798/isoiec-9798-2-bdkey.spthy +417/−0
- data/examples/iso9798/isoiec-9798-2-udkey.spthy +248/−0
- data/examples/iso9798/isoiec-9798-3.spthy +525/−0
- data/examples/iso9798/isoiec-9798-4-bdkey.spthy +122/−0
- data/examples/iso9798/isoiec-9798-4-udkey.spthy +121/−0
- data/index.html +592/−0
- data/isabelle/AUTHORS +5/−0
- data/isabelle/IsaMakefile +31/−0
- data/isabelle/Makefile +37/−0
- data/isabelle/README +165/−0
- data/isabelle/ROOT.ML +1/−0
- data/isabelle/document/root.tex +63/−0
- data/isabelle/src/ESPLogic.thy +27/−0
- data/isabelle/src/ESPLogic/Automation.thy +387/−0
- data/isabelle/src/ESPLogic/Capabilities.thy +258/−0
- data/isabelle/src/ESPLogic/DistinctList.thy +225/−0
- data/isabelle/src/ESPLogic/ExecMessage.thy +496/−0
- data/isabelle/src/ESPLogic/ExplicitModel.thy +1693/−0
- data/isabelle/src/ESPLogic/HOL_ext.thy +248/−0
- data/isabelle/src/ESPLogic/Hints.thy +92/−0
- data/isabelle/src/ESPLogic/InferenceRules.thy +481/−0
- data/isabelle/src/ESPLogic/Protocol.thy +354/−0
- data/isabelle/src/ESPLogic/Syntax.thy +80/−0
- data/isabelle/src/ESPLogic/Unify.thy +652/−0
- data/isabelle/src/ESPLogic/WeakTyping.thy +1150/−0
- data/isabelle/src/ESPLogic/espl_definitions.ML +863/−0
- data/isabelle/src/ESPLogic/espl_methods.ML +285/−0
- data/isabelle/src/ESPLogic/espl_utils.ML +200/−0
- data/isabelle/src/Technical_Report.thy +45/−0
- data/isabelle/src/Tutorial.thy +295/−0
- data/isabelle/src/compromising_adversaries/All_Examples.thy +27/−0
- data/isabelle/src/compromising_adversaries/CR_paper_acm.thy +595/−0
- data/isabelle/src/compromising_adversaries/NS_Public_acm.thy +462/−0
- data/isabelle/src/compromising_adversaries/PFS_acm.thy +472/−0
- data/isabelle/src/compromising_adversaries/TLS_acm.thy +1528/−0
- data/isabelle/src/compromising_adversaries/wPFS_acm.thy +492/−0
- data/isabelle/src/isar-keywords.el +645/−0
- data/js/jquery.js +6240/−0
- data/js/jquery.layout.js +3884/−0
- data/js/json_parse.js +345/−0
- data/js/tooltip/jquery.tooltip.css +9/−0
- data/js/tooltip/jquery.tooltip.js +294/−0
- data/js/tooltip/lib/jquery.bgiframe.js +104/−0
- data/js/tooltip/lib/jquery.dimensions.js +506/−0
- data/js/ui/jquery.effects.core.js +714/−0
- data/js/ui/jquery.ui.core.js +216/−0
- data/js/ui/jquery.ui.draggable.js +797/−0
- data/js/ui/jquery.ui.mouse.js +151/−0
- data/js/ui/jquery.ui.tabs.js +729/−0
- data/js/ui/jquery.ui.widget.js +236/−0
- dist/build/Scyther/Theory/Lexer.hs +579/−0
- dist/build/scyther-proof/scyther-proof-tmp/Scyther/Theory/Lexer.hs +579/−0
- interactive-only-src/Paths_scyther_proof.hs +29/−0
- scyther-proof.cabal +226/−0
- src/Control/Basics.hs +10/−0
- src/Control/Concurrent/ManagedThreads.hs +165/−0
- src/Control/Monad/BoundedDFS.hs +160/−0
- src/Control/Monad/Label.hs +90/−0
- src/Data/Color.hs +246/−0
- src/Data/DAG/Simple.hs +60/−0
- src/Data/Table.hs +268/−0
- src/Data/UnionFind.hs +115/−0
- src/Extension/Prelude.hs +217/−0
- src/Main.hs +857/−0
- src/Scyther/Equalities.hs +697/−0
- src/Scyther/Event.hs +190/−0
- src/Scyther/Facts.hs +1195/−0
- src/Scyther/Formula.hs +267/−0
- src/Scyther/GoalFlow.hs +206/−0
- src/Scyther/Message.hs +401/−0
- src/Scyther/Proof.hs +438/−0
- src/Scyther/Protocol.hs +458/−0
- src/Scyther/Sequent.hs +219/−0
- src/Scyther/Theory.hs +373/−0
- src/Scyther/Theory/Dot.hs +437/−0
- src/Scyther/Theory/Html.hs +393/−0
- src/Scyther/Theory/Lexer.x +372/−0
- src/Scyther/Theory/Parser.hs +894/−0
- src/Scyther/Theory/Pretty.hs +728/−0
- src/Scyther/Typing.hs +186/−0
- src/System/Isabelle.hs +121/−0
- src/System/Timing.hs +20/−0
- src/Text/Dot.hs +274/−0
- src/Text/Isar.hs +312/−0
- src/Text/PrettyPrint/Class.hs +136/−0
@@ -0,0 +1,3 @@+:set -iinteractive-only-src+:set -isrc+:set -Wall
@@ -0,0 +1,674 @@+ GNU GENERAL PUBLIC LICENSE+ Version 3, 29 June 2007++ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.++ Preamble++ The GNU General Public License is a free, copyleft license for+software and other kinds of works.++ The licenses for most software and other practical works are designed+to take away your freedom to share and change the works. By contrast,+the GNU General Public License is intended to guarantee your freedom to+share and change all versions of a program--to make sure it remains free+software for all its users. We, the Free Software Foundation, use the+GNU General Public License for most of our software; it applies also to+any other work released this way by its authors. You can apply it to+your programs, too.++ When we speak of free software, we are referring to freedom, not+price. Our General Public Licenses are designed to make sure that you+have the freedom to distribute copies of free software (and charge for+them if you wish), that you receive source code or can get it if you+want it, that you can change the software or use pieces of it in new+free programs, and that you know you can do these things.++ To protect your rights, we need to prevent others from denying you+these rights or asking you to surrender the rights. Therefore, you have+certain responsibilities if you distribute copies of the software, or if+you modify it: responsibilities to respect the freedom of others.++ For example, if you distribute copies of such a program, whether+gratis or for a fee, you must pass on to the recipients the same+freedoms that you received. You must make sure that they, too, receive+or can get the source code. And you must show them these terms so they+know their rights.++ Developers that use the GNU GPL protect your rights with two steps:+(1) assert copyright on the software, and (2) offer you this License+giving you legal permission to copy, distribute and/or modify it.++ For the developers' and authors' protection, the GPL clearly explains+that there is no warranty for this free software. For both users' and+authors' sake, the GPL requires that modified versions be marked as+changed, so that their problems will not be attributed erroneously to+authors of previous versions.++ Some devices are designed to deny users access to install or run+modified versions of the software inside them, although the manufacturer+can do so. This is fundamentally incompatible with the aim of+protecting users' freedom to change the software. The systematic+pattern of such abuse occurs in the area of products for individuals to+use, which is precisely where it is most unacceptable. Therefore, we+have designed this version of the GPL to prohibit the practice for those+products. If such problems arise substantially in other domains, we+stand ready to extend this provision to those domains in future versions+of the GPL, as needed to protect the freedom of users.++ Finally, every program is threatened constantly by software patents.+States should not allow patents to restrict development and use of+software on general-purpose computers, but in those that do, we wish to+avoid the special danger that patents applied to a free program could+make it effectively proprietary. To prevent this, the GPL assures that+patents cannot be used to render the program non-free.++ The precise terms and conditions for copying, distribution and+modification follow.++ TERMS AND CONDITIONS++ 0. Definitions.++ "This License" refers to version 3 of the GNU General Public License.++ "Copyright" also means copyright-like laws that apply to other kinds of+works, such as semiconductor masks.++ "The Program" refers to any copyrightable work licensed under this+License. Each licensee is addressed as "you". "Licensees" and+"recipients" may be individuals or organizations.++ To "modify" a work means to copy from or adapt all or part of the work+in a fashion requiring copyright permission, other than the making of an+exact copy. The resulting work is called a "modified version" of the+earlier work or a work "based on" the earlier work.++ A "covered work" means either the unmodified Program or a work based+on the Program.++ To "propagate" a work means to do anything with it that, without+permission, would make you directly or secondarily liable for+infringement under applicable copyright law, except executing it on a+computer or modifying a private copy. Propagation includes copying,+distribution (with or without modification), making available to the+public, and in some countries other activities as well.++ To "convey" a work means any kind of propagation that enables other+parties to make or receive copies. Mere interaction with a user through+a computer network, with no transfer of a copy, is not conveying.++ An interactive user interface displays "Appropriate Legal Notices"+to the extent that it includes a convenient and prominently visible+feature that (1) displays an appropriate copyright notice, and (2)+tells the user that there is no warranty for the work (except to the+extent that warranties are provided), that licensees may convey the+work under this License, and how to view a copy of this License. If+the interface presents a list of user commands or options, such as a+menu, a prominent item in the list meets this criterion.++ 1. Source Code.++ The "source code" for a work means the preferred form of the work+for making modifications to it. "Object code" means any non-source+form of a work.++ A "Standard Interface" means an interface that either is an official+standard defined by a recognized standards body, or, in the case of+interfaces specified for a particular programming language, one that+is widely used among developers working in that language.++ The "System Libraries" of an executable work include anything, other+than the work as a whole, that (a) is included in the normal form of+packaging a Major Component, but which is not part of that Major+Component, and (b) serves only to enable use of the work with that+Major Component, or to implement a Standard Interface for which an+implementation is available to the public in source code form. A+"Major Component", in this context, means a major essential component+(kernel, window system, and so on) of the specific operating system+(if any) on which the executable work runs, or a compiler used to+produce the work, or an object code interpreter used to run it.++ The "Corresponding Source" for a work in object code form means all+the source code needed to generate, install, and (for an executable+work) run the object code and to modify the work, including scripts to+control those activities. However, it does not include the work's+System Libraries, or general-purpose tools or generally available free+programs which are used unmodified in performing those activities but+which are not part of the work. For example, Corresponding Source+includes interface definition files associated with source files for+the work, and the source code for shared libraries and dynamically+linked subprograms that the work is specifically designed to require,+such as by intimate data communication or control flow between those+subprograms and other parts of the work.++ The Corresponding Source need not include anything that users+can regenerate automatically from other parts of the Corresponding+Source.++ The Corresponding Source for a work in source code form is that+same work.++ 2. Basic Permissions.++ All rights granted under this License are granted for the term of+copyright on the Program, and are irrevocable provided the stated+conditions are met. This License explicitly affirms your unlimited+permission to run the unmodified Program. The output from running a+covered work is covered by this License only if the output, given its+content, constitutes a covered work. This License acknowledges your+rights of fair use or other equivalent, as provided by copyright law.++ You may make, run and propagate covered works that you do not+convey, without conditions so long as your license otherwise remains+in force. You may convey covered works to others for the sole purpose+of having them make modifications exclusively for you, or provide you+with facilities for running those works, provided that you comply with+the terms of this License in conveying all material for which you do+not control copyright. Those thus making or running the covered works+for you must do so exclusively on your behalf, under your direction+and control, on terms that prohibit them from making any copies of+your copyrighted material outside their relationship with you.++ Conveying under any other circumstances is permitted solely under+the conditions stated below. Sublicensing is not allowed; section 10+makes it unnecessary.++ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.++ No covered work shall be deemed part of an effective technological+measure under any applicable law fulfilling obligations under article+11 of the WIPO copyright treaty adopted on 20 December 1996, or+similar laws prohibiting or restricting circumvention of such+measures.++ When you convey a covered work, you waive any legal power to forbid+circumvention of technological measures to the extent such circumvention+is effected by exercising rights under this License with respect to+the covered work, and you disclaim any intention to limit operation or+modification of the work as a means of enforcing, against the work's+users, your or third parties' legal rights to forbid circumvention of+technological measures.++ 4. Conveying Verbatim Copies.++ You may convey verbatim copies of the Program's source code as you+receive it, in any medium, provided that you conspicuously and+appropriately publish on each copy an appropriate copyright notice;+keep intact all notices stating that this License and any+non-permissive terms added in accord with section 7 apply to the code;+keep intact all notices of the absence of any warranty; and give all+recipients a copy of this License along with the Program.++ You may charge any price or no price for each copy that you convey,+and you may offer support or warranty protection for a fee.++ 5. Conveying Modified Source Versions.++ You may convey a work based on the Program, or the modifications to+produce it from the Program, in the form of source code under the+terms of section 4, provided that you also meet all of these conditions:++ a) The work must carry prominent notices stating that you modified+ it, and giving a relevant date.++ b) The work must carry prominent notices stating that it is+ released under this License and any conditions added under section+ 7. This requirement modifies the requirement in section 4 to+ "keep intact all notices".++ c) You must license the entire work, as a whole, under this+ License to anyone who comes into possession of a copy. This+ License will therefore apply, along with any applicable section 7+ additional terms, to the whole of the work, and all its parts,+ regardless of how they are packaged. This License gives no+ permission to license the work in any other way, but it does not+ invalidate such permission if you have separately received it.++ d) If the work has interactive user interfaces, each must display+ Appropriate Legal Notices; however, if the Program has interactive+ interfaces that do not display Appropriate Legal Notices, your+ work need not make them do so.++ A compilation of a covered work with other separate and independent+works, which are not by their nature extensions of the covered work,+and which are not combined with it such as to form a larger program,+in or on a volume of a storage or distribution medium, is called an+"aggregate" if the compilation and its resulting copyright are not+used to limit the access or legal rights of the compilation's users+beyond what the individual works permit. Inclusion of a covered work+in an aggregate does not cause this License to apply to the other+parts of the aggregate.++ 6. Conveying Non-Source Forms.++ You may convey a covered work in object code form under the terms+of sections 4 and 5, provided that you also convey the+machine-readable Corresponding Source under the terms of this License,+in one of these ways:++ a) Convey the object code in, or embodied in, a physical product+ (including a physical distribution medium), accompanied by the+ Corresponding Source fixed on a durable physical medium+ customarily used for software interchange.++ b) Convey the object code in, or embodied in, a physical product+ (including a physical distribution medium), accompanied by a+ written offer, valid for at least three years and valid for as+ long as you offer spare parts or customer support for that product+ model, to give anyone who possesses the object code either (1) a+ copy of the Corresponding Source for all the software in the+ product that is covered by this License, on a durable physical+ medium customarily used for software interchange, for a price no+ more than your reasonable cost of physically performing this+ conveying of source, or (2) access to copy the+ Corresponding Source from a network server at no charge.++ c) Convey individual copies of the object code with a copy of the+ written offer to provide the Corresponding Source. This+ alternative is allowed only occasionally and noncommercially, and+ only if you received the object code with such an offer, in accord+ with subsection 6b.++ d) Convey the object code by offering access from a designated+ place (gratis or for a charge), and offer equivalent access to the+ Corresponding Source in the same way through the same place at no+ further charge. You need not require recipients to copy the+ Corresponding Source along with the object code. If the place to+ copy the object code is a network server, the Corresponding Source+ may be on a different server (operated by you or a third party)+ that supports equivalent copying facilities, provided you maintain+ clear directions next to the object code saying where to find the+ Corresponding Source. Regardless of what server hosts the+ Corresponding Source, you remain obligated to ensure that it is+ available for as long as needed to satisfy these requirements.++ e) Convey the object code using peer-to-peer transmission, provided+ you inform other peers where the object code and Corresponding+ Source of the work are being offered to the general public at no+ charge under subsection 6d.++ A separable portion of the object code, whose source code is excluded+from the Corresponding Source as a System Library, need not be+included in conveying the object code work.++ A "User Product" is either (1) a "consumer product", which means any+tangible personal property which is normally used for personal, family,+or household purposes, or (2) anything designed or sold for incorporation+into a dwelling. In determining whether a product is a consumer product,+doubtful cases shall be resolved in favor of coverage. For a particular+product received by a particular user, "normally used" refers to a+typical or common use of that class of product, regardless of the status+of the particular user or of the way in which the particular user+actually uses, or expects or is expected to use, the product. A product+is a consumer product regardless of whether the product has substantial+commercial, industrial or non-consumer uses, unless such uses represent+the only significant mode of use of the product.++ "Installation Information" for a User Product means any methods,+procedures, authorization keys, or other information required to install+and execute modified versions of a covered work in that User Product from+a modified version of its Corresponding Source. The information must+suffice to ensure that the continued functioning of the modified object+code is in no case prevented or interfered with solely because+modification has been made.++ If you convey an object code work under this section in, or with, or+specifically for use in, a User Product, and the conveying occurs as+part of a transaction in which the right of possession and use of the+User Product is transferred to the recipient in perpetuity or for a+fixed term (regardless of how the transaction is characterized), the+Corresponding Source conveyed under this section must be accompanied+by the Installation Information. But this requirement does not apply+if neither you nor any third party retains the ability to install+modified object code on the User Product (for example, the work has+been installed in ROM).++ The requirement to provide Installation Information does not include a+requirement to continue to provide support service, warranty, or updates+for a work that has been modified or installed by the recipient, or for+the User Product in which it has been modified or installed. Access to a+network may be denied when the modification itself materially and+adversely affects the operation of the network or violates the rules and+protocols for communication across the network.++ Corresponding Source conveyed, and Installation Information provided,+in accord with this section must be in a format that is publicly+documented (and with an implementation available to the public in+source code form), and must require no special password or key for+unpacking, reading or copying.++ 7. Additional Terms.++ "Additional permissions" are terms that supplement the terms of this+License by making exceptions from one or more of its conditions.+Additional permissions that are applicable to the entire Program shall+be treated as though they were included in this License, to the extent+that they are valid under applicable law. If additional permissions+apply only to part of the Program, that part may be used separately+under those permissions, but the entire Program remains governed by+this License without regard to the additional permissions.++ When you convey a copy of a covered work, you may at your option+remove any additional permissions from that copy, or from any part of+it. (Additional permissions may be written to require their own+removal in certain cases when you modify the work.) You may place+additional permissions on material, added by you to a covered work,+for which you have or can give appropriate copyright permission.++ Notwithstanding any other provision of this License, for material you+add to a covered work, you may (if authorized by the copyright holders of+that material) supplement the terms of this License with terms:++ a) Disclaiming warranty or limiting liability differently from the+ terms of sections 15 and 16 of this License; or++ b) Requiring preservation of specified reasonable legal notices or+ author attributions in that material or in the Appropriate Legal+ Notices displayed by works containing it; or++ c) Prohibiting misrepresentation of the origin of that material, or+ requiring that modified versions of such material be marked in+ reasonable ways as different from the original version; or++ d) Limiting the use for publicity purposes of names of licensors or+ authors of the material; or++ e) Declining to grant rights under trademark law for use of some+ trade names, trademarks, or service marks; or++ f) Requiring indemnification of licensors and authors of that+ material by anyone who conveys the material (or modified versions of+ it) with contractual assumptions of liability to the recipient, for+ any liability that these contractual assumptions directly impose on+ those licensors and authors.++ All other non-permissive additional terms are considered "further+restrictions" within the meaning of section 10. If the Program as you+received it, or any part of it, contains a notice stating that it is+governed by this License along with a term that is a further+restriction, you may remove that term. If a license document contains+a further restriction but permits relicensing or conveying under this+License, you may add to a covered work material governed by the terms+of that license document, provided that the further restriction does+not survive such relicensing or conveying.++ If you add terms to a covered work in accord with this section, you+must place, in the relevant source files, a statement of the+additional terms that apply to those files, or a notice indicating+where to find the applicable terms.++ Additional terms, permissive or non-permissive, may be stated in the+form of a separately written license, or stated as exceptions;+the above requirements apply either way.++ 8. Termination.++ You may not propagate or modify a covered work except as expressly+provided under this License. Any attempt otherwise to propagate or+modify it is void, and will automatically terminate your rights under+this License (including any patent licenses granted under the third+paragraph of section 11).++ However, if you cease all violation of this License, then your+license from a particular copyright holder is reinstated (a)+provisionally, unless and until the copyright holder explicitly and+finally terminates your license, and (b) permanently, if the copyright+holder fails to notify you of the violation by some reasonable means+prior to 60 days after the cessation.++ Moreover, your license from a particular copyright holder is+reinstated permanently if the copyright holder notifies you of the+violation by some reasonable means, this is the first time you have+received notice of violation of this License (for any work) from that+copyright holder, and you cure the violation prior to 30 days after+your receipt of the notice.++ Termination of your rights under this section does not terminate the+licenses of parties who have received copies or rights from you under+this License. If your rights have been terminated and not permanently+reinstated, you do not qualify to receive new licenses for the same+material under section 10.++ 9. Acceptance Not Required for Having Copies.++ You are not required to accept this License in order to receive or+run a copy of the Program. Ancillary propagation of a covered work+occurring solely as a consequence of using peer-to-peer transmission+to receive a copy likewise does not require acceptance. However,+nothing other than this License grants you permission to propagate or+modify any covered work. These actions infringe copyright if you do+not accept this License. Therefore, by modifying or propagating a+covered work, you indicate your acceptance of this License to do so.++ 10. Automatic Licensing of Downstream Recipients.++ Each time you convey a covered work, the recipient automatically+receives a license from the original licensors, to run, modify and+propagate that work, subject to this License. You are not responsible+for enforcing compliance by third parties with this License.++ An "entity transaction" is a transaction transferring control of an+organization, or substantially all assets of one, or subdividing an+organization, or merging organizations. If propagation of a covered+work results from an entity transaction, each party to that+transaction who receives a copy of the work also receives whatever+licenses to the work the party's predecessor in interest had or could+give under the previous paragraph, plus a right to possession of the+Corresponding Source of the work from the predecessor in interest, if+the predecessor has it or can get it with reasonable efforts.++ You may not impose any further restrictions on the exercise of the+rights granted or affirmed under this License. For example, you may+not impose a license fee, royalty, or other charge for exercise of+rights granted under this License, and you may not initiate litigation+(including a cross-claim or counterclaim in a lawsuit) alleging that+any patent claim is infringed by making, using, selling, offering for+sale, or importing the Program or any portion of it.++ 11. Patents.++ A "contributor" is a copyright holder who authorizes use under this+License of the Program or a work on which the Program is based. The+work thus licensed is called the contributor's "contributor version".++ A contributor's "essential patent claims" are all patent claims+owned or controlled by the contributor, whether already acquired or+hereafter acquired, that would be infringed by some manner, permitted+by this License, of making, using, or selling its contributor version,+but do not include claims that would be infringed only as a+consequence of further modification of the contributor version. For+purposes of this definition, "control" includes the right to grant+patent sublicenses in a manner consistent with the requirements of+this License.++ Each contributor grants you a non-exclusive, worldwide, royalty-free+patent license under the contributor's essential patent claims, to+make, use, sell, offer for sale, import and otherwise run, modify and+propagate the contents of its contributor version.++ In the following three paragraphs, a "patent license" is any express+agreement or commitment, however denominated, not to enforce a patent+(such as an express permission to practice a patent or covenant not to+sue for patent infringement). To "grant" such a patent license to a+party means to make such an agreement or commitment not to enforce a+patent against the party.++ If you convey a covered work, knowingly relying on a patent license,+and the Corresponding Source of the work is not available for anyone+to copy, free of charge and under the terms of this License, through a+publicly available network server or other readily accessible means,+then you must either (1) cause the Corresponding Source to be so+available, or (2) arrange to deprive yourself of the benefit of the+patent license for this particular work, or (3) arrange, in a manner+consistent with the requirements of this License, to extend the patent+license to downstream recipients. "Knowingly relying" means you have+actual knowledge that, but for the patent license, your conveying the+covered work in a country, or your recipient's use of the covered work+in a country, would infringe one or more identifiable patents in that+country that you have reason to believe are valid.++ If, pursuant to or in connection with a single transaction or+arrangement, you convey, or propagate by procuring conveyance of, a+covered work, and grant a patent license to some of the parties+receiving the covered work authorizing them to use, propagate, modify+or convey a specific copy of the covered work, then the patent license+you grant is automatically extended to all recipients of the covered+work and works based on it.++ A patent license is "discriminatory" if it does not include within+the scope of its coverage, prohibits the exercise of, or is+conditioned on the non-exercise of one or more of the rights that are+specifically granted under this License. You may not convey a covered+work if you are a party to an arrangement with a third party that is+in the business of distributing software, under which you make payment+to the third party based on the extent of your activity of conveying+the work, and under which the third party grants, to any of the+parties who would receive the covered work from you, a discriminatory+patent license (a) in connection with copies of the covered work+conveyed by you (or copies made from those copies), or (b) primarily+for and in connection with specific products or compilations that+contain the covered work, unless you entered into that arrangement,+or that patent license was granted, prior to 28 March 2007.++ Nothing in this License shall be construed as excluding or limiting+any implied license or other defenses to infringement that may+otherwise be available to you under applicable patent law.++ 12. No Surrender of Others' Freedom.++ If conditions are imposed on you (whether by court order, agreement or+otherwise) that contradict the conditions of this License, they do not+excuse you from the conditions of this License. If you cannot convey a+covered work so as to satisfy simultaneously your obligations under this+License and any other pertinent obligations, then as a consequence you may+not convey it at all. For example, if you agree to terms that obligate you+to collect a royalty for further conveying from those to whom you convey+the Program, the only way you could satisfy both those terms and this+License would be to refrain entirely from conveying the Program.++ 13. Use with the GNU Affero General Public License.++ Notwithstanding any other provision of this License, you have+permission to link or combine any covered work with a work licensed+under version 3 of the GNU Affero General Public License into a single+combined work, and to convey the resulting work. The terms of this+License will continue to apply to the part which is the covered work,+but the special requirements of the GNU Affero General Public License,+section 13, concerning interaction through a network will apply to the+combination as such.++ 14. Revised Versions of this License.++ The Free Software Foundation may publish revised and/or new versions of+the GNU General Public License from time to time. Such new versions will+be similar in spirit to the present version, but may differ in detail to+address new problems or concerns.++ Each version is given a distinguishing version number. If the+Program specifies that a certain numbered version of the GNU General+Public License "or any later version" applies to it, you have the+option of following the terms and conditions either of that numbered+version or of any later version published by the Free Software+Foundation. If the Program does not specify a version number of the+GNU General Public License, you may choose any version ever published+by the Free Software Foundation.++ If the Program specifies that a proxy can decide which future+versions of the GNU General Public License can be used, that proxy's+public statement of acceptance of a version permanently authorizes you+to choose that version for the Program.++ Later license versions may give you additional or different+permissions. However, no additional obligations are imposed on any+author or copyright holder as a result of your choosing to follow a+later version.++ 15. Disclaimer of Warranty.++ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.++ 16. Limitation of Liability.++ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF+SUCH DAMAGES.++ 17. Interpretation of Sections 15 and 16.++ If the disclaimer of warranty and limitation of liability provided+above cannot be given local legal effect according to their terms,+reviewing courts shall apply local law that most closely approximates+an absolute waiver of all civil liability in connection with the+Program, unless a warranty or assumption of liability accompanies a+copy of the Program in return for a fee.++ END OF TERMS AND CONDITIONS++ How to Apply These Terms to Your New Programs++ If you develop a new program, and you want it to be of the greatest+possible use to the public, the best way to achieve this is to make it+free software which everyone can redistribute and change under these terms.++ To do so, attach the following notices to the program. It is safest+to attach them to the start of each source file to most effectively+state the exclusion of warranty; and each file should have at least+the "copyright" line and a pointer to where the full notice is found.++ <one line to give the program's name and a brief idea of what it does.>+ Copyright (C) <year> <name of author>++ This program is free software: you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation, either version 3 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.++ You should have received a copy of the GNU General Public License+ along with this program. If not, see <http://www.gnu.org/licenses/>.++Also add information on how to contact you by electronic and paper mail.++ If the program does terminal interaction, make it output a short+notice like this when it starts in an interactive mode:++ <program> Copyright (C) <year> <name of author>+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.+ This is free software, and you are welcome to redistribute it+ under certain conditions; type `show c' for details.++The hypothetical commands `show w' and `show c' should show the appropriate+parts of the General Public License. Of course, your program's commands+might be different; for a GUI interface, you would use an "about box".++ You should also get your employer (if you work as a programmer) or school,+if any, to sign a "copyright disclaimer" for the program, if necessary.+For more information on this, and how to apply and follow the GNU GPL, see+<http://www.gnu.org/licenses/>.++ The GNU General Public License does not permit incorporating your program+into proprietary programs. If your program is a subroutine library, you+may consider it more useful to permit linking proprietary applications with+the library. If this is what you want to do, use the GNU Lesser General+Public License instead of this License. But first, please read+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
@@ -0,0 +1,165 @@+======================================================================+README for the scyther-proof security protocol verification tool+======================================================================++Author: Simon Meier <simon.meier@inf.ethz.ch>++Creation Date: 13/05/2011+++1. Introduction+===============++ Every distribution of the scyther-proof tool contains a copy of the+ Isabelle/HOL theories formalizing its verification theory and a copy of the+ protocol models that were verified using scyther-proof. In particular, these+ examples include models for all of our repaired versions of the protocols+ from the ISO/IEC-9798 authentication standard. (In the source distribution+ of scyther-proof they can be found at 'data/examples/iso9798'.)++ In the following sections, we give step by step instructions to get the+ whole system working and we explain the usage of our tools and provide+ further information (e.g., building documentation).+++2. Installation instructions+============================++2.1 Installing scyther-proof+----------------------------++ You need a working Haskell environment that provides GHC 7 and the 'cabal+ install' tool. The simplest way to get such an environment is to download and+ install the Haskell Platform package for your OS. + + http://hackage.haskell.org/platform/+ + Then call++ cabal install++ in the root directory of this source code package. This will use the+ Haskell's deployment tool 'cabal-install' to download all missing libraries+ from Hackage, the central Haskell library repository and install the+ 'scyther-proof' executable in the default installation location of+ cabal-install. The installation location is printed at the end of the build+ process.++ Call + + scyther-proof++ without any arguments to get an overview of the arguments supported and the+ paths to the examples and the Isabelle/HOL theories.+++3.2 Installing the Isabelle/HOL theories+----------------------------------------++ Download and install full Isabelle2009-1 according to the installation+ instructions at++ http://isabelle.in.tum.de/website-Isabelle2009-1/download_x86-linux.html++ The first time you call 'scyther-proof' with the '--isabelle' flag it will+ build the logic image of the Isabelle/HOL theories formalizing the security+ protocol verification theory underlying scyther-proof.++ For enabling interactive processing of theory files based using our+ extensions to Isabelle's ISAR proof language use one of the following two+ variants.++ Variant a: Brute Force+ ----------------------++ Overwrite the standard Emacs keywords file+ + $ISABELLE_HOME/etc/isar-keywords.el+ + with the Emacs keywords file provided with the ESPL distribution.+ + $SCYTHER_PROOF_HOME/isabelle/src/isar-keywords.el++ This is needed in order to make the new ISAR keywords "role",+ "protocol", "sources", and "prefix_close" available in the Emacs+ frontend.+++ Variant b: Elegance+ -------------------++ A more elegant way is to copy the keywords file provided with our+ distribution to++ $ISABELLE_HOME/etc/isar-keywords-ESPL.el++ and start Isabelle using the -k switch as follows.++ isabelle emacs -k ESPL <your-theory-file.thy>++ ++3. Usage+========+++3.1 scyther-proof+------------+++ Usage Example+ -------------++ You can now execute the 'scyther-proof' binary without any arguments to get a+ list of the available flags. A simple example usage is (assuming+ 'scyther-proof' is in the PATH).++ scyther-proof $EXAMPLE_DIR/classic/NS_Public.spthy --shortest++ This will parse the NSL protocol modeled in the 'nsl.spthy' file and output+ all specified security properties together with the proof with the fewest+ number of chain rule applications to stdout.++ In order to generate an Isabelle proof script two additional options need to+ be added++ scyther-proof $EXAMPLE_DIR/classic/NS_Public.spthy --shortest --output=nsl_cert.thy --ASCII++ The first one specifies the output file and the second one instructs+ scyther-proof to use Isabelle's ASCII notation as the output format.+++ To build the source code documentation you can use the call++ cabal configure; cabal haddock++ which will use cabal-install and Haskell's source code documentation tool+ 'haddock' to build the source code documentation. The location of this+ documentation is again output on the command line.+++3.2 The Isabelle/HOL theories+-----------------------------++ In the directory output by scyther-proof, load the Tutorial on interactive+ proof construction using the following commands++ cd <theory-dir-output-by-scytherproof>/src+ isabelle emacs Tutorial.thy++ or if you've chosen the elegant variant++ isabelle emacs -k ESPL Tutorial.thy++ Note that in many case the easiest way to start with constructing+ machine-checked proofs interactively is to use a proof script generated by+ scyther-proof.+++***+* Happy Proving :-)+*+* In case of questions do not hesistate to contact me at+* simon.meier@inf.ethz.ch+***+
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
@@ -0,0 +1,52 @@+index.html++js/jquery.js+js/ui/jquery.ui.core.js+js/ui/jquery.ui.widget.js+js/ui/jquery.ui.tabs.js+js/ui/jquery.ui.mouse.js+js/ui/jquery.ui.draggable.js+js/ui/jquery.effects.core.js+js/jquery.layout.js++js/tooltip/jquery.tooltip.css+js/tooltip/lib/jquery.bgiframe.js+js/tooltip/lib/jquery.dimensions.js+js/tooltip/jquery.tooltip.js++js/json_parse.js++css/scyther-proof.css++css/ui-lightness/jquery.ui.all.css+css/ui-lightness/jquery.ui.button.css+css/ui-lightness/jquery.ui.dialog.css+css/ui-lightness/jquery.ui.selectable.css+css/ui-lightness/jquery.ui.theme.css+css/ui-lightness/jquery-ui-1.8.2.custom.css+css/ui-lightness/jquery.ui.autocomplete.css+css/ui-lightness/jquery.ui.core.css+css/ui-lightness/jquery.ui.progressbar.css+css/ui-lightness/jquery.ui.slider.css+css/ui-lightness/jquery.ui.accordion.css+css/ui-lightness/jquery.ui.base.css+css/ui-lightness/jquery.ui.datepicker.css+css/ui-lightness/jquery.ui.resizable.css+css/ui-lightness/jquery.ui.tabs.css++css/ui-lightness/images/ui-anim_basic_16x16.gif+css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png+css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png+css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png+css/ui-lightness/images/ui-icons_ef8c08_256x240.png+css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png+css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png+css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png+css/ui-lightness/images/ui-icons_222222_256x240.png+css/ui-lightness/images/ui-icons_ffd27a_256x240.png+css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png+css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png+css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png+css/ui-lightness/images/ui-icons_228ef1_256x240.png+css/ui-lightness/images/ui-icons_ffffff_256x240.png+
@@ -0,0 +1,58 @@+/* Basic Style + *************/ + +body { + font-family: Arial, sans-serif; + font-size: 0.85em; +} +p { + margin: 1em 0; +} + +a { text-decoration: none } + +/* Special classes and elements + *****************************/ + +.inner { margin-left: 10px; overflow: auto; } +.outer { float: left; height: 100% } + +.highlighted { color:blue } +.hidden { display: none } +.debug { font-size: x-small } +.paragraph { font-weight: bold } + +#gen-info .file { } +#gen-info .header { font-weight: bold } +#gen-info .topic { font-style: italic } +#gen-info .time { font-style: italic } + +.kw-theory { font-weight:bold } +#proof .kw-fact { color: #770000 } +#proof .kw-proof { font-weight:bold } +#proof .kw-property { font-weight:bold } + +div.named-image { margin-bottom: 1em } +div.named-image div { margin-left: 10px } + +#help-tab h1 { font-size: 1.1em; margin: 0px; margin-bottom: 0.3em; padding-top: 0.3em; } +#help-tab h2 { font-size: 1em; margin: 0px; margin-bottom: 0.3em; padding-top: 0.3em; } +#help-tab p { margin: 0px; margin-bottom: 0.3em } + +/* Basic Layout Theme + ********************/ + +.ui-layout-pane { /* all 'panes' */ + background: #FFF; + border: 1px solid #BBB; + padding: 10px; + overflow: auto; +} + +.ui-layout-resizer { /* all 'resizer-bars' */ + background: #DDD; +} + +.ui-layout-toggler { /* all 'toggler-buttons' */ + background: #AAA; +}
binary file changed (absent → 1553 bytes)
binary file changed (absent → 260 bytes)
binary file changed (absent → 251 bytes)
binary file changed (absent → 178 bytes)
binary file changed (absent → 104 bytes)
binary file changed (absent → 125 bytes)
binary file changed (absent → 105 bytes)
binary file changed (absent → 3762 bytes)
binary file changed (absent → 90 bytes)
binary file changed (absent → 129 bytes)
binary file changed (absent → 4369 bytes)
binary file changed (absent → 4369 bytes)
binary file changed (absent → 4369 bytes)
binary file changed (absent → 4369 bytes)
binary file changed (absent → 4369 bytes)
@@ -0,0 +1,489 @@+/*+* jQuery UI CSS Framework+* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.+*/++/* Layout helpers+----------------------------------*/+.ui-helper-hidden { display: none; }+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }+.ui-helper-clearfix { display: inline-block; }+/* required comment for clearfix to work in Opera \*/+* html .ui-helper-clearfix { height:1%; }+.ui-helper-clearfix { display:block; }+/* end clearfix */+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }+++/* Interaction Cues+----------------------------------*/+.ui-state-disabled { cursor: default !important; }+++/* Icons+----------------------------------*/++/* states and images */+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }+++/* Misc visuals+----------------------------------*/++/* Overlays */+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }+++/*+* jQuery UI CSS Framework+* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px+*/+++/* Component containers+----------------------------------*/+.ui-widget { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1.1em; }+.ui-widget .ui-widget { font-size: 1em; }+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Trebuchet MS, Tahoma, Verdana, Arial, sans-serif; font-size: 1em; }+.ui-widget-content { border: 1px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }+.ui-widget-content a { color: #333333; }+.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }+.ui-widget-header a { color: #ffffff; }++/* Interaction states+----------------------------------*/+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; }+.ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; }+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; }+.ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; }+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; }+.ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; }+.ui-widget :active { outline: none; }++/* Interaction Cues+----------------------------------*/+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }+.ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; }+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }+.ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; }+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }++/* Icons+----------------------------------*/++/* states and images */+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }+.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }+.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }++/* positioning */+.ui-icon-carat-1-n { background-position: 0 0; }+.ui-icon-carat-1-ne { background-position: -16px 0; }+.ui-icon-carat-1-e { background-position: -32px 0; }+.ui-icon-carat-1-se { background-position: -48px 0; }+.ui-icon-carat-1-s { background-position: -64px 0; }+.ui-icon-carat-1-sw { background-position: -80px 0; }+.ui-icon-carat-1-w { background-position: -96px 0; }+.ui-icon-carat-1-nw { background-position: -112px 0; }+.ui-icon-carat-2-n-s { background-position: -128px 0; }+.ui-icon-carat-2-e-w { background-position: -144px 0; }+.ui-icon-triangle-1-n { background-position: 0 -16px; }+.ui-icon-triangle-1-ne { background-position: -16px -16px; }+.ui-icon-triangle-1-e { background-position: -32px -16px; }+.ui-icon-triangle-1-se { background-position: -48px -16px; }+.ui-icon-triangle-1-s { background-position: -64px -16px; }+.ui-icon-triangle-1-sw { background-position: -80px -16px; }+.ui-icon-triangle-1-w { background-position: -96px -16px; }+.ui-icon-triangle-1-nw { background-position: -112px -16px; }+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }+.ui-icon-arrow-1-n { background-position: 0 -32px; }+.ui-icon-arrow-1-ne { background-position: -16px -32px; }+.ui-icon-arrow-1-e { background-position: -32px -32px; }+.ui-icon-arrow-1-se { background-position: -48px -32px; }+.ui-icon-arrow-1-s { background-position: -64px -32px; }+.ui-icon-arrow-1-sw { background-position: -80px -32px; }+.ui-icon-arrow-1-w { background-position: -96px -32px; }+.ui-icon-arrow-1-nw { background-position: -112px -32px; }+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }+.ui-icon-arrow-4 { background-position: 0 -80px; }+.ui-icon-arrow-4-diag { background-position: -16px -80px; }+.ui-icon-extlink { background-position: -32px -80px; }+.ui-icon-newwin { background-position: -48px -80px; }+.ui-icon-refresh { background-position: -64px -80px; }+.ui-icon-shuffle { background-position: -80px -80px; }+.ui-icon-transfer-e-w { background-position: -96px -80px; }+.ui-icon-transferthick-e-w { background-position: -112px -80px; }+.ui-icon-folder-collapsed { background-position: 0 -96px; }+.ui-icon-folder-open { background-position: -16px -96px; }+.ui-icon-document { background-position: -32px -96px; }+.ui-icon-document-b { background-position: -48px -96px; }+.ui-icon-note { background-position: -64px -96px; }+.ui-icon-mail-closed { background-position: -80px -96px; }+.ui-icon-mail-open { background-position: -96px -96px; }+.ui-icon-suitcase { background-position: -112px -96px; }+.ui-icon-comment { background-position: -128px -96px; }+.ui-icon-person { background-position: -144px -96px; }+.ui-icon-print { background-position: -160px -96px; }+.ui-icon-trash { background-position: -176px -96px; }+.ui-icon-locked { background-position: -192px -96px; }+.ui-icon-unlocked { background-position: -208px -96px; }+.ui-icon-bookmark { background-position: -224px -96px; }+.ui-icon-tag { background-position: -240px -96px; }+.ui-icon-home { background-position: 0 -112px; }+.ui-icon-flag { background-position: -16px -112px; }+.ui-icon-calendar { background-position: -32px -112px; }+.ui-icon-cart { background-position: -48px -112px; }+.ui-icon-pencil { background-position: -64px -112px; }+.ui-icon-clock { background-position: -80px -112px; }+.ui-icon-disk { background-position: -96px -112px; }+.ui-icon-calculator { background-position: -112px -112px; }+.ui-icon-zoomin { background-position: -128px -112px; }+.ui-icon-zoomout { background-position: -144px -112px; }+.ui-icon-search { background-position: -160px -112px; }+.ui-icon-wrench { background-position: -176px -112px; }+.ui-icon-gear { background-position: -192px -112px; }+.ui-icon-heart { background-position: -208px -112px; }+.ui-icon-star { background-position: -224px -112px; }+.ui-icon-link { background-position: -240px -112px; }+.ui-icon-cancel { background-position: 0 -128px; }+.ui-icon-plus { background-position: -16px -128px; }+.ui-icon-plusthick { background-position: -32px -128px; }+.ui-icon-minus { background-position: -48px -128px; }+.ui-icon-minusthick { background-position: -64px -128px; }+.ui-icon-close { background-position: -80px -128px; }+.ui-icon-closethick { background-position: -96px -128px; }+.ui-icon-key { background-position: -112px -128px; }+.ui-icon-lightbulb { background-position: -128px -128px; }+.ui-icon-scissors { background-position: -144px -128px; }+.ui-icon-clipboard { background-position: -160px -128px; }+.ui-icon-copy { background-position: -176px -128px; }+.ui-icon-contact { background-position: -192px -128px; }+.ui-icon-image { background-position: -208px -128px; }+.ui-icon-video { background-position: -224px -128px; }+.ui-icon-script { background-position: -240px -128px; }+.ui-icon-alert { background-position: 0 -144px; }+.ui-icon-info { background-position: -16px -144px; }+.ui-icon-notice { background-position: -32px -144px; }+.ui-icon-help { background-position: -48px -144px; }+.ui-icon-check { background-position: -64px -144px; }+.ui-icon-bullet { background-position: -80px -144px; }+.ui-icon-radio-off { background-position: -96px -144px; }+.ui-icon-radio-on { background-position: -112px -144px; }+.ui-icon-pin-w { background-position: -128px -144px; }+.ui-icon-pin-s { background-position: -144px -144px; }+.ui-icon-play { background-position: 0 -160px; }+.ui-icon-pause { background-position: -16px -160px; }+.ui-icon-seek-next { background-position: -32px -160px; }+.ui-icon-seek-prev { background-position: -48px -160px; }+.ui-icon-seek-end { background-position: -64px -160px; }+.ui-icon-seek-start { background-position: -80px -160px; }+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */+.ui-icon-seek-first { background-position: -80px -160px; }+.ui-icon-stop { background-position: -96px -160px; }+.ui-icon-eject { background-position: -112px -160px; }+.ui-icon-volume-off { background-position: -128px -160px; }+.ui-icon-volume-on { background-position: -144px -160px; }+.ui-icon-power { background-position: 0 -176px; }+.ui-icon-signal-diag { background-position: -16px -176px; }+.ui-icon-signal { background-position: -32px -176px; }+.ui-icon-battery-0 { background-position: -48px -176px; }+.ui-icon-battery-1 { background-position: -64px -176px; }+.ui-icon-battery-2 { background-position: -80px -176px; }+.ui-icon-battery-3 { background-position: -96px -176px; }+.ui-icon-circle-plus { background-position: 0 -192px; }+.ui-icon-circle-minus { background-position: -16px -192px; }+.ui-icon-circle-close { background-position: -32px -192px; }+.ui-icon-circle-triangle-e { background-position: -48px -192px; }+.ui-icon-circle-triangle-s { background-position: -64px -192px; }+.ui-icon-circle-triangle-w { background-position: -80px -192px; }+.ui-icon-circle-triangle-n { background-position: -96px -192px; }+.ui-icon-circle-arrow-e { background-position: -112px -192px; }+.ui-icon-circle-arrow-s { background-position: -128px -192px; }+.ui-icon-circle-arrow-w { background-position: -144px -192px; }+.ui-icon-circle-arrow-n { background-position: -160px -192px; }+.ui-icon-circle-zoomin { background-position: -176px -192px; }+.ui-icon-circle-zoomout { background-position: -192px -192px; }+.ui-icon-circle-check { background-position: -208px -192px; }+.ui-icon-circlesmall-plus { background-position: 0 -208px; }+.ui-icon-circlesmall-minus { background-position: -16px -208px; }+.ui-icon-circlesmall-close { background-position: -32px -208px; }+.ui-icon-squaresmall-plus { background-position: -48px -208px; }+.ui-icon-squaresmall-minus { background-position: -64px -208px; }+.ui-icon-squaresmall-close { background-position: -80px -208px; }+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }+++/* Misc visuals+----------------------------------*/++/* Corner radius */+.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; }+.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }+.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }+.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }+.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }+.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }+.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }+.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }+.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }++/* Overlays */+.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }+.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }/* Resizable+----------------------------------*/+.ui-resizable { position: relative;}+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}/* Selectable+----------------------------------*/+.ui-selectable-helper { border:1px dotted black }+/* Accordion+----------------------------------*/+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }+.ui-accordion .ui-accordion-li-fix { display: inline; }+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }+/* IE7-/Win - Fix extra vertical space in lists */+.ui-accordion a { zoom: 1; }+.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }+.ui-accordion .ui-accordion-content-active { display: block; }/* Autocomplete+----------------------------------*/+.ui-autocomplete { position: absolute; cursor: default; } +.ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; }++/* workarounds */+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */++/* Menu+----------------------------------*/+.ui-menu {+ list-style:none;+ padding: 2px;+ margin: 0;+ display:block;+}+.ui-menu .ui-menu {+ margin-top: -3px;+}+.ui-menu .ui-menu-item {+ margin:0;+ padding: 0;+ zoom: 1;+ float: left;+ clear: left;+ width: 100%;+}+.ui-menu .ui-menu-item a {+ text-decoration:none;+ display:block;+ padding:.2em .4em;+ line-height:1.5;+ zoom:1;+}+.ui-menu .ui-menu-item a.ui-state-hover,+.ui-menu .ui-menu-item a.ui-state-active {+ font-weight: normal;+ margin: -1px;+}+/* Button+----------------------------------*/++.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */+.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } ++/*button text element */+.ui-button .ui-button-text { display: block; line-height: 1.4; }+.ui-button-text-only .ui-button-text { padding: .4em 1em; }+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }+.ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }+/* no icon support for input elements, provide padding by default */+input.ui-button { padding: .4em 1em; }++/*button icon element(s) */+.ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }+.ui-button-text-icon .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }++/*button sets*/+.ui-buttonset { margin-right: 7px; }+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }++/* workarounds */+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */++++++/* Dialog+----------------------------------*/+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }+.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative; }+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }+.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }+.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }+.ui-draggable .ui-dialog-titlebar { cursor: move; }+/* Slider+----------------------------------*/+.ui-slider { position: relative; text-align: left; }+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }++.ui-slider-horizontal { height: .8em; }+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }+.ui-slider-horizontal .ui-slider-range-min { left: 0; }+.ui-slider-horizontal .ui-slider-range-max { right: 0; }++.ui-slider-vertical { width: .8em; height: 100px; }+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }+.ui-slider-vertical .ui-slider-range-max { top: 0; }/* Tabs+----------------------------------*/+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; padding: 1em 1.4em; background: none; }+.ui-tabs .ui-tabs-hide { display: none !important; }+/* Datepicker+----------------------------------*/+.ui-datepicker { width: 17em; padding: .2em .2em 0; }+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }+.ui-datepicker .ui-datepicker-prev { left:2px; }+.ui-datepicker .ui-datepicker-next { right:2px; }+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }+.ui-datepicker .ui-datepicker-next-hover { right:1px; }+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}+.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;}+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }+.ui-datepicker td { border: 0; padding: 1px; }+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }++/* with multiple calendars */+.ui-datepicker.ui-datepicker-multi { width:auto; }+.ui-datepicker-multi .ui-datepicker-group { float:left; }+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }+.ui-datepicker-row-break { clear:both; width:100%; }++/* RTL support */+.ui-datepicker-rtl { direction: rtl; }+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }+.ui-datepicker-rtl .ui-datepicker-group { float:right; }+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }++/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */+.ui-datepicker-cover {+ display: none; /*sorry for IE5*/+ display/**/: block; /*sorry for IE5*/+ position: absolute; /*must have*/+ z-index: -1; /*must have*/+ filter: mask(); /*must have*/+ top: -4px; /*must have*/+ left: -4px; /*must have*/+ width: 200px; /*must have*/+ height: 200px; /*must have*/+}/* Progressbar+----------------------------------*/+.ui-progressbar { height:2em; text-align: left; }+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
@@ -0,0 +1,12 @@+/* Accordion+----------------------------------*/+.ui-accordion .ui-accordion-header { cursor: pointer; position: relative; margin-top: 1px; zoom: 1; }+.ui-accordion .ui-accordion-li-fix { display: inline; }+.ui-accordion .ui-accordion-header-active { border-bottom: 0 !important; }+.ui-accordion .ui-accordion-header a { display: block; font-size: 1em; padding: .5em .5em .5em .7em; }+/* IE7-/Win - Fix extra vertical space in lists */+.ui-accordion a { zoom: 1; }+.ui-accordion-icons .ui-accordion-header a { padding-left: 2.2em; }+.ui-accordion .ui-accordion-header .ui-icon { position: absolute; left: .5em; top: 50%; margin-top: -8px; }+.ui-accordion .ui-accordion-content { padding: 1em 2.2em; border-top: 0; margin-top: -2px; position: relative; top: 1px; margin-bottom: 2px; overflow: auto; display: none; zoom: 1; }+.ui-accordion .ui-accordion-content-active { display: block; }
@@ -0,0 +1,2 @@+@import "jquery.ui.base.css";+@import "jquery.ui.theme.css";
@@ -0,0 +1,39 @@+/* Autocomplete+----------------------------------*/+.ui-autocomplete { position: absolute; cursor: default; } +.ui-autocomplete-loading { background: white url('images/ui-anim_basic_16x16.gif') right center no-repeat; }++/* workarounds */+* html .ui-autocomplete { width:1px; } /* without this, the menu expands to 100% in IE6 */++/* Menu+----------------------------------*/+.ui-menu {+ list-style:none;+ padding: 2px;+ margin: 0;+ display:block;+}+.ui-menu .ui-menu {+ margin-top: -3px;+}+.ui-menu .ui-menu-item {+ margin:0;+ padding: 0;+ zoom: 1;+ float: left;+ clear: left;+ width: 100%;+}+.ui-menu .ui-menu-item a {+ text-decoration:none;+ display:block;+ padding:.2em .4em;+ line-height:1.5;+ zoom:1;+}+.ui-menu .ui-menu-item a.ui-state-hover,+.ui-menu .ui-menu-item a.ui-state-active {+ font-weight: normal;+ margin: -1px;+}
@@ -0,0 +1,11 @@+@import url("jquery.ui.core.css");+@import url("jquery.ui.resizable.css");+@import url("jquery.ui.selectable.css");+@import url("jquery.ui.accordion.css");+@import url("jquery.ui.autocomplete.css");+@import url("jquery.ui.button.css");+@import url("jquery.ui.dialog.css");+@import url("jquery.ui.slider.css");+@import url("jquery.ui.tabs.css");+@import url("jquery.ui.datepicker.css");+@import url("jquery.ui.progressbar.css");
@@ -0,0 +1,35 @@+/* Button+----------------------------------*/++.ui-button { display: inline-block; position: relative; padding: 0; margin-right: .1em; text-decoration: none !important; cursor: pointer; text-align: center; zoom: 1; overflow: visible; } /* the overflow property removes extra width in IE */+.ui-button-icon-only { width: 2.2em; } /* to make room for the icon, a width needs to be set here */+button.ui-button-icon-only { width: 2.4em; } /* button elements seem to need a little more width */+.ui-button-icons-only { width: 3.4em; } +button.ui-button-icons-only { width: 3.7em; } ++/*button text element */+.ui-button .ui-button-text { display: block; line-height: 1.4; }+.ui-button-text-only .ui-button-text { padding: .4em 1em; }+.ui-button-icon-only .ui-button-text, .ui-button-icons-only .ui-button-text { padding: .4em; text-indent: -9999999px; }+.ui-button-text-icon .ui-button-text, .ui-button-text-icons .ui-button-text { padding: .4em 1em .4em 2.1em; }+.ui-button-text-icons .ui-button-text { padding-left: 2.1em; padding-right: 2.1em; }+/* no icon support for input elements, provide padding by default */+input.ui-button { padding: .4em 1em; }++/*button icon element(s) */+.ui-button-icon-only .ui-icon, .ui-button-text-icon .ui-icon, .ui-button-text-icons .ui-icon, .ui-button-icons-only .ui-icon { position: absolute; top: 50%; margin-top: -8px; }+.ui-button-icon-only .ui-icon { left: 50%; margin-left: -8px; }+.ui-button-text-icon .ui-button-icon-primary, .ui-button-text-icons .ui-button-icon-primary, .ui-button-icons-only .ui-button-icon-primary { left: .5em; }+.ui-button-text-icons .ui-button-icon-secondary, .ui-button-icons-only .ui-button-icon-secondary { right: .5em; }++/*button sets*/+.ui-buttonset { margin-right: 7px; }+.ui-buttonset .ui-button { margin-left: 0; margin-right: -.3em; }++/* workarounds */+button.ui-button::-moz-focus-inner { border: 0; padding: 0; } /* reset extra padding in Firefox */+++++
@@ -0,0 +1,37 @@+/*+* jQuery UI CSS Framework+* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.+*/++/* Layout helpers+----------------------------------*/+.ui-helper-hidden { display: none; }+.ui-helper-hidden-accessible { position: absolute; left: -99999999px; }+.ui-helper-reset { margin: 0; padding: 0; border: 0; outline: 0; line-height: 1.3; text-decoration: none; font-size: 100%; list-style: none; }+.ui-helper-clearfix:after { content: "."; display: block; height: 0; clear: both; visibility: hidden; }+.ui-helper-clearfix { display: inline-block; }+/* required comment for clearfix to work in Opera \*/+* html .ui-helper-clearfix { height:1%; }+.ui-helper-clearfix { display:block; }+/* end clearfix */+.ui-helper-zfix { width: 100%; height: 100%; top: 0; left: 0; position: absolute; opacity: 0; filter:Alpha(Opacity=0); }+++/* Interaction Cues+----------------------------------*/+.ui-state-disabled { cursor: default !important; }+++/* Icons+----------------------------------*/++/* states and images */+.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; }+++/* Misc visuals+----------------------------------*/++/* Overlays */+.ui-widget-overlay { position: absolute; top: 0; left: 0; width: 100%; height: 100%; }
@@ -0,0 +1,61 @@+/* Datepicker+----------------------------------*/+.ui-datepicker { width: 17em; padding: .2em .2em 0; }+.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; }+.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 2px; width: 1.8em; height: 1.8em; }+.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; }+.ui-datepicker .ui-datepicker-prev { left:2px; }+.ui-datepicker .ui-datepicker-next { right:2px; }+.ui-datepicker .ui-datepicker-prev-hover { left:1px; }+.ui-datepicker .ui-datepicker-next-hover { right:1px; }+.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; }+.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; }+.ui-datepicker .ui-datepicker-title select { font-size:1em; margin:1px 0; }+.ui-datepicker select.ui-datepicker-month-year {width: 100%;}+.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;}+.ui-datepicker table {width: 100%; font-size: .9em; border-collapse: collapse; margin:0 0 .4em; }+.ui-datepicker th { padding: .7em .3em; text-align: center; font-weight: bold; border: 0; }+.ui-datepicker td { border: 0; padding: 1px; }+.ui-datepicker td span, .ui-datepicker td a { display: block; padding: .2em; text-align: right; text-decoration: none; }+.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; }+.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; }+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; }++/* with multiple calendars */+.ui-datepicker.ui-datepicker-multi { width:auto; }+.ui-datepicker-multi .ui-datepicker-group { float:left; }+.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; }+.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; }+.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; }+.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; }+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; }+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; }+.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; }+.ui-datepicker-row-break { clear:both; width:100%; }++/* RTL support */+.ui-datepicker-rtl { direction: rtl; }+.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; }+.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; }+.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; }+.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; }+.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; }+.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; }+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; }+.ui-datepicker-rtl .ui-datepicker-group { float:right; }+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; }+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; }++/* IE6 IFRAME FIX (taken from datepicker 1.5.3 */+.ui-datepicker-cover {+ display: none; /*sorry for IE5*/+ display/**/: block; /*sorry for IE5*/+ position: absolute; /*must have*/+ z-index: -1; /*must have*/+ filter: mask(); /*must have*/+ top: -4px; /*must have*/+ left: -4px; /*must have*/+ width: 200px; /*must have*/+ height: 200px; /*must have*/+}
@@ -0,0 +1,13 @@+/* Dialog+----------------------------------*/+.ui-dialog { position: absolute; padding: .2em; width: 300px; overflow: hidden; }+.ui-dialog .ui-dialog-titlebar { padding: .5em 1em .3em; position: relative; }+.ui-dialog .ui-dialog-title { float: left; margin: .1em 16px .2em 0; } +.ui-dialog .ui-dialog-titlebar-close { position: absolute; right: .3em; top: 50%; width: 19px; margin: -10px 0 0 0; padding: 1px; height: 18px; }+.ui-dialog .ui-dialog-titlebar-close span { display: block; margin: 1px; }+.ui-dialog .ui-dialog-titlebar-close:hover, .ui-dialog .ui-dialog-titlebar-close:focus { padding: 0; }+.ui-dialog .ui-dialog-content { border: 0; padding: .5em 1em; background: none; overflow: auto; zoom: 1; }+.ui-dialog .ui-dialog-buttonpane { text-align: left; border-width: 1px 0 0 0; background-image: none; margin: .5em 0 0 0; padding: .3em 1em .5em .4em; }+.ui-dialog .ui-dialog-buttonpane button { float: right; margin: .5em .4em .5em 0; cursor: pointer; padding: .2em .6em .3em .6em; line-height: 1.4em; width:auto; overflow:visible; }+.ui-dialog .ui-resizable-se { width: 14px; height: 14px; right: 3px; bottom: 3px; }+.ui-draggable .ui-dialog-titlebar { cursor: move; }
@@ -0,0 +1,4 @@+/* Progressbar+----------------------------------*/+.ui-progressbar { height:2em; text-align: left; }+.ui-progressbar .ui-progressbar-value {margin: -1px; height:100%; }
@@ -0,0 +1,13 @@+/* Resizable+----------------------------------*/+.ui-resizable { position: relative;}+.ui-resizable-handle { position: absolute;font-size: 0.1px;z-index: 99999; display: block;}+.ui-resizable-disabled .ui-resizable-handle, .ui-resizable-autohide .ui-resizable-handle { display: none; }+.ui-resizable-n { cursor: n-resize; height: 7px; width: 100%; top: -5px; left: 0; }+.ui-resizable-s { cursor: s-resize; height: 7px; width: 100%; bottom: -5px; left: 0; }+.ui-resizable-e { cursor: e-resize; width: 7px; right: -5px; top: 0; height: 100%; }+.ui-resizable-w { cursor: w-resize; width: 7px; left: -5px; top: 0; height: 100%; }+.ui-resizable-se { cursor: se-resize; width: 12px; height: 12px; right: 1px; bottom: 1px; }+.ui-resizable-sw { cursor: sw-resize; width: 9px; height: 9px; left: -5px; bottom: -5px; }+.ui-resizable-nw { cursor: nw-resize; width: 9px; height: 9px; left: -5px; top: -5px; }+.ui-resizable-ne { cursor: ne-resize; width: 9px; height: 9px; right: -5px; top: -5px;}
@@ -0,0 +1,3 @@+/* Selectable+----------------------------------*/+.ui-selectable-helper { border:1px dotted black }
@@ -0,0 +1,17 @@+/* Slider+----------------------------------*/+.ui-slider { position: relative; text-align: left; }+.ui-slider .ui-slider-handle { position: absolute; z-index: 2; width: 1.2em; height: 1.2em; cursor: default; }+.ui-slider .ui-slider-range { position: absolute; z-index: 1; font-size: .7em; display: block; border: 0; background-position: 0 0; }++.ui-slider-horizontal { height: .8em; }+.ui-slider-horizontal .ui-slider-handle { top: -.3em; margin-left: -.6em; }+.ui-slider-horizontal .ui-slider-range { top: 0; height: 100%; }+.ui-slider-horizontal .ui-slider-range-min { left: 0; }+.ui-slider-horizontal .ui-slider-range-max { right: 0; }++.ui-slider-vertical { width: .8em; height: 100px; }+.ui-slider-vertical .ui-slider-handle { left: -.3em; margin-left: 0; margin-bottom: -.6em; }+.ui-slider-vertical .ui-slider-range { left: 0; width: 100%; }+.ui-slider-vertical .ui-slider-range-min { bottom: 0; }+.ui-slider-vertical .ui-slider-range-max { top: 0; }
@@ -0,0 +1,11 @@+/* Tabs+----------------------------------*/+.ui-tabs { position: relative; padding: .2em; zoom: 1; } /* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */+.ui-tabs .ui-tabs-nav { margin: 0; padding: .2em .2em 0; }+.ui-tabs .ui-tabs-nav li { list-style: none; float: left; position: relative; top: 1px; margin: 0 .2em 1px 0; border-bottom: 0 !important; padding: 0; white-space: nowrap; }+.ui-tabs .ui-tabs-nav li a { float: left; padding: .5em 1em; text-decoration: none; }+.ui-tabs .ui-tabs-nav li.ui-tabs-selected { margin-bottom: 0; padding-bottom: 1px; }+.ui-tabs .ui-tabs-nav li.ui-tabs-selected a, .ui-tabs .ui-tabs-nav li.ui-state-disabled a, .ui-tabs .ui-tabs-nav li.ui-state-processing a { cursor: text; }+.ui-tabs .ui-tabs-nav li a, .ui-tabs.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-selected a { cursor: pointer; } /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */+.ui-tabs .ui-tabs-panel { display: block; border-width: 0; background: none; }+.ui-tabs .ui-tabs-hide { display: none !important; }
@@ -0,0 +1,249 @@+++/*+* jQuery UI CSS Framework+* Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)+* Dual licensed under the MIT (MIT-LICENSE.txt) and GPL (GPL-LICENSE.txt) licenses.+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Trebuchet%20MS,%20Tahoma,%20Verdana,%20Arial,%20sans-serif&fwDefault=bold&fsDefault=1.1em&cornerRadius=4px&bgColorHeader=f6a828&bgTextureHeader=12_gloss_wave.png&bgImgOpacityHeader=35&borderColorHeader=e78f08&fcHeader=ffffff&iconColorHeader=ffffff&bgColorContent=eeeeee&bgTextureContent=03_highlight_soft.png&bgImgOpacityContent=100&borderColorContent=dddddd&fcContent=333333&iconColorContent=222222&bgColorDefault=f6f6f6&bgTextureDefault=02_glass.png&bgImgOpacityDefault=100&borderColorDefault=cccccc&fcDefault=1c94c4&iconColorDefault=ef8c08&bgColorHover=fdf5ce&bgTextureHover=02_glass.png&bgImgOpacityHover=100&borderColorHover=fbcb09&fcHover=c77405&iconColorHover=ef8c08&bgColorActive=ffffff&bgTextureActive=02_glass.png&bgImgOpacityActive=65&borderColorActive=fbd850&fcActive=eb8f00&iconColorActive=ef8c08&bgColorHighlight=ffe45c&bgTextureHighlight=03_highlight_soft.png&bgImgOpacityHighlight=75&borderColorHighlight=fed22f&fcHighlight=363636&iconColorHighlight=228ef1&bgColorError=b81900&bgTextureError=08_diagonals_thick.png&bgImgOpacityError=18&borderColorError=cd0a0a&fcError=ffffff&iconColorError=ffd27a&bgColorOverlay=666666&bgTextureOverlay=08_diagonals_thick.png&bgImgOpacityOverlay=20&opacityOverlay=50&bgColorShadow=000000&bgTextureShadow=01_flat.png&bgImgOpacityShadow=10&opacityShadow=20&thicknessShadow=5px&offsetTopShadow=-5px&offsetLeftShadow=-5px&cornerRadiusShadow=5px+*/+++/* Component containers+----------------------------------*/+.ui-widget { font-family: Arial, Verdana, sans-serif; font-size: 0.8em; }+.ui-widget .ui-widget { font-size: 1em; }+.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { font-family: Arial, Verdana, sans-serif; font-size: 0.8em; }+.ui-widget-content { border: 0px solid #dddddd; background: #eeeeee url(images/ui-bg_highlight-soft_100_eeeeee_1x100.png) 50% top repeat-x; color: #333333; }+/* .ui-widget-content a { color: #333333; } */+.ui-widget-header { border: 1px solid #e78f08; background: #f6a828 url(images/ui-bg_gloss-wave_35_f6a828_500x100.png) 50% 50% repeat-x; color: #ffffff; font-weight: bold; }+/* .ui-widget-header a { color: #ffffff; } */++/* Interaction states+----------------------------------*/+.ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default { border: 1px solid #cccccc; background: #f6f6f6 url(images/ui-bg_glass_100_f6f6f6_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #1c94c4; }+/* .ui-state-default a, .ui-state-default a:link, .ui-state-default a:visited { color: #1c94c4; text-decoration: none; } */+.ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus { border: 1px solid #fbcb09; background: #fdf5ce url(images/ui-bg_glass_100_fdf5ce_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #c77405; }+/* .ui-state-hover a, .ui-state-hover a:hover { color: #c77405; text-decoration: none; } */+.ui-state-active, .ui-widget-content .ui-state-active, .ui-widget-header .ui-state-active { border: 1px solid #fbd850; background: #ffffff url(images/ui-bg_glass_65_ffffff_1x400.png) 50% 50% repeat-x; font-weight: bold; color: #eb8f00; }+/* .ui-state-active a, .ui-state-active a:link, .ui-state-active a:visited { color: #eb8f00; text-decoration: none; } */+.ui-widget :active { outline: none; }++/* Interaction Cues+----------------------------------*/+.ui-state-highlight, .ui-widget-content .ui-state-highlight, .ui-widget-header .ui-state-highlight {border: 1px solid #fed22f; background: #ffe45c url(images/ui-bg_highlight-soft_75_ffe45c_1x100.png) 50% top repeat-x; color: #363636; }+/* .ui-state-highlight a, .ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a { color: #363636; } */+.ui-state-error, .ui-widget-content .ui-state-error, .ui-widget-header .ui-state-error {border: 1px solid #cd0a0a; background: #b81900 url(images/ui-bg_diagonals-thick_18_b81900_40x40.png) 50% 50% repeat; color: #ffffff; }+/* .ui-state-error a, .ui-widget-content .ui-state-error a, .ui-widget-header .ui-state-error a { color: #ffffff; } */+.ui-state-error-text, .ui-widget-content .ui-state-error-text, .ui-widget-header .ui-state-error-text { color: #ffffff; }+.ui-priority-primary, .ui-widget-content .ui-priority-primary, .ui-widget-header .ui-priority-primary { font-weight: bold; }+.ui-priority-secondary, .ui-widget-content .ui-priority-secondary, .ui-widget-header .ui-priority-secondary { opacity: .7; filter:Alpha(Opacity=70); font-weight: normal; }+.ui-state-disabled, .ui-widget-content .ui-state-disabled, .ui-widget-header .ui-state-disabled { opacity: .35; filter:Alpha(Opacity=35); background-image: none; }++/* Icons+----------------------------------*/++/* states and images */+.ui-icon { width: 16px; height: 16px; background-image: url(images/ui-icons_222222_256x240.png); }+.ui-widget-content .ui-icon {background-image: url(images/ui-icons_222222_256x240.png); }+.ui-widget-header .ui-icon {background-image: url(images/ui-icons_ffffff_256x240.png); }+.ui-state-default .ui-icon { background-image: url(images/ui-icons_ef8c08_256x240.png); }+.ui-state-hover .ui-icon, .ui-state-focus .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }+.ui-state-active .ui-icon {background-image: url(images/ui-icons_ef8c08_256x240.png); }+.ui-state-highlight .ui-icon {background-image: url(images/ui-icons_228ef1_256x240.png); }+.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(images/ui-icons_ffd27a_256x240.png); }++/* positioning */+.ui-icon-carat-1-n { background-position: 0 0; }+.ui-icon-carat-1-ne { background-position: -16px 0; }+.ui-icon-carat-1-e { background-position: -32px 0; }+.ui-icon-carat-1-se { background-position: -48px 0; }+.ui-icon-carat-1-s { background-position: -64px 0; }+.ui-icon-carat-1-sw { background-position: -80px 0; }+.ui-icon-carat-1-w { background-position: -96px 0; }+.ui-icon-carat-1-nw { background-position: -112px 0; }+.ui-icon-carat-2-n-s { background-position: -128px 0; }+.ui-icon-carat-2-e-w { background-position: -144px 0; }+.ui-icon-triangle-1-n { background-position: 0 -16px; }+.ui-icon-triangle-1-ne { background-position: -16px -16px; }+.ui-icon-triangle-1-e { background-position: -32px -16px; }+.ui-icon-triangle-1-se { background-position: -48px -16px; }+.ui-icon-triangle-1-s { background-position: -64px -16px; }+.ui-icon-triangle-1-sw { background-position: -80px -16px; }+.ui-icon-triangle-1-w { background-position: -96px -16px; }+.ui-icon-triangle-1-nw { background-position: -112px -16px; }+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }+.ui-icon-arrow-1-n { background-position: 0 -32px; }+.ui-icon-arrow-1-ne { background-position: -16px -32px; }+.ui-icon-arrow-1-e { background-position: -32px -32px; }+.ui-icon-arrow-1-se { background-position: -48px -32px; }+.ui-icon-arrow-1-s { background-position: -64px -32px; }+.ui-icon-arrow-1-sw { background-position: -80px -32px; }+.ui-icon-arrow-1-w { background-position: -96px -32px; }+.ui-icon-arrow-1-nw { background-position: -112px -32px; }+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }+.ui-icon-arrow-4 { background-position: 0 -80px; }+.ui-icon-arrow-4-diag { background-position: -16px -80px; }+.ui-icon-extlink { background-position: -32px -80px; }+.ui-icon-newwin { background-position: -48px -80px; }+.ui-icon-refresh { background-position: -64px -80px; }+.ui-icon-shuffle { background-position: -80px -80px; }+.ui-icon-transfer-e-w { background-position: -96px -80px; }+.ui-icon-transferthick-e-w { background-position: -112px -80px; }+.ui-icon-folder-collapsed { background-position: 0 -96px; }+.ui-icon-folder-open { background-position: -16px -96px; }+.ui-icon-document { background-position: -32px -96px; }+.ui-icon-document-b { background-position: -48px -96px; }+.ui-icon-note { background-position: -64px -96px; }+.ui-icon-mail-closed { background-position: -80px -96px; }+.ui-icon-mail-open { background-position: -96px -96px; }+.ui-icon-suitcase { background-position: -112px -96px; }+.ui-icon-comment { background-position: -128px -96px; }+.ui-icon-person { background-position: -144px -96px; }+.ui-icon-print { background-position: -160px -96px; }+.ui-icon-trash { background-position: -176px -96px; }+.ui-icon-locked { background-position: -192px -96px; }+.ui-icon-unlocked { background-position: -208px -96px; }+.ui-icon-bookmark { background-position: -224px -96px; }+.ui-icon-tag { background-position: -240px -96px; }+.ui-icon-home { background-position: 0 -112px; }+.ui-icon-flag { background-position: -16px -112px; }+.ui-icon-calendar { background-position: -32px -112px; }+.ui-icon-cart { background-position: -48px -112px; }+.ui-icon-pencil { background-position: -64px -112px; }+.ui-icon-clock { background-position: -80px -112px; }+.ui-icon-disk { background-position: -96px -112px; }+.ui-icon-calculator { background-position: -112px -112px; }+.ui-icon-zoomin { background-position: -128px -112px; }+.ui-icon-zoomout { background-position: -144px -112px; }+.ui-icon-search { background-position: -160px -112px; }+.ui-icon-wrench { background-position: -176px -112px; }+.ui-icon-gear { background-position: -192px -112px; }+.ui-icon-heart { background-position: -208px -112px; }+.ui-icon-star { background-position: -224px -112px; }+.ui-icon-link { background-position: -240px -112px; }+.ui-icon-cancel { background-position: 0 -128px; }+.ui-icon-plus { background-position: -16px -128px; }+.ui-icon-plusthick { background-position: -32px -128px; }+.ui-icon-minus { background-position: -48px -128px; }+.ui-icon-minusthick { background-position: -64px -128px; }+.ui-icon-close { background-position: -80px -128px; }+.ui-icon-closethick { background-position: -96px -128px; }+.ui-icon-key { background-position: -112px -128px; }+.ui-icon-lightbulb { background-position: -128px -128px; }+.ui-icon-scissors { background-position: -144px -128px; }+.ui-icon-clipboard { background-position: -160px -128px; }+.ui-icon-copy { background-position: -176px -128px; }+.ui-icon-contact { background-position: -192px -128px; }+.ui-icon-image { background-position: -208px -128px; }+.ui-icon-video { background-position: -224px -128px; }+.ui-icon-script { background-position: -240px -128px; }+.ui-icon-alert { background-position: 0 -144px; }+.ui-icon-info { background-position: -16px -144px; }+.ui-icon-notice { background-position: -32px -144px; }+.ui-icon-help { background-position: -48px -144px; }+.ui-icon-check { background-position: -64px -144px; }+.ui-icon-bullet { background-position: -80px -144px; }+.ui-icon-radio-off { background-position: -96px -144px; }+.ui-icon-radio-on { background-position: -112px -144px; }+.ui-icon-pin-w { background-position: -128px -144px; }+.ui-icon-pin-s { background-position: -144px -144px; }+.ui-icon-play { background-position: 0 -160px; }+.ui-icon-pause { background-position: -16px -160px; }+.ui-icon-seek-next { background-position: -32px -160px; }+.ui-icon-seek-prev { background-position: -48px -160px; }+.ui-icon-seek-end { background-position: -64px -160px; }+.ui-icon-seek-start { background-position: -80px -160px; }+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */+.ui-icon-seek-first { background-position: -80px -160px; }+.ui-icon-stop { background-position: -96px -160px; }+.ui-icon-eject { background-position: -112px -160px; }+.ui-icon-volume-off { background-position: -128px -160px; }+.ui-icon-volume-on { background-position: -144px -160px; }+.ui-icon-power { background-position: 0 -176px; }+.ui-icon-signal-diag { background-position: -16px -176px; }+.ui-icon-signal { background-position: -32px -176px; }+.ui-icon-battery-0 { background-position: -48px -176px; }+.ui-icon-battery-1 { background-position: -64px -176px; }+.ui-icon-battery-2 { background-position: -80px -176px; }+.ui-icon-battery-3 { background-position: -96px -176px; }+.ui-icon-circle-plus { background-position: 0 -192px; }+.ui-icon-circle-minus { background-position: -16px -192px; }+.ui-icon-circle-close { background-position: -32px -192px; }+.ui-icon-circle-triangle-e { background-position: -48px -192px; }+.ui-icon-circle-triangle-s { background-position: -64px -192px; }+.ui-icon-circle-triangle-w { background-position: -80px -192px; }+.ui-icon-circle-triangle-n { background-position: -96px -192px; }+.ui-icon-circle-arrow-e { background-position: -112px -192px; }+.ui-icon-circle-arrow-s { background-position: -128px -192px; }+.ui-icon-circle-arrow-w { background-position: -144px -192px; }+.ui-icon-circle-arrow-n { background-position: -160px -192px; }+.ui-icon-circle-zoomin { background-position: -176px -192px; }+.ui-icon-circle-zoomout { background-position: -192px -192px; }+.ui-icon-circle-check { background-position: -208px -192px; }+.ui-icon-circlesmall-plus { background-position: 0 -208px; }+.ui-icon-circlesmall-minus { background-position: -16px -208px; }+.ui-icon-circlesmall-close { background-position: -32px -208px; }+.ui-icon-squaresmall-plus { background-position: -48px -208px; }+.ui-icon-squaresmall-minus { background-position: -64px -208px; }+.ui-icon-squaresmall-close { background-position: -80px -208px; }+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }+++/* Misc visuals+----------------------------------*/++/* Corner radius */+.ui-corner-tl { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; }+.ui-corner-tr { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }+.ui-corner-bl { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }+.ui-corner-br { -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }+.ui-corner-top { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; }+.ui-corner-bottom { -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }+.ui-corner-right { -moz-border-radius-topright: 4px; -webkit-border-top-right-radius: 4px; border-top-right-radius: 4px; -moz-border-radius-bottomright: 4px; -webkit-border-bottom-right-radius: 4px; border-bottom-right-radius: 4px; }+.ui-corner-left { -moz-border-radius-topleft: 4px; -webkit-border-top-left-radius: 4px; border-top-left-radius: 4px; -moz-border-radius-bottomleft: 4px; -webkit-border-bottom-left-radius: 4px; border-bottom-left-radius: 4px; }+.ui-corner-all { -moz-border-radius: 4px; -webkit-border-radius: 4px; border-radius: 4px; }++/* Overlays */+.ui-widget-overlay { background: #666666 url(images/ui-bg_diagonals-thick_20_666666_40x40.png) 50% 50% repeat; opacity: .50;filter:Alpha(Opacity=50); }+.ui-widget-shadow { margin: -5px 0 0 -5px; padding: 5px; background: #000000 url(images/ui-bg_flat_10_000000_40x100.png) 50% 50% repeat-x; opacity: .20;filter:Alpha(Opacity=20); -moz-border-radius: 5px; -webkit-border-radius: 5px; border-radius: 5px; }
@@ -0,0 +1,36 @@++# Generation, checking, and visualization of security proofs for the+# authentication protocols from the ISO/IEC-9798 standard, as described in+# Basin, Cremers, Meier. "Provably Repairing the ISO/IEC 9798 Standard for+# Entity Authentication". 2011. to be published.+#+# Requirements: +# - GraphViz (for the visualization)+# - Isabelle2009-1 (http://isabelle.in.tum.de/index.html)+# - newest scyther-proof with Isabelle support +# (build according to: https://svn.inf.ethz.ch/svn/basin/infsec/trunk/projects/FOSSP/espl/README)++iso9798-generate-proofs:+ scyther-proof iso9798/*.spthy --shortest -Oiso9798/isabelle-proofs --ASCII++iso9798-generate-and-check-proofs:+ scyther-proof iso9798/*.spthy --shortest -Oiso9798/isabelle-proofs --isabelle++iso9798-generate-check-and-visualize-proofs:+ scyther-proof iso9798/*.spthy --shortest -Oiso9798/proofs-visualized --isabelle --html++iso9798-visualize-proofs:+ scyther-proof iso9798/*.spthy --shortest -Oiso9798/proofs-visualized --html++iso9798-generate-parallel-proofs:+ scyther-proof iso9798/*.spthy --compose-parallel --shortest -Oiso9798/isabelle-parallel-proofs --ASCII+ +iso9798-generate-and-check-parallel-proofs:+ scyther-proof iso9798/*.spthy --compose-parallel --shortest -Oiso9798/isabelle-parallel-proofs --isabelle++iso9798-generate-check-and-visualize-parallel-proofs:+ scyther-proof iso9798/*.spthy --compose-parallel --shortest -Oiso9798/parallel-proofs-visualized --isabelle --html++iso9798-visualize-parallel-proofs:+ scyther-proof iso9798/*.spthy --compose-parallel --shortest -Oiso9798/parallel-proofs-visualized --html+
@@ -0,0 +1,30 @@+OVERVIEW of the security protocol models deployed with 'scyther-proof'+----------------------------------------------------------------------++Created: 13/05/11++The examples contained in the same directory as this OVERVIEW file and in its+subdirectories are part of the distribution of the 'scyther-proof' tool. They+are intended to serve as a starting for verifying your own protocols.++The meaning of the subdirectories is the following:++ classic+ + These are models of well-known protocols. They serve as documentation and+ regression tests for the scyther-proof tool.++ iso9798++ These are the models and proofs of our repaired versions of the+ authentication protocols from the ISO/IEC-9798 standard, as described in+ Basin, Cremers, Meier. "Provably Repairing the ISO/IEC 9798 Standard for+ Entity Authentication". 2011. to be published.++ See the 'Makefile' for conventient execution and checking of these proof+ scripts. If you want to load the proof scripts in Isabelle's interactive+ ProofGeneral interface, then please consult the+ '$SCYTHER_PROOF/isabelle/README' file for installing the custom keywords+ file.++
@@ -0,0 +1,65 @@+theory AndrewRPC begin++section{* Andrew Secure RPC *}++text{*+ We do not have the original model of the Isabelle/OFMC AndrewRPC protocol.+ Therefore, we orient ourself on the SPORE library model.++ Notable differences:++ 1. Instead of implicit typing, we are using explicit global constants to+ discern messages.+*}++protocol Andrew {++ 1. I -> R: I, { 'TT1', ni }k(I,R)+ 2. R <- I: { 'TT2', h('TT1', ni), nr }k(I,R)+ 3. I -> R: { 'TT3', h('TT1', nr) }k(I,R)+ 4. I <- R: { 'TT4', kIR, nr2 }k(I,R)++}+++subsection{* Security Properties *}++properties (of Andrew)+ I_sec_kIR: secret(I, 4, kIR, {I, R})+ R_sec_kIR: secret(R, 4, kIR, {I, R})+++property (of Andrew) I_ni_agree:+ premises+ "role(1) = I"+ "step(1, I_4)"+ "uncompromised(I#1,R#1)"+ imply a thread 2 such that+ " role(2) = R+ & I#1 = I#2+ & R#1 = R#2++ // These commented out equalities don't hold because there may be another+ // thread having sent the initial message exchange. Put differently: the+ // protocol is missing a link between nr,ni and nr2,kIR.+ // & ni#1 = ni#2+ // & nr#1 = nr#2++ & nr2#1 = nr2#2+ & kIR#1 = kIR#2 "++property (of Andrew) R_ni_agree:+ premises+ "role(1) = R"+ "step(1, R_4)"+ "uncompromised(I#1,R#1)"+ imply a thread 2 such that+ " role(2) = I+ & I#1 = I#2+ & R#1 = R#2+ & ni#1 = ni#2+ & nr#1 = nr#2"+ // here we don't have agreement on the key because 'R' cannot check if it+ // has been received.++end
@@ -0,0 +1,79 @@+theory BKE+begin++section{* Bilateral Key Exchange with Public Key protocol (BKEPK) *}++text{*+ Modeled after the description 6.6.6 in the Clark-Jacob library:++ http://www.csl.sri.com/users/millen/capsl/library2.html++ Notable differences:++ 1. We are using explicit global constants to identify the different+ encryptions instead of implicit typing.++*}++protocol BKE {+ 1. I -> R: I, { 'TT1', ni, I }pk(R)+ 2. I <- R: { 'TT2', h(ni), nr, R, kir }pk(I)+ 3. I -> R: { 'TT3', h(nr) }kir+}++subsection{* Secrecy Properties *}++properties (of BKE)+ // type invariant inferred from the protocol specification+ auto: msc-typing++ // originated terms secrecy+ I_ni_secrecy: secret(I, -, ni, {I,R}) + R_nr_secrecy: secret(R, -, nr, {I,R}) + R_kir_secrecy: secret(R, -, kir, {I,R}) ++ // composed originated terms secrecy+ I_hash_ni_secrecy: secret(I, -, h(ni), {I,R}) + R_hash_nr_secrecy: secret(R, -, h(nr), {I,R}) ++ // variable secrecy+ I_nr_secrecy: secret(I, 2, nr, {I,R}) + I_kir_secrecy: secret(I, 2, kir, {I,R}) + R_ni_secrecy: secret(R, 3, ni, {I,R}) +++subsection{* Authentication Properties *}++property (of BKE) I_ni_synch:+ premises+ "role(1) = I"+ "step(1, I_3)"+ "uncompromised(I#1,R#1)"+ imply a thread 2 such that+ " role(2) = R+ & I#1 = I#2+ & R#1 = R#2+ & ni#1 = ni#2+ & nr#1 = nr#2+ & kir#1 = kir#2+ & St(1,I_1) < St(2,R_1) + < St(2,R_2) < St(1,I_2) + < St(1,I_3)"++property (of BKE) R_ni_synch:+ premises+ "role(1) = R"+ "step(1, R_3)"+ "uncompromised(I#1,R#1)"+ imply a thread 2 such that+ " role(2) = I+ & I#1 = I#2+ & R#1 = R#2+ & ni#1 = ni#2+ & nr#1 = nr#2+ & kir#1 = kir#2+ & St(2,I_1) < St(1,R_1) + < St(1,R_2) < St(2,I_2) + < St(2,I_3) < St(1,R_3)"+ +end
@@ -0,0 +1,30 @@+theory CR_Paper+begin++section{* The Running Example of Our CSF'10 Paper *}++protocol CR +{+ 1. C -> S: {k}pk(S)+ 2. C <- S: h(k)+}++properties (of CR) + C_k_secrecy: secret(C, -, k, {S} )+++subsection{* Authentication Properties *}++property (of CR) C_ni_synch:+ premises+ "role(1) = C"+ "step(1, C_2)"+ "uncompromised(S#1)"+ imply a thread 2 such that+ " role(2) = S+ & S#1 = S#2+ & k#1 = k#2+ & St(1,C_1) < St(2,S_1) + < St(2,S_2) < St(1,C_2)"++end
@@ -0,0 +1,89 @@+theory DenningSacco+begin+++section{* Denning-Sacco Shared Key Protocol *}++text{*+ Modeled after the description in the SPORE library:++ http://www.lsv.ens-cachan.fr/Software/spore/denningSacco.html++ Notable differences:++ 1. We do not yet have support for reasoning about timestamps.++ 2. We are using explicit global constants instead of implicit typing to+ discern the different encryptions.++ 3. Similar to the model in Isabelle/OFMC, we added a transfer of some+ arbitrary payload to show that the session key really works as intended.++ Note, that we do not require this, as we could also formulate the+ session-key secrecy property directly. See the other example models in+ the 'examples' directory.++*}++protocol DenningSacco+{+ 1. I -> S: I, R+ 2. <- S: S, {'TT1', R, kIR, T, {'TT2', I, kIR, T}k(R,S)}k(I,S)+ I <- : S, {'TT1', R, kIR, T, Ticket }k(I,S)+ 3. I -> : S, Ticket+ -> R: S, {'TT2', I, kIR, T}k(R,S)+ 4. I <- R: R, {'TT3', Payload}kIR+}+++subsection{* Security Properties *}++properties (of DenningSacco)++ // payload secrecy+ R_Payload_secrecy: secret(R, -, Payload, {I,R,S}) + I_Payload_secrecy: secret(I, 4, Payload, {I,R,S}) + ++text{*+ Note that the following authentication properties only ensure the existence+ of partner threads of a certain structure and not the uniqueness.+ + The stronger property of session key freshness has to be specified and proven+ in Isabelle/HOL on the basis of the automatically produced proofs for the+ properties specified in this input file of ScytherP.+*}++property (of DenningSacco) I_auth:+ premises+ "role(1) = I"+ "step(1, I_4)"+ "uncompromised(I#1, R#1, S#1)"+ imply threads 2, 3 such that+ " role(2) = R+ & role(3) = S+ & I#1 = I#2 & I#2 = I#3+ & R#1 = R#2 & R#2 = R#3+ & S#1 = S#2 & S#2 = S#3+ & kIR#1 = kIR#2 & kIR#2 = kIR#3+ & T#1 = T#2 & T#2 = T#3+ & Payload#1 = Payload#2 + "++property (of DenningSacco) R_auth:+ premises+ "role(2) = R"+ "step(2, R_4)"+ "uncompromised(I#2, R#2, S#2)"+ imply threads 1, 3 such that+ " role(1) = I+ & role(3) = S+ & I#1 = I#2 & I#2 = I#3+ & R#1 = R#2 & R#2 = R#3+ & S#1 = S#2 & S#2 = S#3+ & kIR#1 = kIR#2 & kIR#2 = kIR#3+ & T#1 = T#2 & T#2 = T#3+ "++end+
@@ -0,0 +1,208 @@+theory KerberosV_no_timestamps+begin++section{* The Kerberos Protocol, Version V *}++text{*+ Modeled after Bella's model in Isabelle/src/HOL/Auth/KerberosV.thy.++ The differences to Bella's model are the following:++ 1. We do not model the timestamps and the timing properties because our+ model does not support reasoning about them yet.++ 2. We do not model session key leakage, as our support for key compromise+ properties is not ready yet.++ 3. We provide more general authentication and secrecy properties, as we do+ not assume a priory the uncompromisedness of the ticket granting server.+ Furthermore, the authentication propertis are more fine-grained due to+ our more precise execution model.++ 4. We use explicit global constants instead of implicit typing to identify+ the different encryptions.+*}++protocol KerberosV+{+ 1. C -> A: C,T,n1+ + 2. <- A: A, {'TT21', AuthKey, C }k(T,A), {'TT22', AuthKey, n1, T}k(C,A)+ C <- : A, TicketGrantingTicket, {'TT22', AuthKey, n1, T}k(C,A)+++ 3. C -> : A, C, TicketGrantingTicket, {'TT3', C}AuthKey, C, S, n2+ -> T: A, C, {'TT21', AuthKey, C}k(T,A), {'TT3', C}AuthKey, C, S, n2++ 4. <- T: T, {'TT41', ServerKey, C}k(S,T), {'TT42', ServerKey, n2, S}AuthKey + C <- : T, ServerTicket, {'TT42', ServerKey, n2, S}AuthKey+++ 5. C -> : T, ServerTicket, {'TT5', C, t}ServerKey+ -> S: T, {'TT41', ServerKey, C}k(S,T), {'TT5', C, t}ServerKey ++ 6. C <- S: {'TT6', t}ServerKey+}+++subsection{* Secrecy Properties *}++properties (of KerberosV)+ auto: msc-typing++ A_AuthKey_sec: secret(A, -, AuthKey, {C,A,T})+ C_AuthKey_sec: secret(C, 2, AuthKey, {C,A,T})+ T_AuthKey_sec: secret(T, 3, AuthKey, {C,A,T})++ T_ServerKey_sec: secret(T, -, ServerKey, {C,A,T,S})+ C_ServerKey_sec: secret(C, 4, ServerKey, {C,A,T,S})++ C_t_sec: secret(C, -, t, {C,A,T,S})+++subsection{* Authentication Properties *}++text{*+ To simplify proof search, we first prove the following two first send+ properties.+*}++property (of KerberosV) C_n1_first_send:+ premises+ "role(1) = C"+ "knows(n1#1)"+ imply+ "St(1,C_1) < Ln(n1#1)"++property (of KerberosV) C_n2_first_send:+ premises+ "role(1) = C"+ "knows(n2#1)"+ imply+ "St(1,C_3) < Ln(n2#1)"++property (of KerberosV) C_ni_synch:+ premises+ "role(1) = C"+ "uncompromised(C#1, A#1, T#1, S#1)"+ "step(1, C_6)"+ imply threads 2, 3, 4 such that+ "+ // consequence from exchange with authenticator+ role(2) = A &+ A#1 = A#2 & + C#1 = C#2 & + T#1 = T#2 &+ AuthKey#1 = AuthKey#2 & + n1#1 = n1#2 &+ + // consequence from exchange with ticket granting server+ role(3) = T &+ A#1 = A#3 & + C#1 = C#3 & + T#1 = T#3 &+ S#1 = S#3 &+ AuthKey#1 = AuthKey#3 &+ n2#1 = n2#3 &+ ServerKey#1 = ServerKey#3 &++ // consequence from exchange with server+ role(4) = S &+ C#1 = C#4 & + T#1 = T#4 &+ S#1 = S#4 &+ t#1 = t#4 &+ ServerKey#1 = ServerKey#4 &++ // ordering+ St(1, C_1) < St(2, A_1) <+ St(2, A_2) < St(1, C_2) <+ St(1, C_3) < St(3, T_3) <+ St(3, T_4) < St(1, C_4) <+ St(1, C_5) < St(4, S_5) <+ St(4, S_6) < St(1, C_6)+ "++property (of KerberosV) T_ni_synch:+ premises+ "role(3) = T"+ "uncompromised(C#3, A#3, T#3)"+ "step(3, T_3)"+ imply threads 1, 2 such that+ "+ // consequence from receiving from client+ role(1) = C &+ A#1 = A#3 & + C#1 = C#3 & + T#1 = T#3 &+ AuthKey#1 = AuthKey#3 &++ // consequence of client receiving from authenticator+ role(2) = A &+ A#1 = A#2 & + C#1 = C#2 & + T#1 = T#2 &+ AuthKey#1 = AuthKey#2 & + n1#1 = n1#2 &++ // ordering consequences+ St(1, C_1) < St(2, A_1) <+ St(2, A_2) < St(1, C_2) <+ St(1, C_3) < St(3, T_3)+ "++text{*+ here we can only formulate a weaker authentication property because the+ uncompromisedness of the authenticator cannot be verified directly by the server.+ What we can prove is under the assumption that we got our ServerKey from+ some ticket granting server and this server was talking to an uncompromised+ authenticator, then we have sort of an authentication.+*}++property (of KerberosV) S_auth:+ premises+ "role(4) = S"+ "uncompromised(C#4, S#4, T#4)"+ "step(4, S_5)"++ "role(3) = T"+ "uncompromised(A#3)"+ "ServerKey#4 = ServerKey#3"+ imply threads 1, 2 such that+ "+ // consequence from exchange with authenticator+ role(1) = C &+ role(2) = A &+ A#1 = A#2 & + C#1 = C#2 & + T#1 = T#2 &+ AuthKey#1 = AuthKey#2 & + n1#1 = n1#2 &+ + // consequence from exchange with ticket granting server+ A#1 = A#3 & + C#1 = C#3 & + T#1 = T#3 &+ S#1 = S#3 &+ AuthKey#1 = AuthKey#3 &+ n2#1 = n2#3 &+ ServerKey#1 = ServerKey#3 &++ // consequence from exchange with client+ C#1 = C#4 & + T#1 = T#4 &+ S#1 = S#4 &+ t#1 = t#4 &+ ServerKey#1 = ServerKey#4 &++ // ordering consequences+ St(1, C_1) < St(2, A_1) <+ St(2, A_2) < St(1, C_2) <+ St(1, C_3) < St(3, T_3) <+ St(3, T_4) < St(1, C_4) <+ St(1, C_5) < St(4, S_5)+ "++end++
@@ -0,0 +1,70 @@+theory NS_Public+begin++section{* The Needham-Schroeder-Lowe Public-Key Protocol *}++text{*+ Modeled after Paulson's description in Isabelle/HOL/Auth/NS_Public.thy.++ Notable differences:+ + 1. We are using explicit global constants for discerning the different+ encryption instead of the implicit typing.+*}+++protocol ns_public+{+ 1. I -> R: {'1',ni,I}pk(R)+ 2. I <- R: {'2',ni,nr,R}pk(I)+ 3. I -> R: {'3',nr}pk(R)+}+++subsection{* Secrecy Properties *}++properties (of ns_public) + // type invariant inferred from the protocol specification+ auto: msc-typing++ I_ni_secrecy: secret(I, -, ni, {I,R}) + R_nr_secrecy: secret(R, -, nr, {I,R}) + I_nr_secrecy: secret(I, 2, nr, {I,R}) + R_ni_secrecy: secret(R, 3, ni, {I,R}) +++subsection{* Authentication Properties *}++property (of ns_public) I_ni_synch:+ premises+ "role(1) = I"+ "step(1, I_3)"+ "uncompromised(I#1, R#1)"+ imply a thread 2 such that+ " role(2) = R+ & I#1 = I#2+ & R#1 = R#2+ & ni#1 = ni#2+ & nr#1 = nr#2+ & St(1,I_1) < St(2,R_1) + < St(2,R_2) < St(1,I_2) + < St(1,I_3)"++property (of ns_public) R_ni_synch:+ premises+ "role(1) = R"+ "step(1, R_3)"+ "uncompromised(I#1, R#1)"+ imply a thread 2 such that+ " role(2) = I+ & I#1 = I#2+ & R#1 = R#2+ & ni#1 = ni#2+ & nr#1 = nr#2+ & St(2,I_1) < St(1,R_1) + < St(1,R_2) < St(2,I_2) + < St(2,I_3) < St(1,R_3)"+++end+
@@ -0,0 +1,143 @@+theory OtwayRees+begin++section{* The Original Otway-Rees Protocol *}++text{*+ Based on Paulson's model in Isabelle/src/HOL/Auth/OtwayRees.thy. Notable+ differences:++ 1. Instead of implicit typing, we are using explicit global constants to+ differentiate between different encryptions.++ 2. We do not model session key compromise, as our key compromise+ infrastructure is not ready yet.+*}++protocol OtwayRees+{+ 1. I -> : ni, I, R, {'TT1', ni, I, R}k(I,S)+ -> R: ni, I, R, Ticket1+ 2. R -> : ni, I, R, Ticket1, {'TT2', ni, nr, I, R}k(R,S)+ -> S: ni, I, R, {'TT1', ni, I, R}k(I,S), {'TT2', ni, nr, I, R}k(R,S)++ 3. <- S: ni, {'TT3', ni, kIR}k(I,S), {'TT3', nr, kIR}k(R,S) + R <- : ni, Ticket2, {'TT3', nr, kIR}k(R,S) + 4. <- R: ni, Ticket2+ I <- : ni, {'TT3', ni, kIR}k(I,S)+}+++subsection{* Secrecy Properties *}++properties (of OtwayRees)+ S_kIR_sec: secret(S, -, kIR, {I,R,S})+ R_kIR_sec: secret(R, 3, kIR, {I,R,S})+ I_kIR_sec: secret(I, 4, kIR, {I,R,S})+++subsection{* Authentication Properties *}++property (of OtwayRees) ni_first_send:+ premises+ "role(1) = I"+ "knows(ni#1)"+ imply "St(1, I_1) < Ln(ni#1)"++text{*+ Note that the guarantees would be way better, if we the initiator would+ receive an unfakeable message from the responder after he received the+ session key. Currently, we just don't have a means to check that the+ responder received the servers message. Hence, we cannot prove agreement on+ 'kIR'.+*}+property (of OtwayRees) I_auth:+ premises+ "role(1) = I"+ "uncompromised(I#1, R#1, S#1)"+ "step(1, I_4)"+ imply threads 2, 3 such that+ " + role(2) = R &+ role(3) = S &++ I#1 = I#3 &+ R#1 = R#3 &+ S#1 = S#3 &+ ni#1 = ni#3 &+ kIR#1 = kIR#3 &++ I#1 = I#2 &+ R#1 = R#2 &+ S#1 = S#2 &+ ni#1 = ni#2 &++ nr#2 = nr#3 &++ //ordering+ St(1, I_1) < St(2, R_1) <+ St(2, R_2) < St(3, S_2) <+ St(3, S_3) < St(1, I_4)+ "++property (of OtwayRees) R_ni_agree:+ premises+ "role(2) = R"+ "uncompromised(I#2, R#2, S#2)"+ "step(2, R_3)"+ imply threads 1, 3 such that+ " + role(1) = I &+ role(3) = S &++ I#2 = I#1 &+ R#2 = R#1 &+ S#2 = S#1 &+ ni#2 = ni#1 &++ I#2 = I#3 &+ R#2 = R#3 &+ S#2 = S#3 &+ ni#2 = ni#3 &+ nr#2 = nr#3 &+ kIR#2 = kIR#3 &++ //ordering+ St(1, I_1) < St(2, R_1) <+ St(2, R_2) < St(3, S_2) <+ St(3, S_3) < St(2, R_3)+ "++text{*+ Comparing the proofs of S_ni_agree and R_ni_agree we see that they are pretty+ similar. We have yet to find the right formulation that allows to share the+ similar subproofs.+*}++property (of OtwayRees) S_ni_agree:+ premises+ "role(3) = S"+ "uncompromised(I#3, R#3, S#3)"+ "step(3, S_2)"+ imply threads 1, 2 such that+ " + role(1) = I &+ role(2) = R &++ I#2 = I#1 &+ R#2 = R#1 &+ S#2 = S#1 &+ ni#2 = ni#1 &++ I#2 = I#3 &+ R#2 = R#3 &+ S#2 = S#3 &+ ni#2 = ni#3 &+ nr#2 = nr#3 &++ //ordering+ St(1, I_1) < St(2, R_1) <+ St(2, R_2) < St(3, S_2)+ "++end
@@ -0,0 +1,128 @@+theory TLS +begin++section{* TLS Handshake *}++text{*+ Modeled after Paulson's TLS model in Isabelle/src/HOL/Auth/TLS.thy. Notable+ differences are:++ 1. We use explicit global constants to differentiate between different+ encryptions instead of implicit typing.++ 2. We abstract certificates even further to the trivial form of completely+ predistributed certificates pk(A) with their private key pk(A) for any+ agent A. The reason for this abstraction is that we need to generalize+ weak atomicity further before we can support receiving composed terms in+ a variable.++ [TODO: Remove this simplification, as weak-atomicity is now generalized.]++ 3. We model session keys directly as hashes of the relevant information.+ Due to our support for composed keys, we do not need any custom+ axiomatization as Paulson did.++*}++protocol TLS {+ 1. C -> S: C, nc, sid, pc+ 2. C <- S: ns, sid, ps++ 3. C -> S: { 'TT0', pms }pk(S) ,+ { 'TT1', h('TT2', ns, S, pms) }sk(C) ,+ { 'TT3', sid, h('TT4', 'PRF', pms, nc, ns),+ nc, pc, C, ns, ps, S+ } + h('clientKey', nc, ns, h('TT4', 'PRF', pms, nc, ns))++ 4. C <- S: { 'TT3', sid, h('TT4', 'PRF', pms, nc, ns),+ nc, pc, C, ns, ps, S+ } + h('serverKey', nc, ns, h('TT4', 'PRF', pms, nc, ns))+}+++subsection{* Secrecy Properties *}++properties (of TLS)+ C_pms_sec: secret(C, -, pms, {S}) + C_PRF_sec: secret(C, -, h('TT4', 'PRF', pms, nc, ns), {S})+ C_clientKey_sec: + secret(C, -, h('clientKey', nc, ns, h('TT4', 'PRF', pms, nc, ns)), {S})+ C_serverKey_sec: + secret(C, -, h('serverKey', nc, ns, h('TT4', 'PRF', pms, nc, ns)), {S})++ S_pms_sec: secret(S, 4, pms, {C,S})+ S_PRF_sec: secret(S, 4, h('TT4', 'PRF', pms, nc, ns), {C,S})++ S_clientKey_sec: + secret(S, 4, h('clientKey', nc, ns, h('TT4', 'PRF', pms, nc, ns)), {C,S})+ S_serverKey_sec: + secret(S, 4, h('serverKey', nc, ns, h('TT4', 'PRF', pms, nc, ns)), {C,S})+++subsection{* Authentication Properties *}++text{*+ First, we prove two first send properties in order to simplify proof search+ for the authentication properties.+*}++property (of TLS) nc_first_send:+ premises+ "role(1) = C"+ "knows(nc#1)"+ imply+ "St(1, C_1) < Ln(nc#1)"++property (of TLS) ns_first_send:+ premises+ "role(1) = S"+ "knows(ns#1)"+ imply+ "St(1, S_2) < Ln(ns#1)"++property (of TLS) C_ni_synch:+ premises+ "role(1) = C"+ "step(1, C_4)"+ "uncompromised(C#1,S#1)"+ imply a thread 2 such that+ " role(2) = S+ & C#1 = C#2+ & S#1 = S#2+ & nc#1 = nc#2+ & ns#1 = ns#2+ & pc#1 = pc#2+ & ps#1 = ps#2+ & sid#1 = sid#2+ & pms#1 = pms#2+ & St(1, C_1) < St(2, S_1)+ < St(2, S_2) < St(1, C_2)+ < St(1, C_3) < St(2, S_3)+ < St(2, S_4) < St(1, C_4)+ "++property (of TLS) S_ni_synch:+ premises+ "role(2) = S"+ "step(2, S_4)"+ "uncompromised(C#2,S#2)"+ imply a thread 1 such that+ " role(1) = C+ & C#1 = C#2+ & S#1 = S#2+ & nc#1 = nc#2+ & ns#1 = ns#2+ & pc#1 = pc#2+ & ps#1 = ps#2+ & sid#1 = sid#2+ & pms#1 = pms#2+ & St(1, C_1) < St(2, S_1)+ < St(2, S_2) < St(1, C_2)+ < St(1, C_3) < St(2, S_3)+ < St(2, S_4) + "++end+
@@ -0,0 +1,76 @@+theory WideMouthFrog+begin++section{* Wide Mouthed Frog *}++text{*+ The protocol is modeled after the description in the SPORE library:++ http://www.lsv.ens-cachan.fr/Software/spore/wideMouthedFrog.html++ Note that we cannot reason about the timestamps in our current model.+ Furthermore, our current calculus for backwards reasoning is too weak+ to reason about the original protocol++ 1: I -> S: I, {TimeI, R, kIR}k(I,S)+ 2: R <- S: {TimeS, I, kIR}k(R,S)++ because the server S could receive the message {TimeI, R, kIR}k(I,S)+ arbitrarily many times from himself. Therefore, we added global constants+ identifying the different steps.+*}++protocol WMF+{+ 1. I -> S: I,R, {'step1', TimeI, R, kIR}k(I,S)+ 2. R <- S: S,I, {'step2', TimeS, I, kIR}k(R,S)+}+++subsection{* Secrecy Properties *}++properties (of WMF)+ I_kIR_sec: secret(I, -, kIR, {I,R,S}) + S_kIR_sec: secret(S, 1, kIR, {I,R,S}) + R_kIR_sec: secret(R, 2, kIR, {I,R,S}) +++subsection{* Authentication Properties *}++text{*+ The authentication guarantee for the initiator is trivial because it does not+ receive any confirmation that the responder received the new session-key.+*}++property (of WMF) S_ni_synch:+ premises+ "role(3) = S"+ "step(3, S_1)"+ "uncompromised(I#3, S#3)"+ imply threads 1 such that+ " role(1) = I+ & I#1 = I#3 + & R#1 = R#3+ & S#1 = S#3+ & TimeI#1 = TimeI#3+ & kIR#1 = kIR#3 + & St(1, I_1) < St(3, S_1)"++property (of WMF) R_ni_synch:+ premises+ "role(2) = R"+ "step(2, R_2)"+ "uncompromised(I#2, R#2, S#2)"+ imply threads 1, 3 such that+ " role(1) = I+ & role(3) = S+ & I#1 = I#2 & I#2 = I#3+ & R#1 = R#2 & R#2 = R#3+ & S#1 = S#2 & S#2 = S#3+ & TimeI#1 = TimeI#3+ & TimeS#2 = TimeS#3+ & kIR#1 = kIR#2 & kIR#2 = kIR#3+ & St(1, I_1) < St(3, S_1)+ < St(3, S_2) < St(2, R_2)"++end
@@ -0,0 +1,168 @@+theory WooLam+begin++section{* Woo and Lam Mutual Authentication Protocol *}++text{*+ Modeled after the description in the SPORE library:++ http://www.lsv.ens-cachan.fr/Software/spore/wooLamMutual.html++ Notable differences:++ 1. We are using explicit global constants to discern between different+ encryptions instead of the implicit typing, which introduces+ ambiguities. This implies that we are not precisely modeling the Woo and+ Lam protocol of the SPORE library and hence we may miss some attacks+ possible on it. However, every implementation of the SPORE model could+ easily be changed to our version and benefit from the full correctness+ proof.+*}++protocol WooLam+{+ 1. A -> B: A, na+ 2. A <- B: B, nb+ 3. A -> : {'enc3', A, B, na, nb}k(A,S)+ -> B: Ticket1+ 4. B -> : Ticket1, {'enc4', A, B, na, nb}k(B,S)+ -> S: {'enc3', A, B, na, nb}k(A,S), {'enc4', A, B, na, nb}k(A,S)+ 5. <- S: {'enc51', B, na, nb, kab}k(A,S), {'enc52', A, na, nb, kab}k(B,S)+ B <- : Ticket2, {'enc52', A, na, nb, kab}k(B,S)+ 6. <- B: Ticket2, {'enc6', na,nb}kab+ A <- : {'enc51', B, na, nb, kab}k(A,S), {'enc6', na,nb}kab+ 7. A -> B: {'enc7', nb}kab+}+++subsection{* Secrecy Properties *}++properties (of WooLam)+ S_sec_kab: secret(S, -, kab, {A,B,S})+ A_sec_kab: secret(A, 6, kab, {A,B,S})+ B_sec_kab: secret(B, 5, kab, {A,B,S})++ A_sec_inv_kab: secret(A, 6, inv(kab), {A,B,S})+ B_sec_inv_kab: secret(B, 5, inv(kab), {A,B,S})+++subsection{* Authentication *}++property (of WooLam) na_first_send:+ premises+ "role(1) = A"+ "knows(na#1)"+ imply "St(1, A_1) < Ln(na#1)"++property (of WooLam) nb_first_send:+ premises+ "role(1) = B"+ "knows(nb#1)"+ imply "St(1, B_2) < Ln(nb#1)"++property (of WooLam) A_ni_synch:+ premises+ "role(1) = A"+ "uncompromised(A#1, B#1, S#1)"+ "step(1, A_6)"+ imply threads 2, 3 such that+ " role(2) = B &+ role(3) = S &++ A#1 = A#2 &+ B#1 = B#2 &+ S#1 = S#2 &+ na#1 = na#2 &+ nb#1 = nb#2 &+ kab#1 = kab#2 &++ A#1 = A#3 &+ B#1 = B#3 &+ S#1 = S#3 &+ na#1 = na#3 &+ nb#1 = nb#3 &+ kab#1 = kab#3 &++ //ordering+ St(1, A_1) < St(2, B_1) <+ St(2, B_2) < St(1, A_2) <+ St(1, A_3) < St(3, S_4) <+ St(3, S_5) < St(2, B_5) <+ St(2, B_6) < St(1, A_6) + & // we do not get a full ordering, because the ticket receive in B_3+ // does not give any guarantees.+ St(2, B_3) <+ St(2, B_4) < St(3, S_4)+ "++property (of WooLam) B_ni_synch:+ premises+ "role(2) = B"+ "uncompromised(A#2, B#2, S#2)"+ "step(2, B_7)"+ imply threads 1, 3 such that+ " role(1) = A &+ role(3) = S &++ A#2 = A#1 &+ B#2 = B#1 &+ S#2 = S#1 &+ na#2 = na#1 &+ nb#2 = nb#1 &+ kab#2 = kab#1 &++ A#2 = A#3 &+ B#2 = B#3 &+ S#2 = S#3 &+ na#2 = na#3 &+ nb#2 = nb#3 &+ kab#2 = kab#3 &++ //ordering+ St(1, A_1) < St(2, B_1) <+ St(2, B_2) < St(1, A_2) <+ St(1, A_3) < St(3, S_4) <+ St(3, S_5) < St(2, B_5) <+ St(2, B_6) < St(1, A_6) <+ St(1, A_7) < St(2, B_7)+ & // we do not get a full ordering, because the ticket receive in B_3+ // does not give any guarantees.+ St(2, B_3) <+ St(2, B_4) < St(3, S_4)+ "++property (of WooLam) S_ni_synch:+ premises+ "role(3) = S"+ "uncompromised(A#3, B#3, S#3)"+ "step(3, S_4)"+ imply threads 1, 2 such that+ " role(1) = A &+ role(2) = B &++ A#2 = A#1 &+ B#2 = B#1 &+ S#2 = S#1 &+ na#2 = na#1 &+ nb#2 = nb#1 &++ A#2 = A#3 &+ B#2 = B#3 &+ S#2 = S#3 &+ na#2 = na#3 &+ nb#2 = nb#3 &+ + //ordering+ St(1, A_1) < St(2, B_1) <+ St(2, B_2) < St(1, A_2) <+ St(1, A_3) < St(3, S_4)+ & // we do not get a full ordering, because the ticket receive in B_3+ // does not give any guarantees.+ St(2, B_3) <+ St(2, B_4) < St(3, S_4)+ "++end+++
@@ -0,0 +1,79 @@+theory Yahalom2+begin++section{* The Yahalom Protocol, Variant 2 *}++text{*+ Modelled according to Paulson's variant of the Yahalom protocol in+ Isabelle/src/HOL/Auth/Yahalom2.thy. Instead of assuming a typed model we are+ using global constants to ensure distinctness of messages from different+ steps.++ We do not model session key leakage. Once we have incorporated dynamically+ compromosing adversaries into the proof generation algorithm, this will be+ modeled precisely.+*}++protocol yahalom_paulson+{+ 1. I -> R: I, ni++ 2. R -> S: R, nr, {'TT1', I, ni}k(R,S)++ 3. <- S: S, nr, {'TT31', R, kir, ni}k(I,S), {'TT32', I, kir, nr}k(R,S)+ I <- : S, nr, {'TT31', R, kir, ni}k(I,S), Ticket++ 4. I -> : Ticket, {'TT4', nr}kir+ -> R: {'TT32', I, kir, nr}k(R,S), {'TT4', nr}kir++}+++subsection{* Secrecy Properties *}++properties (of yahalom_paulson)+ S_kir_sec: secret(S, -, kir, {I,R,S})+ I_kir_sec: secret(I, 3, kir, {I,R,S})+ R_kir_sec: secret(R, 4, kir, {I,R,S})+++subsection{* Authentication Properties *}++property (of yahalom_paulson) I_ni_synch:+ premises+ "role(1) = I"+ "step(1, I_3)"+ "uncompromised(I#1, R#1, S#1)"+ imply threads 2 ,3 such that+ " role(2) = R+ & role(3) = S+ & I#1 = I#2 & I#2 = I#3+ & R#1 = R#2 & R#2 = R#3+ & ni#1 = ni#2 & ni#2 = ni#3+ & kir#1 = kir#3 // we are not guaranteed that responder received kir+ & St(1,I_1) < St(2,R_1) + < St(2,R_2) < St(3,S_2) + < St(3,S_3) < St(1,I_3)"++property (of yahalom_paulson) R_ni_synch:+ premises+ "role(2) = R"+ "step(2, R_4)"+ "uncompromised(I#2, R#2, S#2)"+ imply threads 1 ,3 such that+ " role(1) = I+ & role(3) = S+ & I#1 = I#2 & I#2 = I#3+ & R#1 = R#2 & R#2 = R#3+ & nr#1 = nr#2 & nr#2 = nr#3+ // no agreement over ni because it is not bound to nr+ // & ni#1 = ni#2 & ni#2 = ni#3+ & kir#1 = kir#2 & kir#2 = kir#3+ & St(2,R_1) + < St(2,R_2) < St(3,S_2) + < St(3,S_3) < St(1,I_3)+ < St(1,I_4) < St(2,R_4)"++end++
@@ -0,0 +1,3214 @@+theory "isoiec-9798-2-bdkey_cert_auto"+imports+ "../ESPLogic"+begin++role isoiec_9798_2_1_bdkey_A+where "isoiec_9798_2_1_bdkey_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_1_enc_1'', sN ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( sKbd (AVar ''A'') (AVar ''B'') )+ |>+ ]"++role isoiec_9798_2_1_bdkey_B+where "isoiec_9798_2_1_bdkey_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_1_enc_1'', sMV ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( sKbd (MVar ''A'') (AVar ''B'') )+ |>+ ]"++role isoiec_9798_2_2_bdkey_A+where "isoiec_9798_2_2_bdkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''RB'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_2_enc_2'', sMV ''RB'', sMV ''B'',+ sMV ''Text2''+ |>+ ( sKbd (MVar ''B'') (AVar ''A'') )+ |>+ ]"++role isoiec_9798_2_2_bdkey_B+where "isoiec_9798_2_2_bdkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''RB'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_2_enc_2'', sN ''RB'', sAV ''B'', sMV ''Text2''+ |>+ ( sKbd (AVar ''B'') (AVar ''A'') )+ |>+ ]"++role isoiec_9798_2_3_bdkey_A+where "isoiec_9798_2_3_bdkey_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_3_enc_1'', sN ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( sKbd (AVar ''A'') (AVar ''B'') )+ |>+ , Recv ''2'' <| sAV ''B'', sAV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_3_enc_2'', sMV ''TNB'', sAV ''A'',+ sMV ''Text3''+ |>+ ( sKbd (AVar ''B'') (AVar ''A'') )+ |>+ ]"++role isoiec_9798_2_3_bdkey_B+where "isoiec_9798_2_3_bdkey_B =+ [ Send ''leak_B'' ( sN ''TNB'' )+ , Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_3_enc_1'', sMV ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( sKbd (MVar ''A'') (AVar ''B'') )+ |>+ , Recv ''text_2'' <| sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''B'', sMV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_3_enc_2'', sN ''TNB'', sMV ''A'',+ sMV ''Text3''+ |>+ ( sKbd (AVar ''B'') (MVar ''A'') )+ |>+ ]"++role isoiec_9798_2_4_bdkey_A+where "isoiec_9798_2_4_bdkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''RB'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_4_enc_1'', sN ''RA'', sMV ''RB'', sMV ''B'',+ sMV ''Text2''+ |>+ ( sKbd (AVar ''A'') (MVar ''B'') )+ |>+ , Recv ''3'' <| sMV ''B'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_4_enc_2'', sMV ''RB'', sN ''RA'',+ sMV ''Text4''+ |>+ ( sKbd (AVar ''A'') (MVar ''B'') )+ |>+ ]"++role isoiec_9798_2_4_bdkey_B+where "isoiec_9798_2_4_bdkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''RB'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_4_enc_1'', sMV ''RA'', sN ''RB'', sAV ''B'',+ sMV ''Text2''+ |>+ ( sKbd (AVar ''A'') (AVar ''B'') )+ |>+ , Recv ''text_3'' <| sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''B'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_4_enc_2'', sN ''RB'', sMV ''RA'',+ sMV ''Text4''+ |>+ ( sKbd (AVar ''A'') (AVar ''B'') )+ |>+ ]"++role isoiec_9798_2_5_bdkey_A+where "isoiec_9798_2_5_bdkey_A =+ [ Send ''leak_A'' <| sN ''TVPa'', sN ''TNa'' |>+ , Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''A'', sAV ''P'', sN ''TVPa'', sAV ''B'',+ sMV ''Text1''+ |>+ , Recv ''2'' <| sAV ''P'', sAV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_5_enc_2_1'', sN ''TVPa'', sMV ''Kab'',+ sAV ''A'', sAV ''B'', sMV ''Text3''+ |>+ ( sKbd (AVar ''A'') (AVar ''P'') ),+ sMV ''TokenPA_for_B''+ |>+ , Recv ''text_3'' <| sMV ''Text5'', sMV ''Text6'' |>+ , Send ''3'' <| sAV ''A'', sAV ''B'', sMV ''Text6'', sAV ''P'',+ sMV ''TokenPA_for_B'',+ PEnc <| sC ''isoiec_9798_2_5_enc_3'', sN ''TNa'', sAV ''B'',+ sMV ''Text5''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''4'' <| sAV ''B'', sAV ''A'', sMV ''Text8'',+ PEnc <| sC ''isoiec_9798_2_5_enc_4'', sMV ''TNb'', sAV ''A'',+ sMV ''Text7''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_5_bdkey_B+where "isoiec_9798_2_5_bdkey_B =+ [ Send ''leak_B'' ( sN ''TNb'' )+ , Recv ''3'' <| sMV ''A'', sAV ''B'', sMV ''Text6'', sMV ''P'',+ PEnc <| sC ''isoiec_9798_2_5_enc_2_2'', sMV ''TNp'', sMV ''Kab'',+ sMV ''A'', sAV ''B'', sMV ''Text2''+ |>+ ( sKbd (AVar ''B'') (MVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_5_enc_3'', sMV ''TNa'', sAV ''B'',+ sMV ''Text5''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''text_4'' <| sMV ''Text7'', sMV ''Text8'' |>+ , Send ''4'' <| sAV ''B'', sMV ''A'', sMV ''Text8'',+ PEnc <| sC ''isoiec_9798_2_5_enc_4'', sN ''TNb'', sMV ''A'',+ sMV ''Text7''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_5_bdkey_P+where "isoiec_9798_2_5_bdkey_P =+ [ Send ''leak_P'' ( sN ''TNp'' )+ , Recv ''1'' <| sMV ''A'', sAV ''P'', sMV ''TVPa'', sMV ''B'',+ sMV ''Text1''+ |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''P'', sMV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_5_enc_2_1'', sMV ''TVPa'', sN ''Kab'',+ sMV ''A'', sMV ''B'', sMV ''Text3''+ |>+ ( sKbd (MVar ''A'') (AVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_5_enc_2_2'', sN ''TNp'', sN ''Kab'',+ sMV ''A'', sMV ''B'', sMV ''Text2''+ |>+ ( sKbd (MVar ''B'') (AVar ''P'') )+ |>+ ]"++role isoiec_9798_2_6_bdkey_A+where "isoiec_9798_2_6_bdkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' ( sMV ''Text2'' )+ , Send ''2'' <| sAV ''A'', sAV ''P'', sN ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ , Recv ''3'' <| sAV ''P'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_6_enc_3_1'', sN ''Ra'', sMV ''Kab'',+ sAV ''A'', sMV ''B'', sMV ''Text4''+ |>+ ( sKbd (AVar ''A'') (AVar ''P'') ),+ sMV ''TokenPA_for_B''+ |>+ , Recv ''text_4'' <| sMV ''Text6'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''A'', sMV ''B'', sMV ''Text7'', sAV ''P'',+ sMV ''TokenPA_for_B'',+ PEnc <| sC ''isoiec_9798_2_6_enc_4'', sN ''Rpa'', sMV ''Rb'',+ sMV ''Text6''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''5'' <| sMV ''B'', sAV ''A'', sMV ''Text9'',+ PEnc <| sC ''isoiec_9798_2_6_enc_5'', sMV ''Rb'', sN ''Rpa'',+ sMV ''Text8''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_6_bdkey_B+where "isoiec_9798_2_6_bdkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''4'' <| sAV ''A'', sAV ''B'', sMV ''Text7'', sMV ''P'',+ PEnc <| sC ''isoiec_9798_2_6_enc_3_2'', sN ''Rb'', sMV ''Kab'',+ sAV ''A'', sAV ''B'', sMV ''Text3''+ |>+ ( sKbd (AVar ''B'') (MVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_6_enc_4'', sMV ''Rpa'', sN ''Rb'',+ sMV ''Text6''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''B'', sAV ''A'', sMV ''Text9'',+ PEnc <| sC ''isoiec_9798_2_6_enc_5'', sN ''Rb'', sMV ''Rpa'',+ sMV ''Text8''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_6_bdkey_P+where "isoiec_9798_2_6_bdkey_P =+ [ Recv ''2'' <| sMV ''A'', sAV ''P'', sMV ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ , Recv ''text_3'' <| sMV ''Text3'', sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''P'', sMV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_6_enc_3_1'', sMV ''Ra'', sN ''Kab'',+ sMV ''A'', sMV ''B'', sMV ''Text4''+ |>+ ( sKbd (MVar ''A'') (AVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_6_enc_3_2'', sMV ''Rb'', sN ''Kab'',+ sMV ''A'', sMV ''B'', sMV ''Text3''+ |>+ ( sKbd (MVar ''B'') (AVar ''P'') )+ |>+ ]"++role isoiec_9798_2_5_special_TTP_bdkey_A+where "isoiec_9798_2_5_special_TTP_bdkey_A =+ [ Send ''leak_A'' <| sN ''TVPa'', sN ''TNa'' |>+ , Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''A'', sAV ''P'', sN ''TVPa'', sAV ''B'',+ sMV ''Text1''+ |>+ , Recv ''2'' <| sAV ''P'', sAV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_2_1'', sN ''TVPa'',+ sMV ''Kab'', sAV ''B'', sMV ''Text3''+ |>+ ( sKbd (AVar ''A'') (AVar ''P'') ),+ sMV ''TokenPA_for_B''+ |>+ , Recv ''text_3'' <| sMV ''Text5'', sMV ''Text6'' |>+ , Send ''3'' <| sAV ''A'', sAV ''B'', sMV ''Text6'', sAV ''P'',+ sMV ''TokenPA_for_B'',+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_3'', sN ''TNa'', sAV ''B'',+ sMV ''Text5''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''4'' <| sAV ''B'', sAV ''A'', sMV ''Text8'',+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_4'', sMV ''TNb'', sAV ''A'',+ sMV ''Text7''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_5_special_TTP_bdkey_B+where "isoiec_9798_2_5_special_TTP_bdkey_B =+ [ Send ''leak_B'' ( sN ''TNb'' )+ , Recv ''3'' <| sMV ''A'', sAV ''B'', sMV ''Text6'', sMV ''P'',+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_2_2'', sMV ''TNp'',+ sMV ''Kab'', sMV ''A'', sMV ''Text2''+ |>+ ( sKbd (AVar ''B'') (MVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_3'', sMV ''TNa'', sAV ''B'',+ sMV ''Text5''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''text_4'' <| sMV ''Text7'', sMV ''Text8'' |>+ , Send ''4'' <| sAV ''B'', sMV ''A'', sMV ''Text8'',+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_4'', sN ''TNb'', sMV ''A'',+ sMV ''Text7''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_5_special_TTP_bdkey_P+where "isoiec_9798_2_5_special_TTP_bdkey_P =+ [ Send ''leak_P'' ( sN ''TNp'' )+ , Recv ''1'' <| sMV ''A'', sAV ''P'', sMV ''TVPa'', sMV ''B'',+ sMV ''Text1''+ |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''P'', sMV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_2_1'', sMV ''TVPa'',+ sN ''Kab'', sMV ''B'', sMV ''Text3''+ |>+ ( sKbd (MVar ''A'') (AVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_2_2'', sN ''TNp'',+ sN ''Kab'', sMV ''A'', sMV ''Text2''+ |>+ ( sKbd (MVar ''B'') (AVar ''P'') )+ |>+ ]"++role isoiec_9798_2_6_special_TTP_bdkey_A+where "isoiec_9798_2_6_special_TTP_bdkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' ( sMV ''Text2'' )+ , Send ''2'' <| sAV ''A'', sAV ''P'', sN ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ , Recv ''3'' <| sAV ''P'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_3_1'', sN ''Ra'',+ sMV ''Kab'', sMV ''B'', sMV ''Text4''+ |>+ ( sKbd (AVar ''A'') (AVar ''P'') ),+ sMV ''TokenPA_for_B''+ |>+ , Recv ''text_4'' <| sMV ''Text6'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''A'', sMV ''B'', sMV ''Text7'', sAV ''P'',+ sMV ''TokenPA_for_B'',+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_4'', sN ''Rpa'', sMV ''Rb'',+ sMV ''Text6''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''5'' <| sMV ''B'', sAV ''A'', sMV ''Text9'',+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_5'', sMV ''Rb'', sN ''Rpa'',+ sMV ''Text8''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_6_special_TTP_bdkey_B+where "isoiec_9798_2_6_special_TTP_bdkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''4'' <| sAV ''A'', sAV ''B'', sMV ''Text7'', sMV ''P'',+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_3_2'', sN ''Rb'',+ sMV ''Kab'', sAV ''A'', sMV ''Text3''+ |>+ ( sKbd (AVar ''B'') (MVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_4'', sMV ''Rpa'', sN ''Rb'',+ sMV ''Text6''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''B'', sAV ''A'', sMV ''Text9'',+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_5'', sN ''Rb'', sMV ''Rpa'',+ sMV ''Text8''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_6_special_TTP_bdkey_P+where "isoiec_9798_2_6_special_TTP_bdkey_P =+ [ Recv ''2'' <| sMV ''A'', sAV ''P'', sMV ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ , Recv ''text_3'' <| sMV ''Text3'', sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''P'', sMV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_3_1'', sMV ''Ra'',+ sN ''Kab'', sMV ''B'', sMV ''Text4''+ |>+ ( sKbd (MVar ''A'') (AVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_3_2'', sMV ''Rb'',+ sN ''Kab'', sMV ''A'', sMV ''Text3''+ |>+ ( sKbd (MVar ''B'') (AVar ''P'') )+ |>+ ]"++protocol isoiec_9798_2_bdkey+where "isoiec_9798_2_bdkey =+{ isoiec_9798_2_1_bdkey_A, isoiec_9798_2_1_bdkey_B,+ isoiec_9798_2_2_bdkey_A, isoiec_9798_2_2_bdkey_B,+ isoiec_9798_2_3_bdkey_A, isoiec_9798_2_3_bdkey_B,+ isoiec_9798_2_4_bdkey_A, isoiec_9798_2_4_bdkey_B,+ isoiec_9798_2_5_bdkey_A, isoiec_9798_2_5_bdkey_B,+ isoiec_9798_2_5_bdkey_P, isoiec_9798_2_6_bdkey_A,+ isoiec_9798_2_6_bdkey_B, isoiec_9798_2_6_bdkey_P,+ isoiec_9798_2_5_special_TTP_bdkey_A, isoiec_9798_2_5_special_TTP_bdkey_B,+ isoiec_9798_2_5_special_TTP_bdkey_P, isoiec_9798_2_6_special_TTP_bdkey_A,+ isoiec_9798_2_6_special_TTP_bdkey_B, isoiec_9798_2_6_special_TTP_bdkey_P+}"++locale restricted_isoiec_9798_2_bdkey_state = isoiec_9798_2_bdkey_state ++ assumes isoiec_9798_2_5_special_TTP_bdkey_different_actors_A_P:+ "!! tid0 tid1.+ [| roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_A;+ roleMap r tid1 = Some isoiec_9798_2_5_special_TTP_bdkey_P;+ s(AV ''P'' tid1) = s(AV ''A'' tid0)+ |] ==> False"+ assumes isoiec_9798_2_6_special_TTP_bdkey_different_actors_A_P:+ "!! tid0 tid1.+ [| roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_A;+ roleMap r tid1 = Some isoiec_9798_2_6_special_TTP_bdkey_P;+ s(AV ''P'' tid1) = s(AV ''A'' tid0)+ |] ==> False"+ assumes isoiec_9798_2_6_special_TTP_bdkey_different_actors_B_P:+ "!! tid0 tid1.+ [| roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_B;+ roleMap r tid1 = Some isoiec_9798_2_6_special_TTP_bdkey_P;+ s(AV ''P'' tid1) = s(AV ''B'' tid0)+ |] ==> False"++type_invariant isoiec_9798_2_bdkey_composed_typing for isoiec_9798_2_bdkey+where "isoiec_9798_2_bdkey_composed_typing = mk_typing+ [ ((isoiec_9798_2_1_bdkey_B, ''A''), (KnownT isoiec_9798_2_1_bdkey_B_1))+ , ((isoiec_9798_2_3_bdkey_B, ''A''), (KnownT isoiec_9798_2_3_bdkey_B_1))+ , ((isoiec_9798_2_5_bdkey_B, ''A''), (KnownT isoiec_9798_2_5_bdkey_B_3))+ , ((isoiec_9798_2_5_bdkey_P, ''A''), (KnownT isoiec_9798_2_5_bdkey_P_1))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''A''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''A''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_1))+ , ((isoiec_9798_2_6_bdkey_P, ''A''), (KnownT isoiec_9798_2_6_bdkey_P_2))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''A''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_2))+ , ((isoiec_9798_2_2_bdkey_A, ''B''), (KnownT isoiec_9798_2_2_bdkey_A_1))+ , ((isoiec_9798_2_4_bdkey_A, ''B''), (KnownT isoiec_9798_2_4_bdkey_A_1))+ , ((isoiec_9798_2_5_bdkey_P, ''B''), (KnownT isoiec_9798_2_5_bdkey_P_1))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''B''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_1))+ , ((isoiec_9798_2_6_bdkey_A, ''B''), (KnownT isoiec_9798_2_6_bdkey_A_1))+ , ((isoiec_9798_2_6_bdkey_P, ''B''), (KnownT isoiec_9798_2_6_bdkey_P_2))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''B''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_1))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''B''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_2))+ , ((isoiec_9798_2_5_bdkey_A, ''Kab''),+ (SumT (KnownT isoiec_9798_2_5_bdkey_A_2) (NonceT isoiec_9798_2_5_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_5_bdkey_B, ''Kab''),+ (SumT (KnownT isoiec_9798_2_5_bdkey_B_3) (NonceT isoiec_9798_2_5_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Kab''),+ (SumT (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_2) (NonceT isoiec_9798_2_5_special_TTP_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''Kab''),+ (SumT (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3) (NonceT isoiec_9798_2_5_special_TTP_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_6_bdkey_A, ''Kab''),+ (SumT (KnownT isoiec_9798_2_6_bdkey_A_3) (NonceT isoiec_9798_2_6_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_6_bdkey_B, ''Kab''),+ (SumT (KnownT isoiec_9798_2_6_bdkey_B_4) (NonceT isoiec_9798_2_6_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Kab''),+ (SumT (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_3) (NonceT isoiec_9798_2_6_special_TTP_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Kab''),+ (SumT (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_4) (NonceT isoiec_9798_2_6_special_TTP_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_5_bdkey_B, ''P''), (KnownT isoiec_9798_2_5_bdkey_B_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''P''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3))+ , ((isoiec_9798_2_6_bdkey_B, ''P''), (KnownT isoiec_9798_2_6_bdkey_B_4))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''P''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_4))+ , ((isoiec_9798_2_4_bdkey_B, ''RA''),+ (SumT (KnownT isoiec_9798_2_4_bdkey_B_2) (NonceT isoiec_9798_2_4_bdkey_A ''RA'')))+ , ((isoiec_9798_2_2_bdkey_A, ''RB''), (KnownT isoiec_9798_2_2_bdkey_A_1))+ , ((isoiec_9798_2_4_bdkey_A, ''RB''), (KnownT isoiec_9798_2_4_bdkey_A_1))+ , ((isoiec_9798_2_6_bdkey_P, ''Ra''), (KnownT isoiec_9798_2_6_bdkey_P_2))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''Ra''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_2))+ , ((isoiec_9798_2_6_bdkey_A, ''Rb''), (KnownT isoiec_9798_2_6_bdkey_A_1))+ , ((isoiec_9798_2_6_bdkey_P, ''Rb''), (KnownT isoiec_9798_2_6_bdkey_P_2))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Rb''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_1))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''Rb''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_2))+ , ((isoiec_9798_2_6_bdkey_B, ''Rpa''),+ (SumT (KnownT isoiec_9798_2_6_bdkey_B_4) (NonceT isoiec_9798_2_6_bdkey_A ''Rpa'')))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Rpa''),+ (SumT (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_4) (NonceT isoiec_9798_2_6_special_TTP_bdkey_A ''Rpa'')))+ , ((isoiec_9798_2_1_bdkey_B, ''TNA''),+ (SumT (KnownT isoiec_9798_2_1_bdkey_B_1) (NonceT isoiec_9798_2_1_bdkey_A ''TNA'')))+ , ((isoiec_9798_2_3_bdkey_B, ''TNA''),+ (SumT (KnownT isoiec_9798_2_3_bdkey_B_1) (NonceT isoiec_9798_2_3_bdkey_A ''TNA'')))+ , ((isoiec_9798_2_3_bdkey_A, ''TNB''),+ (SumT (KnownT isoiec_9798_2_3_bdkey_A_2) (NonceT isoiec_9798_2_3_bdkey_B ''TNB'')))+ , ((isoiec_9798_2_5_bdkey_B, ''TNa''),+ (SumT (KnownT isoiec_9798_2_5_bdkey_B_3) (NonceT isoiec_9798_2_5_bdkey_A ''TNa'')))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''TNa''),+ (SumT (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3) (NonceT isoiec_9798_2_5_special_TTP_bdkey_A ''TNa'')))+ , ((isoiec_9798_2_5_bdkey_A, ''TNb''),+ (SumT (KnownT isoiec_9798_2_5_bdkey_A_4) (NonceT isoiec_9798_2_5_bdkey_B ''TNb'')))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''TNb''),+ (SumT (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_4) (NonceT isoiec_9798_2_5_special_TTP_bdkey_B ''TNb'')))+ , ((isoiec_9798_2_5_bdkey_B, ''TNp''),+ (SumT (KnownT isoiec_9798_2_5_bdkey_B_3) (NonceT isoiec_9798_2_5_bdkey_P ''TNp'')))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''TNp''),+ (SumT (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3) (NonceT isoiec_9798_2_5_special_TTP_bdkey_P ''TNp'')))+ , ((isoiec_9798_2_5_bdkey_P, ''TVPa''),+ (KnownT isoiec_9798_2_5_bdkey_P_1))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''TVPa''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_1))+ , ((isoiec_9798_2_1_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_1_bdkey_A_text_1))+ , ((isoiec_9798_2_1_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_2_1_bdkey_B_1))+ , ((isoiec_9798_2_2_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_2_bdkey_A_1))+ , ((isoiec_9798_2_2_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_2_2_bdkey_B_text_1))+ , ((isoiec_9798_2_3_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_3_bdkey_A_text_1))+ , ((isoiec_9798_2_3_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_2_3_bdkey_B_1))+ , ((isoiec_9798_2_4_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_4_bdkey_A_1))+ , ((isoiec_9798_2_4_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_2_4_bdkey_B_text_1))+ , ((isoiec_9798_2_5_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_5_bdkey_A_text_1))+ , ((isoiec_9798_2_5_bdkey_P, ''Text1''),+ (KnownT isoiec_9798_2_5_bdkey_P_1))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_text_1))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''Text1''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_1))+ , ((isoiec_9798_2_6_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_6_bdkey_A_1))+ , ((isoiec_9798_2_6_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_2_6_bdkey_B_text_1))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_1))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_text_1))+ , ((isoiec_9798_2_1_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_2_1_bdkey_A_text_1))+ , ((isoiec_9798_2_1_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_2_1_bdkey_B_1))+ , ((isoiec_9798_2_2_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_2_2_bdkey_A_text_2))+ , ((isoiec_9798_2_2_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_2_2_bdkey_B_2))+ , ((isoiec_9798_2_3_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_2_3_bdkey_A_text_1))+ , ((isoiec_9798_2_3_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_2_3_bdkey_B_1))+ , ((isoiec_9798_2_4_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_2_4_bdkey_A_text_2))+ , ((isoiec_9798_2_4_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_2_4_bdkey_B_2))+ , ((isoiec_9798_2_5_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_2_5_bdkey_B_3))+ , ((isoiec_9798_2_5_bdkey_P, ''Text2''),+ (KnownT isoiec_9798_2_5_bdkey_P_text_2))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''Text2''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_text_2))+ , ((isoiec_9798_2_6_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_2_6_bdkey_A_text_2))+ , ((isoiec_9798_2_6_bdkey_P, ''Text2''),+ (KnownT isoiec_9798_2_6_bdkey_P_2))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_text_2))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''Text2''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_2))+ , ((isoiec_9798_2_2_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_2_2_bdkey_A_text_2))+ , ((isoiec_9798_2_2_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_2_2_bdkey_B_2))+ , ((isoiec_9798_2_3_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_2_3_bdkey_A_2))+ , ((isoiec_9798_2_3_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_2_3_bdkey_B_text_2))+ , ((isoiec_9798_2_4_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_2_4_bdkey_A_text_2))+ , ((isoiec_9798_2_4_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_2_4_bdkey_B_2))+ , ((isoiec_9798_2_5_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_2_5_bdkey_A_2))+ , ((isoiec_9798_2_5_bdkey_P, ''Text3''),+ (KnownT isoiec_9798_2_5_bdkey_P_text_2))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_2))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''Text3''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_text_2))+ , ((isoiec_9798_2_6_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_2_6_bdkey_B_4))+ , ((isoiec_9798_2_6_bdkey_P, ''Text3''),+ (KnownT isoiec_9798_2_6_bdkey_P_text_3))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_4))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''Text3''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_text_3))+ , ((isoiec_9798_2_3_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_2_3_bdkey_A_2))+ , ((isoiec_9798_2_3_bdkey_B, ''Text4''),+ (KnownT isoiec_9798_2_3_bdkey_B_text_2))+ , ((isoiec_9798_2_4_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_2_4_bdkey_A_3))+ , ((isoiec_9798_2_4_bdkey_B, ''Text4''),+ (KnownT isoiec_9798_2_4_bdkey_B_text_3))+ , ((isoiec_9798_2_5_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_2_5_bdkey_A_2))+ , ((isoiec_9798_2_5_bdkey_P, ''Text4''),+ (KnownT isoiec_9798_2_5_bdkey_P_text_2))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_2))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''Text4''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_text_2))+ , ((isoiec_9798_2_6_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_2_6_bdkey_A_3))+ , ((isoiec_9798_2_6_bdkey_P, ''Text4''),+ (KnownT isoiec_9798_2_6_bdkey_P_text_3))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_3))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''Text4''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_text_3))+ , ((isoiec_9798_2_4_bdkey_A, ''Text5''),+ (KnownT isoiec_9798_2_4_bdkey_A_3))+ , ((isoiec_9798_2_4_bdkey_B, ''Text5''),+ (KnownT isoiec_9798_2_4_bdkey_B_text_3))+ , ((isoiec_9798_2_5_bdkey_A, ''Text5''),+ (KnownT isoiec_9798_2_5_bdkey_A_text_3))+ , ((isoiec_9798_2_5_bdkey_B, ''Text5''),+ (KnownT isoiec_9798_2_5_bdkey_B_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text5''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_text_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''Text5''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3))+ , ((isoiec_9798_2_6_bdkey_A, ''Text5''),+ (KnownT isoiec_9798_2_6_bdkey_A_3))+ , ((isoiec_9798_2_6_bdkey_P, ''Text5''),+ (KnownT isoiec_9798_2_6_bdkey_P_text_3))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text5''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_3))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''Text5''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_text_3))+ , ((isoiec_9798_2_5_bdkey_A, ''Text6''),+ (KnownT isoiec_9798_2_5_bdkey_A_text_3))+ , ((isoiec_9798_2_5_bdkey_B, ''Text6''),+ (KnownT isoiec_9798_2_5_bdkey_B_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text6''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_text_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''Text6''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3))+ , ((isoiec_9798_2_6_bdkey_A, ''Text6''),+ (KnownT isoiec_9798_2_6_bdkey_A_text_4))+ , ((isoiec_9798_2_6_bdkey_B, ''Text6''),+ (KnownT isoiec_9798_2_6_bdkey_B_4))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text6''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_text_4))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Text6''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_4))+ , ((isoiec_9798_2_5_bdkey_A, ''Text7''),+ (KnownT isoiec_9798_2_5_bdkey_A_4))+ , ((isoiec_9798_2_5_bdkey_B, ''Text7''),+ (KnownT isoiec_9798_2_5_bdkey_B_text_4))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text7''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_4))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''Text7''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_text_4))+ , ((isoiec_9798_2_6_bdkey_A, ''Text7''),+ (KnownT isoiec_9798_2_6_bdkey_A_text_4))+ , ((isoiec_9798_2_6_bdkey_B, ''Text7''),+ (KnownT isoiec_9798_2_6_bdkey_B_4))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text7''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_text_4))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Text7''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_4))+ , ((isoiec_9798_2_5_bdkey_A, ''Text8''),+ (KnownT isoiec_9798_2_5_bdkey_A_4))+ , ((isoiec_9798_2_5_bdkey_B, ''Text8''),+ (KnownT isoiec_9798_2_5_bdkey_B_text_4))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text8''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_4))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''Text8''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_text_4))+ , ((isoiec_9798_2_6_bdkey_A, ''Text8''),+ (KnownT isoiec_9798_2_6_bdkey_A_5))+ , ((isoiec_9798_2_6_bdkey_B, ''Text8''),+ (KnownT isoiec_9798_2_6_bdkey_B_text_5))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text8''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_5))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Text8''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_text_5))+ , ((isoiec_9798_2_6_bdkey_A, ''Text9''),+ (KnownT isoiec_9798_2_6_bdkey_A_5))+ , ((isoiec_9798_2_6_bdkey_B, ''Text9''),+ (KnownT isoiec_9798_2_6_bdkey_B_text_5))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text9''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_5))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Text9''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_text_5))+ , ((isoiec_9798_2_5_bdkey_A, ''TokenPA_for_B''),+ (KnownT isoiec_9798_2_5_bdkey_A_2))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''TokenPA_for_B''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_2))+ , ((isoiec_9798_2_6_bdkey_A, ''TokenPA_for_B''),+ (KnownT isoiec_9798_2_6_bdkey_A_3))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''TokenPA_for_B''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_3))+ ]"++sublocale isoiec_9798_2_bdkey_state < isoiec_9798_2_bdkey_composed_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_bdkey_composed_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_bdkey_composed_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_1_bdkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_1_bdkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_1_bdkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_1_bdkey_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_1_enc_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_1_bdkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_1_enc_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_1_bdkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_bdkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_bdkey_A_1_RB t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_bdkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_bdkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_bdkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_bdkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_2_enc_2'', LN ''RB'' tid0, s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_2_bdkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_A_2_TNB t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_2'', s(MV ''TNB'' tid0),+ s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_bdkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_2'', s(MV ''TNB'' tid0),+ s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_bdkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_bdkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_bdkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_B_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_A_1_RB t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_2'', s(MV ''RB'' tid0), LN ''RA'' tid0,+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(MV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_4_bdkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_B_2_RA t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(AV ''B'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_4_bdkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(AV ''B'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_4_bdkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_B_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_B_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_A_2_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_A_2_TokenPA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_A_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_A_text_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_A_4_TNb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_A_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_A_4_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_B_3_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_B_3_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_B_3_P t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_B_3_TNa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_B_3_TNp t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_B_3_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_B_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_B_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_B_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_B_text_4_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_1_TVPa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_3_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_3_TokenPA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_text_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_5'', s(MV ''Rb'' tid0), LN ''Rpa'' tid0,+ s(MV ''Text8'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_A_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_B_4_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_B_4_P t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_B_4_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_B_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_B_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_B_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_B_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_B_text_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_2_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_2_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_2_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_text_3_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_2_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_2_TokenPA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_text_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_4_TNb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_4_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_P t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_TNa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_TNp t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_text_4_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_1_TVPa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_3_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_3_TokenPA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_text_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_5'', s(MV ''Rb'' tid0),+ LN ''Rpa'' tid0, s(MV ''Text8'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_4_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_4_P t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_4_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_4'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(MV ''Text6'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_4'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(MV ''Text6'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_text_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_2_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_2_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_2_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_text_3_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_bdkey_composed_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_1_bdkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_1_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_1_bdkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_1_bdkey_A &+ ( tid1, isoiec_9798_2_1_bdkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_1_enc_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_1_bdkey_A_1_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_2_bdkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_2_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_2_bdkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_2_bdkey_A &+ ( tid1, isoiec_9798_2_2_bdkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(MV ''RB'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''RB'' tid0,+ s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_2_enc_2'', LN ''RB'' tid0, s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_2_bdkey_A_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_3_bdkey_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_3_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_3_bdkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_3_bdkey_B &+ ( tid1, isoiec_9798_2_3_bdkey_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), LN ''TNB'' tid1,+ s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNB'' tid0),+ s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_2'', s(MV ''TNB'' tid0),+ s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_3_bdkey_B_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_3_bdkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_3_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_3_bdkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_3_bdkey_A &+ ( tid1, isoiec_9798_2_3_bdkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_3_bdkey_A_1_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_4_bdkey_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_4_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_4_bdkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_4_bdkey_B &+ ( tid1, isoiec_9798_2_4_bdkey_B_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''RA'' tid1), LN ''RB'' tid1,+ s(MV ''Text2'' tid1), s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''RA'' tid0,+ s(MV ''RB'' tid0), s(MV ''Text2'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_2'', s(MV ''RB'' tid0), LN ''RA'' tid0,+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(MV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_bdkey_B_3_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''A'' tid1) )+ ( s(AV ''B'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(MV ''B'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', LN ''RA'' tid0, LN ''RB'' tid1,+ s(AV ''B'' tid1), s(MV ''Text2'' tid1)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid1) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_bdkey_A_2_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', LN ''RA'' tid0, LN ''RB'' tid1,+ s(AV ''A'' tid0), s(MV ''Text2'' tid1)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''A'' tid1) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_bdkey_A_2_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_4_bdkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_4_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_4_bdkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_4_bdkey_A &+ ( tid1, isoiec_9798_2_4_bdkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''RA'' tid1, s(MV ''RB'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''RA'' tid0),+ LN ''RB'' tid0, s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(AV ''B'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_bdkey_A_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_bdkey_P_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_P"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "LN ''Kab'' tid0 : knows t"+ shows "False"+using facts proof(sources! " LN ''Kab'' tid0 ")+ case isoiec_9798_2_5_bdkey_P_2_Kab note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case isoiec_9798_2_5_bdkey_P_2_Kab_1 note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+qed (insert facts, fastsimp+)?++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_bdkey_A_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_bdkey_A_2 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_bdkey_P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_bdkey_B_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_bdkey_B_3 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_bdkey_P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_bdkey_A_non_injective_agreement_B:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_bdkey_A_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_bdkey_B &+ ( tid1, isoiec_9798_2_5_bdkey_B_4 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), s(MV ''P'' tid1),+ s(MV ''Kab'' tid1), s(MV ''TNa'' tid1), s(MV ''Text5'' tid1),+ LN ''TNb'' tid1, s(MV ''Text7'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''TNa'' tid0, s(MV ''Text5'' tid0),+ s(MV ''TNb'' tid0), s(MV ''Text7'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_bdkey_B_4_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid2),+ LN ''Kab'' tid1, s(AV ''A'' tid0), s(AV ''B'' tid2), s(MV ''Text2'' tid2)+ |}+ ( Kbd ( s(AV ''B'' tid2) ) ( s(MV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc_1 tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid2),+ s(AV ''B'' tid0), s(MV ''Text5'' tid2)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_bdkey_A_3_enc tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid3, LN ''Kab'' tid1,+ s(AV ''A'' tid3), s(AV ''B'' tid0), s(MV ''Text3'' tid3)+ |}+ ( Kbd ( s(AV ''A'' tid3) ) ( s(AV ''P'' tid3) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc tid4) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_bdkey_B_non_injective_agreement_A:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_bdkey_B_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_bdkey_A &+ ( tid1, isoiec_9798_2_5_bdkey_A_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Kab'' tid1), LN ''TNa'' tid1, s(MV ''Text5'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''TNa'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc_1 tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_bdkey_A_3_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid2, LN ''Kab'' tid1,+ s(AV ''A'' tid2), s(AV ''B'' tid0), s(MV ''Text3'' tid2)+ |}+ ( Kbd ( s(AV ''A'' tid2) ) ( s(AV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_bdkey_A_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_bdkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_bdkey_P &+ ( tid1, isoiec_9798_2_5_bdkey_P_2 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1), LN ''Kab'' tid1,+ s(MV ''TVPa'' tid1), s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''TVPa'' tid0, s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_bdkey_B_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_bdkey_B_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_bdkey_P &+ ( tid1, isoiec_9798_2_5_bdkey_P_2 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1), LN ''Kab'' tid1,+ LN ''TNp'' tid1, s(MV ''Text2'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''TNp'' tid0), s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_bdkey_P_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_P"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "LN ''Kab'' tid0 : knows t"+ shows "False"+using facts proof(sources! " LN ''Kab'' tid0 ")+ case isoiec_9798_2_6_bdkey_P_3_Kab note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case isoiec_9798_2_6_bdkey_P_3_Kab_1 note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+qed (insert facts, fastsimp+)?++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_bdkey_A_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_bdkey_A_3 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_bdkey_P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_bdkey_B_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_bdkey_B_4 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_bdkey_P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_bdkey_A_non_injective_agreement_B:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_bdkey_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_bdkey_B &+ ( tid1, isoiec_9798_2_6_bdkey_B_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''P'' tid1),+ s(MV ''Kab'' tid1), s(MV ''Rpa'' tid1), LN ''Rb'' tid1,+ s(MV ''Text6'' tid1), s(MV ''Text8'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''Rpa'' tid0, s(MV ''Rb'' tid0),+ s(MV ''Text6'' tid0), s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_5'', s(MV ''Rb'' tid0), LN ''Rpa'' tid0,+ s(MV ''Text8'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_bdkey_B_5_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid2, LN ''Kab'' tid1,+ s(AV ''A'' tid2), s(AV ''B'' tid2), s(MV ''Text3'' tid2)+ |}+ ( Kbd ( s(AV ''B'' tid2) ) ( s(MV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc_1 tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', LN ''Rpa'' tid0, LN ''Rb'' tid2,+ s(MV ''Text6'' tid2)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_bdkey_A_4_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_bdkey_B_non_injective_agreement_A:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_bdkey_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_bdkey_A &+ ( tid1, isoiec_9798_2_6_bdkey_A_4 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Kab'' tid1), LN ''Rpa'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text6'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_bdkey_A_4_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid2, LN ''Kab'' tid1,+ s(AV ''A'' tid2), s(MV ''B'' tid2), s(MV ''Text4'' tid2)+ |}+ ( Kbd ( s(AV ''A'' tid2) ) ( s(AV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_bdkey_A_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_bdkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_bdkey_P &+ ( tid1, isoiec_9798_2_6_bdkey_P_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Ra'' tid1), LN ''Kab'' tid1, s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''P'' tid0),+ LN ''Ra'' tid0, s(MV ''Kab'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_bdkey_B_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_bdkey_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_bdkey_P &+ ( tid1, isoiec_9798_2_6_bdkey_P_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Rb'' tid1), LN ''Kab'' tid1, s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ LN ''Rb'' tid0, s(MV ''Kab'' tid0), s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed+++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_special_TTP_bdkey_P_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_P"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "LN ''Kab'' tid0 : knows t"+ shows "False"+using facts proof(sources! " LN ''Kab'' tid0 ")+ case isoiec_9798_2_5_special_TTP_bdkey_P_2_Kab note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case isoiec_9798_2_5_special_TTP_bdkey_P_2_Kab_1 note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+qed (insert facts, fastsimp+)?++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_special_TTP_bdkey_A_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_special_TTP_bdkey_A_2 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''A'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_special_TTP_bdkey_B_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_special_TTP_bdkey_B_3 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc_1 tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''B'' tid1) ) = Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_special_TTP_bdkey_A_non_injective_agreement_B:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_special_TTP_bdkey_A_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_special_TTP_bdkey_B &+ ( tid1, isoiec_9798_2_5_special_TTP_bdkey_B_4 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), s(MV ''P'' tid1),+ s(MV ''Kab'' tid1), s(MV ''TNa'' tid1), s(MV ''Text5'' tid1),+ LN ''TNb'' tid1, s(MV ''Text7'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''TNa'' tid0, s(MV ''Text5'' tid0),+ s(MV ''TNb'' tid0), s(MV ''Text7'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''A'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_4_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_3'', s(MV ''TNa'' tid2),+ s(AV ''B'' tid2), s(MV ''Text5'' tid2)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_3_enc tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid3,+ LN ''Kab'' tid1, s(AV ''B'' tid2), s(MV ''Text3'' tid3)+ |}+ ( Kbd ( s(AV ''A'' tid3) ) ( s(AV ''P'' tid3) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc tid4) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid2),+ LN ''Kab'' tid1, s(AV ''A'' tid0), s(MV ''Text2'' tid2)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc_1 tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_special_TTP_bdkey_B_non_injective_agreement_A:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_special_TTP_bdkey_B_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_special_TTP_bdkey_A &+ ( tid1, isoiec_9798_2_5_special_TTP_bdkey_A_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Kab'' tid1), LN ''TNa'' tid1, s(MV ''Text5'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''TNa'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_B_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid1,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid1)+ |}+ ( Kbd ( s(AV ''A'' tid1) ) ( s(AV ''P'' tid1) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_B_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc tid2) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid2) )+ ( s(MV ''A'' tid2) ) = Kbd ( s(AV ''A'' tid1) ) ( s(AV ''P'' tid1) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid0),+ LN ''Kab'' tid2, s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc_1 tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_special_TTP_bdkey_A_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_special_TTP_bdkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_special_TTP_bdkey_P &+ ( tid1, isoiec_9798_2_5_special_TTP_bdkey_P_2 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1), LN ''Kab'' tid1,+ s(MV ''TVPa'' tid1), s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''TVPa'' tid0, s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''A'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_special_TTP_bdkey_B_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_special_TTP_bdkey_B_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_special_TTP_bdkey_P &+ ( tid1, isoiec_9798_2_5_special_TTP_bdkey_P_2 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1), LN ''Kab'' tid1,+ LN ''TNp'' tid1, s(MV ''Text2'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''TNp'' tid0), s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc_1 tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''B'' tid1) ) = Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_3_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid2,+ LN ''Kab'' tid1, s(AV ''B'' tid0), s(MV ''Text3'' tid2)+ |}+ ( Kbd ( s(AV ''A'' tid2) ) ( s(AV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_special_TTP_bdkey_P_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_P"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "LN ''Kab'' tid0 : knows t"+ shows "False"+using facts proof(sources! " LN ''Kab'' tid0 ")+ case isoiec_9798_2_6_special_TTP_bdkey_P_3_Kab note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case isoiec_9798_2_6_special_TTP_bdkey_P_3_Kab_1 note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+qed (insert facts, fastsimp+)?++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_special_TTP_bdkey_A_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_special_TTP_bdkey_A_3 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''A'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_special_TTP_bdkey_B_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_special_TTP_bdkey_B_4 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc_1 tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''B'' tid1) ) = Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_different_actors_B_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_special_TTP_bdkey_A_non_injective_agreement_B:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_special_TTP_bdkey_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_special_TTP_bdkey_B &+ ( tid1, isoiec_9798_2_6_special_TTP_bdkey_B_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''P'' tid1),+ s(MV ''Kab'' tid1), s(MV ''Rpa'' tid1), LN ''Rb'' tid1,+ s(MV ''Text6'' tid1), s(MV ''Text8'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''Rpa'' tid0, s(MV ''Rb'' tid0),+ s(MV ''Text6'' tid0), s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''A'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_5'', s(MV ''Rb'' tid0),+ LN ''Rpa'' tid0, s(MV ''Text8'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_5_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_2'', LN ''Rb'' tid2,+ LN ''Kab'' tid1, s(AV ''A'' tid2), s(MV ''Text3'' tid2)+ |}+ ( Kbd ( s(AV ''B'' tid2) ) ( s(MV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc_1 tid3) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid0) )+ ( s(MV ''B'' tid0) ) = Kbd ( s(AV ''B'' tid2) ) ( s(MV ''P'' tid2) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_different_actors_B_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_4'', LN ''Rpa'' tid0,+ LN ''Rb'' tid2, s(MV ''Text6'' tid2)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_4_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_special_TTP_bdkey_B_non_injective_agreement_A:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_special_TTP_bdkey_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_special_TTP_bdkey_A &+ ( tid1, isoiec_9798_2_6_special_TTP_bdkey_A_4 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Kab'' tid1), LN ''Rpa'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text6'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc_1 tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''B'' tid1) ) = Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_different_actors_B_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_4'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(MV ''Text6'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_4_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_1'', LN ''Ra'' tid2,+ LN ''Kab'' tid1, s(MV ''B'' tid2), s(MV ''Text4'' tid2)+ |}+ ( Kbd ( s(AV ''A'' tid2) ) ( s(AV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc tid3) note_unified facts = this facts+ hence "Kbd ( s(AV ''A'' tid2) )+ ( s(AV ''P'' tid2) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid1) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_different_actors_A_P intro: event_predOrdI)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_special_TTP_bdkey_A_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_special_TTP_bdkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_special_TTP_bdkey_P &+ ( tid1, isoiec_9798_2_6_special_TTP_bdkey_P_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Ra'' tid1), LN ''Kab'' tid1, s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''P'' tid0),+ LN ''Ra'' tid0, s(MV ''Kab'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''A'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_special_TTP_bdkey_B_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_special_TTP_bdkey_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_special_TTP_bdkey_P &+ ( tid1, isoiec_9798_2_6_special_TTP_bdkey_P_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Rb'' tid1), LN ''Kab'' tid1, s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ LN ''Rb'' tid0, s(MV ''Kab'' tid0), s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc_1 tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''B'' tid1) ) = Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_special_TTP_bdkey_different_actors_B_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++end
@@ -0,0 +1,1843 @@+theory "isoiec-9798-2-udkey_cert_auto"+imports+ "../ESPLogic"+begin++role isoiec_9798_2_1_udkey_A+where "isoiec_9798_2_1_udkey_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_1_enc_1'', sN ''TNA'', sMV ''Text1'' |>+ ( sK ''A'' ''B'' )+ |>+ ]"++role isoiec_9798_2_1_udkey_B+where "isoiec_9798_2_1_udkey_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_1_enc_1'', sMV ''TNA'', sMV ''Text1'' |>+ ( PSymK ( sMV ''A'' ) ( sAV ''B'' ) )+ |>+ ]"++role isoiec_9798_2_2_udkey_A+where "isoiec_9798_2_2_udkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''RB'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_2_enc_2'', sMV ''RB'', sMV ''Text2'' |>+ ( PSymK ( sAV ''A'' ) ( sMV ''B'' ) )+ |>+ ]"++role isoiec_9798_2_2_udkey_B+where "isoiec_9798_2_2_udkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''RB'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_2_enc_2'', sN ''RB'', sMV ''Text2'' |>+ ( sK ''A'' ''B'' )+ |>+ ]"++role isoiec_9798_2_3_udkey_A+where "isoiec_9798_2_3_udkey_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_3_enc_1'', sN ''TNA'', sMV ''Text1'' |>+ ( sK ''A'' ''B'' )+ |>+ , Recv ''2'' <| sAV ''B'', sAV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_3_enc_2'', sMV ''TNB'', sMV ''Text3'' |>+ ( sK ''B'' ''A'' )+ |>+ ]"++role isoiec_9798_2_3_udkey_B+where "isoiec_9798_2_3_udkey_B =+ [ Send ''leak_B'' ( sN ''TNB'' )+ , Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_3_enc_1'', sMV ''TNA'', sMV ''Text1'' |>+ ( PSymK ( sMV ''A'' ) ( sAV ''B'' ) )+ |>+ , Recv ''text_2'' <| sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''B'', sMV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_3_enc_2'', sN ''TNB'', sMV ''Text3'' |>+ ( PSymK ( sAV ''B'' ) ( sMV ''A'' ) )+ |>+ ]"++role isoiec_9798_2_4_udkey_A+where "isoiec_9798_2_4_udkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''RB'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_4_enc_1'', sN ''RA'', sMV ''RB'',+ sMV ''Text2''+ |>+ ( PSymK ( sAV ''A'' ) ( sMV ''B'' ) )+ |>+ , Recv ''3'' <| sMV ''B'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_4_enc_2'', sMV ''RB'', sN ''RA'',+ sMV ''Text4''+ |>+ ( PSymK ( sMV ''B'' ) ( sAV ''A'' ) )+ |>+ ]"++role isoiec_9798_2_4_udkey_B+where "isoiec_9798_2_4_udkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''RB'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_4_enc_1'', sMV ''RA'', sN ''RB'',+ sMV ''Text2''+ |>+ ( sK ''A'' ''B'' )+ |>+ , Recv ''text_3'' <| sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''B'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_4_enc_2'', sN ''RB'', sMV ''RA'',+ sMV ''Text4''+ |>+ ( sK ''B'' ''A'' )+ |>+ ]"++role isoiec_9798_2_5_udkey_A+where "isoiec_9798_2_5_udkey_A =+ [ Send ''leak_A'' <| sN ''TVPa'', sN ''TNa'' |>+ , Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''A'', sAV ''P'', sN ''TVPa'', sAV ''B'',+ sMV ''Text1''+ |>+ , Recv ''2'' <| sAV ''P'', sAV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_5_enc_2_1'', sN ''TVPa'', sMV ''Kab'',+ sAV ''B'', sMV ''Text3''+ |>+ ( sK ''A'' ''P'' ),+ sMV ''TokenPA_for_B''+ |>+ , Recv ''text_3'' <| sMV ''Text5'', sMV ''Text6'' |>+ , Send ''3'' <| sAV ''A'', sAV ''B'', sMV ''Text6'', sAV ''P'',+ sMV ''TokenPA_for_B'',+ PEnc <| sC ''isoiec_9798_2_5_enc_3'', sN ''TNa'', sAV ''B'',+ sMV ''Text5''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''4'' <| sAV ''B'', sAV ''A'', sMV ''Text8'',+ PEnc <| sC ''isoiec_9798_2_5_enc_4'', sMV ''TNb'', sAV ''A'',+ sMV ''Text7''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_5_udkey_B+where "isoiec_9798_2_5_udkey_B =+ [ Send ''leak_B'' ( sN ''TNb'' )+ , Recv ''3'' <| sMV ''A'', sAV ''B'', sMV ''Text6'', sMV ''P'',+ PEnc <| sC ''isoiec_9798_2_5_enc_2_2'', sMV ''TNp'', sMV ''Kab'',+ sMV ''A'', sMV ''Text2''+ |>+ ( PSymK ( sAV ''B'' ) ( sMV ''P'' ) ),+ PEnc <| sC ''isoiec_9798_2_5_enc_3'', sMV ''TNa'', sAV ''B'',+ sMV ''Text5''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''text_4'' <| sMV ''Text7'', sMV ''Text8'' |>+ , Send ''4'' <| sAV ''B'', sMV ''A'', sMV ''Text8'',+ PEnc <| sC ''isoiec_9798_2_5_enc_4'', sN ''TNb'', sMV ''A'',+ sMV ''Text7''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_5_udkey_P+where "isoiec_9798_2_5_udkey_P =+ [ Send ''leak_P'' ( sN ''TNp'' )+ , Recv ''1'' <| sMV ''A'', sAV ''P'', sMV ''TVPa'', sMV ''B'',+ sMV ''Text1''+ |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''P'', sMV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_5_enc_2_1'', sMV ''TVPa'', sN ''Kab'',+ sMV ''B'', sMV ''Text3''+ |>+ ( PSymK ( sMV ''A'' ) ( sAV ''P'' ) ),+ PEnc <| sC ''isoiec_9798_2_5_enc_2_2'', sN ''TNp'', sN ''Kab'',+ sMV ''A'', sMV ''Text2''+ |>+ ( PSymK ( sMV ''B'' ) ( sAV ''P'' ) )+ |>+ ]"++role isoiec_9798_2_6_udkey_A+where "isoiec_9798_2_6_udkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' ( sMV ''Text2'' )+ , Send ''2'' <| sAV ''A'', sAV ''P'', sN ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ , Recv ''3'' <| sAV ''P'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_6_enc_3_1'', sN ''Ra'', sMV ''Kab'',+ sMV ''B'', sMV ''Text4''+ |>+ ( sK ''A'' ''P'' ),+ sMV ''TokenPA_for_B''+ |>+ , Recv ''text_4'' <| sMV ''Text6'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''A'', sMV ''B'', sMV ''Text7'', sAV ''P'',+ sMV ''TokenPA_for_B'',+ PEnc <| sC ''isoiec_9798_2_6_enc_4'', sN ''Rpa'', sMV ''Rb'',+ sMV ''Text6''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''5'' <| sMV ''B'', sAV ''A'', sMV ''Text9'',+ PEnc <| sC ''isoiec_9798_2_6_enc_5'', sMV ''Rb'', sN ''Rpa'',+ sMV ''Text8''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_6_udkey_B+where "isoiec_9798_2_6_udkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''4'' <| sAV ''A'', sAV ''B'', sMV ''Text7'', sMV ''P'',+ PEnc <| sC ''isoiec_9798_2_6_enc_3_2'', sN ''Rb'', sMV ''Kab'',+ sAV ''A'', sMV ''Text3''+ |>+ ( PSymK ( sAV ''B'' ) ( sMV ''P'' ) ),+ PEnc <| sC ''isoiec_9798_2_6_enc_4'', sMV ''Rpa'', sN ''Rb'',+ sMV ''Text6''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''B'', sAV ''A'', sMV ''Text9'',+ PEnc <| sC ''isoiec_9798_2_6_enc_5'', sN ''Rb'', sMV ''Rpa'',+ sMV ''Text8''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_6_udkey_P+where "isoiec_9798_2_6_udkey_P =+ [ Recv ''2'' <| sMV ''A'', sAV ''P'', sMV ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ , Recv ''text_3'' <| sMV ''Text3'', sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''P'', sMV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_6_enc_3_1'', sMV ''Ra'', sN ''Kab'',+ sMV ''B'', sMV ''Text4''+ |>+ ( PSymK ( sMV ''A'' ) ( sAV ''P'' ) ),+ PEnc <| sC ''isoiec_9798_2_6_enc_3_2'', sMV ''Rb'', sN ''Kab'',+ sMV ''A'', sMV ''Text3''+ |>+ ( PSymK ( sMV ''B'' ) ( sAV ''P'' ) )+ |>+ ]"++protocol isoiec_9798_2_bdkey+where "isoiec_9798_2_bdkey =+{ isoiec_9798_2_1_udkey_A, isoiec_9798_2_1_udkey_B,+ isoiec_9798_2_2_udkey_A, isoiec_9798_2_2_udkey_B,+ isoiec_9798_2_3_udkey_A, isoiec_9798_2_3_udkey_B,+ isoiec_9798_2_4_udkey_A, isoiec_9798_2_4_udkey_B,+ isoiec_9798_2_5_udkey_A, isoiec_9798_2_5_udkey_B,+ isoiec_9798_2_5_udkey_P, isoiec_9798_2_6_udkey_A,+ isoiec_9798_2_6_udkey_B, isoiec_9798_2_6_udkey_P+}"++locale restricted_isoiec_9798_2_bdkey_state = isoiec_9798_2_bdkey_state++type_invariant isoiec_9798_2_bdkey_composed_typing for isoiec_9798_2_bdkey+where "isoiec_9798_2_bdkey_composed_typing = mk_typing+ [ ((isoiec_9798_2_1_udkey_B, ''A''), (KnownT isoiec_9798_2_1_udkey_B_1))+ , ((isoiec_9798_2_3_udkey_B, ''A''), (KnownT isoiec_9798_2_3_udkey_B_1))+ , ((isoiec_9798_2_5_udkey_B, ''A''), (KnownT isoiec_9798_2_5_udkey_B_3))+ , ((isoiec_9798_2_5_udkey_P, ''A''), (KnownT isoiec_9798_2_5_udkey_P_1))+ , ((isoiec_9798_2_6_udkey_P, ''A''), (KnownT isoiec_9798_2_6_udkey_P_2))+ , ((isoiec_9798_2_2_udkey_A, ''B''), (KnownT isoiec_9798_2_2_udkey_A_1))+ , ((isoiec_9798_2_4_udkey_A, ''B''), (KnownT isoiec_9798_2_4_udkey_A_1))+ , ((isoiec_9798_2_5_udkey_P, ''B''), (KnownT isoiec_9798_2_5_udkey_P_1))+ , ((isoiec_9798_2_6_udkey_A, ''B''), (KnownT isoiec_9798_2_6_udkey_A_1))+ , ((isoiec_9798_2_6_udkey_P, ''B''), (KnownT isoiec_9798_2_6_udkey_P_2))+ , ((isoiec_9798_2_5_udkey_A, ''Kab''),+ (SumT (KnownT isoiec_9798_2_5_udkey_A_2) (NonceT isoiec_9798_2_5_udkey_P ''Kab'')))+ , ((isoiec_9798_2_5_udkey_B, ''Kab''),+ (SumT (KnownT isoiec_9798_2_5_udkey_B_3) (NonceT isoiec_9798_2_5_udkey_P ''Kab'')))+ , ((isoiec_9798_2_6_udkey_A, ''Kab''),+ (SumT (KnownT isoiec_9798_2_6_udkey_A_3) (NonceT isoiec_9798_2_6_udkey_P ''Kab'')))+ , ((isoiec_9798_2_6_udkey_B, ''Kab''),+ (SumT (KnownT isoiec_9798_2_6_udkey_B_4) (NonceT isoiec_9798_2_6_udkey_P ''Kab'')))+ , ((isoiec_9798_2_5_udkey_B, ''P''), (KnownT isoiec_9798_2_5_udkey_B_3))+ , ((isoiec_9798_2_6_udkey_B, ''P''), (KnownT isoiec_9798_2_6_udkey_B_4))+ , ((isoiec_9798_2_4_udkey_B, ''RA''),+ (SumT (KnownT isoiec_9798_2_4_udkey_B_2) (NonceT isoiec_9798_2_4_udkey_A ''RA'')))+ , ((isoiec_9798_2_2_udkey_A, ''RB''), (KnownT isoiec_9798_2_2_udkey_A_1))+ , ((isoiec_9798_2_4_udkey_A, ''RB''), (KnownT isoiec_9798_2_4_udkey_A_1))+ , ((isoiec_9798_2_6_udkey_P, ''Ra''), (KnownT isoiec_9798_2_6_udkey_P_2))+ , ((isoiec_9798_2_6_udkey_A, ''Rb''), (KnownT isoiec_9798_2_6_udkey_A_1))+ , ((isoiec_9798_2_6_udkey_P, ''Rb''), (KnownT isoiec_9798_2_6_udkey_P_2))+ , ((isoiec_9798_2_6_udkey_B, ''Rpa''),+ (SumT (KnownT isoiec_9798_2_6_udkey_B_4) (NonceT isoiec_9798_2_6_udkey_A ''Rpa'')))+ , ((isoiec_9798_2_1_udkey_B, ''TNA''),+ (SumT (KnownT isoiec_9798_2_1_udkey_B_1) (NonceT isoiec_9798_2_1_udkey_A ''TNA'')))+ , ((isoiec_9798_2_3_udkey_B, ''TNA''),+ (SumT (KnownT isoiec_9798_2_3_udkey_B_1) (NonceT isoiec_9798_2_3_udkey_A ''TNA'')))+ , ((isoiec_9798_2_3_udkey_A, ''TNB''),+ (SumT (KnownT isoiec_9798_2_3_udkey_A_2) (NonceT isoiec_9798_2_3_udkey_B ''TNB'')))+ , ((isoiec_9798_2_5_udkey_B, ''TNa''),+ (SumT (KnownT isoiec_9798_2_5_udkey_B_3) (NonceT isoiec_9798_2_5_udkey_A ''TNa'')))+ , ((isoiec_9798_2_5_udkey_A, ''TNb''),+ (SumT (KnownT isoiec_9798_2_5_udkey_A_4) (NonceT isoiec_9798_2_5_udkey_B ''TNb'')))+ , ((isoiec_9798_2_5_udkey_B, ''TNp''),+ (SumT (KnownT isoiec_9798_2_5_udkey_B_3) (NonceT isoiec_9798_2_5_udkey_P ''TNp'')))+ , ((isoiec_9798_2_5_udkey_P, ''TVPa''),+ (KnownT isoiec_9798_2_5_udkey_P_1))+ , ((isoiec_9798_2_1_udkey_A, ''Text1''),+ (KnownT isoiec_9798_2_1_udkey_A_text_1))+ , ((isoiec_9798_2_1_udkey_B, ''Text1''),+ (KnownT isoiec_9798_2_1_udkey_B_1))+ , ((isoiec_9798_2_2_udkey_A, ''Text1''),+ (KnownT isoiec_9798_2_2_udkey_A_1))+ , ((isoiec_9798_2_2_udkey_B, ''Text1''),+ (KnownT isoiec_9798_2_2_udkey_B_text_1))+ , ((isoiec_9798_2_3_udkey_A, ''Text1''),+ (KnownT isoiec_9798_2_3_udkey_A_text_1))+ , ((isoiec_9798_2_3_udkey_B, ''Text1''),+ (KnownT isoiec_9798_2_3_udkey_B_1))+ , ((isoiec_9798_2_4_udkey_A, ''Text1''),+ (KnownT isoiec_9798_2_4_udkey_A_1))+ , ((isoiec_9798_2_4_udkey_B, ''Text1''),+ (KnownT isoiec_9798_2_4_udkey_B_text_1))+ , ((isoiec_9798_2_5_udkey_A, ''Text1''),+ (KnownT isoiec_9798_2_5_udkey_A_text_1))+ , ((isoiec_9798_2_5_udkey_P, ''Text1''),+ (KnownT isoiec_9798_2_5_udkey_P_1))+ , ((isoiec_9798_2_6_udkey_A, ''Text1''),+ (KnownT isoiec_9798_2_6_udkey_A_1))+ , ((isoiec_9798_2_6_udkey_B, ''Text1''),+ (KnownT isoiec_9798_2_6_udkey_B_text_1))+ , ((isoiec_9798_2_1_udkey_A, ''Text2''),+ (KnownT isoiec_9798_2_1_udkey_A_text_1))+ , ((isoiec_9798_2_1_udkey_B, ''Text2''),+ (KnownT isoiec_9798_2_1_udkey_B_1))+ , ((isoiec_9798_2_2_udkey_A, ''Text2''),+ (KnownT isoiec_9798_2_2_udkey_A_text_2))+ , ((isoiec_9798_2_2_udkey_B, ''Text2''),+ (KnownT isoiec_9798_2_2_udkey_B_2))+ , ((isoiec_9798_2_3_udkey_A, ''Text2''),+ (KnownT isoiec_9798_2_3_udkey_A_text_1))+ , ((isoiec_9798_2_3_udkey_B, ''Text2''),+ (KnownT isoiec_9798_2_3_udkey_B_1))+ , ((isoiec_9798_2_4_udkey_A, ''Text2''),+ (KnownT isoiec_9798_2_4_udkey_A_text_2))+ , ((isoiec_9798_2_4_udkey_B, ''Text2''),+ (KnownT isoiec_9798_2_4_udkey_B_2))+ , ((isoiec_9798_2_5_udkey_B, ''Text2''),+ (KnownT isoiec_9798_2_5_udkey_B_3))+ , ((isoiec_9798_2_5_udkey_P, ''Text2''),+ (KnownT isoiec_9798_2_5_udkey_P_text_2))+ , ((isoiec_9798_2_6_udkey_A, ''Text2''),+ (KnownT isoiec_9798_2_6_udkey_A_text_2))+ , ((isoiec_9798_2_6_udkey_P, ''Text2''),+ (KnownT isoiec_9798_2_6_udkey_P_2))+ , ((isoiec_9798_2_2_udkey_A, ''Text3''),+ (KnownT isoiec_9798_2_2_udkey_A_text_2))+ , ((isoiec_9798_2_2_udkey_B, ''Text3''),+ (KnownT isoiec_9798_2_2_udkey_B_2))+ , ((isoiec_9798_2_3_udkey_A, ''Text3''),+ (KnownT isoiec_9798_2_3_udkey_A_2))+ , ((isoiec_9798_2_3_udkey_B, ''Text3''),+ (KnownT isoiec_9798_2_3_udkey_B_text_2))+ , ((isoiec_9798_2_4_udkey_A, ''Text3''),+ (KnownT isoiec_9798_2_4_udkey_A_text_2))+ , ((isoiec_9798_2_4_udkey_B, ''Text3''),+ (KnownT isoiec_9798_2_4_udkey_B_2))+ , ((isoiec_9798_2_5_udkey_A, ''Text3''),+ (KnownT isoiec_9798_2_5_udkey_A_2))+ , ((isoiec_9798_2_5_udkey_P, ''Text3''),+ (KnownT isoiec_9798_2_5_udkey_P_text_2))+ , ((isoiec_9798_2_6_udkey_B, ''Text3''),+ (KnownT isoiec_9798_2_6_udkey_B_4))+ , ((isoiec_9798_2_6_udkey_P, ''Text3''),+ (KnownT isoiec_9798_2_6_udkey_P_text_3))+ , ((isoiec_9798_2_3_udkey_A, ''Text4''),+ (KnownT isoiec_9798_2_3_udkey_A_2))+ , ((isoiec_9798_2_3_udkey_B, ''Text4''),+ (KnownT isoiec_9798_2_3_udkey_B_text_2))+ , ((isoiec_9798_2_4_udkey_A, ''Text4''),+ (KnownT isoiec_9798_2_4_udkey_A_3))+ , ((isoiec_9798_2_4_udkey_B, ''Text4''),+ (KnownT isoiec_9798_2_4_udkey_B_text_3))+ , ((isoiec_9798_2_5_udkey_A, ''Text4''),+ (KnownT isoiec_9798_2_5_udkey_A_2))+ , ((isoiec_9798_2_5_udkey_P, ''Text4''),+ (KnownT isoiec_9798_2_5_udkey_P_text_2))+ , ((isoiec_9798_2_6_udkey_A, ''Text4''),+ (KnownT isoiec_9798_2_6_udkey_A_3))+ , ((isoiec_9798_2_6_udkey_P, ''Text4''),+ (KnownT isoiec_9798_2_6_udkey_P_text_3))+ , ((isoiec_9798_2_4_udkey_A, ''Text5''),+ (KnownT isoiec_9798_2_4_udkey_A_3))+ , ((isoiec_9798_2_4_udkey_B, ''Text5''),+ (KnownT isoiec_9798_2_4_udkey_B_text_3))+ , ((isoiec_9798_2_5_udkey_A, ''Text5''),+ (KnownT isoiec_9798_2_5_udkey_A_text_3))+ , ((isoiec_9798_2_5_udkey_B, ''Text5''),+ (KnownT isoiec_9798_2_5_udkey_B_3))+ , ((isoiec_9798_2_6_udkey_A, ''Text5''),+ (KnownT isoiec_9798_2_6_udkey_A_3))+ , ((isoiec_9798_2_6_udkey_P, ''Text5''),+ (KnownT isoiec_9798_2_6_udkey_P_text_3))+ , ((isoiec_9798_2_5_udkey_A, ''Text6''),+ (KnownT isoiec_9798_2_5_udkey_A_text_3))+ , ((isoiec_9798_2_5_udkey_B, ''Text6''),+ (KnownT isoiec_9798_2_5_udkey_B_3))+ , ((isoiec_9798_2_6_udkey_A, ''Text6''),+ (KnownT isoiec_9798_2_6_udkey_A_text_4))+ , ((isoiec_9798_2_6_udkey_B, ''Text6''),+ (KnownT isoiec_9798_2_6_udkey_B_4))+ , ((isoiec_9798_2_5_udkey_A, ''Text7''),+ (KnownT isoiec_9798_2_5_udkey_A_4))+ , ((isoiec_9798_2_5_udkey_B, ''Text7''),+ (KnownT isoiec_9798_2_5_udkey_B_text_4))+ , ((isoiec_9798_2_6_udkey_A, ''Text7''),+ (KnownT isoiec_9798_2_6_udkey_A_text_4))+ , ((isoiec_9798_2_6_udkey_B, ''Text7''),+ (KnownT isoiec_9798_2_6_udkey_B_4))+ , ((isoiec_9798_2_5_udkey_A, ''Text8''),+ (KnownT isoiec_9798_2_5_udkey_A_4))+ , ((isoiec_9798_2_5_udkey_B, ''Text8''),+ (KnownT isoiec_9798_2_5_udkey_B_text_4))+ , ((isoiec_9798_2_6_udkey_A, ''Text8''),+ (KnownT isoiec_9798_2_6_udkey_A_5))+ , ((isoiec_9798_2_6_udkey_B, ''Text8''),+ (KnownT isoiec_9798_2_6_udkey_B_text_5))+ , ((isoiec_9798_2_6_udkey_A, ''Text9''),+ (KnownT isoiec_9798_2_6_udkey_A_5))+ , ((isoiec_9798_2_6_udkey_B, ''Text9''),+ (KnownT isoiec_9798_2_6_udkey_B_text_5))+ , ((isoiec_9798_2_5_udkey_A, ''TokenPA_for_B''),+ (KnownT isoiec_9798_2_5_udkey_A_2))+ , ((isoiec_9798_2_6_udkey_A, ''TokenPA_for_B''),+ (KnownT isoiec_9798_2_6_udkey_A_3))+ ]"++sublocale isoiec_9798_2_bdkey_state < isoiec_9798_2_bdkey_composed_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_bdkey_composed_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_bdkey_composed_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_1_udkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_1_udkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_1_udkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_1_udkey_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_1_enc_1'', s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |}+ ( K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_1_udkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_1_enc_1'', s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |}+ ( K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_1_udkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_udkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_udkey_A_1_RB t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_udkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_udkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_udkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_udkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_2_enc_2'', LN ''RB'' tid0, s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_2_udkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_A_2_TNB t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_2'', s(MV ''TNB'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(AV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_udkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_2'', s(MV ''TNB'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(AV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_udkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_1'', s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |}+ ( K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_udkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_1'', s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |}+ ( K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_udkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_B_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_A_1_RB t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_2'', s(MV ''RB'' tid0), LN ''RA'' tid0,+ s(MV ''Text4'' tid0)+ |}+ ( K ( s(MV ''B'' tid0) ) ( s(AV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_4_udkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_B_2_RA t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_4_udkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_4_udkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_B_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_B_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_A_2_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_A_2_TokenPA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_A_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_A_text_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_A_4_TNb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_A_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_A_4_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_B_3_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_B_3_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_B_3_P t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_B_3_TNa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_B_3_TNp t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_B_3_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_B_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_B_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_B_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_B_text_4_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_1_TVPa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_3_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_3_TokenPA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_text_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_5'', s(MV ''Rb'' tid0), LN ''Rpa'' tid0,+ s(MV ''Text8'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_A_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_B_4_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_B_4_P t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_B_4_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_B_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_B_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_B_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_B_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_B_text_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_2_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_2_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_2_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_text_3_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_bdkey_composed_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_1_udkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_1_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_1_udkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_1_udkey_A &+ ( tid1, isoiec_9798_2_1_udkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_1_enc_1'', s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |}+ ( K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_1_udkey_A_1_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_2_udkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_2_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_2_udkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_2_udkey_A &+ ( tid1, isoiec_9798_2_2_udkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(MV ''RB'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''RB'' tid0,+ s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_2_enc_2'', LN ''RB'' tid0, s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_2_udkey_A_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_3_udkey_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_3_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_3_udkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_3_udkey_B &+ ( tid1, isoiec_9798_2_3_udkey_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), LN ''TNB'' tid1,+ s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNB'' tid0),+ s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_2'', s(MV ''TNB'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_3_udkey_B_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_3_udkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_3_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_3_udkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_3_udkey_A &+ ( tid1, isoiec_9798_2_3_udkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_1'', s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |}+ ( K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_3_udkey_A_1_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_4_udkey_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_4_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_4_udkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_4_udkey_B &+ ( tid1, isoiec_9798_2_4_udkey_B_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''RA'' tid1), LN ''RB'' tid1,+ s(MV ''Text2'' tid1), s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''RA'' tid0,+ s(MV ''RB'' tid0), s(MV ''Text2'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_2'', s(MV ''RB'' tid0), LN ''RA'' tid0,+ s(MV ''Text4'' tid0)+ |}+ ( K ( s(MV ''B'' tid0) ) ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_udkey_B_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', LN ''RA'' tid0, LN ''RB'' tid1,+ s(MV ''Text2'' tid1)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid1) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_udkey_A_2_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_4_udkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_4_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_4_udkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_4_udkey_A &+ ( tid1, isoiec_9798_2_4_udkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''RA'' tid1, s(MV ''RB'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''RA'' tid0),+ LN ''RB'' tid0, s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_udkey_A_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_udkey_P_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_P"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "LN ''Kab'' tid0 : knows t"+ shows "False"+using facts proof(sources! " LN ''Kab'' tid0 ")+ case isoiec_9798_2_5_udkey_P_2_Kab note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case isoiec_9798_2_5_udkey_P_2_Kab_1 note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+qed (insert facts, fastsimp+)?++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_udkey_A_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_udkey_A_2 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_udkey_P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_udkey_B_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_udkey_B_3 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_udkey_P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_udkey_A_non_injective_agreement_B:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_udkey_A_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_udkey_B &+ ( tid1, isoiec_9798_2_5_udkey_B_4 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), s(MV ''P'' tid1),+ s(MV ''Kab'' tid1), s(MV ''TNa'' tid1), s(MV ''Text5'' tid1),+ LN ''TNb'' tid1, s(MV ''Text7'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''TNa'' tid0, s(MV ''Text5'' tid0),+ s(MV ''TNb'' tid0), s(MV ''Text7'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_udkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_udkey_B_4_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid2),+ LN ''Kab'' tid1, s(AV ''A'' tid0), s(MV ''Text2'' tid2)+ |}+ ( K ( s(AV ''B'' tid2) ) ( s(MV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_udkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc_1 tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid2),+ s(AV ''B'' tid0), s(MV ''Text5'' tid2)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_udkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_udkey_A_3_enc tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid3, LN ''Kab'' tid1,+ s(AV ''B'' tid0), s(MV ''Text3'' tid3)+ |}+ ( K ( s(AV ''A'' tid3) ) ( s(AV ''P'' tid3) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_udkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc tid4) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_udkey_B_non_injective_agreement_A:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_udkey_B_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_udkey_A &+ ( tid1, isoiec_9798_2_5_udkey_A_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Kab'' tid1), LN ''TNa'' tid1, s(MV ''Text5'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''TNa'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc_1 tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_udkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_udkey_A_3_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid2, LN ''Kab'' tid1,+ s(AV ''B'' tid0), s(MV ''Text3'' tid2)+ |}+ ( K ( s(AV ''A'' tid2) ) ( s(AV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_5_udkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_udkey_A_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_udkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_udkey_P &+ ( tid1, isoiec_9798_2_5_udkey_P_2 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1), LN ''Kab'' tid1,+ s(MV ''TVPa'' tid1), s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''TVPa'' tid0, s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_5_udkey_B_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_udkey_B_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_udkey_P &+ ( tid1, isoiec_9798_2_5_udkey_P_2 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1), LN ''Kab'' tid1,+ LN ''TNp'' tid1, s(MV ''Text2'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''TNp'' tid0), s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_udkey_P_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_P"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "LN ''Kab'' tid0 : knows t"+ shows "False"+using facts proof(sources! " LN ''Kab'' tid0 ")+ case isoiec_9798_2_6_udkey_P_3_Kab note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case isoiec_9798_2_6_udkey_P_3_Kab_1 note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+qed (insert facts, fastsimp+)?++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_udkey_A_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_udkey_A_3 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_udkey_P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_udkey_B_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_udkey_B_4 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_udkey_P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_udkey_A_non_injective_agreement_B:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_udkey_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_udkey_B &+ ( tid1, isoiec_9798_2_6_udkey_B_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''P'' tid1),+ s(MV ''Kab'' tid1), s(MV ''Rpa'' tid1), LN ''Rb'' tid1,+ s(MV ''Text6'' tid1), s(MV ''Text8'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''Rpa'' tid0, s(MV ''Rb'' tid0),+ s(MV ''Text6'' tid0), s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_5'', s(MV ''Rb'' tid0), LN ''Rpa'' tid0,+ s(MV ''Text8'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_udkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_udkey_B_5_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid2, LN ''Kab'' tid1,+ s(AV ''A'' tid2), s(MV ''Text3'' tid2)+ |}+ ( K ( s(AV ''B'' tid2) ) ( s(MV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_udkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc_1 tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', LN ''Rpa'' tid0, LN ''Rb'' tid2,+ s(MV ''Text6'' tid2)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_udkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_udkey_A_4_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_udkey_B_non_injective_agreement_A:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_udkey_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_udkey_A &+ ( tid1, isoiec_9798_2_6_udkey_A_4 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Kab'' tid1), LN ''Rpa'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text6'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_udkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_udkey_A_4_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid2, LN ''Kab'' tid1,+ s(MV ''B'' tid2), s(MV ''Text4'' tid2)+ |}+ ( K ( s(AV ''A'' tid2) ) ( s(AV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: isoiec_9798_2_6_udkey_P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_udkey_A_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_udkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_udkey_P &+ ( tid1, isoiec_9798_2_6_udkey_P_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Ra'' tid1), LN ''Kab'' tid1, s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''P'' tid0),+ LN ''Ra'' tid0, s(MV ''Kab'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_bdkey_state) isoiec_9798_2_6_udkey_B_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_udkey_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_udkey_P &+ ( tid1, isoiec_9798_2_6_udkey_P_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Rb'' tid1), LN ''Kab'' tid1, s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ LN ''Rb'' tid0, s(MV ''Kab'' tid0), s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++end
@@ -0,0 +1,2773 @@+theory "isoiec-9798-3_cert_auto"+imports+ "../ESPLogic"+begin++role isoiec_9798_3_1_A+where "isoiec_9798_3_1_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sMV ''Text2'',+ PSign <| sC ''isoiec_9798_3_1_sig_1'', sN ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( sPK ''A'' )+ |>+ ]"++role isoiec_9798_3_1_B+where "isoiec_9798_3_1_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Text2'',+ PSign <| sC ''isoiec_9798_3_1_sig_1'', sMV ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( PAsymPK ( sMV ''A'' ) )+ |>+ ]"++role isoiec_9798_3_2_A+where "isoiec_9798_3_2_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'',+ PSign <| sC ''isoiec_9798_3_2_sig_2'', sN ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ ( sPK ''A'' )+ |>+ ]"++role isoiec_9798_3_2_B+where "isoiec_9798_3_2_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'',+ PSign <| sC ''isoiec_9798_3_2_sig_2'', sMV ''Ra'', sN ''Rb'', sAV ''B'',+ sMV ''Text2''+ |>+ ( sPK ''A'' )+ |>+ ]"++role isoiec_9798_3_3_A+where "isoiec_9798_3_3_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sMV ''Text2'',+ PSign <| sC ''isoiec_9798_3_3_sig_1'', sN ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( sPK ''A'' )+ |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text4'',+ PSign <| sC ''isoiec_9798_3_3_sig_2'', sMV ''TNB'', sAV ''A'',+ sMV ''Text3''+ |>+ ( sPK ''B'' )+ |>+ ]"++role isoiec_9798_3_3_B+where "isoiec_9798_3_3_B =+ [ Send ''leak_B'' ( sN ''TNB'' )+ , Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Text2'',+ PSign <| sC ''isoiec_9798_3_3_sig_1'', sMV ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( PAsymPK ( sMV ''A'' ) )+ |>+ , Recv ''text_2'' <| sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sMV ''A'', sAV ''B'', sMV ''Text4'',+ PSign <| sC ''isoiec_9798_3_3_sig_2'', sN ''TNB'', sMV ''A'',+ sMV ''Text3''+ |>+ ( sPK ''B'' )+ |>+ ]"++role isoiec_9798_3_4_A+where "isoiec_9798_3_4_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''RB'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'',+ PSign <| sC ''isoiec_9798_3_4_sig_1'', sN ''RA'', sMV ''RB'', sMV ''B'',+ sMV ''Text2''+ |>+ ( sPK ''A'' )+ |>+ , Recv ''3'' <| sMV ''B'', sAV ''A'', sMV ''Text5'',+ PSign <| sC ''isoiec_9798_3_4_sig_2'', sMV ''RB'', sN ''RA'', sAV ''A'',+ sMV ''Text4''+ |>+ ( PAsymPK ( sMV ''B'' ) )+ |>+ ]"++role isoiec_9798_3_4_B+where "isoiec_9798_3_4_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''RB'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'',+ PSign <| sC ''isoiec_9798_3_4_sig_1'', sMV ''RA'', sN ''RB'', sAV ''B'',+ sMV ''Text2''+ |>+ ( sPK ''A'' )+ |>+ , Recv ''text_3'' <| sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''B'', sAV ''A'', sMV ''Text5'',+ PSign <| sC ''isoiec_9798_3_4_sig_2'', sN ''RB'', sMV ''RA'', sAV ''A'',+ sMV ''Text4''+ |>+ ( sPK ''B'' )+ |>+ ]"++role isoiec_9798_3_5_A+where "isoiec_9798_3_5_A =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''RA'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''B'', sAV ''A'', sMV ''RB'', sMV ''Text2'' |>+ , Recv ''3'' <| sAV ''B'', sAV ''A'', sMV ''Text6'',+ PSign <| sC ''isoiec_9798_3_5_sig_1'', sMV ''RB'', sN ''RA'', sAV ''A'',+ sMV ''Text5''+ |>+ ( sPK ''B'' )+ |>+ , Recv ''text_4'' <| sMV ''Text3'', sMV ''Text4'' |>+ , Send ''4'' <| sAV ''A'', sAV ''B'', sMV ''Text4'',+ PSign <| sC ''isoiec_9798_3_5_sig_2'', sN ''RA'', sMV ''RB'', sAV ''B'',+ sMV ''Text3''+ |>+ ( sPK ''A'' )+ |>+ ]"++role isoiec_9798_3_5_B+where "isoiec_9798_3_5_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''RA'', sMV ''Text1'' |>+ , Recv ''text_2'' ( sMV ''Text2'' )+ , Send ''2'' <| sAV ''B'', sMV ''A'', sN ''RB'', sMV ''Text2'' |>+ , Recv ''text_3'' <| sMV ''Text5'', sMV ''Text6'' |>+ , Send ''3'' <| sAV ''B'', sMV ''A'', sMV ''Text6'',+ PSign <| sC ''isoiec_9798_3_5_sig_1'', sN ''RB'', sMV ''RA'', sMV ''A'',+ sMV ''Text5''+ |>+ ( sPK ''B'' )+ |>+ , Recv ''4'' <| sMV ''A'', sAV ''B'', sMV ''Text4'',+ PSign <| sC ''isoiec_9798_3_5_sig_2'', sMV ''RA'', sN ''RB'', sAV ''B'',+ sMV ''Text3''+ |>+ ( PAsymPK ( sMV ''A'' ) )+ |>+ ]"++role isoiec_9798_3_6_1_A+where "isoiec_9798_3_6_1_A =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''Ra'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sN ''Ra'', sMV ''Rb'',+ sMV ''Text3'', sMV ''TokenBA''+ |>+ , Recv ''text_3'' ( sMV ''Text4'' )+ , Send ''3'' <| sAV ''A'', sAV ''T'', sN ''Rpa'', sMV ''Rb'', sAV ''B'',+ sMV ''Text4''+ |>+ , Recv ''4'' <| sAV ''T'', sAV ''A'', sMV ''Text7'', sAV ''A'',+ sPK ''A'', sAV ''B'', sMV ''pkB'',+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_4_1'', sN ''Rpa'', sAV ''B'',+ sMV ''pkB'', sMV ''Text6''+ |>+ ( sPK ''T'' ),+ sMV ''TokenTA_for_B''+ |>+ , Send ''check_4_out'' ( PEnc <| sC ''check_4'', sMV ''TokenBA'' |>+ ( sN ''check_nonce_4'' )+ )+ , Recv ''check_4_in'' ( PEnc <| sC ''check_4'',+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_2'', sAV ''B'', sN ''Ra'',+ sMV ''Rb'', sAV ''A'', sMV ''Text2''+ |>+ ( sMV ''pkB'' )+ |>+ ( sN ''check_nonce_4'' )+ )+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''A'', sAV ''B'', sMV ''Text9'', sAV ''T'',+ sMV ''TokenTA_for_B'',+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_5'', sMV ''Rb'', sN ''Ra'',+ sAV ''B'', sAV ''A'', sMV ''Text8''+ |>+ ( sPK ''A'' )+ |>+ ]"++role isoiec_9798_3_6_1_B+where "isoiec_9798_3_6_1_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Ra'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sMV ''A'', sAV ''B'', sMV ''Ra'', sN ''Rb'',+ sMV ''Text3'',+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_2'', sAV ''B'', sMV ''Ra'',+ sN ''Rb'', sMV ''A'', sMV ''Text2''+ |>+ ( sPK ''B'' )+ |>+ , Recv ''5'' <| sMV ''A'', sAV ''B'', sMV ''Text9'', sMV ''T'',+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_4_2'', sN ''Rb'', sMV ''A'',+ sMV ''pkA'', sMV ''Text5''+ |>+ ( PAsymPK ( sMV ''T'' ) ),+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_5'', sN ''Rb'', sMV ''Ra5'',+ sAV ''B'', sMV ''A'', sMV ''Text8''+ |>+ ( sMV ''pkA'' )+ |>+ ]"++role isoiec_9798_3_6_1_T+where "isoiec_9798_3_6_1_T =+ [ Recv ''3'' <| sMV ''A'', sAV ''T'', sMV ''Rpa'', sMV ''Rb'', sMV ''B'',+ sMV ''Text4''+ |>+ , Recv ''text_4'' <| sMV ''Text5'', sMV ''Text6'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''T'', sMV ''A'', sMV ''Text7'', sMV ''A'',+ PAsymPK ( sMV ''A'' ), sMV ''B'', PAsymPK ( sMV ''B'' ),+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_4_1'', sMV ''Rpa'', sMV ''B'',+ PAsymPK ( sMV ''B'' ), sMV ''Text6''+ |>+ ( sPK ''T'' ),+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_4_2'', sMV ''Rb'', sMV ''A'',+ PAsymPK ( sMV ''A'' ), sMV ''Text5''+ |>+ ( sPK ''T'' )+ |>+ ]"++role isoiec_9798_3_6_2_A+where "isoiec_9798_3_6_2_A =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''Ra'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sN ''Ra'', sMV ''Rb'',+ sMV ''Text3'', sMV ''TokenBA''+ |>+ , Recv ''text_3'' ( sMV ''Text4'' )+ , Send ''3'' <| sAV ''A'', sAV ''T'', sN ''Rpa'', sMV ''Rb'', sAV ''B'',+ sMV ''Text4''+ |>+ , Recv ''4'' <| sAV ''T'', sAV ''A'', sMV ''Text7'', sAV ''A'',+ sPK ''A'', sAV ''B'', sMV ''pkB'', sMV ''TokenTA''+ |>+ , Send ''check_4_out'' ( PEnc <| sC ''check_4'', sMV ''TokenTA'',+ sMV ''TokenBA''+ |>+ ( sN ''check_nonce_4'' )+ )+ , Recv ''check_4_in'' ( PEnc <| sC ''check_4'',+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_4'', sN ''Rpa'', sMV ''Rb'',+ sAV ''A'', sMV ''pkA'', sAV ''B'', sMV ''pkB'', sMV ''Text5''+ |>+ ( sPK ''T'' ),+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_2'', sAV ''B'', sN ''Ra'',+ sMV ''Rb'', sAV ''A'', sMV ''Text2''+ |>+ ( sMV ''pkB'' )+ |>+ ( sN ''check_nonce_4'' )+ )+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''A'', sAV ''B'', sN ''Rpa'', sMV ''Text9'',+ sAV ''T'', sMV ''TokenTA'',+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_5'', sMV ''Rb'', sN ''Ra'',+ sAV ''B'', sAV ''A'', sMV ''Text8''+ |>+ ( sPK ''A'' )+ |>+ ]"++role isoiec_9798_3_6_2_B+where "isoiec_9798_3_6_2_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Ra'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sMV ''A'', sAV ''B'', sMV ''Ra'', sN ''Rb'',+ sMV ''Text3'',+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_2'', sAV ''B'', sMV ''Ra'',+ sN ''Rb'', sMV ''A'', sMV ''Text2''+ |>+ ( sPK ''B'' )+ |>+ , Recv ''5'' <| sMV ''A'', sAV ''B'', sMV ''Rpa'', sMV ''Text9'',+ sMV ''T'',+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_4'', sMV ''Rpa'', sN ''Rb'',+ sMV ''A'', sMV ''pkA'', sAV ''B'', sMV ''pkB'', sMV ''Text5''+ |>+ ( PAsymPK ( sMV ''T'' ) ),+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_5'', sN ''Rb'', sMV ''Ra5'',+ sAV ''B'', sMV ''A'', sMV ''Text8''+ |>+ ( sMV ''pkA'' )+ |>+ ]"++role isoiec_9798_3_6_2_T+where "isoiec_9798_3_6_2_T =+ [ Recv ''3'' <| sMV ''A'', sAV ''T'', sMV ''Rpa'', sMV ''Rb'', sMV ''B'',+ sMV ''Text4''+ |>+ , Recv ''text_4'' <| sMV ''Text5'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''T'', sMV ''A'', sMV ''Text7'', sMV ''A'',+ PAsymPK ( sMV ''A'' ), sMV ''B'', PAsymPK ( sMV ''B'' ),+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_4'', sMV ''Rpa'', sMV ''Rb'',+ sMV ''A'', PAsymPK ( sMV ''A'' ), sMV ''B'', PAsymPK ( sMV ''B'' ),+ sMV ''Text5''+ |>+ ( sPK ''T'' )+ |>+ ]"++role isoiec_9798_3_7_1_A+where "isoiec_9798_3_7_1_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' ( sMV ''Text2'' )+ , Send ''2'' <| sAV ''A'', sAV ''T'', sN ''Rpa'', sMV ''Rb'', sAV ''A'',+ sMV ''B'', sMV ''Text2''+ |>+ , Recv ''3'' <| sAV ''T'', sAV ''A'', sMV ''Text5'', sAV ''A'',+ sPK ''A'', sMV ''B'', sMV ''pkB'',+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_3_1'', sN ''Rpa'', sMV ''B'',+ sMV ''pkB'', sMV ''Text4''+ |>+ ( sPK ''T'' ),+ sMV ''TokenTA_for_B''+ |>+ , Recv ''text_4'' <| sMV ''Text6'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''A'', sMV ''B'', sN ''Rpa'', sMV ''Text7'',+ sAV ''T'', sMV ''TokenTA_for_B'',+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_4'', sMV ''Rb'', sN ''Ra'',+ sMV ''B'', sAV ''A'', sMV ''Text6''+ |>+ ( sPK ''A'' )+ |>+ , Recv ''5'' <| sAV ''A'', sMV ''B'', sN ''Ra'', sMV ''Rb'',+ sMV ''Text9'',+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_5'', sN ''Ra'', sMV ''Rb'',+ sAV ''A'', sMV ''B'', sMV ''Text8''+ |>+ ( sMV ''pkB'' )+ |>+ ]"++role isoiec_9798_3_7_1_B+where "isoiec_9798_3_7_1_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''4'' <| sAV ''A'', sAV ''B'', sMV ''Rpa'', sMV ''Text9'',+ sMV ''T'',+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_3_2'', sN ''Rb'', sAV ''A'',+ sMV ''pkA'', sMV ''Text3''+ |>+ ( PAsymPK ( sMV ''T'' ) ),+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_4'', sN ''Rb'', sMV ''Ra'',+ sAV ''B'', sAV ''A'', sMV ''Text6''+ |>+ ( sMV ''pkA'' )+ |>+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''A'', sAV ''B'', sMV ''Ra'', sN ''Rb'',+ sMV ''Text9'',+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_5'', sMV ''Ra'', sN ''Rb'',+ sAV ''A'', sAV ''B'', sMV ''Text8''+ |>+ ( sPK ''B'' )+ |>+ ]"++role isoiec_9798_3_7_1_T+where "isoiec_9798_3_7_1_T =+ [ Recv ''2'' <| sMV ''A'', sAV ''T'', sMV ''Rpa'', sMV ''Rb'', sMV ''A'',+ sMV ''B'', sMV ''Text2''+ |>+ , Recv ''text_3'' <| sMV ''Text3'', sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''T'', sMV ''A'', sMV ''Text5'', sMV ''A'',+ PAsymPK ( sMV ''A'' ), sMV ''B'', PAsymPK ( sMV ''B'' ),+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_3_1'', sMV ''Rpa'', sMV ''B'',+ PAsymPK ( sMV ''B'' ), sMV ''Text4''+ |>+ ( sPK ''T'' ),+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_3_2'', sMV ''Rb'', sMV ''A'',+ PAsymPK ( sMV ''A'' ), sMV ''Text3''+ |>+ ( sPK ''T'' )+ |>+ ]"++role isoiec_9798_3_7_2_A+where "isoiec_9798_3_7_2_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' ( sMV ''Text2'' )+ , Send ''2'' <| sAV ''A'', sAV ''T'', sN ''Rpa'', sMV ''Rb'', sAV ''A'',+ sMV ''B'', sMV ''Text2''+ |>+ , Recv ''3'' <| sAV ''T'', sAV ''A'', sMV ''Text5'', sAV ''A'',+ sPK ''A'', sMV ''B'', sMV ''pkB'', sMV ''TokenTA''+ |>+ , Send ''check_3_out'' ( PEnc <| sC ''check_4'', sMV ''TokenTA'' |>+ ( sN ''check_nonce_4'' )+ )+ , Recv ''check_3_in'' ( PEnc <| sC ''check_4'',+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_3'', sN ''Rpa'', sMV ''Rb'',+ sAV ''A'', sMV ''pkA'', sMV ''B'', sMV ''pkB'', sMV ''Text3''+ |>+ ( sPK ''T'' )+ |>+ ( sN ''check_nonce_4'' )+ )+ , Recv ''text_4'' <| sMV ''Text6'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''A'', sMV ''B'', sN ''Rpa'', sMV ''Text7'',+ sAV ''T'', sMV ''TokenTA'',+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_4'', sMV ''Rb'', sN ''Ra'',+ sMV ''B'', sAV ''A'', sMV ''Text6''+ |>+ ( sPK ''A'' )+ |>+ , Recv ''5'' <| sAV ''A'', sMV ''B'', sN ''Ra'', sMV ''Rb'',+ sMV ''Text9'',+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_5'', sN ''Ra'', sMV ''Rb'',+ sAV ''A'', sMV ''B'', sMV ''Text8''+ |>+ ( sMV ''pkB'' )+ |>+ ]"++role isoiec_9798_3_7_2_B+where "isoiec_9798_3_7_2_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''4'' <| sAV ''A'', sAV ''B'', sMV ''Rpa'', sMV ''Text9'',+ sMV ''T'',+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_3'', sMV ''Rpa'', sN ''Rb'',+ sAV ''A'', sMV ''pkA'', sAV ''B'', sMV ''pkB'', sMV ''Text3''+ |>+ ( PAsymPK ( sMV ''T'' ) ),+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_4'', sN ''Rb'', sMV ''Ra'',+ sAV ''B'', sAV ''A'', sMV ''Text6''+ |>+ ( sMV ''pkA'' )+ |>+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''A'', sAV ''B'', sMV ''Ra'', sN ''Rb'',+ sMV ''Text9'',+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_5'', sMV ''Ra'', sN ''Rb'',+ sAV ''A'', sAV ''B'', sMV ''Text8''+ |>+ ( sPK ''B'' )+ |>+ ]"++role isoiec_9798_3_7_2_T+where "isoiec_9798_3_7_2_T =+ [ Recv ''2'' <| sMV ''A'', sAV ''T'', sMV ''Rpa'', sMV ''Rb'', sMV ''A'',+ sMV ''B'', sMV ''Text2''+ |>+ , Recv ''text_3'' <| sMV ''Text3'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''T'', sMV ''A'', sMV ''Text5'', sMV ''A'',+ PAsymPK ( sMV ''A'' ), sMV ''B'', PAsymPK ( sMV ''B'' ),+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_3'', sMV ''Rpa'', sMV ''Rb'',+ sMV ''A'', PAsymPK ( sMV ''A'' ), sMV ''B'', PAsymPK ( sMV ''B'' ),+ sMV ''Text3''+ |>+ ( sPK ''T'' )+ |>+ ]"++protocol isoiec_9798_3+where "isoiec_9798_3 =+{ isoiec_9798_3_1_A, isoiec_9798_3_1_B, isoiec_9798_3_2_A,+ isoiec_9798_3_2_B, isoiec_9798_3_3_A, isoiec_9798_3_3_B,+ isoiec_9798_3_4_A, isoiec_9798_3_4_B, isoiec_9798_3_5_A,+ isoiec_9798_3_5_B, isoiec_9798_3_6_1_A, isoiec_9798_3_6_1_B,+ isoiec_9798_3_6_1_T, isoiec_9798_3_6_2_A, isoiec_9798_3_6_2_B,+ isoiec_9798_3_6_2_T, isoiec_9798_3_7_1_A, isoiec_9798_3_7_1_B,+ isoiec_9798_3_7_1_T, isoiec_9798_3_7_2_A, isoiec_9798_3_7_2_B,+ isoiec_9798_3_7_2_T+}"++locale restricted_isoiec_9798_3_state = isoiec_9798_3_state++type_invariant isoiec_9798_3_composed_typing for isoiec_9798_3+where "isoiec_9798_3_composed_typing = mk_typing+ [ ((isoiec_9798_3_1_B, ''A''), (KnownT isoiec_9798_3_1_B_1))+ , ((isoiec_9798_3_3_B, ''A''), (KnownT isoiec_9798_3_3_B_1))+ , ((isoiec_9798_3_5_B, ''A''), (KnownT isoiec_9798_3_5_B_1))+ , ((isoiec_9798_3_6_1_B, ''A''), (KnownT isoiec_9798_3_6_1_B_1))+ , ((isoiec_9798_3_6_1_T, ''A''), (KnownT isoiec_9798_3_6_1_T_3))+ , ((isoiec_9798_3_6_2_B, ''A''), (KnownT isoiec_9798_3_6_2_B_1))+ , ((isoiec_9798_3_6_2_T, ''A''), (KnownT isoiec_9798_3_6_2_T_3))+ , ((isoiec_9798_3_7_1_T, ''A''), (KnownT isoiec_9798_3_7_1_T_2))+ , ((isoiec_9798_3_7_2_T, ''A''), (KnownT isoiec_9798_3_7_2_T_2))+ , ((isoiec_9798_3_2_A, ''B''), (KnownT isoiec_9798_3_2_A_1))+ , ((isoiec_9798_3_4_A, ''B''), (KnownT isoiec_9798_3_4_A_1))+ , ((isoiec_9798_3_6_1_T, ''B''), (KnownT isoiec_9798_3_6_1_T_3))+ , ((isoiec_9798_3_6_2_T, ''B''), (KnownT isoiec_9798_3_6_2_T_3))+ , ((isoiec_9798_3_7_1_A, ''B''), (KnownT isoiec_9798_3_7_1_A_1))+ , ((isoiec_9798_3_7_1_T, ''B''), (KnownT isoiec_9798_3_7_1_T_2))+ , ((isoiec_9798_3_7_2_A, ''B''), (KnownT isoiec_9798_3_7_2_A_1))+ , ((isoiec_9798_3_7_2_T, ''B''), (KnownT isoiec_9798_3_7_2_T_2))+ , ((isoiec_9798_3_4_B, ''RA''), (KnownT isoiec_9798_3_4_B_2))+ , ((isoiec_9798_3_5_B, ''RA''), (KnownT isoiec_9798_3_5_B_1))+ , ((isoiec_9798_3_4_A, ''RB''), (KnownT isoiec_9798_3_4_A_1))+ , ((isoiec_9798_3_5_A, ''RB''), (KnownT isoiec_9798_3_5_A_2))+ , ((isoiec_9798_3_2_B, ''Ra''), (KnownT isoiec_9798_3_2_B_2))+ , ((isoiec_9798_3_6_1_B, ''Ra''), (KnownT isoiec_9798_3_6_1_B_1))+ , ((isoiec_9798_3_6_2_B, ''Ra''), (KnownT isoiec_9798_3_6_2_B_1))+ , ((isoiec_9798_3_7_1_B, ''Ra''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_2_B, ''Ra''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_6_1_B, ''Ra5''), (KnownT isoiec_9798_3_6_1_B_5))+ , ((isoiec_9798_3_6_2_B, ''Ra5''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_2_A, ''Rb''), (KnownT isoiec_9798_3_2_A_1))+ , ((isoiec_9798_3_6_1_A, ''Rb''), (KnownT isoiec_9798_3_6_1_A_2))+ , ((isoiec_9798_3_6_1_T, ''Rb''), (KnownT isoiec_9798_3_6_1_T_3))+ , ((isoiec_9798_3_6_2_A, ''Rb''), (KnownT isoiec_9798_3_6_2_A_2))+ , ((isoiec_9798_3_6_2_T, ''Rb''), (KnownT isoiec_9798_3_6_2_T_3))+ , ((isoiec_9798_3_7_1_A, ''Rb''), (KnownT isoiec_9798_3_7_1_A_1))+ , ((isoiec_9798_3_7_1_T, ''Rb''), (KnownT isoiec_9798_3_7_1_T_2))+ , ((isoiec_9798_3_7_2_A, ''Rb''), (KnownT isoiec_9798_3_7_2_A_1))+ , ((isoiec_9798_3_7_2_T, ''Rb''), (KnownT isoiec_9798_3_7_2_T_2))+ , ((isoiec_9798_3_6_1_T, ''Rpa''), (KnownT isoiec_9798_3_6_1_T_3))+ , ((isoiec_9798_3_6_2_B, ''Rpa''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_6_2_T, ''Rpa''), (KnownT isoiec_9798_3_6_2_T_3))+ , ((isoiec_9798_3_7_1_B, ''Rpa''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_1_T, ''Rpa''), (KnownT isoiec_9798_3_7_1_T_2))+ , ((isoiec_9798_3_7_2_B, ''Rpa''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_7_2_T, ''Rpa''), (KnownT isoiec_9798_3_7_2_T_2))+ , ((isoiec_9798_3_6_1_B, ''T''), (KnownT isoiec_9798_3_6_1_B_5))+ , ((isoiec_9798_3_6_2_B, ''T''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_7_1_B, ''T''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_2_B, ''T''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_1_B, ''TNA''), (KnownT isoiec_9798_3_1_B_1))+ , ((isoiec_9798_3_3_B, ''TNA''), (KnownT isoiec_9798_3_3_B_1))+ , ((isoiec_9798_3_3_A, ''TNB''), (KnownT isoiec_9798_3_3_A_2))+ , ((isoiec_9798_3_1_A, ''Text1''), (KnownT isoiec_9798_3_1_A_text_1))+ , ((isoiec_9798_3_1_B, ''Text1''), (KnownT isoiec_9798_3_1_B_1))+ , ((isoiec_9798_3_2_A, ''Text1''), (KnownT isoiec_9798_3_2_A_1))+ , ((isoiec_9798_3_2_B, ''Text1''), (KnownT isoiec_9798_3_2_B_text_1))+ , ((isoiec_9798_3_3_A, ''Text1''), (KnownT isoiec_9798_3_3_A_text_1))+ , ((isoiec_9798_3_3_B, ''Text1''), (KnownT isoiec_9798_3_3_B_1))+ , ((isoiec_9798_3_4_A, ''Text1''), (KnownT isoiec_9798_3_4_A_1))+ , ((isoiec_9798_3_4_B, ''Text1''), (KnownT isoiec_9798_3_4_B_text_1))+ , ((isoiec_9798_3_5_A, ''Text1''), (KnownT isoiec_9798_3_5_A_text_1))+ , ((isoiec_9798_3_5_B, ''Text1''), (KnownT isoiec_9798_3_5_B_1))+ , ((isoiec_9798_3_6_1_A, ''Text1''), (KnownT isoiec_9798_3_6_1_A_text_1))+ , ((isoiec_9798_3_6_1_B, ''Text1''), (KnownT isoiec_9798_3_6_1_B_1))+ , ((isoiec_9798_3_6_2_A, ''Text1''), (KnownT isoiec_9798_3_6_2_A_text_1))+ , ((isoiec_9798_3_6_2_B, ''Text1''), (KnownT isoiec_9798_3_6_2_B_1))+ , ((isoiec_9798_3_7_1_A, ''Text1''), (KnownT isoiec_9798_3_7_1_A_1))+ , ((isoiec_9798_3_7_1_B, ''Text1''), (KnownT isoiec_9798_3_7_1_B_text_1))+ , ((isoiec_9798_3_7_2_A, ''Text1''), (KnownT isoiec_9798_3_7_2_A_1))+ , ((isoiec_9798_3_7_2_B, ''Text1''), (KnownT isoiec_9798_3_7_2_B_text_1))+ , ((isoiec_9798_3_1_A, ''Text2''), (KnownT isoiec_9798_3_1_A_text_1))+ , ((isoiec_9798_3_1_B, ''Text2''), (KnownT isoiec_9798_3_1_B_1))+ , ((isoiec_9798_3_2_A, ''Text2''), (KnownT isoiec_9798_3_2_A_text_2))+ , ((isoiec_9798_3_2_B, ''Text2''), (KnownT isoiec_9798_3_2_B_2))+ , ((isoiec_9798_3_3_A, ''Text2''), (KnownT isoiec_9798_3_3_A_text_1))+ , ((isoiec_9798_3_3_B, ''Text2''), (KnownT isoiec_9798_3_3_B_1))+ , ((isoiec_9798_3_4_A, ''Text2''), (KnownT isoiec_9798_3_4_A_text_2))+ , ((isoiec_9798_3_4_B, ''Text2''), (KnownT isoiec_9798_3_4_B_2))+ , ((isoiec_9798_3_5_A, ''Text2''), (KnownT isoiec_9798_3_5_A_2))+ , ((isoiec_9798_3_5_B, ''Text2''), (KnownT isoiec_9798_3_5_B_text_2))+ , ((isoiec_9798_3_6_1_A, ''Text2''),+ (KnownT isoiec_9798_3_6_1_A_check_4_in))+ , ((isoiec_9798_3_6_1_B, ''Text2''), (KnownT isoiec_9798_3_6_1_B_text_2))+ , ((isoiec_9798_3_6_2_A, ''Text2''),+ (KnownT isoiec_9798_3_6_2_A_check_4_in))+ , ((isoiec_9798_3_6_2_B, ''Text2''), (KnownT isoiec_9798_3_6_2_B_text_2))+ , ((isoiec_9798_3_7_1_A, ''Text2''), (KnownT isoiec_9798_3_7_1_A_text_2))+ , ((isoiec_9798_3_7_1_T, ''Text2''), (KnownT isoiec_9798_3_7_1_T_2))+ , ((isoiec_9798_3_7_2_A, ''Text2''), (KnownT isoiec_9798_3_7_2_A_text_2))+ , ((isoiec_9798_3_7_2_T, ''Text2''), (KnownT isoiec_9798_3_7_2_T_2))+ , ((isoiec_9798_3_2_A, ''Text3''), (KnownT isoiec_9798_3_2_A_text_2))+ , ((isoiec_9798_3_2_B, ''Text3''), (KnownT isoiec_9798_3_2_B_2))+ , ((isoiec_9798_3_3_A, ''Text3''), (KnownT isoiec_9798_3_3_A_2))+ , ((isoiec_9798_3_3_B, ''Text3''), (KnownT isoiec_9798_3_3_B_text_2))+ , ((isoiec_9798_3_4_A, ''Text3''), (KnownT isoiec_9798_3_4_A_text_2))+ , ((isoiec_9798_3_4_B, ''Text3''), (KnownT isoiec_9798_3_4_B_2))+ , ((isoiec_9798_3_5_A, ''Text3''), (KnownT isoiec_9798_3_5_A_text_4))+ , ((isoiec_9798_3_5_B, ''Text3''), (KnownT isoiec_9798_3_5_B_4))+ , ((isoiec_9798_3_6_1_A, ''Text3''), (KnownT isoiec_9798_3_6_1_A_2))+ , ((isoiec_9798_3_6_1_B, ''Text3''), (KnownT isoiec_9798_3_6_1_B_text_2))+ , ((isoiec_9798_3_6_2_A, ''Text3''), (KnownT isoiec_9798_3_6_2_A_2))+ , ((isoiec_9798_3_6_2_B, ''Text3''), (KnownT isoiec_9798_3_6_2_B_text_2))+ , ((isoiec_9798_3_7_1_B, ''Text3''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_1_T, ''Text3''), (KnownT isoiec_9798_3_7_1_T_text_3))+ , ((isoiec_9798_3_7_2_A, ''Text3''),+ (KnownT isoiec_9798_3_7_2_A_check_3_in))+ , ((isoiec_9798_3_7_2_B, ''Text3''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_7_2_T, ''Text3''), (KnownT isoiec_9798_3_7_2_T_text_3))+ , ((isoiec_9798_3_3_A, ''Text4''), (KnownT isoiec_9798_3_3_A_2))+ , ((isoiec_9798_3_3_B, ''Text4''), (KnownT isoiec_9798_3_3_B_text_2))+ , ((isoiec_9798_3_4_A, ''Text4''), (KnownT isoiec_9798_3_4_A_3))+ , ((isoiec_9798_3_4_B, ''Text4''), (KnownT isoiec_9798_3_4_B_text_3))+ , ((isoiec_9798_3_5_A, ''Text4''), (KnownT isoiec_9798_3_5_A_text_4))+ , ((isoiec_9798_3_5_B, ''Text4''), (KnownT isoiec_9798_3_5_B_4))+ , ((isoiec_9798_3_6_1_A, ''Text4''), (KnownT isoiec_9798_3_6_1_A_text_3))+ , ((isoiec_9798_3_6_1_T, ''Text4''), (KnownT isoiec_9798_3_6_1_T_3))+ , ((isoiec_9798_3_6_2_A, ''Text4''), (KnownT isoiec_9798_3_6_2_A_text_3))+ , ((isoiec_9798_3_6_2_T, ''Text4''), (KnownT isoiec_9798_3_6_2_T_3))+ , ((isoiec_9798_3_7_1_A, ''Text4''), (KnownT isoiec_9798_3_7_1_A_3))+ , ((isoiec_9798_3_7_1_T, ''Text4''), (KnownT isoiec_9798_3_7_1_T_text_3))+ , ((isoiec_9798_3_4_A, ''Text5''), (KnownT isoiec_9798_3_4_A_3))+ , ((isoiec_9798_3_4_B, ''Text5''), (KnownT isoiec_9798_3_4_B_text_3))+ , ((isoiec_9798_3_5_A, ''Text5''), (KnownT isoiec_9798_3_5_A_3))+ , ((isoiec_9798_3_5_B, ''Text5''), (KnownT isoiec_9798_3_5_B_text_3))+ , ((isoiec_9798_3_6_1_B, ''Text5''), (KnownT isoiec_9798_3_6_1_B_5))+ , ((isoiec_9798_3_6_1_T, ''Text5''), (KnownT isoiec_9798_3_6_1_T_text_4))+ , ((isoiec_9798_3_6_2_A, ''Text5''),+ (KnownT isoiec_9798_3_6_2_A_check_4_in))+ , ((isoiec_9798_3_6_2_B, ''Text5''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_6_2_T, ''Text5''), (KnownT isoiec_9798_3_6_2_T_text_4))+ , ((isoiec_9798_3_7_1_A, ''Text5''), (KnownT isoiec_9798_3_7_1_A_3))+ , ((isoiec_9798_3_7_1_T, ''Text5''), (KnownT isoiec_9798_3_7_1_T_text_3))+ , ((isoiec_9798_3_7_2_A, ''Text5''), (KnownT isoiec_9798_3_7_2_A_3))+ , ((isoiec_9798_3_7_2_T, ''Text5''), (KnownT isoiec_9798_3_7_2_T_text_3))+ , ((isoiec_9798_3_5_A, ''Text6''), (KnownT isoiec_9798_3_5_A_3))+ , ((isoiec_9798_3_5_B, ''Text6''), (KnownT isoiec_9798_3_5_B_text_3))+ , ((isoiec_9798_3_6_1_A, ''Text6''), (KnownT isoiec_9798_3_6_1_A_4))+ , ((isoiec_9798_3_6_1_T, ''Text6''), (KnownT isoiec_9798_3_6_1_T_text_4))+ , ((isoiec_9798_3_7_1_A, ''Text6''), (KnownT isoiec_9798_3_7_1_A_text_4))+ , ((isoiec_9798_3_7_1_B, ''Text6''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_2_A, ''Text6''), (KnownT isoiec_9798_3_7_2_A_text_4))+ , ((isoiec_9798_3_7_2_B, ''Text6''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_6_1_A, ''Text7''), (KnownT isoiec_9798_3_6_1_A_4))+ , ((isoiec_9798_3_6_1_T, ''Text7''), (KnownT isoiec_9798_3_6_1_T_text_4))+ , ((isoiec_9798_3_6_2_A, ''Text7''), (KnownT isoiec_9798_3_6_2_A_4))+ , ((isoiec_9798_3_6_2_T, ''Text7''), (KnownT isoiec_9798_3_6_2_T_text_4))+ , ((isoiec_9798_3_7_1_A, ''Text7''), (KnownT isoiec_9798_3_7_1_A_text_4))+ , ((isoiec_9798_3_7_2_A, ''Text7''), (KnownT isoiec_9798_3_7_2_A_text_4))+ , ((isoiec_9798_3_6_1_A, ''Text8''), (KnownT isoiec_9798_3_6_1_A_text_5))+ , ((isoiec_9798_3_6_1_B, ''Text8''), (KnownT isoiec_9798_3_6_1_B_5))+ , ((isoiec_9798_3_6_2_A, ''Text8''), (KnownT isoiec_9798_3_6_2_A_text_5))+ , ((isoiec_9798_3_6_2_B, ''Text8''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_7_1_A, ''Text8''), (KnownT isoiec_9798_3_7_1_A_5))+ , ((isoiec_9798_3_7_1_B, ''Text8''), (KnownT isoiec_9798_3_7_1_B_text_5))+ , ((isoiec_9798_3_7_2_A, ''Text8''), (KnownT isoiec_9798_3_7_2_A_5))+ , ((isoiec_9798_3_7_2_B, ''Text8''), (KnownT isoiec_9798_3_7_2_B_text_5))+ , ((isoiec_9798_3_6_1_A, ''Text9''), (KnownT isoiec_9798_3_6_1_A_text_5))+ , ((isoiec_9798_3_6_1_B, ''Text9''), (KnownT isoiec_9798_3_6_1_B_5))+ , ((isoiec_9798_3_6_2_A, ''Text9''), (KnownT isoiec_9798_3_6_2_A_text_5))+ , ((isoiec_9798_3_6_2_B, ''Text9''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_7_1_A, ''Text9''), (KnownT isoiec_9798_3_7_1_A_5))+ , ((isoiec_9798_3_7_1_B, ''Text9''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_2_A, ''Text9''), (KnownT isoiec_9798_3_7_2_A_5))+ , ((isoiec_9798_3_7_2_B, ''Text9''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_6_1_A, ''TokenBA''), (KnownT isoiec_9798_3_6_1_A_2))+ , ((isoiec_9798_3_6_2_A, ''TokenBA''), (KnownT isoiec_9798_3_6_2_A_2))+ , ((isoiec_9798_3_6_2_A, ''TokenTA''), (KnownT isoiec_9798_3_6_2_A_4))+ , ((isoiec_9798_3_7_2_A, ''TokenTA''), (KnownT isoiec_9798_3_7_2_A_3))+ , ((isoiec_9798_3_6_1_A, ''TokenTA_for_B''),+ (KnownT isoiec_9798_3_6_1_A_4))+ , ((isoiec_9798_3_7_1_A, ''TokenTA_for_B''),+ (KnownT isoiec_9798_3_7_1_A_3))+ , ((isoiec_9798_3_6_1_B, ''pkA''), (KnownT isoiec_9798_3_6_1_B_5))+ , ((isoiec_9798_3_6_2_A, ''pkA''),+ (KnownT isoiec_9798_3_6_2_A_check_4_in))+ , ((isoiec_9798_3_6_2_B, ''pkA''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_7_1_B, ''pkA''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_2_A, ''pkA''),+ (KnownT isoiec_9798_3_7_2_A_check_3_in))+ , ((isoiec_9798_3_7_2_B, ''pkA''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_6_1_A, ''pkB''), (KnownT isoiec_9798_3_6_1_A_4))+ , ((isoiec_9798_3_6_2_A, ''pkB''), (KnownT isoiec_9798_3_6_2_A_4))+ , ((isoiec_9798_3_6_2_B, ''pkB''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_7_1_A, ''pkB''), (KnownT isoiec_9798_3_7_1_A_3))+ , ((isoiec_9798_3_7_2_A, ''pkB''), (KnownT isoiec_9798_3_7_2_A_3))+ , ((isoiec_9798_3_7_2_B, ''pkB''), (KnownT isoiec_9798_3_7_2_B_4))+ ]"++sublocale isoiec_9798_3_state < isoiec_9798_3_composed_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_3_composed_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_3_composed_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_3_1_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_1_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_1_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_1_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_1_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_1_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_B_2_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_A_2_TNB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_B_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_1_RB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_B_2_RA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_B_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_B_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_A_2_RB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_A_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_A_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_A_text_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_A_text_4_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_1_RA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_text_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_4_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_2_TokenBA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_4_TokenTA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_4_pkB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_check_4_in_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''check_4'',+ {| LC ''isoiec_9798_3_6_opt_1_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_3_6_1_A_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_text_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_1_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_5_Ra5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_5_T t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_5_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_5_pkA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_3_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_3_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_3_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_3_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_text_4_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_text_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_2_TokenBA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_4_TokenTA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_4_pkB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_check_4_in_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''check_4'',+ {| {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |},+ {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_3_6_2_A_check_4_in_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''check_4'',+ {| {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |},+ {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_3_6_2_A_check_4_in_pkA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''check_4'',+ {| {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |},+ {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_3_6_2_A_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_text_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_1_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_Ra5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_T t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_pkA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_pkB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_3_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_3_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_3_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_3_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_text_4_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_3_TokenTA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_3_pkB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_text_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_T t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_pkA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_2_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_2_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_2_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_text_3_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_3_TokenTA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_3_pkB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_check_3_in_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''check_4'',+ {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_3_7_2_A_check_3_in_pkA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''check_4'',+ {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_3_7_2_A_text_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_T t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_pkA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_pkB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_2_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_2_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_2_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_text_3_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_3_composed_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_3_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_1_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_1_B"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_1_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_1_A &+ ( tid1, isoiec_9798_3_1_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_1_sig_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( SK ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_1_A_1_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_2_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_2_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_2_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_2_A &+ ( tid1, isoiec_9798_3_2_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra'' tid0),+ LN ''Rb'' tid0, s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_2_sig_2'', s(MV ''Ra'' tid0), LN ''Rb'' tid0,+ s(AV ''B'' tid0), s(MV ''Text2'' tid0)+ |}+ ( SK ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_2_A_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_3_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_3_A"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_3_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_3_B &+ ( tid1, isoiec_9798_3_3_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), LN ''TNB'' tid1,+ s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNB'' tid0),+ s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_3_sig_2'', s(MV ''TNB'' tid0),+ s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_3_B_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_3_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_3_B"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_3_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_3_A &+ ( tid1, isoiec_9798_3_3_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_3_sig_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( SK ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_3_A_1_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_4_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_4_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_4_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_4_B &+ ( tid1, isoiec_9798_3_4_B_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''RA'' tid1), LN ''RB'' tid1,+ s(MV ''Text2'' tid1), s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''RA'' tid0,+ s(MV ''RB'' tid0), s(MV ''Text2'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_4_sig_2'', s(MV ''RB'' tid0), LN ''RA'' tid0,+ s(AV ''A'' tid0), s(MV ''Text4'' tid0)+ |}+ ( SK ( s(MV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_4_B_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_4_sig_1'', LN ''RA'' tid0, LN ''RB'' tid1,+ s(AV ''B'' tid1), s(MV ''Text2'' tid1)+ |}+ ( SK ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_4_A_2_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_4_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_4_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_4_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_4_A &+ ( tid1, isoiec_9798_3_4_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''RA'' tid1, s(MV ''RB'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''RA'' tid0),+ LN ''RB'' tid0, s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_4_sig_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(AV ''B'' tid0), s(MV ''Text2'' tid0)+ |}+ ( SK ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_4_A_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_5_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_5_A"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_5_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_5_B &+ ( tid1, isoiec_9798_3_5_B_3 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), s(MV ''RA'' tid1), LN ''RB'' tid1,+ s(MV ''Text5'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''RA'' tid0,+ s(MV ''RB'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_5_sig_1'', s(MV ''RB'' tid0), LN ''RA'' tid0,+ s(AV ''A'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_5_B_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_5_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_5_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_5_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_5_A &+ ( tid1, isoiec_9798_3_5_A_4 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''RA'' tid1, s(MV ''RB'' tid1),+ s(MV ''Text3'' tid1), s(MV ''Text5'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''RA'' tid0),+ LN ''RB'' tid0, s(MV ''Text3'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_5_sig_2'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_5_A_4_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_5_sig_1'', LN ''RB'' tid0, LN ''RA'' tid1,+ s(AV ''A'' tid1), s(MV ''Text5'' tid1)+ |}+ ( SK ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_5_B_3_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_6_1_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_1_A"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_1_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_1_B &+ ( tid1, isoiec_9798_3_6_1_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), s(MV ''Ra'' tid1), LN ''Rb'' tid1,+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''check_4'',+ {| LC ''isoiec_9798_3_6_opt_1_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! " LN ''check_nonce_4'' tid0 ")+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_6_1_A_check_4_out_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_4_1'', LN ''Rpa'' tid0,+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text6'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_1_T_4_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_6_1_B_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_6_1_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_1_B"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_1_B_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_1_A &+ ( tid1, isoiec_9798_3_6_1_A_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text8'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra5'' tid0),+ LN ''Rb'' tid0, s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_4_2'', LN ''Rb'' tid0,+ s(MV ''A'' tid0), s(MV ''pkA'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_1_T_4_enc_1 tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_5'', LN ''Rb'' tid0,+ s(MV ''Ra5'' tid0), s(AV ''B'' tid0), s(MV ''A'' tid0),+ s(MV ''Text8'' tid0)+ |}+ ( SK ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_1_A_5_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_6_1_A_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_1_A"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_1_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_1_T &+ ( tid1, isoiec_9798_3_6_1_T_4 ) : steps t &+ {| s(MV ''B'' tid1), s(AV ''T'' tid1), s(MV ''Rpa'' tid1),+ PK ( s(MV ''B'' tid1) ), s(MV ''Text6'' tid1)+ |} = {| s(AV ''B'' tid0), s(AV ''T'' tid0), LN ''Rpa'' tid0,+ s(MV ''pkB'' tid0), s(MV ''Text6'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_4_1'', LN ''Rpa'' tid0,+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text6'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_1_T_4_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_6_1_B_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_1_B"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_1_B_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_1_T &+ ( tid1, isoiec_9798_3_6_1_T_4 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''T'' tid1), s(MV ''Rb'' tid1),+ PK ( s(MV ''A'' tid1) ), s(MV ''Text5'' tid1)+ |} = {| s(MV ''A'' tid0), s(MV ''T'' tid0), LN ''Rb'' tid0,+ s(MV ''pkA'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_4_2'', LN ''Rb'' tid0,+ s(MV ''A'' tid0), s(MV ''pkA'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_1_T_4_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_6_2_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_2_A"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_2_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_2_B &+ ( tid1, isoiec_9798_3_6_2_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), s(MV ''Ra'' tid1), LN ''Rb'' tid1,+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''check_4'',+ {| {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |},+ {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! " LN ''check_nonce_4'' tid0 ")+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_6_2_A_check_4_out_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_2_T_4_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_6_2_B_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_6_2_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_2_B"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_2_B_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_2_A &+ ( tid1, isoiec_9798_3_6_2_A_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text8'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra5'' tid0),+ LN ''Rb'' tid0, s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(MV ''A'' tid0), s(MV ''pkA'' tid0), s(AV ''B'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_2_T_4_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_5'', LN ''Rb'' tid0,+ s(MV ''Ra5'' tid0), s(AV ''B'' tid0), s(MV ''A'' tid0),+ s(MV ''Text8'' tid0)+ |}+ ( SK ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_2_A_5_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_6_2_A_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_2_A"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_2_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_2_T &+ ( tid1, isoiec_9798_3_6_2_T_4 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''T'' tid1),+ s(MV ''Rpa'' tid1), s(MV ''Rb'' tid1), PK ( s(MV ''A'' tid1) ),+ PK ( s(MV ''B'' tid1) ), s(MV ''Text5'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''T'' tid0),+ LN ''Rpa'' tid0, s(MV ''Rb'' tid0), s(MV ''pkA'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''check_4'',+ {| {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |},+ {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! " LN ''check_nonce_4'' tid0 ")+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_6_2_A_check_4_out_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_2_T_4_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_6_2_B_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_2_B"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_2_B_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_2_T &+ ( tid1, isoiec_9798_3_6_2_T_4 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''T'' tid1),+ s(MV ''Rpa'' tid1), s(MV ''Rb'' tid1), PK ( s(MV ''A'' tid1) ),+ PK ( s(MV ''B'' tid1) ), s(MV ''Text5'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''T'' tid0),+ s(MV ''Rpa'' tid0), LN ''Rb'' tid0, s(MV ''pkA'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(MV ''A'' tid0), s(MV ''pkA'' tid0), s(AV ''B'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_2_T_4_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_7_1_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_1_A"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_1_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_1_B &+ ( tid1, isoiec_9798_3_7_1_B_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''Ra'' tid1), LN ''Rb'' tid1,+ s(MV ''Text8'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_1_sig_3_1'', LN ''Rpa'' tid0,+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text4'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_1_T_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_1_sig_5'', LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text8'' tid0)+ |}+ ( SK ( s(MV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_1_B_5_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_7_1_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_1_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_1_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_1_A &+ ( tid1, isoiec_9798_3_7_1_A_4 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text6'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra'' tid0),+ LN ''Rb'' tid0, s(MV ''Text6'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_1_sig_3_2'', LN ''Rb'' tid0,+ s(AV ''A'' tid0), s(MV ''pkA'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_1_T_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_1_sig_4'', LN ''Rb'' tid0,+ s(MV ''Ra'' tid0), s(AV ''B'' tid0), s(AV ''A'' tid0),+ s(MV ''Text6'' tid0)+ |}+ ( SK ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_1_A_4_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_7_1_A_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_1_A"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_1_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_1_T &+ ( tid1, isoiec_9798_3_7_1_T_3 ) : steps t &+ {| s(MV ''B'' tid1), s(AV ''T'' tid1), s(MV ''Rpa'' tid1),+ PK ( s(MV ''B'' tid1) ), s(MV ''Text4'' tid1)+ |} = {| s(MV ''B'' tid0), s(AV ''T'' tid0), LN ''Rpa'' tid0,+ s(MV ''pkB'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_1_sig_3_1'', LN ''Rpa'' tid0,+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text4'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_1_T_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_7_1_B_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_1_B"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_1_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_1_T &+ ( tid1, isoiec_9798_3_7_1_T_3 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''T'' tid1), s(MV ''Rb'' tid1),+ PK ( s(MV ''A'' tid1) ), s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''T'' tid0), LN ''Rb'' tid0,+ s(MV ''pkA'' tid0), s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_1_sig_3_2'', LN ''Rb'' tid0,+ s(AV ''A'' tid0), s(MV ''pkA'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_1_T_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_7_2_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_2_A"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_2_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_2_B &+ ( tid1, isoiec_9798_3_7_2_B_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''Ra'' tid1), LN ''Rb'' tid1,+ s(MV ''Text8'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''check_4'',+ {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! " LN ''check_nonce_4'' tid0 ")+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_7_2_A_check_3_out_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_2_T_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_5'', LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text8'' tid0)+ |}+ ( SK ( s(MV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_2_B_5_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_7_2_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_2_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_2_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_2_A &+ ( tid1, isoiec_9798_3_7_2_A_4 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text6'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra'' tid0),+ LN ''Rb'' tid0, s(MV ''Text6'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(AV ''A'' tid0), s(MV ''pkA'' tid0), s(AV ''B'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_2_T_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_4'', LN ''Rb'' tid0,+ s(MV ''Ra'' tid0), s(AV ''B'' tid0), s(AV ''A'' tid0),+ s(MV ''Text6'' tid0)+ |}+ ( SK ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_2_A_4_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_7_2_A_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_2_A"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_2_A_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_2_T &+ ( tid1, isoiec_9798_3_7_2_T_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''T'' tid1),+ s(MV ''Rpa'' tid1), s(MV ''Rb'' tid1), PK ( s(MV ''A'' tid1) ),+ PK ( s(MV ''B'' tid1) ), s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''T'' tid0),+ LN ''Rpa'' tid0, s(MV ''Rb'' tid0), s(MV ''pkA'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''check_4'',+ {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! " LN ''check_nonce_4'' tid0 ")+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_7_2_A_check_3_out_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_2_T_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_state) isoiec_9798_3_7_2_B_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_2_B"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_2_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_2_T &+ ( tid1, isoiec_9798_3_7_2_T_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''T'' tid1),+ s(MV ''Rpa'' tid1), s(MV ''Rb'' tid1), PK ( s(MV ''A'' tid1) ),+ PK ( s(MV ''B'' tid1) ), s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''T'' tid0),+ s(MV ''Rpa'' tid0), LN ''Rb'' tid0, s(MV ''pkA'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(AV ''A'' tid0), s(MV ''pkA'' tid0), s(AV ''B'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_2_T_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++end
@@ -0,0 +1,693 @@+theory "isoiec-9798-4-bdkey_cert_auto"+imports+ "../ESPLogic"+begin++role isoiec_9798_4_1_bdkey_A+where "isoiec_9798_4_1_bdkey_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''TNA'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_1_ccf_1'', sN ''TNA'', sAV ''B'', sMV ''Text1''+ |>+ |>+ ]"++role isoiec_9798_4_1_bdkey_B+where "isoiec_9798_4_1_bdkey_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''TNA'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', sKbd (MVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_1_ccf_1'', sMV ''TNA'', sAV ''B'', sMV ''Text1''+ |>+ |>+ ]"++role isoiec_9798_4_2_bdkey_A+where "isoiec_9798_4_2_bdkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'', sMV ''Rb'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (MVar ''B'') |>,+ sC ''isoiec_9798_4_2_ccf_2'', sMV ''Rb'', sMV ''B'', sMV ''Text2''+ |>+ |>+ ]"++role isoiec_9798_4_2_bdkey_B+where "isoiec_9798_4_2_bdkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'', sN ''Rb'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_2_ccf_2'', sN ''Rb'', sAV ''B'', sMV ''Text2''+ |>+ |>+ ]"++role isoiec_9798_4_3_bdkey_A+where "isoiec_9798_4_3_bdkey_A =+ [ Send ''leak_A'' ( sN ''TNa'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''TNa'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_3_ccf_1'', sN ''TNa'', sAV ''B'', sMV ''Text1''+ |>+ |>+ , Recv ''2'' <| sAV ''B'', sAV ''A'', sMV ''TNb'', sMV ''Text4'',+ sMV ''Text3'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_3_ccf_2'', sMV ''TNb'', sAV ''A'', sMV ''Text3''+ |>+ |>+ ]"++role isoiec_9798_4_3_bdkey_B+where "isoiec_9798_4_3_bdkey_B =+ [ Send ''leak_B'' ( sN ''TNb'' )+ , Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''TNa'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', sKbd (MVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_3_ccf_1'', sMV ''TNa'', sAV ''B'', sMV ''Text1''+ |>+ |>+ , Recv ''text_2'' <| sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''B'', sMV ''A'', sN ''TNb'', sMV ''Text4'',+ sMV ''Text3'',+ PHash <| <| sC ''CCF'', sKbd (MVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_3_ccf_2'', sN ''TNb'', sMV ''A'', sMV ''Text3''+ |>+ |>+ ]"++role isoiec_9798_4_4_bdkey_A+where "isoiec_9798_4_4_bdkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sN ''Ra'', sMV ''Text3'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (MVar ''B'') |>,+ sC ''isoiec_9798_4_4_ccf_2'', sN ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ |>+ , Recv ''3'' <| sMV ''B'', sAV ''A'', sMV ''Text5'', sMV ''Text4'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (MVar ''B'') |>,+ sC ''isoiec_9798_4_4_ccf_3'', sMV ''Rb'', sN ''Ra'', sMV ''Text4''+ |>+ |>+ ]"++role isoiec_9798_4_4_bdkey_B+where "isoiec_9798_4_4_bdkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Ra'', sMV ''Text3'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_4_ccf_2'', sMV ''Ra'', sN ''Rb'', sAV ''B'',+ sMV ''Text2''+ |>+ |>+ , Recv ''text_3'' <| sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''B'', sAV ''A'', sMV ''Text5'', sMV ''Text4'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_4_ccf_3'', sN ''Rb'', sMV ''Ra'', sMV ''Text4''+ |>+ |>+ ]"++protocol isoiec_9798_4_bdkey+where "isoiec_9798_4_bdkey =+{ isoiec_9798_4_1_bdkey_A, isoiec_9798_4_1_bdkey_B,+ isoiec_9798_4_2_bdkey_A, isoiec_9798_4_2_bdkey_B,+ isoiec_9798_4_3_bdkey_A, isoiec_9798_4_3_bdkey_B,+ isoiec_9798_4_4_bdkey_A, isoiec_9798_4_4_bdkey_B+}"++locale restricted_isoiec_9798_4_bdkey_state = isoiec_9798_4_bdkey_state++type_invariant isoiec_9798_4_bdkey_composed_typing for isoiec_9798_4_bdkey+where "isoiec_9798_4_bdkey_composed_typing = mk_typing+ [ ((isoiec_9798_4_1_bdkey_B, ''A''), (KnownT isoiec_9798_4_1_bdkey_B_1))+ , ((isoiec_9798_4_3_bdkey_B, ''A''), (KnownT isoiec_9798_4_3_bdkey_B_1))+ , ((isoiec_9798_4_2_bdkey_A, ''B''), (KnownT isoiec_9798_4_2_bdkey_A_1))+ , ((isoiec_9798_4_4_bdkey_A, ''B''), (KnownT isoiec_9798_4_4_bdkey_A_1))+ , ((isoiec_9798_4_4_bdkey_B, ''Ra''), (KnownT isoiec_9798_4_4_bdkey_B_2))+ , ((isoiec_9798_4_2_bdkey_A, ''Rb''), (KnownT isoiec_9798_4_2_bdkey_A_1))+ , ((isoiec_9798_4_4_bdkey_A, ''Rb''), (KnownT isoiec_9798_4_4_bdkey_A_1))+ , ((isoiec_9798_4_1_bdkey_B, ''TNA''),+ (KnownT isoiec_9798_4_1_bdkey_B_1))+ , ((isoiec_9798_4_3_bdkey_B, ''TNa''),+ (KnownT isoiec_9798_4_3_bdkey_B_1))+ , ((isoiec_9798_4_3_bdkey_A, ''TNb''),+ (KnownT isoiec_9798_4_3_bdkey_A_2))+ , ((isoiec_9798_4_1_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_4_1_bdkey_A_text_1))+ , ((isoiec_9798_4_1_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_4_1_bdkey_B_1))+ , ((isoiec_9798_4_2_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_4_2_bdkey_A_1))+ , ((isoiec_9798_4_2_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_4_2_bdkey_B_text_1))+ , ((isoiec_9798_4_3_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_4_3_bdkey_A_text_1))+ , ((isoiec_9798_4_3_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_4_3_bdkey_B_1))+ , ((isoiec_9798_4_4_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_4_4_bdkey_A_1))+ , ((isoiec_9798_4_4_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_4_4_bdkey_B_text_1))+ , ((isoiec_9798_4_1_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_4_1_bdkey_A_text_1))+ , ((isoiec_9798_4_1_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_4_1_bdkey_B_1))+ , ((isoiec_9798_4_2_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_4_2_bdkey_A_text_2))+ , ((isoiec_9798_4_2_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_4_2_bdkey_B_2))+ , ((isoiec_9798_4_3_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_4_3_bdkey_A_text_1))+ , ((isoiec_9798_4_3_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_4_3_bdkey_B_1))+ , ((isoiec_9798_4_4_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_4_4_bdkey_A_text_2))+ , ((isoiec_9798_4_4_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_4_4_bdkey_B_2))+ , ((isoiec_9798_4_2_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_4_2_bdkey_A_text_2))+ , ((isoiec_9798_4_2_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_4_2_bdkey_B_2))+ , ((isoiec_9798_4_3_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_4_3_bdkey_A_2))+ , ((isoiec_9798_4_3_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_4_3_bdkey_B_text_2))+ , ((isoiec_9798_4_4_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_4_4_bdkey_A_text_2))+ , ((isoiec_9798_4_4_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_4_4_bdkey_B_2))+ , ((isoiec_9798_4_3_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_4_3_bdkey_A_2))+ , ((isoiec_9798_4_3_bdkey_B, ''Text4''),+ (KnownT isoiec_9798_4_3_bdkey_B_text_2))+ , ((isoiec_9798_4_4_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_4_4_bdkey_A_3))+ , ((isoiec_9798_4_4_bdkey_B, ''Text4''),+ (KnownT isoiec_9798_4_4_bdkey_B_text_3))+ , ((isoiec_9798_4_4_bdkey_A, ''Text5''),+ (KnownT isoiec_9798_4_4_bdkey_A_3))+ , ((isoiec_9798_4_4_bdkey_B, ''Text5''),+ (KnownT isoiec_9798_4_4_bdkey_B_text_3))+ ]"++sublocale isoiec_9798_4_bdkey_state < isoiec_9798_4_bdkey_composed_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_4_bdkey_composed_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_4_bdkey_composed_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_4_1_bdkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_bdkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_bdkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_bdkey_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_bdkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_bdkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_A_2_TNb t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_B_1_TNa t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_B_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_B_2_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_B_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_B_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_bdkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_4_bdkey_composed_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_4_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_4_bdkey_state) isoiec_9798_4_1_bdkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_1_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_1_bdkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_1_bdkey_A &+ ( tid1, isoiec_9798_4_1_bdkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) |},+ LC ''isoiec_9798_4_1_ccf_1'', s(MV ''TNA'' tid0), s(AV ''B'' tid0),+ s(MV ''Text1'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_1_bdkey_A_1_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_bdkey_state) isoiec_9798_4_2_bdkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_2_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_2_bdkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_2_bdkey_A &+ ( tid1, isoiec_9798_4_2_bdkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(MV ''Rb'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''Rb'' tid0,+ s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_2_ccf_2'', LN ''Rb'' tid0, s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_2_bdkey_A_2_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_bdkey_state) isoiec_9798_4_3_bdkey_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_3_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_3_bdkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_3_bdkey_B &+ ( tid1, isoiec_9798_4_3_bdkey_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), LN ''TNb'' tid1,+ s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNb'' tid0),+ s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_3_ccf_2'', s(MV ''TNb'' tid0), s(AV ''A'' tid0),+ s(MV ''Text3'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_3_bdkey_B_2_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_bdkey_state) isoiec_9798_4_3_bdkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_3_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_3_bdkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_3_bdkey_A &+ ( tid1, isoiec_9798_4_3_bdkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNa'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNa'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) |},+ LC ''isoiec_9798_4_3_ccf_1'', s(MV ''TNa'' tid0), s(AV ''B'' tid0),+ s(MV ''Text1'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_3_bdkey_A_1_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_bdkey_state) isoiec_9798_4_4_bdkey_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_4_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_4_bdkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_4_bdkey_B &+ ( tid1, isoiec_9798_4_4_bdkey_B_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''Ra'' tid1), LN ''Rb'' tid1,+ s(MV ''Text2'' tid1), s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(MV ''Text2'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''A'' tid0) ) ( s(MV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_4_ccf_3'', s(MV ''Rb'' tid0), LN ''Ra'' tid0,+ s(MV ''Text4'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_bdkey_B_3_hash tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''A'' tid1) )+ ( s(AV ''B'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(MV ''B'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid1) ) |},+ LC ''isoiec_9798_4_4_ccf_2'', LN ''Ra'' tid0, LN ''Rb'' tid1,+ s(AV ''B'' tid1), s(MV ''Text2'' tid1)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_bdkey_A_2_hash tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''A'' tid0) ) ( s(AV ''A'' tid1) ) |},+ LC ''isoiec_9798_4_4_ccf_2'', LN ''Ra'' tid0, LN ''Rb'' tid1,+ s(AV ''A'' tid0), s(MV ''Text2'' tid1)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_bdkey_A_2_hash tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_bdkey_state) isoiec_9798_4_4_bdkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_4_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_4_bdkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_4_bdkey_A &+ ( tid1, isoiec_9798_4_4_bdkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra'' tid0),+ LN ''Rb'' tid0, s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_4_ccf_2'', s(MV ''Ra'' tid0), LN ''Rb'' tid0,+ s(AV ''B'' tid0), s(MV ''Text2'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_bdkey_A_2_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++end
@@ -0,0 +1,668 @@+theory "isoiec-9798-4-udkey_cert_auto"+imports+ "../ESPLogic"+begin++role isoiec_9798_4_1_udkey_A+where "isoiec_9798_4_1_udkey_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''TNA'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', sK ''A'' ''B'' |>, sC ''isoiec_9798_4_1_ccf_1'',+ sN ''TNA'', sMV ''Text1''+ |>+ |>+ ]"++role isoiec_9798_4_1_udkey_B+where "isoiec_9798_4_1_udkey_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''TNA'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', PSymK ( sMV ''A'' ) ( sAV ''B'' ) |>,+ sC ''isoiec_9798_4_1_ccf_1'', sMV ''TNA'', sMV ''Text1''+ |>+ |>+ ]"++role isoiec_9798_4_2_udkey_A+where "isoiec_9798_4_2_udkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'', sMV ''Rb'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', PSymK ( sAV ''A'' ) ( sMV ''B'' ) |>,+ sC ''isoiec_9798_4_2_ccf_2'', sMV ''Rb'', sMV ''Text2''+ |>+ |>+ ]"++role isoiec_9798_4_2_udkey_B+where "isoiec_9798_4_2_udkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'', sN ''Rb'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', sK ''A'' ''B'' |>, sC ''isoiec_9798_4_2_ccf_2'',+ sN ''Rb'', sMV ''Text2''+ |>+ |>+ ]"++role isoiec_9798_4_3_udkey_A+where "isoiec_9798_4_3_udkey_A =+ [ Send ''leak_A'' ( sN ''TNa'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''TNa'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', sK ''A'' ''B'' |>, sC ''isoiec_9798_4_3_ccf_1'',+ sN ''TNa'', sMV ''Text1''+ |>+ |>+ , Recv ''2'' <| sAV ''B'', sAV ''A'', sMV ''TNb'', sMV ''Text4'',+ sMV ''Text3'',+ PHash <| <| sC ''CCF'', sK ''A'' ''B'' |>, sC ''isoiec_9798_4_3_ccf_2'',+ sMV ''TNb'', sMV ''Text3''+ |>+ |>+ ]"++role isoiec_9798_4_3_udkey_B+where "isoiec_9798_4_3_udkey_B =+ [ Send ''leak_B'' ( sN ''TNb'' )+ , Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''TNa'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', PSymK ( sMV ''A'' ) ( sAV ''B'' ) |>,+ sC ''isoiec_9798_4_3_ccf_1'', sMV ''TNa'', sMV ''Text1''+ |>+ |>+ , Recv ''text_2'' <| sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''B'', sMV ''A'', sN ''TNb'', sMV ''Text4'',+ sMV ''Text3'',+ PHash <| <| sC ''CCF'', PSymK ( sMV ''A'' ) ( sAV ''B'' ) |>,+ sC ''isoiec_9798_4_3_ccf_2'', sN ''TNb'', sMV ''Text3''+ |>+ |>+ ]"++role isoiec_9798_4_4_udkey_A+where "isoiec_9798_4_4_udkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sN ''Ra'', sMV ''Text3'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', PSymK ( sAV ''A'' ) ( sMV ''B'' ) |>,+ sC ''isoiec_9798_4_4_ccf_2'', sN ''Ra'', sMV ''Rb'', sMV ''Text2''+ |>+ |>+ , Recv ''3'' <| sMV ''B'', sAV ''A'', sMV ''Text5'', sMV ''Text4'',+ PHash <| <| sC ''CCF'', PSymK ( sAV ''A'' ) ( sMV ''B'' ) |>,+ sC ''isoiec_9798_4_4_ccf_3'', sMV ''Rb'', sN ''Ra'', sMV ''Text4''+ |>+ |>+ ]"++role isoiec_9798_4_4_udkey_B+where "isoiec_9798_4_4_udkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Ra'', sMV ''Text3'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', sK ''A'' ''B'' |>, sC ''isoiec_9798_4_4_ccf_2'',+ sMV ''Ra'', sN ''Rb'', sMV ''Text2''+ |>+ |>+ , Recv ''text_3'' <| sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''B'', sAV ''A'', sMV ''Text5'', sMV ''Text4'',+ PHash <| <| sC ''CCF'', sK ''A'' ''B'' |>, sC ''isoiec_9798_4_4_ccf_3'',+ sN ''Rb'', sMV ''Ra'', sMV ''Text4''+ |>+ |>+ ]"++protocol isoiec_9798_4_udkey+where "isoiec_9798_4_udkey =+{ isoiec_9798_4_1_udkey_A, isoiec_9798_4_1_udkey_B,+ isoiec_9798_4_2_udkey_A, isoiec_9798_4_2_udkey_B,+ isoiec_9798_4_3_udkey_A, isoiec_9798_4_3_udkey_B,+ isoiec_9798_4_4_udkey_A, isoiec_9798_4_4_udkey_B+}"++locale restricted_isoiec_9798_4_udkey_state = isoiec_9798_4_udkey_state++type_invariant isoiec_9798_4_udkey_composed_typing for isoiec_9798_4_udkey+where "isoiec_9798_4_udkey_composed_typing = mk_typing+ [ ((isoiec_9798_4_1_udkey_B, ''A''), (KnownT isoiec_9798_4_1_udkey_B_1))+ , ((isoiec_9798_4_3_udkey_B, ''A''), (KnownT isoiec_9798_4_3_udkey_B_1))+ , ((isoiec_9798_4_2_udkey_A, ''B''), (KnownT isoiec_9798_4_2_udkey_A_1))+ , ((isoiec_9798_4_4_udkey_A, ''B''), (KnownT isoiec_9798_4_4_udkey_A_1))+ , ((isoiec_9798_4_4_udkey_B, ''Ra''), (KnownT isoiec_9798_4_4_udkey_B_2))+ , ((isoiec_9798_4_2_udkey_A, ''Rb''), (KnownT isoiec_9798_4_2_udkey_A_1))+ , ((isoiec_9798_4_4_udkey_A, ''Rb''), (KnownT isoiec_9798_4_4_udkey_A_1))+ , ((isoiec_9798_4_1_udkey_B, ''TNA''),+ (KnownT isoiec_9798_4_1_udkey_B_1))+ , ((isoiec_9798_4_3_udkey_B, ''TNa''),+ (KnownT isoiec_9798_4_3_udkey_B_1))+ , ((isoiec_9798_4_3_udkey_A, ''TNb''),+ (KnownT isoiec_9798_4_3_udkey_A_2))+ , ((isoiec_9798_4_1_udkey_A, ''Text1''),+ (KnownT isoiec_9798_4_1_udkey_A_text_1))+ , ((isoiec_9798_4_1_udkey_B, ''Text1''),+ (KnownT isoiec_9798_4_1_udkey_B_1))+ , ((isoiec_9798_4_2_udkey_A, ''Text1''),+ (KnownT isoiec_9798_4_2_udkey_A_1))+ , ((isoiec_9798_4_2_udkey_B, ''Text1''),+ (KnownT isoiec_9798_4_2_udkey_B_text_1))+ , ((isoiec_9798_4_3_udkey_A, ''Text1''),+ (KnownT isoiec_9798_4_3_udkey_A_text_1))+ , ((isoiec_9798_4_3_udkey_B, ''Text1''),+ (KnownT isoiec_9798_4_3_udkey_B_1))+ , ((isoiec_9798_4_4_udkey_A, ''Text1''),+ (KnownT isoiec_9798_4_4_udkey_A_1))+ , ((isoiec_9798_4_4_udkey_B, ''Text1''),+ (KnownT isoiec_9798_4_4_udkey_B_text_1))+ , ((isoiec_9798_4_1_udkey_A, ''Text2''),+ (KnownT isoiec_9798_4_1_udkey_A_text_1))+ , ((isoiec_9798_4_1_udkey_B, ''Text2''),+ (KnownT isoiec_9798_4_1_udkey_B_1))+ , ((isoiec_9798_4_2_udkey_A, ''Text2''),+ (KnownT isoiec_9798_4_2_udkey_A_text_2))+ , ((isoiec_9798_4_2_udkey_B, ''Text2''),+ (KnownT isoiec_9798_4_2_udkey_B_2))+ , ((isoiec_9798_4_3_udkey_A, ''Text2''),+ (KnownT isoiec_9798_4_3_udkey_A_text_1))+ , ((isoiec_9798_4_3_udkey_B, ''Text2''),+ (KnownT isoiec_9798_4_3_udkey_B_1))+ , ((isoiec_9798_4_4_udkey_A, ''Text2''),+ (KnownT isoiec_9798_4_4_udkey_A_text_2))+ , ((isoiec_9798_4_4_udkey_B, ''Text2''),+ (KnownT isoiec_9798_4_4_udkey_B_2))+ , ((isoiec_9798_4_2_udkey_A, ''Text3''),+ (KnownT isoiec_9798_4_2_udkey_A_text_2))+ , ((isoiec_9798_4_2_udkey_B, ''Text3''),+ (KnownT isoiec_9798_4_2_udkey_B_2))+ , ((isoiec_9798_4_3_udkey_A, ''Text3''),+ (KnownT isoiec_9798_4_3_udkey_A_2))+ , ((isoiec_9798_4_3_udkey_B, ''Text3''),+ (KnownT isoiec_9798_4_3_udkey_B_text_2))+ , ((isoiec_9798_4_4_udkey_A, ''Text3''),+ (KnownT isoiec_9798_4_4_udkey_A_text_2))+ , ((isoiec_9798_4_4_udkey_B, ''Text3''),+ (KnownT isoiec_9798_4_4_udkey_B_2))+ , ((isoiec_9798_4_3_udkey_A, ''Text4''),+ (KnownT isoiec_9798_4_3_udkey_A_2))+ , ((isoiec_9798_4_3_udkey_B, ''Text4''),+ (KnownT isoiec_9798_4_3_udkey_B_text_2))+ , ((isoiec_9798_4_4_udkey_A, ''Text4''),+ (KnownT isoiec_9798_4_4_udkey_A_3))+ , ((isoiec_9798_4_4_udkey_B, ''Text4''),+ (KnownT isoiec_9798_4_4_udkey_B_text_3))+ , ((isoiec_9798_4_4_udkey_A, ''Text5''),+ (KnownT isoiec_9798_4_4_udkey_A_3))+ , ((isoiec_9798_4_4_udkey_B, ''Text5''),+ (KnownT isoiec_9798_4_4_udkey_B_text_3))+ ]"++sublocale isoiec_9798_4_udkey_state < isoiec_9798_4_udkey_composed_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_4_udkey_composed_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_4_udkey_composed_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_4_1_udkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_udkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_udkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_udkey_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_udkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_udkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_A_2_TNb t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_B_1_TNa t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_B_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_B_2_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_B_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_B_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_udkey_composed_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_4_udkey_composed_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_4_udkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_4_udkey_state) isoiec_9798_4_1_udkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_1_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_1_udkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_1_udkey_A &+ ( tid1, isoiec_9798_4_1_udkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_1_ccf_1'', s(MV ''TNA'' tid0), s(MV ''Text1'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_1_udkey_A_1_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_udkey_state) isoiec_9798_4_2_udkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_2_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_2_udkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_2_udkey_A &+ ( tid1, isoiec_9798_4_2_udkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(MV ''Rb'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''Rb'' tid0,+ s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_2_ccf_2'', LN ''Rb'' tid0, s(MV ''Text2'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_2_udkey_A_2_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_udkey_state) isoiec_9798_4_3_udkey_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_3_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_3_udkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_3_udkey_B &+ ( tid1, isoiec_9798_4_3_udkey_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), LN ''TNb'' tid1,+ s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNb'' tid0),+ s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_3_ccf_2'', s(MV ''TNb'' tid0), s(MV ''Text3'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_3_udkey_B_2_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_udkey_state) isoiec_9798_4_3_udkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_3_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_3_udkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_3_udkey_A &+ ( tid1, isoiec_9798_4_3_udkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNa'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNa'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_3_ccf_1'', s(MV ''TNa'' tid0), s(MV ''Text1'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_3_udkey_A_1_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_udkey_state) isoiec_9798_4_4_udkey_A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_4_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_4_udkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_4_udkey_B &+ ( tid1, isoiec_9798_4_4_udkey_B_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''Ra'' tid1), LN ''Rb'' tid1,+ s(MV ''Text2'' tid1), s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(MV ''Text2'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(AV ''A'' tid0) ) ( s(MV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_4_ccf_3'', s(MV ''Rb'' tid0), LN ''Ra'' tid0,+ s(MV ''Text4'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_udkey_B_3_hash tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid1) ) |},+ LC ''isoiec_9798_4_4_ccf_2'', LN ''Ra'' tid0, LN ''Rb'' tid1,+ s(MV ''Text2'' tid1)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_udkey_A_2_hash tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_udkey_state) isoiec_9798_4_4_udkey_B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_4_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_4_udkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_4_udkey_A &+ ( tid1, isoiec_9798_4_4_udkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra'' tid0),+ LN ''Rb'' tid0, s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_4_ccf_2'', s(MV ''Ra'' tid0), LN ''Rb'' tid0,+ s(MV ''Text2'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_udkey_A_2_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++end
@@ -0,0 +1,3702 @@+theory "isoiec-9798-2-bdkey_cert_auto"+imports+ "../ESPLogic"+begin++role isoiec_9798_2_1_bdkey_A+where "isoiec_9798_2_1_bdkey_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_1_enc_1'', sN ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( sKbd (AVar ''A'') (AVar ''B'') )+ |>+ ]"++role isoiec_9798_2_1_bdkey_B+where "isoiec_9798_2_1_bdkey_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_1_enc_1'', sMV ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( sKbd (MVar ''A'') (AVar ''B'') )+ |>+ ]"++protocol isoiec_9798_2_1_bdkey+where "isoiec_9798_2_1_bdkey =+{ isoiec_9798_2_1_bdkey_A, isoiec_9798_2_1_bdkey_B }"++locale restricted_isoiec_9798_2_1_bdkey_state = isoiec_9798_2_1_bdkey_state++type_invariant isoiec_9798_2_1_bdkey_msc_typing for isoiec_9798_2_1_bdkey+where "isoiec_9798_2_1_bdkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_1_bdkey_B, ''A''), (KnownT isoiec_9798_2_1_bdkey_B_1))+ , ((isoiec_9798_2_1_bdkey_B, ''TNA''),+ (SumT (KnownT isoiec_9798_2_1_bdkey_B_1) (NonceT isoiec_9798_2_1_bdkey_A ''TNA'')))+ , ((isoiec_9798_2_1_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_1_bdkey_A_text_1))+ , ((isoiec_9798_2_1_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_2_1_bdkey_B_1))+ , ((isoiec_9798_2_1_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_2_1_bdkey_A_text_1))+ , ((isoiec_9798_2_1_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_2_1_bdkey_B_1))+ ]"++sublocale isoiec_9798_2_1_bdkey_state < isoiec_9798_2_1_bdkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_1_bdkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_1_bdkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_1_bdkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_1_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_1_bdkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_1_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_1_bdkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_1_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_1_bdkey_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_1_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_1_enc_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_1_bdkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_1_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_1_enc_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_1_bdkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_1_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_1_bdkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_1_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_1_bdkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_1_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_1_bdkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_1_bdkey_A &+ ( tid1, isoiec_9798_2_1_bdkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_1_enc_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_1_bdkey_A_1_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_2_2_bdkey_A+where "isoiec_9798_2_2_bdkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''RB'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_2_enc_2'', sMV ''RB'', sMV ''B'',+ sMV ''Text2''+ |>+ ( sKbd (MVar ''B'') (AVar ''A'') )+ |>+ ]"++role isoiec_9798_2_2_bdkey_B+where "isoiec_9798_2_2_bdkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''RB'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_2_enc_2'', sN ''RB'', sAV ''B'', sMV ''Text2''+ |>+ ( sKbd (AVar ''B'') (AVar ''A'') )+ |>+ ]"++protocol isoiec_9798_2_2_bdkey+where "isoiec_9798_2_2_bdkey =+{ isoiec_9798_2_2_bdkey_A, isoiec_9798_2_2_bdkey_B }"++locale restricted_isoiec_9798_2_2_bdkey_state = isoiec_9798_2_2_bdkey_state++type_invariant isoiec_9798_2_2_bdkey_msc_typing for isoiec_9798_2_2_bdkey+where "isoiec_9798_2_2_bdkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_2_bdkey_A, ''B''), (KnownT isoiec_9798_2_2_bdkey_A_1))+ , ((isoiec_9798_2_2_bdkey_A, ''RB''), (KnownT isoiec_9798_2_2_bdkey_A_1))+ , ((isoiec_9798_2_2_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_2_bdkey_A_1))+ , ((isoiec_9798_2_2_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_2_2_bdkey_B_text_1))+ , ((isoiec_9798_2_2_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_2_2_bdkey_A_text_2))+ , ((isoiec_9798_2_2_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_2_2_bdkey_B_2))+ , ((isoiec_9798_2_2_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_2_2_bdkey_A_text_2))+ , ((isoiec_9798_2_2_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_2_2_bdkey_B_2))+ ]"++sublocale isoiec_9798_2_2_bdkey_state < isoiec_9798_2_2_bdkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_2_bdkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_2_bdkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_2_bdkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_bdkey_A_1_RB t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_bdkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_bdkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_bdkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_bdkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_2_enc_2'', LN ''RB'' tid0, s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_2_bdkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_2_bdkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_2_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_2_bdkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_2_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_2_bdkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_2_bdkey_A &+ ( tid1, isoiec_9798_2_2_bdkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(MV ''RB'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''RB'' tid0,+ s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_2_enc_2'', LN ''RB'' tid0, s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_2_bdkey_A_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_2_3_bdkey_A+where "isoiec_9798_2_3_bdkey_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_3_enc_1'', sN ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( sKbd (AVar ''A'') (AVar ''B'') )+ |>+ , Recv ''2'' <| sAV ''B'', sAV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_3_enc_2'', sMV ''TNB'', sAV ''A'',+ sMV ''Text3''+ |>+ ( sKbd (AVar ''B'') (AVar ''A'') )+ |>+ ]"++role isoiec_9798_2_3_bdkey_B+where "isoiec_9798_2_3_bdkey_B =+ [ Send ''leak_B'' ( sN ''TNB'' )+ , Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_3_enc_1'', sMV ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( sKbd (MVar ''A'') (AVar ''B'') )+ |>+ , Recv ''text_2'' <| sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''B'', sMV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_3_enc_2'', sN ''TNB'', sMV ''A'',+ sMV ''Text3''+ |>+ ( sKbd (AVar ''B'') (MVar ''A'') )+ |>+ ]"++protocol isoiec_9798_2_3_bdkey+where "isoiec_9798_2_3_bdkey =+{ isoiec_9798_2_3_bdkey_A, isoiec_9798_2_3_bdkey_B }"++locale restricted_isoiec_9798_2_3_bdkey_state = isoiec_9798_2_3_bdkey_state++type_invariant isoiec_9798_2_3_bdkey_msc_typing for isoiec_9798_2_3_bdkey+where "isoiec_9798_2_3_bdkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_3_bdkey_B, ''A''), (KnownT isoiec_9798_2_3_bdkey_B_1))+ , ((isoiec_9798_2_3_bdkey_B, ''TNA''),+ (SumT (KnownT isoiec_9798_2_3_bdkey_B_1) (NonceT isoiec_9798_2_3_bdkey_A ''TNA'')))+ , ((isoiec_9798_2_3_bdkey_A, ''TNB''),+ (SumT (KnownT isoiec_9798_2_3_bdkey_A_2) (NonceT isoiec_9798_2_3_bdkey_B ''TNB'')))+ , ((isoiec_9798_2_3_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_3_bdkey_A_text_1))+ , ((isoiec_9798_2_3_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_2_3_bdkey_B_1))+ , ((isoiec_9798_2_3_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_2_3_bdkey_A_text_1))+ , ((isoiec_9798_2_3_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_2_3_bdkey_B_1))+ , ((isoiec_9798_2_3_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_2_3_bdkey_A_2))+ , ((isoiec_9798_2_3_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_2_3_bdkey_B_text_2))+ , ((isoiec_9798_2_3_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_2_3_bdkey_A_2))+ , ((isoiec_9798_2_3_bdkey_B, ''Text4''),+ (KnownT isoiec_9798_2_3_bdkey_B_text_2))+ ]"++sublocale isoiec_9798_2_3_bdkey_state < isoiec_9798_2_3_bdkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_3_bdkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_3_bdkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_3_bdkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_A_2_TNB t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_2'', s(MV ''TNB'' tid0),+ s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_bdkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_2'', s(MV ''TNB'' tid0),+ s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_bdkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_bdkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_bdkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_bdkey_B_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_3_bdkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_3_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_3_bdkey_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_3_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_3_bdkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_3_bdkey_B &+ ( tid1, isoiec_9798_2_3_bdkey_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), LN ''TNB'' tid1,+ s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNB'' tid0),+ s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_2'', s(MV ''TNB'' tid0),+ s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_3_bdkey_B_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_3_bdkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_3_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_3_bdkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_3_bdkey_A &+ ( tid1, isoiec_9798_2_3_bdkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_3_bdkey_A_1_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_2_4_bdkey_A+where "isoiec_9798_2_4_bdkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''RB'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_4_enc_1'', sN ''RA'', sMV ''RB'', sMV ''B'',+ sMV ''Text2''+ |>+ ( sKbd (AVar ''A'') (MVar ''B'') )+ |>+ , Recv ''3'' <| sMV ''B'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_4_enc_2'', sMV ''RB'', sN ''RA'',+ sMV ''Text4''+ |>+ ( sKbd (AVar ''A'') (MVar ''B'') )+ |>+ ]"++role isoiec_9798_2_4_bdkey_B+where "isoiec_9798_2_4_bdkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''RB'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_4_enc_1'', sMV ''RA'', sN ''RB'', sAV ''B'',+ sMV ''Text2''+ |>+ ( sKbd (AVar ''A'') (AVar ''B'') )+ |>+ , Recv ''text_3'' <| sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''B'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_4_enc_2'', sN ''RB'', sMV ''RA'',+ sMV ''Text4''+ |>+ ( sKbd (AVar ''A'') (AVar ''B'') )+ |>+ ]"++protocol isoiec_9798_2_4_bdkey+where "isoiec_9798_2_4_bdkey =+{ isoiec_9798_2_4_bdkey_A, isoiec_9798_2_4_bdkey_B }"++locale restricted_isoiec_9798_2_4_bdkey_state = isoiec_9798_2_4_bdkey_state++type_invariant isoiec_9798_2_4_bdkey_msc_typing for isoiec_9798_2_4_bdkey+where "isoiec_9798_2_4_bdkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_4_bdkey_A, ''B''), (KnownT isoiec_9798_2_4_bdkey_A_1))+ , ((isoiec_9798_2_4_bdkey_B, ''RA''),+ (SumT (KnownT isoiec_9798_2_4_bdkey_B_2) (NonceT isoiec_9798_2_4_bdkey_A ''RA'')))+ , ((isoiec_9798_2_4_bdkey_A, ''RB''), (KnownT isoiec_9798_2_4_bdkey_A_1))+ , ((isoiec_9798_2_4_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_4_bdkey_A_1))+ , ((isoiec_9798_2_4_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_2_4_bdkey_B_text_1))+ , ((isoiec_9798_2_4_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_2_4_bdkey_A_text_2))+ , ((isoiec_9798_2_4_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_2_4_bdkey_B_2))+ , ((isoiec_9798_2_4_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_2_4_bdkey_A_text_2))+ , ((isoiec_9798_2_4_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_2_4_bdkey_B_2))+ , ((isoiec_9798_2_4_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_2_4_bdkey_A_3))+ , ((isoiec_9798_2_4_bdkey_B, ''Text4''),+ (KnownT isoiec_9798_2_4_bdkey_B_text_3))+ , ((isoiec_9798_2_4_bdkey_A, ''Text5''),+ (KnownT isoiec_9798_2_4_bdkey_A_3))+ , ((isoiec_9798_2_4_bdkey_B, ''Text5''),+ (KnownT isoiec_9798_2_4_bdkey_B_text_3))+ ]"++sublocale isoiec_9798_2_4_bdkey_state < isoiec_9798_2_4_bdkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_4_bdkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_4_bdkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_4_bdkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_A_1_RB t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_2'', s(MV ''RB'' tid0), LN ''RA'' tid0,+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(MV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_4_bdkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_B_2_RA t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(AV ''B'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_4_bdkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(AV ''B'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_4_bdkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_B_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_bdkey_B_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_4_bdkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_4_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_4_bdkey_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_4_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_4_bdkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_4_bdkey_B &+ ( tid1, isoiec_9798_2_4_bdkey_B_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''RA'' tid1), LN ''RB'' tid1,+ s(MV ''Text2'' tid1), s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''RA'' tid0,+ s(MV ''RB'' tid0), s(MV ''Text2'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_2'', s(MV ''RB'' tid0), LN ''RA'' tid0,+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(MV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_bdkey_B_3_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''A'' tid1) )+ ( s(AV ''B'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(MV ''B'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', LN ''RA'' tid0, LN ''RB'' tid1,+ s(AV ''B'' tid1), s(MV ''Text2'' tid1)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid1) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_bdkey_A_2_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', LN ''RA'' tid0, LN ''RB'' tid1,+ s(AV ''A'' tid0), s(MV ''Text2'' tid1)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''A'' tid1) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_bdkey_A_2_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_4_bdkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_4_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_4_bdkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_4_bdkey_A &+ ( tid1, isoiec_9798_2_4_bdkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''RA'' tid1, s(MV ''RB'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''RA'' tid0),+ LN ''RB'' tid0, s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(AV ''B'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_bdkey_A_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_2_5_bdkey_A+where "isoiec_9798_2_5_bdkey_A =+ [ Send ''leak_A'' <| sN ''TVPa'', sN ''TNa'' |>+ , Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''A'', sAV ''P'', sN ''TVPa'', sAV ''B'',+ sMV ''Text1''+ |>+ , Recv ''2'' <| sAV ''P'', sAV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_5_enc_2_1'', sN ''TVPa'', sMV ''Kab'',+ sAV ''A'', sAV ''B'', sMV ''Text3''+ |>+ ( sKbd (AVar ''A'') (AVar ''P'') ),+ sMV ''TokenPA_for_B''+ |>+ , Recv ''text_3'' <| sMV ''Text5'', sMV ''Text6'' |>+ , Send ''3'' <| sAV ''A'', sAV ''B'', sMV ''Text6'', sAV ''P'',+ sMV ''TokenPA_for_B'',+ PEnc <| sC ''isoiec_9798_2_5_enc_3'', sN ''TNa'', sAV ''B'',+ sMV ''Text5''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''4'' <| sAV ''B'', sAV ''A'', sMV ''Text8'',+ PEnc <| sC ''isoiec_9798_2_5_enc_4'', sMV ''TNb'', sAV ''A'',+ sMV ''Text7''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_5_bdkey_B+where "isoiec_9798_2_5_bdkey_B =+ [ Send ''leak_B'' ( sN ''TNb'' )+ , Recv ''3'' <| sMV ''A'', sAV ''B'', sMV ''Text6'', sMV ''P'',+ PEnc <| sC ''isoiec_9798_2_5_enc_2_2'', sMV ''TNp'', sMV ''Kab'',+ sMV ''A'', sAV ''B'', sMV ''Text2''+ |>+ ( sKbd (AVar ''B'') (MVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_5_enc_3'', sMV ''TNa'', sAV ''B'',+ sMV ''Text5''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''text_4'' <| sMV ''Text7'', sMV ''Text8'' |>+ , Send ''4'' <| sAV ''B'', sMV ''A'', sMV ''Text8'',+ PEnc <| sC ''isoiec_9798_2_5_enc_4'', sN ''TNb'', sMV ''A'',+ sMV ''Text7''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_5_bdkey_P+where "isoiec_9798_2_5_bdkey_P =+ [ Send ''leak_P'' ( sN ''TNp'' )+ , Recv ''1'' <| sMV ''A'', sAV ''P'', sMV ''TVPa'', sMV ''B'',+ sMV ''Text1''+ |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''P'', sMV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_5_enc_2_1'', sMV ''TVPa'', sN ''Kab'',+ sMV ''A'', sMV ''B'', sMV ''Text3''+ |>+ ( sKbd (MVar ''A'') (AVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_5_enc_2_2'', sN ''TNp'', sN ''Kab'',+ sMV ''A'', sMV ''B'', sMV ''Text2''+ |>+ ( sKbd (MVar ''B'') (AVar ''P'') )+ |>+ ]"++protocol isoiec_9798_2_5_bdkey+where "isoiec_9798_2_5_bdkey =+{ isoiec_9798_2_5_bdkey_A, isoiec_9798_2_5_bdkey_B,+ isoiec_9798_2_5_bdkey_P+}"++locale restricted_isoiec_9798_2_5_bdkey_state = isoiec_9798_2_5_bdkey_state++type_invariant isoiec_9798_2_5_bdkey_msc_typing for isoiec_9798_2_5_bdkey+where "isoiec_9798_2_5_bdkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_5_bdkey_B, ''A''), (KnownT isoiec_9798_2_5_bdkey_B_3))+ , ((isoiec_9798_2_5_bdkey_P, ''A''), (KnownT isoiec_9798_2_5_bdkey_P_1))+ , ((isoiec_9798_2_5_bdkey_P, ''B''), (KnownT isoiec_9798_2_5_bdkey_P_1))+ , ((isoiec_9798_2_5_bdkey_A, ''Kab''),+ (SumT (KnownT isoiec_9798_2_5_bdkey_A_2) (NonceT isoiec_9798_2_5_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_5_bdkey_B, ''Kab''),+ (SumT (KnownT isoiec_9798_2_5_bdkey_B_3) (NonceT isoiec_9798_2_5_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_5_bdkey_B, ''P''), (KnownT isoiec_9798_2_5_bdkey_B_3))+ , ((isoiec_9798_2_5_bdkey_B, ''TNa''),+ (SumT (KnownT isoiec_9798_2_5_bdkey_B_3) (NonceT isoiec_9798_2_5_bdkey_A ''TNa'')))+ , ((isoiec_9798_2_5_bdkey_A, ''TNb''),+ (SumT (KnownT isoiec_9798_2_5_bdkey_A_4) (NonceT isoiec_9798_2_5_bdkey_B ''TNb'')))+ , ((isoiec_9798_2_5_bdkey_B, ''TNp''),+ (SumT (KnownT isoiec_9798_2_5_bdkey_B_3) (NonceT isoiec_9798_2_5_bdkey_P ''TNp'')))+ , ((isoiec_9798_2_5_bdkey_P, ''TVPa''),+ (KnownT isoiec_9798_2_5_bdkey_P_1))+ , ((isoiec_9798_2_5_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_5_bdkey_A_text_1))+ , ((isoiec_9798_2_5_bdkey_P, ''Text1''),+ (KnownT isoiec_9798_2_5_bdkey_P_1))+ , ((isoiec_9798_2_5_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_2_5_bdkey_B_3))+ , ((isoiec_9798_2_5_bdkey_P, ''Text2''),+ (KnownT isoiec_9798_2_5_bdkey_P_text_2))+ , ((isoiec_9798_2_5_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_2_5_bdkey_A_2))+ , ((isoiec_9798_2_5_bdkey_P, ''Text3''),+ (KnownT isoiec_9798_2_5_bdkey_P_text_2))+ , ((isoiec_9798_2_5_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_2_5_bdkey_A_2))+ , ((isoiec_9798_2_5_bdkey_P, ''Text4''),+ (KnownT isoiec_9798_2_5_bdkey_P_text_2))+ , ((isoiec_9798_2_5_bdkey_A, ''Text5''),+ (KnownT isoiec_9798_2_5_bdkey_A_text_3))+ , ((isoiec_9798_2_5_bdkey_B, ''Text5''),+ (KnownT isoiec_9798_2_5_bdkey_B_3))+ , ((isoiec_9798_2_5_bdkey_A, ''Text6''),+ (KnownT isoiec_9798_2_5_bdkey_A_text_3))+ , ((isoiec_9798_2_5_bdkey_B, ''Text6''),+ (KnownT isoiec_9798_2_5_bdkey_B_3))+ , ((isoiec_9798_2_5_bdkey_A, ''Text7''),+ (KnownT isoiec_9798_2_5_bdkey_A_4))+ , ((isoiec_9798_2_5_bdkey_B, ''Text7''),+ (KnownT isoiec_9798_2_5_bdkey_B_text_4))+ , ((isoiec_9798_2_5_bdkey_A, ''Text8''),+ (KnownT isoiec_9798_2_5_bdkey_A_4))+ , ((isoiec_9798_2_5_bdkey_B, ''Text8''),+ (KnownT isoiec_9798_2_5_bdkey_B_text_4))+ , ((isoiec_9798_2_5_bdkey_A, ''TokenPA_for_B''),+ (KnownT isoiec_9798_2_5_bdkey_A_2))+ ]"++sublocale isoiec_9798_2_5_bdkey_state < isoiec_9798_2_5_bdkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_5_bdkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_5_bdkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_5_bdkey_A_2_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_A_2_TokenPA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_A_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_A_text_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_A_4_TNb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_A_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_A_4_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_B_3_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_B_3_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_B_3_P t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_B_3_TNa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_B_3_TNp t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_B_3_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_B_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_bdkey_B_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_B_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_B_text_4_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_1_TVPa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_bdkey_P_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_5_bdkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_5_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_5_bdkey_state) P_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_P"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "LN ''Kab'' tid0 : knows t"+ shows "False"+using facts proof(sources! " LN ''Kab'' tid0 ")+ case isoiec_9798_2_5_bdkey_P_2_Kab note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case isoiec_9798_2_5_bdkey_P_2_Kab_1 note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+qed (insert facts, fastsimp+)?++lemma (in restricted_isoiec_9798_2_5_bdkey_state) A_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_bdkey_A_2 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_bdkey_state) B_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_bdkey_B_3 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_bdkey_state) A_non_injective_agreement_B:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_bdkey_A_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_bdkey_B &+ ( tid1, isoiec_9798_2_5_bdkey_B_4 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), s(MV ''P'' tid1),+ s(MV ''Kab'' tid1), s(MV ''TNa'' tid1), s(MV ''Text5'' tid1),+ LN ''TNb'' tid1, s(MV ''Text7'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''TNa'' tid0, s(MV ''Text5'' tid0),+ s(MV ''TNb'' tid0), s(MV ''Text7'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_bdkey_B_4_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid2),+ LN ''Kab'' tid1, s(AV ''A'' tid0), s(AV ''B'' tid2), s(MV ''Text2'' tid2)+ |}+ ( Kbd ( s(AV ''B'' tid2) ) ( s(MV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc_1 tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid2),+ s(AV ''B'' tid0), s(MV ''Text5'' tid2)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_bdkey_A_3_enc tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid3, LN ''Kab'' tid1,+ s(AV ''A'' tid3), s(AV ''B'' tid0), s(MV ''Text3'' tid3)+ |}+ ( Kbd ( s(AV ''A'' tid3) ) ( s(AV ''P'' tid3) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc tid4) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_bdkey_state) B_non_injective_agreement_A:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_bdkey_B_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_bdkey_A &+ ( tid1, isoiec_9798_2_5_bdkey_A_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Kab'' tid1), LN ''TNa'' tid1, s(MV ''Text5'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''TNa'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc_1 tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_bdkey_A_3_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid2, LN ''Kab'' tid1,+ s(AV ''A'' tid2), s(AV ''B'' tid0), s(MV ''Text3'' tid2)+ |}+ ( Kbd ( s(AV ''A'' tid2) ) ( s(AV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_bdkey_state) A_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_bdkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_bdkey_P &+ ( tid1, isoiec_9798_2_5_bdkey_P_2 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1), LN ''Kab'' tid1,+ s(MV ''TVPa'' tid1), s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''TVPa'' tid0, s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_bdkey_state) B_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_bdkey_B_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_bdkey_P &+ ( tid1, isoiec_9798_2_5_bdkey_P_2 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1), LN ''Kab'' tid1,+ LN ''TNp'' tid1, s(MV ''Text2'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''TNp'' tid0), s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_bdkey_P_2_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_2_6_bdkey_A+where "isoiec_9798_2_6_bdkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' ( sMV ''Text2'' )+ , Send ''2'' <| sAV ''A'', sAV ''P'', sN ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ , Recv ''3'' <| sAV ''P'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_6_enc_3_1'', sN ''Ra'', sMV ''Kab'',+ sAV ''A'', sMV ''B'', sMV ''Text4''+ |>+ ( sKbd (AVar ''A'') (AVar ''P'') ),+ sMV ''TokenPA_for_B''+ |>+ , Recv ''text_4'' <| sMV ''Text6'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''A'', sMV ''B'', sMV ''Text7'', sAV ''P'',+ sMV ''TokenPA_for_B'',+ PEnc <| sC ''isoiec_9798_2_6_enc_4'', sN ''Rpa'', sMV ''Rb'',+ sMV ''Text6''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''5'' <| sMV ''B'', sAV ''A'', sMV ''Text9'',+ PEnc <| sC ''isoiec_9798_2_6_enc_5'', sMV ''Rb'', sN ''Rpa'',+ sMV ''Text8''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_6_bdkey_B+where "isoiec_9798_2_6_bdkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''4'' <| sAV ''A'', sAV ''B'', sMV ''Text7'', sMV ''P'',+ PEnc <| sC ''isoiec_9798_2_6_enc_3_2'', sN ''Rb'', sMV ''Kab'',+ sAV ''A'', sAV ''B'', sMV ''Text3''+ |>+ ( sKbd (AVar ''B'') (MVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_6_enc_4'', sMV ''Rpa'', sN ''Rb'',+ sMV ''Text6''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''B'', sAV ''A'', sMV ''Text9'',+ PEnc <| sC ''isoiec_9798_2_6_enc_5'', sN ''Rb'', sMV ''Rpa'',+ sMV ''Text8''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_6_bdkey_P+where "isoiec_9798_2_6_bdkey_P =+ [ Recv ''2'' <| sMV ''A'', sAV ''P'', sMV ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ , Recv ''text_3'' <| sMV ''Text3'', sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''P'', sMV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_6_enc_3_1'', sMV ''Ra'', sN ''Kab'',+ sMV ''A'', sMV ''B'', sMV ''Text4''+ |>+ ( sKbd (MVar ''A'') (AVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_6_enc_3_2'', sMV ''Rb'', sN ''Kab'',+ sMV ''A'', sMV ''B'', sMV ''Text3''+ |>+ ( sKbd (MVar ''B'') (AVar ''P'') )+ |>+ ]"++protocol isoiec_9798_2_6_bdkey+where "isoiec_9798_2_6_bdkey =+{ isoiec_9798_2_6_bdkey_A, isoiec_9798_2_6_bdkey_B,+ isoiec_9798_2_6_bdkey_P+}"++locale restricted_isoiec_9798_2_6_bdkey_state = isoiec_9798_2_6_bdkey_state++type_invariant isoiec_9798_2_6_bdkey_msc_typing for isoiec_9798_2_6_bdkey+where "isoiec_9798_2_6_bdkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_6_bdkey_P, ''A''), (KnownT isoiec_9798_2_6_bdkey_P_2))+ , ((isoiec_9798_2_6_bdkey_A, ''B''), (KnownT isoiec_9798_2_6_bdkey_A_1))+ , ((isoiec_9798_2_6_bdkey_P, ''B''), (KnownT isoiec_9798_2_6_bdkey_P_2))+ , ((isoiec_9798_2_6_bdkey_A, ''Kab''),+ (SumT (KnownT isoiec_9798_2_6_bdkey_A_3) (NonceT isoiec_9798_2_6_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_6_bdkey_B, ''Kab''),+ (SumT (KnownT isoiec_9798_2_6_bdkey_B_4) (NonceT isoiec_9798_2_6_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_6_bdkey_B, ''P''), (KnownT isoiec_9798_2_6_bdkey_B_4))+ , ((isoiec_9798_2_6_bdkey_P, ''Ra''), (KnownT isoiec_9798_2_6_bdkey_P_2))+ , ((isoiec_9798_2_6_bdkey_A, ''Rb''), (KnownT isoiec_9798_2_6_bdkey_A_1))+ , ((isoiec_9798_2_6_bdkey_P, ''Rb''), (KnownT isoiec_9798_2_6_bdkey_P_2))+ , ((isoiec_9798_2_6_bdkey_B, ''Rpa''),+ (SumT (KnownT isoiec_9798_2_6_bdkey_B_4) (NonceT isoiec_9798_2_6_bdkey_A ''Rpa'')))+ , ((isoiec_9798_2_6_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_6_bdkey_A_1))+ , ((isoiec_9798_2_6_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_2_6_bdkey_B_text_1))+ , ((isoiec_9798_2_6_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_2_6_bdkey_A_text_2))+ , ((isoiec_9798_2_6_bdkey_P, ''Text2''),+ (KnownT isoiec_9798_2_6_bdkey_P_2))+ , ((isoiec_9798_2_6_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_2_6_bdkey_B_4))+ , ((isoiec_9798_2_6_bdkey_P, ''Text3''),+ (KnownT isoiec_9798_2_6_bdkey_P_text_3))+ , ((isoiec_9798_2_6_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_2_6_bdkey_A_3))+ , ((isoiec_9798_2_6_bdkey_P, ''Text4''),+ (KnownT isoiec_9798_2_6_bdkey_P_text_3))+ , ((isoiec_9798_2_6_bdkey_A, ''Text5''),+ (KnownT isoiec_9798_2_6_bdkey_A_3))+ , ((isoiec_9798_2_6_bdkey_P, ''Text5''),+ (KnownT isoiec_9798_2_6_bdkey_P_text_3))+ , ((isoiec_9798_2_6_bdkey_A, ''Text6''),+ (KnownT isoiec_9798_2_6_bdkey_A_text_4))+ , ((isoiec_9798_2_6_bdkey_B, ''Text6''),+ (KnownT isoiec_9798_2_6_bdkey_B_4))+ , ((isoiec_9798_2_6_bdkey_A, ''Text7''),+ (KnownT isoiec_9798_2_6_bdkey_A_text_4))+ , ((isoiec_9798_2_6_bdkey_B, ''Text7''),+ (KnownT isoiec_9798_2_6_bdkey_B_4))+ , ((isoiec_9798_2_6_bdkey_A, ''Text8''),+ (KnownT isoiec_9798_2_6_bdkey_A_5))+ , ((isoiec_9798_2_6_bdkey_B, ''Text8''),+ (KnownT isoiec_9798_2_6_bdkey_B_text_5))+ , ((isoiec_9798_2_6_bdkey_A, ''Text9''),+ (KnownT isoiec_9798_2_6_bdkey_A_5))+ , ((isoiec_9798_2_6_bdkey_B, ''Text9''),+ (KnownT isoiec_9798_2_6_bdkey_B_text_5))+ , ((isoiec_9798_2_6_bdkey_A, ''TokenPA_for_B''),+ (KnownT isoiec_9798_2_6_bdkey_A_3))+ ]"++sublocale isoiec_9798_2_6_bdkey_state < isoiec_9798_2_6_bdkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_6_bdkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_6_bdkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_6_bdkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_3_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_3_TokenPA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_text_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_A_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_5'', s(MV ''Rb'' tid0), LN ''Rpa'' tid0,+ s(MV ''Text8'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_A_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_B_4_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_B_4_P t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_B_4_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_B_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_B_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_bdkey_B_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_B_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_B_text_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_2_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_2_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_2_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_text_3_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_bdkey_P_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_6_bdkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_6_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_6_bdkey_state) P_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_P"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "LN ''Kab'' tid0 : knows t"+ shows "False"+using facts proof(sources! " LN ''Kab'' tid0 ")+ case isoiec_9798_2_6_bdkey_P_3_Kab note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case isoiec_9798_2_6_bdkey_P_3_Kab_1 note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+qed (insert facts, fastsimp+)?++lemma (in restricted_isoiec_9798_2_6_bdkey_state) A_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_bdkey_A_3 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_bdkey_state) B_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_bdkey_B_4 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_bdkey_state) A_non_injective_agreement_B:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_bdkey_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_bdkey_B &+ ( tid1, isoiec_9798_2_6_bdkey_B_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''P'' tid1),+ s(MV ''Kab'' tid1), s(MV ''Rpa'' tid1), LN ''Rb'' tid1,+ s(MV ''Text6'' tid1), s(MV ''Text8'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''Rpa'' tid0, s(MV ''Rb'' tid0),+ s(MV ''Text6'' tid0), s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_5'', s(MV ''Rb'' tid0), LN ''Rpa'' tid0,+ s(MV ''Text8'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_bdkey_B_5_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid2, LN ''Kab'' tid1,+ s(AV ''A'' tid2), s(AV ''B'' tid2), s(MV ''Text3'' tid2)+ |}+ ( Kbd ( s(AV ''B'' tid2) ) ( s(MV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc_1 tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', LN ''Rpa'' tid0, LN ''Rb'' tid2,+ s(MV ''Text6'' tid2)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_bdkey_A_4_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_bdkey_state) B_non_injective_agreement_A:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_bdkey_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_bdkey_A &+ ( tid1, isoiec_9798_2_6_bdkey_A_4 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Kab'' tid1), LN ''Rpa'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text6'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_bdkey_A_4_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid2, LN ''Kab'' tid1,+ s(AV ''A'' tid2), s(MV ''B'' tid2), s(MV ''Text4'' tid2)+ |}+ ( Kbd ( s(AV ''A'' tid2) ) ( s(AV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_bdkey_state) A_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_bdkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_bdkey_P &+ ( tid1, isoiec_9798_2_6_bdkey_P_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Ra'' tid1), LN ''Kab'' tid1, s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''P'' tid0),+ LN ''Ra'' tid0, s(MV ''Kab'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_bdkey_state) B_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_bdkey_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_bdkey_P &+ ( tid1, isoiec_9798_2_6_bdkey_P_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Rb'' tid1), LN ''Kab'' tid1, s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ LN ''Rb'' tid0, s(MV ''Kab'' tid0), s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(AV ''B'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_bdkey_P_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_2_5_special_TTP_bdkey_A+where "isoiec_9798_2_5_special_TTP_bdkey_A =+ [ Send ''leak_A'' <| sN ''TVPa'', sN ''TNa'' |>+ , Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''A'', sAV ''P'', sN ''TVPa'', sAV ''B'',+ sMV ''Text1''+ |>+ , Recv ''2'' <| sAV ''P'', sAV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_2_1'', sN ''TVPa'',+ sMV ''Kab'', sAV ''B'', sMV ''Text3''+ |>+ ( sKbd (AVar ''A'') (AVar ''P'') ),+ sMV ''TokenPA_for_B''+ |>+ , Recv ''text_3'' <| sMV ''Text5'', sMV ''Text6'' |>+ , Send ''3'' <| sAV ''A'', sAV ''B'', sMV ''Text6'', sAV ''P'',+ sMV ''TokenPA_for_B'',+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_3'', sN ''TNa'', sAV ''B'',+ sMV ''Text5''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''4'' <| sAV ''B'', sAV ''A'', sMV ''Text8'',+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_4'', sMV ''TNb'', sAV ''A'',+ sMV ''Text7''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_5_special_TTP_bdkey_B+where "isoiec_9798_2_5_special_TTP_bdkey_B =+ [ Send ''leak_B'' ( sN ''TNb'' )+ , Recv ''3'' <| sMV ''A'', sAV ''B'', sMV ''Text6'', sMV ''P'',+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_2_2'', sMV ''TNp'',+ sMV ''Kab'', sMV ''A'', sMV ''Text2''+ |>+ ( sKbd (AVar ''B'') (MVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_3'', sMV ''TNa'', sAV ''B'',+ sMV ''Text5''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''text_4'' <| sMV ''Text7'', sMV ''Text8'' |>+ , Send ''4'' <| sAV ''B'', sMV ''A'', sMV ''Text8'',+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_4'', sN ''TNb'', sMV ''A'',+ sMV ''Text7''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_5_special_TTP_bdkey_P+where "isoiec_9798_2_5_special_TTP_bdkey_P =+ [ Send ''leak_P'' ( sN ''TNp'' )+ , Recv ''1'' <| sMV ''A'', sAV ''P'', sMV ''TVPa'', sMV ''B'',+ sMV ''Text1''+ |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''P'', sMV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_2_1'', sMV ''TVPa'',+ sN ''Kab'', sMV ''B'', sMV ''Text3''+ |>+ ( sKbd (MVar ''A'') (AVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_5_special_TTP_enc_2_2'', sN ''TNp'',+ sN ''Kab'', sMV ''A'', sMV ''Text2''+ |>+ ( sKbd (MVar ''B'') (AVar ''P'') )+ |>+ ]"++protocol isoiec_9798_2_5_special_TTP_bdkey+where "isoiec_9798_2_5_special_TTP_bdkey =+{ isoiec_9798_2_5_special_TTP_bdkey_A,+ isoiec_9798_2_5_special_TTP_bdkey_B, isoiec_9798_2_5_special_TTP_bdkey_P+}"++locale restricted_isoiec_9798_2_5_special_TTP_bdkey_state = isoiec_9798_2_5_special_TTP_bdkey_state ++ assumes different_actors_A_P:+ "!! tid0 tid1.+ [| roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_A;+ roleMap r tid1 = Some isoiec_9798_2_5_special_TTP_bdkey_P;+ s(AV ''P'' tid1) = s(AV ''A'' tid0)+ |] ==> False"++type_invariant isoiec_9798_2_5_special_TTP_bdkey_msc_typing for isoiec_9798_2_5_special_TTP_bdkey+where "isoiec_9798_2_5_special_TTP_bdkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_5_special_TTP_bdkey_B, ''A''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''A''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_1))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''B''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_1))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Kab''),+ (SumT (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_2) (NonceT isoiec_9798_2_5_special_TTP_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''Kab''),+ (SumT (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3) (NonceT isoiec_9798_2_5_special_TTP_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''P''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''TNa''),+ (SumT (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3) (NonceT isoiec_9798_2_5_special_TTP_bdkey_A ''TNa'')))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''TNb''),+ (SumT (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_4) (NonceT isoiec_9798_2_5_special_TTP_bdkey_B ''TNb'')))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''TNp''),+ (SumT (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3) (NonceT isoiec_9798_2_5_special_TTP_bdkey_P ''TNp'')))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''TVPa''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_1))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_text_1))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''Text1''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_1))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''Text2''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_text_2))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_2))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''Text3''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_text_2))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_2))+ , ((isoiec_9798_2_5_special_TTP_bdkey_P, ''Text4''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_P_text_2))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text5''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_text_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''Text5''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text6''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_text_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''Text6''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_3))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text7''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_4))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''Text7''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_text_4))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''Text8''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_4))+ , ((isoiec_9798_2_5_special_TTP_bdkey_B, ''Text8''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_B_text_4))+ , ((isoiec_9798_2_5_special_TTP_bdkey_A, ''TokenPA_for_B''),+ (KnownT isoiec_9798_2_5_special_TTP_bdkey_A_2))+ ]"++sublocale isoiec_9798_2_5_special_TTP_bdkey_state < isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_5_special_TTP_bdkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_5_special_TTP_bdkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_5_special_TTP_bdkey_A_2_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_2_TokenPA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_text_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_4_TNb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_4_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_P t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_TNa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_TNp t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_text_4_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_1_TVPa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_5_special_TTP_bdkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_5_special_TTP_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end+++lemma (in restricted_isoiec_9798_2_5_special_TTP_bdkey_state) P_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_P"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "LN ''Kab'' tid0 : knows t"+ shows "False"+using facts proof(sources! " LN ''Kab'' tid0 ")+ case isoiec_9798_2_5_special_TTP_bdkey_P_2_Kab note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case isoiec_9798_2_5_special_TTP_bdkey_P_2_Kab_1 note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+qed (insert facts, fastsimp+)?++lemma (in restricted_isoiec_9798_2_5_special_TTP_bdkey_state) A_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_special_TTP_bdkey_A_2 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''A'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_special_TTP_bdkey_state) B_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_special_TTP_bdkey_B_3 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc_1 tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''B'' tid1) ) = Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_special_TTP_bdkey_state) A_non_injective_agreement_B:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_special_TTP_bdkey_A_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_special_TTP_bdkey_B &+ ( tid1, isoiec_9798_2_5_special_TTP_bdkey_B_4 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), s(MV ''P'' tid1),+ s(MV ''Kab'' tid1), s(MV ''TNa'' tid1), s(MV ''Text5'' tid1),+ LN ''TNb'' tid1, s(MV ''Text7'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''TNa'' tid0, s(MV ''Text5'' tid0),+ s(MV ''TNb'' tid0), s(MV ''Text7'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''A'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_B_4_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_3'', s(MV ''TNa'' tid2),+ s(AV ''B'' tid2), s(MV ''Text5'' tid2)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_3_enc tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid3,+ LN ''Kab'' tid1, s(AV ''B'' tid2), s(MV ''Text3'' tid3)+ |}+ ( Kbd ( s(AV ''A'' tid3) ) ( s(AV ''P'' tid3) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc tid4) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid2),+ LN ''Kab'' tid1, s(AV ''A'' tid0), s(MV ''Text2'' tid2)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc_1 tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_special_TTP_bdkey_state) B_non_injective_agreement_A:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_special_TTP_bdkey_B_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_special_TTP_bdkey_A &+ ( tid1, isoiec_9798_2_5_special_TTP_bdkey_A_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Kab'' tid1), LN ''TNa'' tid1, s(MV ''Text5'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''TNa'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: B_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid1,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid1)+ |}+ ( Kbd ( s(AV ''A'' tid1) ) ( s(AV ''P'' tid1) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: B_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc tid2) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid2) )+ ( s(MV ''A'' tid2) ) = Kbd ( s(AV ''A'' tid1) ) ( s(AV ''P'' tid1) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid0),+ LN ''Kab'' tid2, s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc_1 tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_special_TTP_bdkey_state) A_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_special_TTP_bdkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_special_TTP_bdkey_P &+ ( tid1, isoiec_9798_2_5_special_TTP_bdkey_P_2 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1), LN ''Kab'' tid1,+ s(MV ''TVPa'' tid1), s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''TVPa'' tid0, s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''A'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_special_TTP_bdkey_state) B_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_special_TTP_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_special_TTP_bdkey_B_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_special_TTP_bdkey_P &+ ( tid1, isoiec_9798_2_5_special_TTP_bdkey_P_2 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1), LN ''Kab'' tid1,+ LN ''TNp'' tid1, s(MV ''Text2'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''TNp'' tid0), s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc_1 tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''B'' tid1) ) = Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_A_3_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_special_TTP_enc_2_1'', LN ''TVPa'' tid2,+ LN ''Kab'' tid1, s(AV ''B'' tid0), s(MV ''Text3'' tid2)+ |}+ ( Kbd ( s(AV ''A'' tid2) ) ( s(AV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_special_TTP_bdkey_P_2_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_2_6_special_TTP_bdkey_A+where "isoiec_9798_2_6_special_TTP_bdkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' ( sMV ''Text2'' )+ , Send ''2'' <| sAV ''A'', sAV ''P'', sN ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ , Recv ''3'' <| sAV ''P'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_3_1'', sN ''Ra'',+ sMV ''Kab'', sMV ''B'', sMV ''Text4''+ |>+ ( sKbd (AVar ''A'') (AVar ''P'') ),+ sMV ''TokenPA_for_B''+ |>+ , Recv ''text_4'' <| sMV ''Text6'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''A'', sMV ''B'', sMV ''Text7'', sAV ''P'',+ sMV ''TokenPA_for_B'',+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_4'', sN ''Rpa'', sMV ''Rb'',+ sMV ''Text6''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''5'' <| sMV ''B'', sAV ''A'', sMV ''Text9'',+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_5'', sMV ''Rb'', sN ''Rpa'',+ sMV ''Text8''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_6_special_TTP_bdkey_B+where "isoiec_9798_2_6_special_TTP_bdkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''4'' <| sAV ''A'', sAV ''B'', sMV ''Text7'', sMV ''P'',+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_3_2'', sN ''Rb'',+ sMV ''Kab'', sAV ''A'', sMV ''Text3''+ |>+ ( sKbd (AVar ''B'') (MVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_4'', sMV ''Rpa'', sN ''Rb'',+ sMV ''Text6''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''B'', sAV ''A'', sMV ''Text9'',+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_5'', sN ''Rb'', sMV ''Rpa'',+ sMV ''Text8''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_6_special_TTP_bdkey_P+where "isoiec_9798_2_6_special_TTP_bdkey_P =+ [ Recv ''2'' <| sMV ''A'', sAV ''P'', sMV ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ , Recv ''text_3'' <| sMV ''Text3'', sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''P'', sMV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_3_1'', sMV ''Ra'',+ sN ''Kab'', sMV ''B'', sMV ''Text4''+ |>+ ( sKbd (MVar ''A'') (AVar ''P'') ),+ PEnc <| sC ''isoiec_9798_2_6_special_TTP_enc_3_2'', sMV ''Rb'',+ sN ''Kab'', sMV ''A'', sMV ''Text3''+ |>+ ( sKbd (MVar ''B'') (AVar ''P'') )+ |>+ ]"++protocol isoiec_9798_2_6_special_TTP_bdkey+where "isoiec_9798_2_6_special_TTP_bdkey =+{ isoiec_9798_2_6_special_TTP_bdkey_A,+ isoiec_9798_2_6_special_TTP_bdkey_B, isoiec_9798_2_6_special_TTP_bdkey_P+}"++locale restricted_isoiec_9798_2_6_special_TTP_bdkey_state = isoiec_9798_2_6_special_TTP_bdkey_state ++ assumes different_actors_A_P:+ "!! tid0 tid1.+ [| roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_A;+ roleMap r tid1 = Some isoiec_9798_2_6_special_TTP_bdkey_P;+ s(AV ''P'' tid1) = s(AV ''A'' tid0)+ |] ==> False"+ assumes different_actors_B_P:+ "!! tid0 tid1.+ [| roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_B;+ roleMap r tid1 = Some isoiec_9798_2_6_special_TTP_bdkey_P;+ s(AV ''P'' tid1) = s(AV ''B'' tid0)+ |] ==> False"++type_invariant isoiec_9798_2_6_special_TTP_bdkey_msc_typing for isoiec_9798_2_6_special_TTP_bdkey+where "isoiec_9798_2_6_special_TTP_bdkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_6_special_TTP_bdkey_P, ''A''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_2))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''B''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_1))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''B''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_2))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Kab''),+ (SumT (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_3) (NonceT isoiec_9798_2_6_special_TTP_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Kab''),+ (SumT (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_4) (NonceT isoiec_9798_2_6_special_TTP_bdkey_P ''Kab'')))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''P''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_4))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''Ra''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_2))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Rb''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_1))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''Rb''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_2))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Rpa''),+ (SumT (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_4) (NonceT isoiec_9798_2_6_special_TTP_bdkey_A ''Rpa'')))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_1))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_text_1))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_text_2))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''Text2''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_2))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_4))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''Text3''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_text_3))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_3))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''Text4''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_text_3))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text5''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_3))+ , ((isoiec_9798_2_6_special_TTP_bdkey_P, ''Text5''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_P_text_3))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text6''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_text_4))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Text6''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_4))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text7''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_text_4))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Text7''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_4))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text8''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_5))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Text8''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_text_5))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''Text9''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_5))+ , ((isoiec_9798_2_6_special_TTP_bdkey_B, ''Text9''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_B_text_5))+ , ((isoiec_9798_2_6_special_TTP_bdkey_A, ''TokenPA_for_B''),+ (KnownT isoiec_9798_2_6_special_TTP_bdkey_A_3))+ ]"++sublocale isoiec_9798_2_6_special_TTP_bdkey_state < isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_6_special_TTP_bdkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_6_special_TTP_bdkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_6_special_TTP_bdkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_3_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_3_TokenPA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_text_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_5'', s(MV ''Rb'' tid0),+ LN ''Rpa'' tid0, s(MV ''Text8'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_4_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_4_P t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_4_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_4'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(MV ''Text6'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_4'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(MV ''Text6'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_text_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_2_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_2_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_2_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_text_3_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_6_special_TTP_bdkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_6_special_TTP_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++++lemma (in restricted_isoiec_9798_2_6_special_TTP_bdkey_state) P_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_P"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "LN ''Kab'' tid0 : knows t"+ shows "False"+using facts proof(sources! " LN ''Kab'' tid0 ")+ case isoiec_9798_2_6_special_TTP_bdkey_P_3_Kab note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case isoiec_9798_2_6_special_TTP_bdkey_P_3_Kab_1 note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+qed (insert facts, fastsimp+)?++lemma (in restricted_isoiec_9798_2_6_special_TTP_bdkey_state) A_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_special_TTP_bdkey_A_3 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''A'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_special_TTP_bdkey_state) B_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_special_TTP_bdkey_B_4 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc_1 tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''B'' tid1) ) = Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: different_actors_B_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_special_TTP_bdkey_state) A_non_injective_agreement_B:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_special_TTP_bdkey_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_special_TTP_bdkey_B &+ ( tid1, isoiec_9798_2_6_special_TTP_bdkey_B_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''P'' tid1),+ s(MV ''Kab'' tid1), s(MV ''Rpa'' tid1), LN ''Rb'' tid1,+ s(MV ''Text6'' tid1), s(MV ''Text8'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''Rpa'' tid0, s(MV ''Rb'' tid0),+ s(MV ''Text6'' tid0), s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''A'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_5'', s(MV ''Rb'' tid0),+ LN ''Rpa'' tid0, s(MV ''Text8'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_B_5_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_2'', LN ''Rb'' tid2,+ LN ''Kab'' tid1, s(AV ''A'' tid2), s(MV ''Text3'' tid2)+ |}+ ( Kbd ( s(AV ''B'' tid2) ) ( s(MV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc_1 tid3) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid0) )+ ( s(MV ''B'' tid0) ) = Kbd ( s(AV ''B'' tid2) ) ( s(MV ''P'' tid2) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: different_actors_B_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_4'', LN ''Rpa'' tid0,+ LN ''Rb'' tid2, s(MV ''Text6'' tid2)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_4_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_special_TTP_bdkey_state) B_non_injective_agreement_A:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_special_TTP_bdkey_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_special_TTP_bdkey_A &+ ( tid1, isoiec_9798_2_6_special_TTP_bdkey_A_4 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Kab'' tid1), LN ''Rpa'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text6'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc_1 tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''B'' tid1) ) = Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: different_actors_B_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_4'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(MV ''Text6'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_A_4_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_1'', LN ''Ra'' tid2,+ LN ''Kab'' tid1, s(MV ''B'' tid2), s(MV ''Text4'' tid2)+ |}+ ( Kbd ( s(AV ''A'' tid2) ) ( s(AV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc tid3) note_unified facts = this facts+ hence "Kbd ( s(AV ''A'' tid2) )+ ( s(AV ''P'' tid2) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid1) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp dest: different_actors_A_P intro: event_predOrdI)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_special_TTP_bdkey_state) A_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_special_TTP_bdkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_special_TTP_bdkey_P &+ ( tid1, isoiec_9798_2_6_special_TTP_bdkey_P_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Ra'' tid1), LN ''Kab'' tid1, s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''P'' tid0),+ LN ''Ra'' tid0, s(MV ''Kab'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''A'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: different_actors_A_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_special_TTP_bdkey_state) B_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_special_TTP_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_special_TTP_bdkey_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_special_TTP_bdkey_P &+ ( tid1, isoiec_9798_2_6_special_TTP_bdkey_P_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Rb'' tid1), LN ''Kab'' tid1, s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ LN ''Rb'' tid0, s(MV ''Kab'' tid0), s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_special_TTP_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_special_TTP_bdkey_P_3_enc_1 tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''P'' tid1) )+ ( s(MV ''B'' tid1) ) = Kbd ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis by (fastsimp dest: different_actors_B_P intro: event_predOrdI)+ next+ case swapped note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++end
@@ -0,0 +1,2190 @@+theory "isoiec-9798-2-udkey_cert_auto"+imports+ "../ESPLogic"+begin++role isoiec_9798_2_1_udkey_A+where "isoiec_9798_2_1_udkey_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_1_enc_1'', sN ''TNA'', sMV ''Text1'' |>+ ( sK ''A'' ''B'' )+ |>+ ]"++role isoiec_9798_2_1_udkey_B+where "isoiec_9798_2_1_udkey_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_1_enc_1'', sMV ''TNA'', sMV ''Text1'' |>+ ( PSymK ( sMV ''A'' ) ( sAV ''B'' ) )+ |>+ ]"++protocol isoiec_9798_2_1_udkey+where "isoiec_9798_2_1_udkey =+{ isoiec_9798_2_1_udkey_A, isoiec_9798_2_1_udkey_B }"++locale restricted_isoiec_9798_2_1_udkey_state = isoiec_9798_2_1_udkey_state++type_invariant isoiec_9798_2_1_udkey_msc_typing for isoiec_9798_2_1_udkey+where "isoiec_9798_2_1_udkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_1_udkey_B, ''A''), (KnownT isoiec_9798_2_1_udkey_B_1))+ , ((isoiec_9798_2_1_udkey_B, ''TNA''),+ (SumT (KnownT isoiec_9798_2_1_udkey_B_1) (NonceT isoiec_9798_2_1_udkey_A ''TNA'')))+ , ((isoiec_9798_2_1_udkey_A, ''Text1''),+ (KnownT isoiec_9798_2_1_udkey_A_text_1))+ , ((isoiec_9798_2_1_udkey_B, ''Text1''),+ (KnownT isoiec_9798_2_1_udkey_B_1))+ , ((isoiec_9798_2_1_udkey_A, ''Text2''),+ (KnownT isoiec_9798_2_1_udkey_A_text_1))+ , ((isoiec_9798_2_1_udkey_B, ''Text2''),+ (KnownT isoiec_9798_2_1_udkey_B_1))+ ]"++sublocale isoiec_9798_2_1_udkey_state < isoiec_9798_2_1_udkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_1_udkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_1_udkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_1_udkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_1_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_1_udkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_1_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_1_udkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_1_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_1_udkey_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_1_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_1_enc_1'', s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |}+ ( K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_1_udkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_1_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_1_enc_1'', s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |}+ ( K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_1_udkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_1_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_1_udkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_1_udkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_1_udkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_1_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_1_udkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_1_udkey_A &+ ( tid1, isoiec_9798_2_1_udkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_1_enc_1'', s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |}+ ( K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_1_udkey_A_1_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_2_2_udkey_A+where "isoiec_9798_2_2_udkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''RB'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_2_enc_2'', sMV ''RB'', sMV ''Text2'' |>+ ( PSymK ( sAV ''A'' ) ( sMV ''B'' ) )+ |>+ ]"++role isoiec_9798_2_2_udkey_B+where "isoiec_9798_2_2_udkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''RB'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_2_enc_2'', sN ''RB'', sMV ''Text2'' |>+ ( sK ''A'' ''B'' )+ |>+ ]"++protocol isoiec_9798_2_2_udkey+where "isoiec_9798_2_2_udkey =+{ isoiec_9798_2_2_udkey_A, isoiec_9798_2_2_udkey_B }"++locale restricted_isoiec_9798_2_2_udkey_state = isoiec_9798_2_2_udkey_state++type_invariant isoiec_9798_2_2_udkey_msc_typing for isoiec_9798_2_2_udkey+where "isoiec_9798_2_2_udkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_2_udkey_A, ''B''), (KnownT isoiec_9798_2_2_udkey_A_1))+ , ((isoiec_9798_2_2_udkey_A, ''RB''), (KnownT isoiec_9798_2_2_udkey_A_1))+ , ((isoiec_9798_2_2_udkey_A, ''Text1''),+ (KnownT isoiec_9798_2_2_udkey_A_1))+ , ((isoiec_9798_2_2_udkey_B, ''Text1''),+ (KnownT isoiec_9798_2_2_udkey_B_text_1))+ , ((isoiec_9798_2_2_udkey_A, ''Text2''),+ (KnownT isoiec_9798_2_2_udkey_A_text_2))+ , ((isoiec_9798_2_2_udkey_B, ''Text2''),+ (KnownT isoiec_9798_2_2_udkey_B_2))+ , ((isoiec_9798_2_2_udkey_A, ''Text3''),+ (KnownT isoiec_9798_2_2_udkey_A_text_2))+ , ((isoiec_9798_2_2_udkey_B, ''Text3''),+ (KnownT isoiec_9798_2_2_udkey_B_2))+ ]"++sublocale isoiec_9798_2_2_udkey_state < isoiec_9798_2_2_udkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_2_udkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_2_udkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_2_udkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_udkey_A_1_RB t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_udkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_udkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_udkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_2_udkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_2_enc_2'', LN ''RB'' tid0, s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_2_udkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_2_udkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_2_udkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_2_udkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_2_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_2_udkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_2_udkey_A &+ ( tid1, isoiec_9798_2_2_udkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(MV ''RB'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''RB'' tid0,+ s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_2_enc_2'', LN ''RB'' tid0, s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_2_udkey_A_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_2_3_udkey_A+where "isoiec_9798_2_3_udkey_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_3_enc_1'', sN ''TNA'', sMV ''Text1'' |>+ ( sK ''A'' ''B'' )+ |>+ , Recv ''2'' <| sAV ''B'', sAV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_3_enc_2'', sMV ''TNB'', sMV ''Text3'' |>+ ( sK ''B'' ''A'' )+ |>+ ]"++role isoiec_9798_2_3_udkey_B+where "isoiec_9798_2_3_udkey_B =+ [ Send ''leak_B'' ( sN ''TNB'' )+ , Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Text2'',+ PEnc <| sC ''isoiec_9798_2_3_enc_1'', sMV ''TNA'', sMV ''Text1'' |>+ ( PSymK ( sMV ''A'' ) ( sAV ''B'' ) )+ |>+ , Recv ''text_2'' <| sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''B'', sMV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_3_enc_2'', sN ''TNB'', sMV ''Text3'' |>+ ( PSymK ( sAV ''B'' ) ( sMV ''A'' ) )+ |>+ ]"++protocol isoiec_9798_2_3_udkey+where "isoiec_9798_2_3_udkey =+{ isoiec_9798_2_3_udkey_A, isoiec_9798_2_3_udkey_B }"++locale restricted_isoiec_9798_2_3_udkey_state = isoiec_9798_2_3_udkey_state++type_invariant isoiec_9798_2_3_udkey_msc_typing for isoiec_9798_2_3_udkey+where "isoiec_9798_2_3_udkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_3_udkey_B, ''A''), (KnownT isoiec_9798_2_3_udkey_B_1))+ , ((isoiec_9798_2_3_udkey_B, ''TNA''),+ (SumT (KnownT isoiec_9798_2_3_udkey_B_1) (NonceT isoiec_9798_2_3_udkey_A ''TNA'')))+ , ((isoiec_9798_2_3_udkey_A, ''TNB''),+ (SumT (KnownT isoiec_9798_2_3_udkey_A_2) (NonceT isoiec_9798_2_3_udkey_B ''TNB'')))+ , ((isoiec_9798_2_3_udkey_A, ''Text1''),+ (KnownT isoiec_9798_2_3_udkey_A_text_1))+ , ((isoiec_9798_2_3_udkey_B, ''Text1''),+ (KnownT isoiec_9798_2_3_udkey_B_1))+ , ((isoiec_9798_2_3_udkey_A, ''Text2''),+ (KnownT isoiec_9798_2_3_udkey_A_text_1))+ , ((isoiec_9798_2_3_udkey_B, ''Text2''),+ (KnownT isoiec_9798_2_3_udkey_B_1))+ , ((isoiec_9798_2_3_udkey_A, ''Text3''),+ (KnownT isoiec_9798_2_3_udkey_A_2))+ , ((isoiec_9798_2_3_udkey_B, ''Text3''),+ (KnownT isoiec_9798_2_3_udkey_B_text_2))+ , ((isoiec_9798_2_3_udkey_A, ''Text4''),+ (KnownT isoiec_9798_2_3_udkey_A_2))+ , ((isoiec_9798_2_3_udkey_B, ''Text4''),+ (KnownT isoiec_9798_2_3_udkey_B_text_2))+ ]"++sublocale isoiec_9798_2_3_udkey_state < isoiec_9798_2_3_udkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_3_udkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_3_udkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_3_udkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_A_2_TNB t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_2'', s(MV ''TNB'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(AV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_udkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_2'', s(MV ''TNB'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(AV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_udkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_1'', s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |}+ ( K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_udkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_1'', s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |}+ ( K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_3_udkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_3_udkey_B_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_3_udkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_3_udkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_3_udkey_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_3_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_3_udkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_3_udkey_B &+ ( tid1, isoiec_9798_2_3_udkey_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), LN ''TNB'' tid1,+ s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNB'' tid0),+ s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_2'', s(MV ''TNB'' tid0),+ s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_3_udkey_B_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_3_udkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_3_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_3_udkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_3_udkey_A &+ ( tid1, isoiec_9798_2_3_udkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_3_enc_1'', s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |}+ ( K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_3_udkey_A_1_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_2_4_udkey_A+where "isoiec_9798_2_4_udkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''RB'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_4_enc_1'', sN ''RA'', sMV ''RB'',+ sMV ''Text2''+ |>+ ( PSymK ( sAV ''A'' ) ( sMV ''B'' ) )+ |>+ , Recv ''3'' <| sMV ''B'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_4_enc_2'', sMV ''RB'', sN ''RA'',+ sMV ''Text4''+ |>+ ( PSymK ( sMV ''B'' ) ( sAV ''A'' ) )+ |>+ ]"++role isoiec_9798_2_4_udkey_B+where "isoiec_9798_2_4_udkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''RB'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'',+ PEnc <| sC ''isoiec_9798_2_4_enc_1'', sMV ''RA'', sN ''RB'',+ sMV ''Text2''+ |>+ ( sK ''A'' ''B'' )+ |>+ , Recv ''text_3'' <| sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''B'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_4_enc_2'', sN ''RB'', sMV ''RA'',+ sMV ''Text4''+ |>+ ( sK ''B'' ''A'' )+ |>+ ]"++protocol isoiec_9798_2_4_udkey+where "isoiec_9798_2_4_udkey =+{ isoiec_9798_2_4_udkey_A, isoiec_9798_2_4_udkey_B }"++locale restricted_isoiec_9798_2_4_udkey_state = isoiec_9798_2_4_udkey_state++type_invariant isoiec_9798_2_4_udkey_msc_typing for isoiec_9798_2_4_udkey+where "isoiec_9798_2_4_udkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_4_udkey_A, ''B''), (KnownT isoiec_9798_2_4_udkey_A_1))+ , ((isoiec_9798_2_4_udkey_B, ''RA''),+ (SumT (KnownT isoiec_9798_2_4_udkey_B_2) (NonceT isoiec_9798_2_4_udkey_A ''RA'')))+ , ((isoiec_9798_2_4_udkey_A, ''RB''), (KnownT isoiec_9798_2_4_udkey_A_1))+ , ((isoiec_9798_2_4_udkey_A, ''Text1''),+ (KnownT isoiec_9798_2_4_udkey_A_1))+ , ((isoiec_9798_2_4_udkey_B, ''Text1''),+ (KnownT isoiec_9798_2_4_udkey_B_text_1))+ , ((isoiec_9798_2_4_udkey_A, ''Text2''),+ (KnownT isoiec_9798_2_4_udkey_A_text_2))+ , ((isoiec_9798_2_4_udkey_B, ''Text2''),+ (KnownT isoiec_9798_2_4_udkey_B_2))+ , ((isoiec_9798_2_4_udkey_A, ''Text3''),+ (KnownT isoiec_9798_2_4_udkey_A_text_2))+ , ((isoiec_9798_2_4_udkey_B, ''Text3''),+ (KnownT isoiec_9798_2_4_udkey_B_2))+ , ((isoiec_9798_2_4_udkey_A, ''Text4''),+ (KnownT isoiec_9798_2_4_udkey_A_3))+ , ((isoiec_9798_2_4_udkey_B, ''Text4''),+ (KnownT isoiec_9798_2_4_udkey_B_text_3))+ , ((isoiec_9798_2_4_udkey_A, ''Text5''),+ (KnownT isoiec_9798_2_4_udkey_A_3))+ , ((isoiec_9798_2_4_udkey_B, ''Text5''),+ (KnownT isoiec_9798_2_4_udkey_B_text_3))+ ]"++sublocale isoiec_9798_2_4_udkey_state < isoiec_9798_2_4_udkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_4_udkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_4_udkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_4_udkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_A_1_RB t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_2'', s(MV ''RB'' tid0), LN ''RA'' tid0,+ s(MV ''Text4'' tid0)+ |}+ ( K ( s(MV ''B'' tid0) ) ( s(AV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_4_udkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_B_2_RA t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_4_udkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_4_udkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_B_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_4_udkey_B_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_4_udkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_4_udkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_4_udkey_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_4_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_4_udkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_4_udkey_B &+ ( tid1, isoiec_9798_2_4_udkey_B_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''RA'' tid1), LN ''RB'' tid1,+ s(MV ''Text2'' tid1), s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''RA'' tid0,+ s(MV ''RB'' tid0), s(MV ''Text2'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_2'', s(MV ''RB'' tid0), LN ''RA'' tid0,+ s(MV ''Text4'' tid0)+ |}+ ( K ( s(MV ''B'' tid0) ) ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_udkey_B_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', LN ''RA'' tid0, LN ''RB'' tid1,+ s(MV ''Text2'' tid1)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid1) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_udkey_A_2_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_4_udkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_4_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_4_udkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_4_udkey_A &+ ( tid1, isoiec_9798_2_4_udkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''RA'' tid1, s(MV ''RB'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''RA'' tid0),+ LN ''RB'' tid0, s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_4_enc_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_4_udkey_A_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_2_5_udkey_A+where "isoiec_9798_2_5_udkey_A =+ [ Send ''leak_A'' <| sN ''TVPa'', sN ''TNa'' |>+ , Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''A'', sAV ''P'', sN ''TVPa'', sAV ''B'',+ sMV ''Text1''+ |>+ , Recv ''2'' <| sAV ''P'', sAV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_5_enc_2_1'', sN ''TVPa'', sMV ''Kab'',+ sAV ''B'', sMV ''Text3''+ |>+ ( sK ''A'' ''P'' ),+ sMV ''TokenPA_for_B''+ |>+ , Recv ''text_3'' <| sMV ''Text5'', sMV ''Text6'' |>+ , Send ''3'' <| sAV ''A'', sAV ''B'', sMV ''Text6'', sAV ''P'',+ sMV ''TokenPA_for_B'',+ PEnc <| sC ''isoiec_9798_2_5_enc_3'', sN ''TNa'', sAV ''B'',+ sMV ''Text5''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''4'' <| sAV ''B'', sAV ''A'', sMV ''Text8'',+ PEnc <| sC ''isoiec_9798_2_5_enc_4'', sMV ''TNb'', sAV ''A'',+ sMV ''Text7''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_5_udkey_B+where "isoiec_9798_2_5_udkey_B =+ [ Send ''leak_B'' ( sN ''TNb'' )+ , Recv ''3'' <| sMV ''A'', sAV ''B'', sMV ''Text6'', sMV ''P'',+ PEnc <| sC ''isoiec_9798_2_5_enc_2_2'', sMV ''TNp'', sMV ''Kab'',+ sMV ''A'', sMV ''Text2''+ |>+ ( PSymK ( sAV ''B'' ) ( sMV ''P'' ) ),+ PEnc <| sC ''isoiec_9798_2_5_enc_3'', sMV ''TNa'', sAV ''B'',+ sMV ''Text5''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''text_4'' <| sMV ''Text7'', sMV ''Text8'' |>+ , Send ''4'' <| sAV ''B'', sMV ''A'', sMV ''Text8'',+ PEnc <| sC ''isoiec_9798_2_5_enc_4'', sN ''TNb'', sMV ''A'',+ sMV ''Text7''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_5_udkey_P+where "isoiec_9798_2_5_udkey_P =+ [ Send ''leak_P'' ( sN ''TNp'' )+ , Recv ''1'' <| sMV ''A'', sAV ''P'', sMV ''TVPa'', sMV ''B'',+ sMV ''Text1''+ |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''P'', sMV ''A'', sMV ''Text4'',+ PEnc <| sC ''isoiec_9798_2_5_enc_2_1'', sMV ''TVPa'', sN ''Kab'',+ sMV ''B'', sMV ''Text3''+ |>+ ( PSymK ( sMV ''A'' ) ( sAV ''P'' ) ),+ PEnc <| sC ''isoiec_9798_2_5_enc_2_2'', sN ''TNp'', sN ''Kab'',+ sMV ''A'', sMV ''Text2''+ |>+ ( PSymK ( sMV ''B'' ) ( sAV ''P'' ) )+ |>+ ]"++protocol isoiec_9798_2_5_udkey+where "isoiec_9798_2_5_udkey =+{ isoiec_9798_2_5_udkey_A, isoiec_9798_2_5_udkey_B,+ isoiec_9798_2_5_udkey_P+}"++locale restricted_isoiec_9798_2_5_udkey_state = isoiec_9798_2_5_udkey_state++type_invariant isoiec_9798_2_5_udkey_msc_typing for isoiec_9798_2_5_udkey+where "isoiec_9798_2_5_udkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_5_udkey_B, ''A''), (KnownT isoiec_9798_2_5_udkey_B_3))+ , ((isoiec_9798_2_5_udkey_P, ''A''), (KnownT isoiec_9798_2_5_udkey_P_1))+ , ((isoiec_9798_2_5_udkey_P, ''B''), (KnownT isoiec_9798_2_5_udkey_P_1))+ , ((isoiec_9798_2_5_udkey_A, ''Kab''),+ (SumT (KnownT isoiec_9798_2_5_udkey_A_2) (NonceT isoiec_9798_2_5_udkey_P ''Kab'')))+ , ((isoiec_9798_2_5_udkey_B, ''Kab''),+ (SumT (KnownT isoiec_9798_2_5_udkey_B_3) (NonceT isoiec_9798_2_5_udkey_P ''Kab'')))+ , ((isoiec_9798_2_5_udkey_B, ''P''), (KnownT isoiec_9798_2_5_udkey_B_3))+ , ((isoiec_9798_2_5_udkey_B, ''TNa''),+ (SumT (KnownT isoiec_9798_2_5_udkey_B_3) (NonceT isoiec_9798_2_5_udkey_A ''TNa'')))+ , ((isoiec_9798_2_5_udkey_A, ''TNb''),+ (SumT (KnownT isoiec_9798_2_5_udkey_A_4) (NonceT isoiec_9798_2_5_udkey_B ''TNb'')))+ , ((isoiec_9798_2_5_udkey_B, ''TNp''),+ (SumT (KnownT isoiec_9798_2_5_udkey_B_3) (NonceT isoiec_9798_2_5_udkey_P ''TNp'')))+ , ((isoiec_9798_2_5_udkey_P, ''TVPa''),+ (KnownT isoiec_9798_2_5_udkey_P_1))+ , ((isoiec_9798_2_5_udkey_A, ''Text1''),+ (KnownT isoiec_9798_2_5_udkey_A_text_1))+ , ((isoiec_9798_2_5_udkey_P, ''Text1''),+ (KnownT isoiec_9798_2_5_udkey_P_1))+ , ((isoiec_9798_2_5_udkey_B, ''Text2''),+ (KnownT isoiec_9798_2_5_udkey_B_3))+ , ((isoiec_9798_2_5_udkey_P, ''Text2''),+ (KnownT isoiec_9798_2_5_udkey_P_text_2))+ , ((isoiec_9798_2_5_udkey_A, ''Text3''),+ (KnownT isoiec_9798_2_5_udkey_A_2))+ , ((isoiec_9798_2_5_udkey_P, ''Text3''),+ (KnownT isoiec_9798_2_5_udkey_P_text_2))+ , ((isoiec_9798_2_5_udkey_A, ''Text4''),+ (KnownT isoiec_9798_2_5_udkey_A_2))+ , ((isoiec_9798_2_5_udkey_P, ''Text4''),+ (KnownT isoiec_9798_2_5_udkey_P_text_2))+ , ((isoiec_9798_2_5_udkey_A, ''Text5''),+ (KnownT isoiec_9798_2_5_udkey_A_text_3))+ , ((isoiec_9798_2_5_udkey_B, ''Text5''),+ (KnownT isoiec_9798_2_5_udkey_B_3))+ , ((isoiec_9798_2_5_udkey_A, ''Text6''),+ (KnownT isoiec_9798_2_5_udkey_A_text_3))+ , ((isoiec_9798_2_5_udkey_B, ''Text6''),+ (KnownT isoiec_9798_2_5_udkey_B_3))+ , ((isoiec_9798_2_5_udkey_A, ''Text7''),+ (KnownT isoiec_9798_2_5_udkey_A_4))+ , ((isoiec_9798_2_5_udkey_B, ''Text7''),+ (KnownT isoiec_9798_2_5_udkey_B_text_4))+ , ((isoiec_9798_2_5_udkey_A, ''Text8''),+ (KnownT isoiec_9798_2_5_udkey_A_4))+ , ((isoiec_9798_2_5_udkey_B, ''Text8''),+ (KnownT isoiec_9798_2_5_udkey_B_text_4))+ , ((isoiec_9798_2_5_udkey_A, ''TokenPA_for_B''),+ (KnownT isoiec_9798_2_5_udkey_A_2))+ ]"++sublocale isoiec_9798_2_5_udkey_state < isoiec_9798_2_5_udkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_5_udkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_5_udkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_5_udkey_A_2_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_A_2_TokenPA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_A_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_A_text_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_A_4_TNb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_A_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_A_4_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_B_3_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_B_3_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_B_3_P t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_B_3_TNa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_B_3_TNp t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_B_3_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_B_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_5_udkey_B_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_B_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_B_text_4_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_1_TVPa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_5_udkey_P_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_5_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_5_udkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_5_udkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_5_udkey_state) P_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_P"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "LN ''Kab'' tid0 : knows t"+ shows "False"+using facts proof(sources! " LN ''Kab'' tid0 ")+ case isoiec_9798_2_5_udkey_P_2_Kab note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case isoiec_9798_2_5_udkey_P_2_Kab_1 note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+qed (insert facts, fastsimp+)?++lemma (in restricted_isoiec_9798_2_5_udkey_state) A_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_udkey_A_2 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_udkey_state) B_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_udkey_B_3 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_udkey_state) A_non_injective_agreement_B:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_udkey_A_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_udkey_B &+ ( tid1, isoiec_9798_2_5_udkey_B_4 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), s(MV ''P'' tid1),+ s(MV ''Kab'' tid1), s(MV ''TNa'' tid1), s(MV ''Text5'' tid1),+ LN ''TNb'' tid1, s(MV ''Text7'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''TNa'' tid0, s(MV ''Text5'' tid0),+ s(MV ''TNb'' tid0), s(MV ''Text7'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_4'', s(MV ''TNb'' tid0),+ s(AV ''A'' tid0), s(MV ''Text7'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_udkey_B_4_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid2),+ LN ''Kab'' tid1, s(AV ''A'' tid0), s(MV ''Text2'' tid2)+ |}+ ( K ( s(AV ''B'' tid2) ) ( s(MV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc_1 tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid2),+ s(AV ''B'' tid0), s(MV ''Text5'' tid2)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_udkey_A_3_enc tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid3, LN ''Kab'' tid1,+ s(AV ''B'' tid0), s(MV ''Text3'' tid3)+ |}+ ( K ( s(AV ''A'' tid3) ) ( s(AV ''P'' tid3) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc tid4) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_udkey_state) B_non_injective_agreement_A:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_udkey_B_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_udkey_A &+ ( tid1, isoiec_9798_2_5_udkey_A_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Kab'' tid1), LN ''TNa'' tid1, s(MV ''Text5'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''TNa'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc_1 tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_3'', s(MV ''TNa'' tid0),+ s(AV ''B'' tid0), s(MV ''Text5'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_udkey_A_3_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid2, LN ''Kab'' tid1,+ s(AV ''B'' tid0), s(MV ''Text3'' tid2)+ |}+ ( K ( s(AV ''A'' tid2) ) ( s(AV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_udkey_state) A_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_udkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_udkey_P &+ ( tid1, isoiec_9798_2_5_udkey_P_2 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1), LN ''Kab'' tid1,+ s(MV ''TVPa'' tid1), s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''TVPa'' tid0, s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_1'', LN ''TVPa'' tid0,+ s(MV ''Kab'' tid0), s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_5_udkey_state) B_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_5_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_5_udkey_B_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_5_udkey_P &+ ( tid1, isoiec_9798_2_5_udkey_P_2 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1), LN ''Kab'' tid1,+ LN ''TNp'' tid1, s(MV ''Text2'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''TNp'' tid0), s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_5_enc_2_2'', s(MV ''TNp'' tid0),+ s(MV ''Kab'' tid0), s(MV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_5_udkey_P_2_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_2_6_udkey_A+where "isoiec_9798_2_6_udkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' ( sMV ''Text2'' )+ , Send ''2'' <| sAV ''A'', sAV ''P'', sN ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ , Recv ''3'' <| sAV ''P'', sAV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_6_enc_3_1'', sN ''Ra'', sMV ''Kab'',+ sMV ''B'', sMV ''Text4''+ |>+ ( sK ''A'' ''P'' ),+ sMV ''TokenPA_for_B''+ |>+ , Recv ''text_4'' <| sMV ''Text6'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''A'', sMV ''B'', sMV ''Text7'', sAV ''P'',+ sMV ''TokenPA_for_B'',+ PEnc <| sC ''isoiec_9798_2_6_enc_4'', sN ''Rpa'', sMV ''Rb'',+ sMV ''Text6''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''5'' <| sMV ''B'', sAV ''A'', sMV ''Text9'',+ PEnc <| sC ''isoiec_9798_2_6_enc_5'', sMV ''Rb'', sN ''Rpa'',+ sMV ''Text8''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_6_udkey_B+where "isoiec_9798_2_6_udkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''4'' <| sAV ''A'', sAV ''B'', sMV ''Text7'', sMV ''P'',+ PEnc <| sC ''isoiec_9798_2_6_enc_3_2'', sN ''Rb'', sMV ''Kab'',+ sAV ''A'', sMV ''Text3''+ |>+ ( PSymK ( sAV ''B'' ) ( sMV ''P'' ) ),+ PEnc <| sC ''isoiec_9798_2_6_enc_4'', sMV ''Rpa'', sN ''Rb'',+ sMV ''Text6''+ |>+ ( sMV ''Kab'' )+ |>+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''B'', sAV ''A'', sMV ''Text9'',+ PEnc <| sC ''isoiec_9798_2_6_enc_5'', sN ''Rb'', sMV ''Rpa'',+ sMV ''Text8''+ |>+ ( sMV ''Kab'' )+ |>+ ]"++role isoiec_9798_2_6_udkey_P+where "isoiec_9798_2_6_udkey_P =+ [ Recv ''2'' <| sMV ''A'', sAV ''P'', sMV ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ , Recv ''text_3'' <| sMV ''Text3'', sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''P'', sMV ''A'', sMV ''Text5'',+ PEnc <| sC ''isoiec_9798_2_6_enc_3_1'', sMV ''Ra'', sN ''Kab'',+ sMV ''B'', sMV ''Text4''+ |>+ ( PSymK ( sMV ''A'' ) ( sAV ''P'' ) ),+ PEnc <| sC ''isoiec_9798_2_6_enc_3_2'', sMV ''Rb'', sN ''Kab'',+ sMV ''A'', sMV ''Text3''+ |>+ ( PSymK ( sMV ''B'' ) ( sAV ''P'' ) )+ |>+ ]"++protocol isoiec_9798_2_6_udkey+where "isoiec_9798_2_6_udkey =+{ isoiec_9798_2_6_udkey_A, isoiec_9798_2_6_udkey_B,+ isoiec_9798_2_6_udkey_P+}"++locale restricted_isoiec_9798_2_6_udkey_state = isoiec_9798_2_6_udkey_state++type_invariant isoiec_9798_2_6_udkey_msc_typing for isoiec_9798_2_6_udkey+where "isoiec_9798_2_6_udkey_msc_typing = mk_typing+ [ ((isoiec_9798_2_6_udkey_P, ''A''), (KnownT isoiec_9798_2_6_udkey_P_2))+ , ((isoiec_9798_2_6_udkey_A, ''B''), (KnownT isoiec_9798_2_6_udkey_A_1))+ , ((isoiec_9798_2_6_udkey_P, ''B''), (KnownT isoiec_9798_2_6_udkey_P_2))+ , ((isoiec_9798_2_6_udkey_A, ''Kab''),+ (SumT (KnownT isoiec_9798_2_6_udkey_A_3) (NonceT isoiec_9798_2_6_udkey_P ''Kab'')))+ , ((isoiec_9798_2_6_udkey_B, ''Kab''),+ (SumT (KnownT isoiec_9798_2_6_udkey_B_4) (NonceT isoiec_9798_2_6_udkey_P ''Kab'')))+ , ((isoiec_9798_2_6_udkey_B, ''P''), (KnownT isoiec_9798_2_6_udkey_B_4))+ , ((isoiec_9798_2_6_udkey_P, ''Ra''), (KnownT isoiec_9798_2_6_udkey_P_2))+ , ((isoiec_9798_2_6_udkey_A, ''Rb''), (KnownT isoiec_9798_2_6_udkey_A_1))+ , ((isoiec_9798_2_6_udkey_P, ''Rb''), (KnownT isoiec_9798_2_6_udkey_P_2))+ , ((isoiec_9798_2_6_udkey_B, ''Rpa''),+ (SumT (KnownT isoiec_9798_2_6_udkey_B_4) (NonceT isoiec_9798_2_6_udkey_A ''Rpa'')))+ , ((isoiec_9798_2_6_udkey_A, ''Text1''),+ (KnownT isoiec_9798_2_6_udkey_A_1))+ , ((isoiec_9798_2_6_udkey_B, ''Text1''),+ (KnownT isoiec_9798_2_6_udkey_B_text_1))+ , ((isoiec_9798_2_6_udkey_A, ''Text2''),+ (KnownT isoiec_9798_2_6_udkey_A_text_2))+ , ((isoiec_9798_2_6_udkey_P, ''Text2''),+ (KnownT isoiec_9798_2_6_udkey_P_2))+ , ((isoiec_9798_2_6_udkey_B, ''Text3''),+ (KnownT isoiec_9798_2_6_udkey_B_4))+ , ((isoiec_9798_2_6_udkey_P, ''Text3''),+ (KnownT isoiec_9798_2_6_udkey_P_text_3))+ , ((isoiec_9798_2_6_udkey_A, ''Text4''),+ (KnownT isoiec_9798_2_6_udkey_A_3))+ , ((isoiec_9798_2_6_udkey_P, ''Text4''),+ (KnownT isoiec_9798_2_6_udkey_P_text_3))+ , ((isoiec_9798_2_6_udkey_A, ''Text5''),+ (KnownT isoiec_9798_2_6_udkey_A_3))+ , ((isoiec_9798_2_6_udkey_P, ''Text5''),+ (KnownT isoiec_9798_2_6_udkey_P_text_3))+ , ((isoiec_9798_2_6_udkey_A, ''Text6''),+ (KnownT isoiec_9798_2_6_udkey_A_text_4))+ , ((isoiec_9798_2_6_udkey_B, ''Text6''),+ (KnownT isoiec_9798_2_6_udkey_B_4))+ , ((isoiec_9798_2_6_udkey_A, ''Text7''),+ (KnownT isoiec_9798_2_6_udkey_A_text_4))+ , ((isoiec_9798_2_6_udkey_B, ''Text7''),+ (KnownT isoiec_9798_2_6_udkey_B_4))+ , ((isoiec_9798_2_6_udkey_A, ''Text8''),+ (KnownT isoiec_9798_2_6_udkey_A_5))+ , ((isoiec_9798_2_6_udkey_B, ''Text8''),+ (KnownT isoiec_9798_2_6_udkey_B_text_5))+ , ((isoiec_9798_2_6_udkey_A, ''Text9''),+ (KnownT isoiec_9798_2_6_udkey_A_5))+ , ((isoiec_9798_2_6_udkey_B, ''Text9''),+ (KnownT isoiec_9798_2_6_udkey_B_text_5))+ , ((isoiec_9798_2_6_udkey_A, ''TokenPA_for_B''),+ (KnownT isoiec_9798_2_6_udkey_A_3))+ ]"++sublocale isoiec_9798_2_6_udkey_state < isoiec_9798_2_6_udkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_2_6_udkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_2_6_udkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_2_6_udkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_3_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_3_TokenPA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_text_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_A_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_5'', s(MV ''Rb'' tid0), LN ''Rpa'' tid0,+ s(MV ''Text8'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_A_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_B_4_Kab t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_B_4_P t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_B_4_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_B_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_B_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |}+ ( s(MV ''Kab'' tid0) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_2_6_udkey_B_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_B_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_B_text_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_2_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_2_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_2_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_text_3_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_2_6_udkey_P_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_2_6_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_2_6_udkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_2_6_udkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_2_6_udkey_state) P_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_P"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "LN ''Kab'' tid0 : knows t"+ shows "False"+using facts proof(sources! " LN ''Kab'' tid0 ")+ case isoiec_9798_2_6_udkey_P_3_Kab note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case isoiec_9798_2_6_udkey_P_3_Kab_1 note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+qed (insert facts, fastsimp+)?++lemma (in restricted_isoiec_9798_2_6_udkey_state) A_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_udkey_A_3 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_udkey_state) B_secret_Kab:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_udkey_B_4 ) : steps t"+ "s(MV ''Kab'' tid0) : knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_udkey_state) A_non_injective_agreement_B:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_udkey_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_udkey_B &+ ( tid1, isoiec_9798_2_6_udkey_B_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''P'' tid1),+ s(MV ''Kab'' tid1), s(MV ''Rpa'' tid1), LN ''Rb'' tid1,+ s(MV ''Text6'' tid1), s(MV ''Text8'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''P'' tid0),+ s(MV ''Kab'' tid0), LN ''Rpa'' tid0, s(MV ''Rb'' tid0),+ s(MV ''Text6'' tid0), s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_5'', s(MV ''Rb'' tid0), LN ''Rpa'' tid0,+ s(MV ''Text8'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_udkey_B_5_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid2, LN ''Kab'' tid1,+ s(AV ''A'' tid2), s(MV ''Text3'' tid2)+ |}+ ( K ( s(AV ''B'' tid2) ) ( s(MV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc_1 tid3) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', LN ''Rpa'' tid0, LN ''Rb'' tid2,+ s(MV ''Text6'' tid2)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_udkey_A_4_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_udkey_state) B_non_injective_agreement_A:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_udkey_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_udkey_A &+ ( tid1, isoiec_9798_2_6_udkey_A_4 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Kab'' tid1), LN ''Rpa'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text6'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ s(MV ''Kab'' tid0), s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_4'', s(MV ''Rpa'' tid0), LN ''Rb'' tid0,+ s(MV ''Text6'' tid0)+ |}+ ( LN ''Kab'' tid1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_udkey_A_4_enc tid2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid2, LN ''Kab'' tid1,+ s(MV ''B'' tid2), s(MV ''Text4'' tid2)+ |}+ ( K ( s(AV ''A'' tid2) ) ( s(AV ''P'' tid2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: P_secret_Kab intro: event_predOrdI)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc tid3) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_udkey_state) A_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''P'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_udkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_udkey_P &+ ( tid1, isoiec_9798_2_6_udkey_P_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Ra'' tid1), LN ''Kab'' tid1, s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''P'' tid0),+ LN ''Ra'' tid0, s(MV ''Kab'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_1'', LN ''Ra'' tid0,+ s(MV ''Kab'' tid0), s(MV ''B'' tid0), s(MV ''Text4'' tid0)+ |}+ ( K ( s(AV ''A'' tid0) ) ( s(AV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_2_6_udkey_state) B_non_injective_agreement_P:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_2_6_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''P'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_2_6_udkey_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_2_6_udkey_P &+ ( tid1, isoiec_9798_2_6_udkey_P_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''P'' tid1),+ s(MV ''Rb'' tid1), LN ''Kab'' tid1, s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''P'' tid0),+ LN ''Rb'' tid0, s(MV ''Kab'' tid0), s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_2_6_enc_3_2'', LN ''Rb'' tid0,+ s(MV ''Kab'' tid0), s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( K ( s(AV ''B'' tid0) ) ( s(MV ''P'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_2_6_udkey_P_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++end
@@ -0,0 +1,3320 @@+theory "isoiec-9798-3_cert_auto"+imports+ "../ESPLogic"+begin++role isoiec_9798_3_1_A+where "isoiec_9798_3_1_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sMV ''Text2'',+ PSign <| sC ''isoiec_9798_3_1_sig_1'', sN ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( sPK ''A'' )+ |>+ ]"++role isoiec_9798_3_1_B+where "isoiec_9798_3_1_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Text2'',+ PSign <| sC ''isoiec_9798_3_1_sig_1'', sMV ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( PAsymPK ( sMV ''A'' ) )+ |>+ ]"++protocol isoiec_9798_3_1+where "isoiec_9798_3_1 = { isoiec_9798_3_1_A, isoiec_9798_3_1_B }"++locale restricted_isoiec_9798_3_1_state = isoiec_9798_3_1_state++type_invariant isoiec_9798_3_1_msc_typing for isoiec_9798_3_1+where "isoiec_9798_3_1_msc_typing = mk_typing+ [ ((isoiec_9798_3_1_B, ''A''), (KnownT isoiec_9798_3_1_B_1))+ , ((isoiec_9798_3_1_B, ''TNA''), (KnownT isoiec_9798_3_1_B_1))+ , ((isoiec_9798_3_1_A, ''Text1''), (KnownT isoiec_9798_3_1_A_text_1))+ , ((isoiec_9798_3_1_B, ''Text1''), (KnownT isoiec_9798_3_1_B_1))+ , ((isoiec_9798_3_1_A, ''Text2''), (KnownT isoiec_9798_3_1_A_text_1))+ , ((isoiec_9798_3_1_B, ''Text2''), (KnownT isoiec_9798_3_1_B_1))+ ]"++sublocale isoiec_9798_3_1_state < isoiec_9798_3_1_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_3_1_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_3_1_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_3_1_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_1_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_1_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_1_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_1_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_1_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_3_1_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_3_1_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_3_1_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_1_B"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_1_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_1_A &+ ( tid1, isoiec_9798_3_1_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_1_sig_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( SK ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_1_A_1_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_3_2_A+where "isoiec_9798_3_2_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'',+ PSign <| sC ''isoiec_9798_3_2_sig_2'', sN ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ ( sPK ''A'' )+ |>+ ]"++role isoiec_9798_3_2_B+where "isoiec_9798_3_2_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'',+ PSign <| sC ''isoiec_9798_3_2_sig_2'', sMV ''Ra'', sN ''Rb'', sAV ''B'',+ sMV ''Text2''+ |>+ ( sPK ''A'' )+ |>+ ]"++protocol isoiec_9798_3_2+where "isoiec_9798_3_2 = { isoiec_9798_3_2_A, isoiec_9798_3_2_B }"++locale restricted_isoiec_9798_3_2_state = isoiec_9798_3_2_state++type_invariant isoiec_9798_3_2_msc_typing for isoiec_9798_3_2+where "isoiec_9798_3_2_msc_typing = mk_typing+ [ ((isoiec_9798_3_2_A, ''B''), (KnownT isoiec_9798_3_2_A_1))+ , ((isoiec_9798_3_2_B, ''Ra''), (KnownT isoiec_9798_3_2_B_2))+ , ((isoiec_9798_3_2_A, ''Rb''), (KnownT isoiec_9798_3_2_A_1))+ , ((isoiec_9798_3_2_A, ''Text1''), (KnownT isoiec_9798_3_2_A_1))+ , ((isoiec_9798_3_2_B, ''Text1''), (KnownT isoiec_9798_3_2_B_text_1))+ , ((isoiec_9798_3_2_A, ''Text2''), (KnownT isoiec_9798_3_2_A_text_2))+ , ((isoiec_9798_3_2_B, ''Text2''), (KnownT isoiec_9798_3_2_B_2))+ , ((isoiec_9798_3_2_A, ''Text3''), (KnownT isoiec_9798_3_2_A_text_2))+ , ((isoiec_9798_3_2_B, ''Text3''), (KnownT isoiec_9798_3_2_B_2))+ ]"++sublocale isoiec_9798_3_2_state < isoiec_9798_3_2_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_3_2_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_3_2_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_3_2_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_B_2_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_2_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_3_2_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_3_2_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_3_2_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_2_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_2_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_2_A &+ ( tid1, isoiec_9798_3_2_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra'' tid0),+ LN ''Rb'' tid0, s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_2_sig_2'', s(MV ''Ra'' tid0), LN ''Rb'' tid0,+ s(AV ''B'' tid0), s(MV ''Text2'' tid0)+ |}+ ( SK ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_2_A_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_3_3_A+where "isoiec_9798_3_3_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sMV ''Text2'',+ PSign <| sC ''isoiec_9798_3_3_sig_1'', sN ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( sPK ''A'' )+ |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text4'',+ PSign <| sC ''isoiec_9798_3_3_sig_2'', sMV ''TNB'', sAV ''A'',+ sMV ''Text3''+ |>+ ( sPK ''B'' )+ |>+ ]"++role isoiec_9798_3_3_B+where "isoiec_9798_3_3_B =+ [ Send ''leak_B'' ( sN ''TNB'' )+ , Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Text2'',+ PSign <| sC ''isoiec_9798_3_3_sig_1'', sMV ''TNA'', sAV ''B'',+ sMV ''Text1''+ |>+ ( PAsymPK ( sMV ''A'' ) )+ |>+ , Recv ''text_2'' <| sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sMV ''A'', sAV ''B'', sMV ''Text4'',+ PSign <| sC ''isoiec_9798_3_3_sig_2'', sN ''TNB'', sMV ''A'',+ sMV ''Text3''+ |>+ ( sPK ''B'' )+ |>+ ]"++protocol isoiec_9798_3_3+where "isoiec_9798_3_3 = { isoiec_9798_3_3_A, isoiec_9798_3_3_B }"++locale restricted_isoiec_9798_3_3_state = isoiec_9798_3_3_state++type_invariant isoiec_9798_3_3_msc_typing for isoiec_9798_3_3+where "isoiec_9798_3_3_msc_typing = mk_typing+ [ ((isoiec_9798_3_3_B, ''A''), (KnownT isoiec_9798_3_3_B_1))+ , ((isoiec_9798_3_3_B, ''TNA''), (KnownT isoiec_9798_3_3_B_1))+ , ((isoiec_9798_3_3_A, ''TNB''), (KnownT isoiec_9798_3_3_A_2))+ , ((isoiec_9798_3_3_A, ''Text1''), (KnownT isoiec_9798_3_3_A_text_1))+ , ((isoiec_9798_3_3_B, ''Text1''), (KnownT isoiec_9798_3_3_B_1))+ , ((isoiec_9798_3_3_A, ''Text2''), (KnownT isoiec_9798_3_3_A_text_1))+ , ((isoiec_9798_3_3_B, ''Text2''), (KnownT isoiec_9798_3_3_B_1))+ , ((isoiec_9798_3_3_A, ''Text3''), (KnownT isoiec_9798_3_3_A_2))+ , ((isoiec_9798_3_3_B, ''Text3''), (KnownT isoiec_9798_3_3_B_text_2))+ , ((isoiec_9798_3_3_A, ''Text4''), (KnownT isoiec_9798_3_3_A_2))+ , ((isoiec_9798_3_3_B, ''Text4''), (KnownT isoiec_9798_3_3_B_text_2))+ ]"++sublocale isoiec_9798_3_3_state < isoiec_9798_3_3_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_3_3_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_3_3_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_3_3_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_3_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_3_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_A_2_TNB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_3_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_3_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_3_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_3_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_3_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_3_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_3_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_3_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_3_B_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_3_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_3_3_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_3_3_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_3_3_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_3_A"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_3_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_3_B &+ ( tid1, isoiec_9798_3_3_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), LN ''TNB'' tid1,+ s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNB'' tid0),+ s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_3_sig_2'', s(MV ''TNB'' tid0),+ s(AV ''A'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_3_B_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_3_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_3_B"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_3_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_3_A &+ ( tid1, isoiec_9798_3_3_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_3_sig_1'', s(MV ''TNA'' tid0),+ s(AV ''B'' tid0), s(MV ''Text1'' tid0)+ |}+ ( SK ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_3_A_1_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_3_4_A+where "isoiec_9798_3_4_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''RB'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'',+ PSign <| sC ''isoiec_9798_3_4_sig_1'', sN ''RA'', sMV ''RB'', sMV ''B'',+ sMV ''Text2''+ |>+ ( sPK ''A'' )+ |>+ , Recv ''3'' <| sMV ''B'', sAV ''A'', sMV ''Text5'',+ PSign <| sC ''isoiec_9798_3_4_sig_2'', sMV ''RB'', sN ''RA'', sAV ''A'',+ sMV ''Text4''+ |>+ ( PAsymPK ( sMV ''B'' ) )+ |>+ ]"++role isoiec_9798_3_4_B+where "isoiec_9798_3_4_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''RB'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'',+ PSign <| sC ''isoiec_9798_3_4_sig_1'', sMV ''RA'', sN ''RB'', sAV ''B'',+ sMV ''Text2''+ |>+ ( sPK ''A'' )+ |>+ , Recv ''text_3'' <| sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''B'', sAV ''A'', sMV ''Text5'',+ PSign <| sC ''isoiec_9798_3_4_sig_2'', sN ''RB'', sMV ''RA'', sAV ''A'',+ sMV ''Text4''+ |>+ ( sPK ''B'' )+ |>+ ]"++protocol isoiec_9798_3_4+where "isoiec_9798_3_4 = { isoiec_9798_3_4_A, isoiec_9798_3_4_B }"++locale restricted_isoiec_9798_3_4_state = isoiec_9798_3_4_state++type_invariant isoiec_9798_3_4_msc_typing for isoiec_9798_3_4+where "isoiec_9798_3_4_msc_typing = mk_typing+ [ ((isoiec_9798_3_4_A, ''B''), (KnownT isoiec_9798_3_4_A_1))+ , ((isoiec_9798_3_4_B, ''RA''), (KnownT isoiec_9798_3_4_B_2))+ , ((isoiec_9798_3_4_A, ''RB''), (KnownT isoiec_9798_3_4_A_1))+ , ((isoiec_9798_3_4_A, ''Text1''), (KnownT isoiec_9798_3_4_A_1))+ , ((isoiec_9798_3_4_B, ''Text1''), (KnownT isoiec_9798_3_4_B_text_1))+ , ((isoiec_9798_3_4_A, ''Text2''), (KnownT isoiec_9798_3_4_A_text_2))+ , ((isoiec_9798_3_4_B, ''Text2''), (KnownT isoiec_9798_3_4_B_2))+ , ((isoiec_9798_3_4_A, ''Text3''), (KnownT isoiec_9798_3_4_A_text_2))+ , ((isoiec_9798_3_4_B, ''Text3''), (KnownT isoiec_9798_3_4_B_2))+ , ((isoiec_9798_3_4_A, ''Text4''), (KnownT isoiec_9798_3_4_A_3))+ , ((isoiec_9798_3_4_B, ''Text4''), (KnownT isoiec_9798_3_4_B_text_3))+ , ((isoiec_9798_3_4_A, ''Text5''), (KnownT isoiec_9798_3_4_A_3))+ , ((isoiec_9798_3_4_B, ''Text5''), (KnownT isoiec_9798_3_4_B_text_3))+ ]"++sublocale isoiec_9798_3_4_state < isoiec_9798_3_4_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_3_4_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_3_4_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_3_4_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_4_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_1_RB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_4_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_4_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_4_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_4_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_4_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_4_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_B_2_RA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_4_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_4_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_4_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_B_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_4_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_4_B_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_4_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_3_4_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_3_4_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_3_4_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_4_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_4_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_4_B &+ ( tid1, isoiec_9798_3_4_B_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''RA'' tid1), LN ''RB'' tid1,+ s(MV ''Text2'' tid1), s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''RA'' tid0,+ s(MV ''RB'' tid0), s(MV ''Text2'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_4_sig_2'', s(MV ''RB'' tid0), LN ''RA'' tid0,+ s(AV ''A'' tid0), s(MV ''Text4'' tid0)+ |}+ ( SK ( s(MV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_4_B_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_4_sig_1'', LN ''RA'' tid0, LN ''RB'' tid1,+ s(AV ''B'' tid1), s(MV ''Text2'' tid1)+ |}+ ( SK ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_4_A_2_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_4_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_4_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_4_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_4_A &+ ( tid1, isoiec_9798_3_4_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''RA'' tid1, s(MV ''RB'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''RA'' tid0),+ LN ''RB'' tid0, s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_4_sig_1'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(AV ''B'' tid0), s(MV ''Text2'' tid0)+ |}+ ( SK ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_4_A_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_3_5_A+where "isoiec_9798_3_5_A =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''RA'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''B'', sAV ''A'', sMV ''RB'', sMV ''Text2'' |>+ , Recv ''3'' <| sAV ''B'', sAV ''A'', sMV ''Text6'',+ PSign <| sC ''isoiec_9798_3_5_sig_1'', sMV ''RB'', sN ''RA'', sAV ''A'',+ sMV ''Text5''+ |>+ ( sPK ''B'' )+ |>+ , Recv ''text_4'' <| sMV ''Text3'', sMV ''Text4'' |>+ , Send ''4'' <| sAV ''A'', sAV ''B'', sMV ''Text4'',+ PSign <| sC ''isoiec_9798_3_5_sig_2'', sN ''RA'', sMV ''RB'', sAV ''B'',+ sMV ''Text3''+ |>+ ( sPK ''A'' )+ |>+ ]"++role isoiec_9798_3_5_B+where "isoiec_9798_3_5_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''RA'', sMV ''Text1'' |>+ , Recv ''text_2'' ( sMV ''Text2'' )+ , Send ''2'' <| sAV ''B'', sMV ''A'', sN ''RB'', sMV ''Text2'' |>+ , Recv ''text_3'' <| sMV ''Text5'', sMV ''Text6'' |>+ , Send ''3'' <| sAV ''B'', sMV ''A'', sMV ''Text6'',+ PSign <| sC ''isoiec_9798_3_5_sig_1'', sN ''RB'', sMV ''RA'', sMV ''A'',+ sMV ''Text5''+ |>+ ( sPK ''B'' )+ |>+ , Recv ''4'' <| sMV ''A'', sAV ''B'', sMV ''Text4'',+ PSign <| sC ''isoiec_9798_3_5_sig_2'', sMV ''RA'', sN ''RB'', sAV ''B'',+ sMV ''Text3''+ |>+ ( PAsymPK ( sMV ''A'' ) )+ |>+ ]"++protocol isoiec_9798_3_5+where "isoiec_9798_3_5 = { isoiec_9798_3_5_A, isoiec_9798_3_5_B }"++locale restricted_isoiec_9798_3_5_state = isoiec_9798_3_5_state++type_invariant isoiec_9798_3_5_msc_typing for isoiec_9798_3_5+where "isoiec_9798_3_5_msc_typing = mk_typing+ [ ((isoiec_9798_3_5_B, ''A''), (KnownT isoiec_9798_3_5_B_1))+ , ((isoiec_9798_3_5_B, ''RA''), (KnownT isoiec_9798_3_5_B_1))+ , ((isoiec_9798_3_5_A, ''RB''), (KnownT isoiec_9798_3_5_A_2))+ , ((isoiec_9798_3_5_A, ''Text1''), (KnownT isoiec_9798_3_5_A_text_1))+ , ((isoiec_9798_3_5_B, ''Text1''), (KnownT isoiec_9798_3_5_B_1))+ , ((isoiec_9798_3_5_A, ''Text2''), (KnownT isoiec_9798_3_5_A_2))+ , ((isoiec_9798_3_5_B, ''Text2''), (KnownT isoiec_9798_3_5_B_text_2))+ , ((isoiec_9798_3_5_A, ''Text3''), (KnownT isoiec_9798_3_5_A_text_4))+ , ((isoiec_9798_3_5_B, ''Text3''), (KnownT isoiec_9798_3_5_B_4))+ , ((isoiec_9798_3_5_A, ''Text4''), (KnownT isoiec_9798_3_5_A_text_4))+ , ((isoiec_9798_3_5_B, ''Text4''), (KnownT isoiec_9798_3_5_B_4))+ , ((isoiec_9798_3_5_A, ''Text5''), (KnownT isoiec_9798_3_5_A_3))+ , ((isoiec_9798_3_5_B, ''Text5''), (KnownT isoiec_9798_3_5_B_text_3))+ , ((isoiec_9798_3_5_A, ''Text6''), (KnownT isoiec_9798_3_5_A_3))+ , ((isoiec_9798_3_5_B, ''Text6''), (KnownT isoiec_9798_3_5_B_text_3))+ ]"++sublocale isoiec_9798_3_5_state < isoiec_9798_3_5_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_3_5_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_3_5_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_3_5_A_2_RB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_A_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_A_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_A_text_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_A_text_4_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_1_RA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_text_3_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_5_B_4_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_5_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_3_5_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_3_5_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_3_5_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_5_A"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_5_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_5_B &+ ( tid1, isoiec_9798_3_5_B_3 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), s(MV ''RA'' tid1), LN ''RB'' tid1,+ s(MV ''Text5'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''RA'' tid0,+ s(MV ''RB'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_5_sig_1'', s(MV ''RB'' tid0), LN ''RA'' tid0,+ s(AV ''A'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_5_B_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_5_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_5_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_5_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_5_A &+ ( tid1, isoiec_9798_3_5_A_4 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''RA'' tid1, s(MV ''RB'' tid1),+ s(MV ''Text3'' tid1), s(MV ''Text5'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''RA'' tid0),+ LN ''RB'' tid0, s(MV ''Text3'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_5_sig_2'', s(MV ''RA'' tid0), LN ''RB'' tid0,+ s(AV ''B'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_5_A_4_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_5_sig_1'', LN ''RB'' tid0, LN ''RA'' tid1,+ s(AV ''A'' tid1), s(MV ''Text5'' tid1)+ |}+ ( SK ( s(AV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_5_B_3_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_3_6_1_A+where "isoiec_9798_3_6_1_A =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''Ra'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sN ''Ra'', sMV ''Rb'',+ sMV ''Text3'', sMV ''TokenBA''+ |>+ , Recv ''text_3'' ( sMV ''Text4'' )+ , Send ''3'' <| sAV ''A'', sAV ''T'', sN ''Rpa'', sMV ''Rb'', sAV ''B'',+ sMV ''Text4''+ |>+ , Recv ''4'' <| sAV ''T'', sAV ''A'', sMV ''Text7'', sAV ''A'',+ sPK ''A'', sAV ''B'', sMV ''pkB'',+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_4_1'', sN ''Rpa'', sAV ''B'',+ sMV ''pkB'', sMV ''Text6''+ |>+ ( sPK ''T'' ),+ sMV ''TokenTA_for_B''+ |>+ , Send ''check_4_out'' ( PEnc <| sC ''check_4'', sMV ''TokenBA'' |>+ ( sN ''check_nonce_4'' )+ )+ , Recv ''check_4_in'' ( PEnc <| sC ''check_4'',+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_2'', sAV ''B'', sN ''Ra'',+ sMV ''Rb'', sAV ''A'', sMV ''Text2''+ |>+ ( sMV ''pkB'' )+ |>+ ( sN ''check_nonce_4'' )+ )+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''A'', sAV ''B'', sMV ''Text9'', sAV ''T'',+ sMV ''TokenTA_for_B'',+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_5'', sMV ''Rb'', sN ''Ra'',+ sAV ''B'', sAV ''A'', sMV ''Text8''+ |>+ ( sPK ''A'' )+ |>+ ]"++role isoiec_9798_3_6_1_B+where "isoiec_9798_3_6_1_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Ra'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sMV ''A'', sAV ''B'', sMV ''Ra'', sN ''Rb'',+ sMV ''Text3'',+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_2'', sAV ''B'', sMV ''Ra'',+ sN ''Rb'', sMV ''A'', sMV ''Text2''+ |>+ ( sPK ''B'' )+ |>+ , Recv ''5'' <| sMV ''A'', sAV ''B'', sMV ''Text9'', sMV ''T'',+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_4_2'', sN ''Rb'', sMV ''A'',+ sMV ''pkA'', sMV ''Text5''+ |>+ ( PAsymPK ( sMV ''T'' ) ),+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_5'', sN ''Rb'', sMV ''Ra5'',+ sAV ''B'', sMV ''A'', sMV ''Text8''+ |>+ ( sMV ''pkA'' )+ |>+ ]"++role isoiec_9798_3_6_1_T+where "isoiec_9798_3_6_1_T =+ [ Recv ''3'' <| sMV ''A'', sAV ''T'', sMV ''Rpa'', sMV ''Rb'', sMV ''B'',+ sMV ''Text4''+ |>+ , Recv ''text_4'' <| sMV ''Text5'', sMV ''Text6'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''T'', sMV ''A'', sMV ''Text7'', sMV ''A'',+ PAsymPK ( sMV ''A'' ), sMV ''B'', PAsymPK ( sMV ''B'' ),+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_4_1'', sMV ''Rpa'', sMV ''B'',+ PAsymPK ( sMV ''B'' ), sMV ''Text6''+ |>+ ( sPK ''T'' ),+ PSign <| sC ''isoiec_9798_3_6_opt_1_sig_4_2'', sMV ''Rb'', sMV ''A'',+ PAsymPK ( sMV ''A'' ), sMV ''Text5''+ |>+ ( sPK ''T'' )+ |>+ ]"++protocol isoiec_9798_3_6_1+where "isoiec_9798_3_6_1 =+{ isoiec_9798_3_6_1_A, isoiec_9798_3_6_1_B, isoiec_9798_3_6_1_T }"++locale restricted_isoiec_9798_3_6_1_state = isoiec_9798_3_6_1_state++type_invariant isoiec_9798_3_6_1_msc_typing for isoiec_9798_3_6_1+where "isoiec_9798_3_6_1_msc_typing = mk_typing+ [ ((isoiec_9798_3_6_1_B, ''A''), (KnownT isoiec_9798_3_6_1_B_1))+ , ((isoiec_9798_3_6_1_T, ''A''), (KnownT isoiec_9798_3_6_1_T_3))+ , ((isoiec_9798_3_6_1_T, ''B''), (KnownT isoiec_9798_3_6_1_T_3))+ , ((isoiec_9798_3_6_1_B, ''Ra''), (KnownT isoiec_9798_3_6_1_B_1))+ , ((isoiec_9798_3_6_1_B, ''Ra5''), (KnownT isoiec_9798_3_6_1_B_5))+ , ((isoiec_9798_3_6_1_A, ''Rb''), (KnownT isoiec_9798_3_6_1_A_2))+ , ((isoiec_9798_3_6_1_T, ''Rb''), (KnownT isoiec_9798_3_6_1_T_3))+ , ((isoiec_9798_3_6_1_T, ''Rpa''), (KnownT isoiec_9798_3_6_1_T_3))+ , ((isoiec_9798_3_6_1_B, ''T''), (KnownT isoiec_9798_3_6_1_B_5))+ , ((isoiec_9798_3_6_1_A, ''Text1''), (KnownT isoiec_9798_3_6_1_A_text_1))+ , ((isoiec_9798_3_6_1_B, ''Text1''), (KnownT isoiec_9798_3_6_1_B_1))+ , ((isoiec_9798_3_6_1_A, ''Text2''),+ (KnownT isoiec_9798_3_6_1_A_check_4_in))+ , ((isoiec_9798_3_6_1_B, ''Text2''), (KnownT isoiec_9798_3_6_1_B_text_2))+ , ((isoiec_9798_3_6_1_A, ''Text3''), (KnownT isoiec_9798_3_6_1_A_2))+ , ((isoiec_9798_3_6_1_B, ''Text3''), (KnownT isoiec_9798_3_6_1_B_text_2))+ , ((isoiec_9798_3_6_1_A, ''Text4''), (KnownT isoiec_9798_3_6_1_A_text_3))+ , ((isoiec_9798_3_6_1_T, ''Text4''), (KnownT isoiec_9798_3_6_1_T_3))+ , ((isoiec_9798_3_6_1_B, ''Text5''), (KnownT isoiec_9798_3_6_1_B_5))+ , ((isoiec_9798_3_6_1_T, ''Text5''), (KnownT isoiec_9798_3_6_1_T_text_4))+ , ((isoiec_9798_3_6_1_A, ''Text6''), (KnownT isoiec_9798_3_6_1_A_4))+ , ((isoiec_9798_3_6_1_T, ''Text6''), (KnownT isoiec_9798_3_6_1_T_text_4))+ , ((isoiec_9798_3_6_1_A, ''Text7''), (KnownT isoiec_9798_3_6_1_A_4))+ , ((isoiec_9798_3_6_1_T, ''Text7''), (KnownT isoiec_9798_3_6_1_T_text_4))+ , ((isoiec_9798_3_6_1_A, ''Text8''), (KnownT isoiec_9798_3_6_1_A_text_5))+ , ((isoiec_9798_3_6_1_B, ''Text8''), (KnownT isoiec_9798_3_6_1_B_5))+ , ((isoiec_9798_3_6_1_A, ''Text9''), (KnownT isoiec_9798_3_6_1_A_text_5))+ , ((isoiec_9798_3_6_1_B, ''Text9''), (KnownT isoiec_9798_3_6_1_B_5))+ , ((isoiec_9798_3_6_1_A, ''TokenBA''), (KnownT isoiec_9798_3_6_1_A_2))+ , ((isoiec_9798_3_6_1_A, ''TokenTA_for_B''),+ (KnownT isoiec_9798_3_6_1_A_4))+ , ((isoiec_9798_3_6_1_B, ''pkA''), (KnownT isoiec_9798_3_6_1_B_5))+ , ((isoiec_9798_3_6_1_A, ''pkB''), (KnownT isoiec_9798_3_6_1_A_4))+ ]"++sublocale isoiec_9798_3_6_1_state < isoiec_9798_3_6_1_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_3_6_1_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_3_6_1_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_3_6_1_A_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_2_TokenBA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_4_TokenTA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_4_pkB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_check_4_in_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''check_4'',+ {| LC ''isoiec_9798_3_6_opt_1_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_3_6_1_A_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_A_text_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_1_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_5_Ra5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_5_T t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_5_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_B_5_pkA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_3_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_3_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_3_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_3_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_text_4_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_text_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_1_T_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_3_6_1_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_3_6_1_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_3_6_1_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_1_A"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_1_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_1_B &+ ( tid1, isoiec_9798_3_6_1_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), s(MV ''Ra'' tid1), LN ''Rb'' tid1,+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''check_4'',+ {| LC ''isoiec_9798_3_6_opt_1_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! " LN ''check_nonce_4'' tid0 ")+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_6_1_A_check_4_out_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_4_1'', LN ''Rpa'' tid0,+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text6'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_1_T_4_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_6_1_B_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_6_1_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_1_B"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_1_B_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_1_A &+ ( tid1, isoiec_9798_3_6_1_A_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text8'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra5'' tid0),+ LN ''Rb'' tid0, s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_4_2'', LN ''Rb'' tid0,+ s(MV ''A'' tid0), s(MV ''pkA'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_1_T_4_enc_1 tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_5'', LN ''Rb'' tid0,+ s(MV ''Ra5'' tid0), s(AV ''B'' tid0), s(MV ''A'' tid0),+ s(MV ''Text8'' tid0)+ |}+ ( SK ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_1_A_5_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_6_1_state) A_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_1_A"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_1_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_1_T &+ ( tid1, isoiec_9798_3_6_1_T_4 ) : steps t &+ {| s(MV ''B'' tid1), s(AV ''T'' tid1), s(MV ''Rpa'' tid1),+ PK ( s(MV ''B'' tid1) ), s(MV ''Text6'' tid1)+ |} = {| s(AV ''B'' tid0), s(AV ''T'' tid0), LN ''Rpa'' tid0,+ s(MV ''pkB'' tid0), s(MV ''Text6'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_4_1'', LN ''Rpa'' tid0,+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text6'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_1_T_4_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_6_1_state) B_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_1_B"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_1_B_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_1_T &+ ( tid1, isoiec_9798_3_6_1_T_4 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''T'' tid1), s(MV ''Rb'' tid1),+ PK ( s(MV ''A'' tid1) ), s(MV ''Text5'' tid1)+ |} = {| s(MV ''A'' tid0), s(MV ''T'' tid0), LN ''Rb'' tid0,+ s(MV ''pkA'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_1_sig_4_2'', LN ''Rb'' tid0,+ s(MV ''A'' tid0), s(MV ''pkA'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_1_T_4_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_3_6_2_A+where "isoiec_9798_3_6_2_A =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''Ra'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sN ''Ra'', sMV ''Rb'',+ sMV ''Text3'', sMV ''TokenBA''+ |>+ , Recv ''text_3'' ( sMV ''Text4'' )+ , Send ''3'' <| sAV ''A'', sAV ''T'', sN ''Rpa'', sMV ''Rb'', sAV ''B'',+ sMV ''Text4''+ |>+ , Recv ''4'' <| sAV ''T'', sAV ''A'', sMV ''Text7'', sAV ''A'',+ sPK ''A'', sAV ''B'', sMV ''pkB'', sMV ''TokenTA''+ |>+ , Send ''check_4_out'' ( PEnc <| sC ''check_4'', sMV ''TokenTA'',+ sMV ''TokenBA''+ |>+ ( sN ''check_nonce_4'' )+ )+ , Recv ''check_4_in'' ( PEnc <| sC ''check_4'',+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_4'', sN ''Rpa'', sMV ''Rb'',+ sAV ''A'', sMV ''pkA'', sAV ''B'', sMV ''pkB'', sMV ''Text5''+ |>+ ( sPK ''T'' ),+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_2'', sAV ''B'', sN ''Ra'',+ sMV ''Rb'', sAV ''A'', sMV ''Text2''+ |>+ ( sMV ''pkB'' )+ |>+ ( sN ''check_nonce_4'' )+ )+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''A'', sAV ''B'', sN ''Rpa'', sMV ''Text9'',+ sAV ''T'', sMV ''TokenTA'',+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_5'', sMV ''Rb'', sN ''Ra'',+ sAV ''B'', sAV ''A'', sMV ''Text8''+ |>+ ( sPK ''A'' )+ |>+ ]"++role isoiec_9798_3_6_2_B+where "isoiec_9798_3_6_2_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''Ra'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sMV ''A'', sAV ''B'', sMV ''Ra'', sN ''Rb'',+ sMV ''Text3'',+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_2'', sAV ''B'', sMV ''Ra'',+ sN ''Rb'', sMV ''A'', sMV ''Text2''+ |>+ ( sPK ''B'' )+ |>+ , Recv ''5'' <| sMV ''A'', sAV ''B'', sMV ''Rpa'', sMV ''Text9'',+ sMV ''T'',+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_4'', sMV ''Rpa'', sN ''Rb'',+ sMV ''A'', sMV ''pkA'', sAV ''B'', sMV ''pkB'', sMV ''Text5''+ |>+ ( PAsymPK ( sMV ''T'' ) ),+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_5'', sN ''Rb'', sMV ''Ra5'',+ sAV ''B'', sMV ''A'', sMV ''Text8''+ |>+ ( sMV ''pkA'' )+ |>+ ]"++role isoiec_9798_3_6_2_T+where "isoiec_9798_3_6_2_T =+ [ Recv ''3'' <| sMV ''A'', sAV ''T'', sMV ''Rpa'', sMV ''Rb'', sMV ''B'',+ sMV ''Text4''+ |>+ , Recv ''text_4'' <| sMV ''Text5'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''T'', sMV ''A'', sMV ''Text7'', sMV ''A'',+ PAsymPK ( sMV ''A'' ), sMV ''B'', PAsymPK ( sMV ''B'' ),+ PSign <| sC ''isoiec_9798_3_6_opt_2_sig_4'', sMV ''Rpa'', sMV ''Rb'',+ sMV ''A'', PAsymPK ( sMV ''A'' ), sMV ''B'', PAsymPK ( sMV ''B'' ),+ sMV ''Text5''+ |>+ ( sPK ''T'' )+ |>+ ]"++protocol isoiec_9798_3_6_2+where "isoiec_9798_3_6_2 =+{ isoiec_9798_3_6_2_A, isoiec_9798_3_6_2_B, isoiec_9798_3_6_2_T }"++locale restricted_isoiec_9798_3_6_2_state = isoiec_9798_3_6_2_state++type_invariant isoiec_9798_3_6_2_msc_typing for isoiec_9798_3_6_2+where "isoiec_9798_3_6_2_msc_typing = mk_typing+ [ ((isoiec_9798_3_6_2_B, ''A''), (KnownT isoiec_9798_3_6_2_B_1))+ , ((isoiec_9798_3_6_2_T, ''A''), (KnownT isoiec_9798_3_6_2_T_3))+ , ((isoiec_9798_3_6_2_T, ''B''), (KnownT isoiec_9798_3_6_2_T_3))+ , ((isoiec_9798_3_6_2_B, ''Ra''), (KnownT isoiec_9798_3_6_2_B_1))+ , ((isoiec_9798_3_6_2_B, ''Ra5''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_6_2_A, ''Rb''), (KnownT isoiec_9798_3_6_2_A_2))+ , ((isoiec_9798_3_6_2_T, ''Rb''), (KnownT isoiec_9798_3_6_2_T_3))+ , ((isoiec_9798_3_6_2_B, ''Rpa''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_6_2_T, ''Rpa''), (KnownT isoiec_9798_3_6_2_T_3))+ , ((isoiec_9798_3_6_2_B, ''T''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_6_2_A, ''Text1''), (KnownT isoiec_9798_3_6_2_A_text_1))+ , ((isoiec_9798_3_6_2_B, ''Text1''), (KnownT isoiec_9798_3_6_2_B_1))+ , ((isoiec_9798_3_6_2_A, ''Text2''),+ (KnownT isoiec_9798_3_6_2_A_check_4_in))+ , ((isoiec_9798_3_6_2_B, ''Text2''), (KnownT isoiec_9798_3_6_2_B_text_2))+ , ((isoiec_9798_3_6_2_A, ''Text3''), (KnownT isoiec_9798_3_6_2_A_2))+ , ((isoiec_9798_3_6_2_B, ''Text3''), (KnownT isoiec_9798_3_6_2_B_text_2))+ , ((isoiec_9798_3_6_2_A, ''Text4''), (KnownT isoiec_9798_3_6_2_A_text_3))+ , ((isoiec_9798_3_6_2_T, ''Text4''), (KnownT isoiec_9798_3_6_2_T_3))+ , ((isoiec_9798_3_6_2_A, ''Text5''),+ (KnownT isoiec_9798_3_6_2_A_check_4_in))+ , ((isoiec_9798_3_6_2_B, ''Text5''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_6_2_T, ''Text5''), (KnownT isoiec_9798_3_6_2_T_text_4))+ , ((isoiec_9798_3_6_2_A, ''Text7''), (KnownT isoiec_9798_3_6_2_A_4))+ , ((isoiec_9798_3_6_2_T, ''Text7''), (KnownT isoiec_9798_3_6_2_T_text_4))+ , ((isoiec_9798_3_6_2_A, ''Text8''), (KnownT isoiec_9798_3_6_2_A_text_5))+ , ((isoiec_9798_3_6_2_B, ''Text8''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_6_2_A, ''Text9''), (KnownT isoiec_9798_3_6_2_A_text_5))+ , ((isoiec_9798_3_6_2_B, ''Text9''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_6_2_A, ''TokenBA''), (KnownT isoiec_9798_3_6_2_A_2))+ , ((isoiec_9798_3_6_2_A, ''TokenTA''), (KnownT isoiec_9798_3_6_2_A_4))+ , ((isoiec_9798_3_6_2_A, ''pkA''),+ (KnownT isoiec_9798_3_6_2_A_check_4_in))+ , ((isoiec_9798_3_6_2_B, ''pkA''), (KnownT isoiec_9798_3_6_2_B_5))+ , ((isoiec_9798_3_6_2_A, ''pkB''), (KnownT isoiec_9798_3_6_2_A_4))+ , ((isoiec_9798_3_6_2_B, ''pkB''), (KnownT isoiec_9798_3_6_2_B_5))+ ]"++sublocale isoiec_9798_3_6_2_state < isoiec_9798_3_6_2_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_3_6_2_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_3_6_2_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_3_6_2_A_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_2_TokenBA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_4_TokenTA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_4_pkB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_check_4_in_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''check_4'',+ {| {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |},+ {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_3_6_2_A_check_4_in_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''check_4'',+ {| {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |},+ {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_3_6_2_A_check_4_in_pkA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''check_4'',+ {| {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |},+ {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_3_6_2_A_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_A_text_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_1_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_Ra5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_T t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_pkA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_B_5_pkB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_3_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_3_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_3_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_3_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_text_4_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_6_2_T_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_6_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_3_6_2_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_3_6_2_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_3_6_2_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_2_A"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_2_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_2_B &+ ( tid1, isoiec_9798_3_6_2_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), s(MV ''Ra'' tid1), LN ''Rb'' tid1,+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''check_4'',+ {| {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |},+ {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! " LN ''check_nonce_4'' tid0 ")+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_6_2_A_check_4_out_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_2_T_4_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_6_2_B_2_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_6_2_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_2_B"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_2_B_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_2_A &+ ( tid1, isoiec_9798_3_6_2_A_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text8'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra5'' tid0),+ LN ''Rb'' tid0, s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(MV ''A'' tid0), s(MV ''pkA'' tid0), s(AV ''B'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_2_T_4_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_5'', LN ''Rb'' tid0,+ s(MV ''Ra5'' tid0), s(AV ''B'' tid0), s(MV ''A'' tid0),+ s(MV ''Text8'' tid0)+ |}+ ( SK ( s(MV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_2_A_5_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_6_2_state) A_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_2_A"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_2_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_2_T &+ ( tid1, isoiec_9798_3_6_2_T_4 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''T'' tid1),+ s(MV ''Rpa'' tid1), s(MV ''Rb'' tid1), PK ( s(MV ''A'' tid1) ),+ PK ( s(MV ''B'' tid1) ), s(MV ''Text5'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(AV ''T'' tid0),+ LN ''Rpa'' tid0, s(MV ''Rb'' tid0), s(MV ''pkA'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''check_4'',+ {| {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |},+ {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_2'', s(AV ''B'' tid0),+ LN ''Ra'' tid0, s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''Text2'' tid0)+ |}+ ( inv(s(MV ''pkB'' tid0)) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! " LN ''check_nonce_4'' tid0 ")+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_6_2_A_check_4_out_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(AV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_2_T_4_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_6_2_state) B_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_6_2_B"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_6_2_B_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_6_2_T &+ ( tid1, isoiec_9798_3_6_2_T_4 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''T'' tid1),+ s(MV ''Rpa'' tid1), s(MV ''Rb'' tid1), PK ( s(MV ''A'' tid1) ),+ PK ( s(MV ''B'' tid1) ), s(MV ''Text5'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''T'' tid0),+ s(MV ''Rpa'' tid0), LN ''Rb'' tid0, s(MV ''pkA'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_6_opt_2_sig_4'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(MV ''A'' tid0), s(MV ''pkA'' tid0), s(AV ''B'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text5'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_6_2_T_4_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_3_7_1_A+where "isoiec_9798_3_7_1_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' ( sMV ''Text2'' )+ , Send ''2'' <| sAV ''A'', sAV ''T'', sN ''Rpa'', sMV ''Rb'', sAV ''A'',+ sMV ''B'', sMV ''Text2''+ |>+ , Recv ''3'' <| sAV ''T'', sAV ''A'', sMV ''Text5'', sAV ''A'',+ sPK ''A'', sMV ''B'', sMV ''pkB'',+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_3_1'', sN ''Rpa'', sMV ''B'',+ sMV ''pkB'', sMV ''Text4''+ |>+ ( sPK ''T'' ),+ sMV ''TokenTA_for_B''+ |>+ , Recv ''text_4'' <| sMV ''Text6'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''A'', sMV ''B'', sN ''Rpa'', sMV ''Text7'',+ sAV ''T'', sMV ''TokenTA_for_B'',+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_4'', sMV ''Rb'', sN ''Ra'',+ sMV ''B'', sAV ''A'', sMV ''Text6''+ |>+ ( sPK ''A'' )+ |>+ , Recv ''5'' <| sAV ''A'', sMV ''B'', sN ''Ra'', sMV ''Rb'',+ sMV ''Text9'',+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_5'', sN ''Ra'', sMV ''Rb'',+ sAV ''A'', sMV ''B'', sMV ''Text8''+ |>+ ( sMV ''pkB'' )+ |>+ ]"++role isoiec_9798_3_7_1_B+where "isoiec_9798_3_7_1_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''4'' <| sAV ''A'', sAV ''B'', sMV ''Rpa'', sMV ''Text9'',+ sMV ''T'',+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_3_2'', sN ''Rb'', sAV ''A'',+ sMV ''pkA'', sMV ''Text3''+ |>+ ( PAsymPK ( sMV ''T'' ) ),+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_4'', sN ''Rb'', sMV ''Ra'',+ sAV ''B'', sAV ''A'', sMV ''Text6''+ |>+ ( sMV ''pkA'' )+ |>+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''A'', sAV ''B'', sMV ''Ra'', sN ''Rb'',+ sMV ''Text9'',+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_5'', sMV ''Ra'', sN ''Rb'',+ sAV ''A'', sAV ''B'', sMV ''Text8''+ |>+ ( sPK ''B'' )+ |>+ ]"++role isoiec_9798_3_7_1_T+where "isoiec_9798_3_7_1_T =+ [ Recv ''2'' <| sMV ''A'', sAV ''T'', sMV ''Rpa'', sMV ''Rb'', sMV ''A'',+ sMV ''B'', sMV ''Text2''+ |>+ , Recv ''text_3'' <| sMV ''Text3'', sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''T'', sMV ''A'', sMV ''Text5'', sMV ''A'',+ PAsymPK ( sMV ''A'' ), sMV ''B'', PAsymPK ( sMV ''B'' ),+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_3_1'', sMV ''Rpa'', sMV ''B'',+ PAsymPK ( sMV ''B'' ), sMV ''Text4''+ |>+ ( sPK ''T'' ),+ PSign <| sC ''isoiec_9798_3_7_opt_1_sig_3_2'', sMV ''Rb'', sMV ''A'',+ PAsymPK ( sMV ''A'' ), sMV ''Text3''+ |>+ ( sPK ''T'' )+ |>+ ]"++protocol isoiec_9798_3_7_1+where "isoiec_9798_3_7_1 =+{ isoiec_9798_3_7_1_A, isoiec_9798_3_7_1_B, isoiec_9798_3_7_1_T }"++locale restricted_isoiec_9798_3_7_1_state = isoiec_9798_3_7_1_state++type_invariant isoiec_9798_3_7_1_msc_typing for isoiec_9798_3_7_1+where "isoiec_9798_3_7_1_msc_typing = mk_typing+ [ ((isoiec_9798_3_7_1_T, ''A''), (KnownT isoiec_9798_3_7_1_T_2))+ , ((isoiec_9798_3_7_1_A, ''B''), (KnownT isoiec_9798_3_7_1_A_1))+ , ((isoiec_9798_3_7_1_T, ''B''), (KnownT isoiec_9798_3_7_1_T_2))+ , ((isoiec_9798_3_7_1_B, ''Ra''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_1_A, ''Rb''), (KnownT isoiec_9798_3_7_1_A_1))+ , ((isoiec_9798_3_7_1_T, ''Rb''), (KnownT isoiec_9798_3_7_1_T_2))+ , ((isoiec_9798_3_7_1_B, ''Rpa''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_1_T, ''Rpa''), (KnownT isoiec_9798_3_7_1_T_2))+ , ((isoiec_9798_3_7_1_B, ''T''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_1_A, ''Text1''), (KnownT isoiec_9798_3_7_1_A_1))+ , ((isoiec_9798_3_7_1_B, ''Text1''), (KnownT isoiec_9798_3_7_1_B_text_1))+ , ((isoiec_9798_3_7_1_A, ''Text2''), (KnownT isoiec_9798_3_7_1_A_text_2))+ , ((isoiec_9798_3_7_1_T, ''Text2''), (KnownT isoiec_9798_3_7_1_T_2))+ , ((isoiec_9798_3_7_1_B, ''Text3''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_1_T, ''Text3''), (KnownT isoiec_9798_3_7_1_T_text_3))+ , ((isoiec_9798_3_7_1_A, ''Text4''), (KnownT isoiec_9798_3_7_1_A_3))+ , ((isoiec_9798_3_7_1_T, ''Text4''), (KnownT isoiec_9798_3_7_1_T_text_3))+ , ((isoiec_9798_3_7_1_A, ''Text5''), (KnownT isoiec_9798_3_7_1_A_3))+ , ((isoiec_9798_3_7_1_T, ''Text5''), (KnownT isoiec_9798_3_7_1_T_text_3))+ , ((isoiec_9798_3_7_1_A, ''Text6''), (KnownT isoiec_9798_3_7_1_A_text_4))+ , ((isoiec_9798_3_7_1_B, ''Text6''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_1_A, ''Text7''), (KnownT isoiec_9798_3_7_1_A_text_4))+ , ((isoiec_9798_3_7_1_A, ''Text8''), (KnownT isoiec_9798_3_7_1_A_5))+ , ((isoiec_9798_3_7_1_B, ''Text8''), (KnownT isoiec_9798_3_7_1_B_text_5))+ , ((isoiec_9798_3_7_1_A, ''Text9''), (KnownT isoiec_9798_3_7_1_A_5))+ , ((isoiec_9798_3_7_1_B, ''Text9''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_1_A, ''TokenTA_for_B''),+ (KnownT isoiec_9798_3_7_1_A_3))+ , ((isoiec_9798_3_7_1_B, ''pkA''), (KnownT isoiec_9798_3_7_1_B_4))+ , ((isoiec_9798_3_7_1_A, ''pkB''), (KnownT isoiec_9798_3_7_1_A_3))+ ]"++sublocale isoiec_9798_3_7_1_state < isoiec_9798_3_7_1_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_3_7_1_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_3_7_1_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_3_7_1_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_3_TokenTA_for_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_3_pkB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_text_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_A_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_T t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_4_pkA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_B_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_2_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_2_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_2_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_text_3_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_1_T_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_1_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_3_7_1_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_3_7_1_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_3_7_1_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_1_A"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_1_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_1_B &+ ( tid1, isoiec_9798_3_7_1_B_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''Ra'' tid1), LN ''Rb'' tid1,+ s(MV ''Text8'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_1_sig_3_1'', LN ''Rpa'' tid0,+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text4'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_1_T_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_1_sig_5'', LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text8'' tid0)+ |}+ ( SK ( s(MV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_1_B_5_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_7_1_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_1_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_1_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_1_A &+ ( tid1, isoiec_9798_3_7_1_A_4 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text6'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra'' tid0),+ LN ''Rb'' tid0, s(MV ''Text6'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_1_sig_3_2'', LN ''Rb'' tid0,+ s(AV ''A'' tid0), s(MV ''pkA'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_1_T_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_1_sig_4'', LN ''Rb'' tid0,+ s(MV ''Ra'' tid0), s(AV ''B'' tid0), s(AV ''A'' tid0),+ s(MV ''Text6'' tid0)+ |}+ ( SK ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_1_A_4_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_7_1_state) A_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_1_A"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_1_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_1_T &+ ( tid1, isoiec_9798_3_7_1_T_3 ) : steps t &+ {| s(MV ''B'' tid1), s(AV ''T'' tid1), s(MV ''Rpa'' tid1),+ PK ( s(MV ''B'' tid1) ), s(MV ''Text4'' tid1)+ |} = {| s(MV ''B'' tid0), s(AV ''T'' tid0), LN ''Rpa'' tid0,+ s(MV ''pkB'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_1_sig_3_1'', LN ''Rpa'' tid0,+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text4'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_1_T_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_7_1_state) B_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_1_B"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_1_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_1_T &+ ( tid1, isoiec_9798_3_7_1_T_3 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''T'' tid1), s(MV ''Rb'' tid1),+ PK ( s(MV ''A'' tid1) ), s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''T'' tid0), LN ''Rb'' tid0,+ s(MV ''pkA'' tid0), s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_1_sig_3_2'', LN ''Rb'' tid0,+ s(AV ''A'' tid0), s(MV ''pkA'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_1_T_3_enc_1 tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_3_7_2_A+where "isoiec_9798_3_7_2_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' ( sMV ''Text2'' )+ , Send ''2'' <| sAV ''A'', sAV ''T'', sN ''Rpa'', sMV ''Rb'', sAV ''A'',+ sMV ''B'', sMV ''Text2''+ |>+ , Recv ''3'' <| sAV ''T'', sAV ''A'', sMV ''Text5'', sAV ''A'',+ sPK ''A'', sMV ''B'', sMV ''pkB'', sMV ''TokenTA''+ |>+ , Send ''check_3_out'' ( PEnc <| sC ''check_4'', sMV ''TokenTA'' |>+ ( sN ''check_nonce_4'' )+ )+ , Recv ''check_3_in'' ( PEnc <| sC ''check_4'',+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_3'', sN ''Rpa'', sMV ''Rb'',+ sAV ''A'', sMV ''pkA'', sMV ''B'', sMV ''pkB'', sMV ''Text3''+ |>+ ( sPK ''T'' )+ |>+ ( sN ''check_nonce_4'' )+ )+ , Recv ''text_4'' <| sMV ''Text6'', sMV ''Text7'' |>+ , Send ''4'' <| sAV ''A'', sMV ''B'', sN ''Rpa'', sMV ''Text7'',+ sAV ''T'', sMV ''TokenTA'',+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_4'', sMV ''Rb'', sN ''Ra'',+ sMV ''B'', sAV ''A'', sMV ''Text6''+ |>+ ( sPK ''A'' )+ |>+ , Recv ''5'' <| sAV ''A'', sMV ''B'', sN ''Ra'', sMV ''Rb'',+ sMV ''Text9'',+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_5'', sN ''Ra'', sMV ''Rb'',+ sAV ''A'', sMV ''B'', sMV ''Text8''+ |>+ ( sMV ''pkB'' )+ |>+ ]"++role isoiec_9798_3_7_2_B+where "isoiec_9798_3_7_2_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''4'' <| sAV ''A'', sAV ''B'', sMV ''Rpa'', sMV ''Text9'',+ sMV ''T'',+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_3'', sMV ''Rpa'', sN ''Rb'',+ sAV ''A'', sMV ''pkA'', sAV ''B'', sMV ''pkB'', sMV ''Text3''+ |>+ ( PAsymPK ( sMV ''T'' ) ),+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_4'', sN ''Rb'', sMV ''Ra'',+ sAV ''B'', sAV ''A'', sMV ''Text6''+ |>+ ( sMV ''pkA'' )+ |>+ , Recv ''text_5'' <| sMV ''Text8'', sMV ''Text9'' |>+ , Send ''5'' <| sAV ''A'', sAV ''B'', sMV ''Ra'', sN ''Rb'',+ sMV ''Text9'',+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_5'', sMV ''Ra'', sN ''Rb'',+ sAV ''A'', sAV ''B'', sMV ''Text8''+ |>+ ( sPK ''B'' )+ |>+ ]"++role isoiec_9798_3_7_2_T+where "isoiec_9798_3_7_2_T =+ [ Recv ''2'' <| sMV ''A'', sAV ''T'', sMV ''Rpa'', sMV ''Rb'', sMV ''A'',+ sMV ''B'', sMV ''Text2''+ |>+ , Recv ''text_3'' <| sMV ''Text3'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''T'', sMV ''A'', sMV ''Text5'', sMV ''A'',+ PAsymPK ( sMV ''A'' ), sMV ''B'', PAsymPK ( sMV ''B'' ),+ PSign <| sC ''isoiec_9798_3_7_opt_2_sig_3'', sMV ''Rpa'', sMV ''Rb'',+ sMV ''A'', PAsymPK ( sMV ''A'' ), sMV ''B'', PAsymPK ( sMV ''B'' ),+ sMV ''Text3''+ |>+ ( sPK ''T'' )+ |>+ ]"++protocol isoiec_9798_3_7_2+where "isoiec_9798_3_7_2 =+{ isoiec_9798_3_7_2_A, isoiec_9798_3_7_2_B, isoiec_9798_3_7_2_T }"++locale restricted_isoiec_9798_3_7_2_state = isoiec_9798_3_7_2_state++type_invariant isoiec_9798_3_7_2_msc_typing for isoiec_9798_3_7_2+where "isoiec_9798_3_7_2_msc_typing = mk_typing+ [ ((isoiec_9798_3_7_2_T, ''A''), (KnownT isoiec_9798_3_7_2_T_2))+ , ((isoiec_9798_3_7_2_A, ''B''), (KnownT isoiec_9798_3_7_2_A_1))+ , ((isoiec_9798_3_7_2_T, ''B''), (KnownT isoiec_9798_3_7_2_T_2))+ , ((isoiec_9798_3_7_2_B, ''Ra''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_7_2_A, ''Rb''), (KnownT isoiec_9798_3_7_2_A_1))+ , ((isoiec_9798_3_7_2_T, ''Rb''), (KnownT isoiec_9798_3_7_2_T_2))+ , ((isoiec_9798_3_7_2_B, ''Rpa''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_7_2_T, ''Rpa''), (KnownT isoiec_9798_3_7_2_T_2))+ , ((isoiec_9798_3_7_2_B, ''T''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_7_2_A, ''Text1''), (KnownT isoiec_9798_3_7_2_A_1))+ , ((isoiec_9798_3_7_2_B, ''Text1''), (KnownT isoiec_9798_3_7_2_B_text_1))+ , ((isoiec_9798_3_7_2_A, ''Text2''), (KnownT isoiec_9798_3_7_2_A_text_2))+ , ((isoiec_9798_3_7_2_T, ''Text2''), (KnownT isoiec_9798_3_7_2_T_2))+ , ((isoiec_9798_3_7_2_A, ''Text3''),+ (KnownT isoiec_9798_3_7_2_A_check_3_in))+ , ((isoiec_9798_3_7_2_B, ''Text3''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_7_2_T, ''Text3''), (KnownT isoiec_9798_3_7_2_T_text_3))+ , ((isoiec_9798_3_7_2_A, ''Text5''), (KnownT isoiec_9798_3_7_2_A_3))+ , ((isoiec_9798_3_7_2_T, ''Text5''), (KnownT isoiec_9798_3_7_2_T_text_3))+ , ((isoiec_9798_3_7_2_A, ''Text6''), (KnownT isoiec_9798_3_7_2_A_text_4))+ , ((isoiec_9798_3_7_2_B, ''Text6''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_7_2_A, ''Text7''), (KnownT isoiec_9798_3_7_2_A_text_4))+ , ((isoiec_9798_3_7_2_A, ''Text8''), (KnownT isoiec_9798_3_7_2_A_5))+ , ((isoiec_9798_3_7_2_B, ''Text8''), (KnownT isoiec_9798_3_7_2_B_text_5))+ , ((isoiec_9798_3_7_2_A, ''Text9''), (KnownT isoiec_9798_3_7_2_A_5))+ , ((isoiec_9798_3_7_2_B, ''Text9''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_7_2_A, ''TokenTA''), (KnownT isoiec_9798_3_7_2_A_3))+ , ((isoiec_9798_3_7_2_A, ''pkA''),+ (KnownT isoiec_9798_3_7_2_A_check_3_in))+ , ((isoiec_9798_3_7_2_B, ''pkA''), (KnownT isoiec_9798_3_7_2_B_4))+ , ((isoiec_9798_3_7_2_A, ''pkB''), (KnownT isoiec_9798_3_7_2_A_3))+ , ((isoiec_9798_3_7_2_B, ''pkB''), (KnownT isoiec_9798_3_7_2_B_4))+ ]"++sublocale isoiec_9798_3_7_2_state < isoiec_9798_3_7_2_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_3_7_2_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_3_7_2_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_3_7_2_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_3_TokenTA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_3_pkB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_check_3_in_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''check_4'',+ {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_3_7_2_A_check_3_in_pkA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''check_4'',+ {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (isoiec_9798_3_7_2_A_text_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_text_4_Text7 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_A_5_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_T t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_Text6 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_Text9 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_pkA t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_4_pkB t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_B_text_5_Text8 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_2_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_2_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_2_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_2_Rpa t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_text_3_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_3_7_2_T_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_3_7_2_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_3_7_2_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_3_7_2_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_3_7_2_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_2_A"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_2_A_5 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_2_B &+ ( tid1, isoiec_9798_3_7_2_B_5 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''Ra'' tid1), LN ''Rb'' tid1,+ s(MV ''Text8'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(MV ''Text8'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''check_4'',+ {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! " LN ''check_nonce_4'' tid0 ")+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_7_2_A_check_3_out_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_2_T_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_5'', LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''B'' tid0),+ s(MV ''Text8'' tid0)+ |}+ ( SK ( s(MV ''B'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_2_B_5_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_7_2_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_2_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_2_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_2_A &+ ( tid1, isoiec_9798_3_7_2_A_4 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text6'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra'' tid0),+ LN ''Rb'' tid0, s(MV ''Text6'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(AV ''A'' tid0), s(MV ''pkA'' tid0), s(AV ''B'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_2_T_3_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_4'', LN ''Rb'' tid0,+ s(MV ''Ra'' tid0), s(AV ''B'' tid0), s(AV ''A'' tid0),+ s(MV ''Text6'' tid0)+ |}+ ( SK ( s(AV ''A'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_2_A_4_enc tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_7_2_state) A_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_2_A"+ "RLKR(s(AV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_2_A_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_2_T &+ ( tid1, isoiec_9798_3_7_2_T_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''T'' tid1),+ s(MV ''Rpa'' tid1), s(MV ''Rb'' tid1), PK ( s(MV ''A'' tid1) ),+ PK ( s(MV ''B'' tid1) ), s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), s(AV ''T'' tid0),+ LN ''Rpa'' tid0, s(MV ''Rb'' tid0), s(MV ''pkA'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''check_4'',+ {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |},+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) )+ |}+ ( LN ''check_nonce_4'' tid0 ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! " LN ''check_nonce_4'' tid0 ")+ qed (insert facts, fastsimp+)?+ next+ case (isoiec_9798_3_7_2_A_check_3_out_enc tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', LN ''Rpa'' tid0,+ s(MV ''Rb'' tid0), s(AV ''A'' tid0), s(MV ''pkA'' tid0),+ s(MV ''B'' tid0), s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(AV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_2_T_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_3_7_2_state) B_non_injective_agreement_T:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_3_7_2_B"+ "RLKR(s(MV ''T'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_3_7_2_B_4 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_3_7_2_T &+ ( tid1, isoiec_9798_3_7_2_T_3 ) : steps t &+ {| s(MV ''A'' tid1), s(MV ''B'' tid1), s(AV ''T'' tid1),+ s(MV ''Rpa'' tid1), s(MV ''Rb'' tid1), PK ( s(MV ''A'' tid1) ),+ PK ( s(MV ''B'' tid1) ), s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''T'' tid0),+ s(MV ''Rpa'' tid0), LN ''Rb'' tid0, s(MV ''pkA'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Enc {| LC ''isoiec_9798_3_7_opt_2_sig_3'', s(MV ''Rpa'' tid0),+ LN ''Rb'' tid0, s(AV ''A'' tid0), s(MV ''pkA'' tid0), s(AV ''B'' tid0),+ s(MV ''pkB'' tid0), s(MV ''Text3'' tid0)+ |}+ ( SK ( s(MV ''T'' tid0) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_3_7_2_T_3_enc tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++end
@@ -0,0 +1,899 @@+theory "isoiec-9798-4-bdkey_cert_auto"+imports+ "../ESPLogic"+begin++role isoiec_9798_4_1_bdkey_A+where "isoiec_9798_4_1_bdkey_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''TNA'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_1_ccf_1'', sN ''TNA'', sAV ''B'', sMV ''Text1''+ |>+ |>+ ]"++role isoiec_9798_4_1_bdkey_B+where "isoiec_9798_4_1_bdkey_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''TNA'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', sKbd (MVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_1_ccf_1'', sMV ''TNA'', sAV ''B'', sMV ''Text1''+ |>+ |>+ ]"++protocol isoiec_9798_4_1_bdkey+where "isoiec_9798_4_1_bdkey =+{ isoiec_9798_4_1_bdkey_A, isoiec_9798_4_1_bdkey_B }"++locale restricted_isoiec_9798_4_1_bdkey_state = isoiec_9798_4_1_bdkey_state++type_invariant isoiec_9798_4_1_bdkey_msc_typing for isoiec_9798_4_1_bdkey+where "isoiec_9798_4_1_bdkey_msc_typing = mk_typing+ [ ((isoiec_9798_4_1_bdkey_B, ''A''), (KnownT isoiec_9798_4_1_bdkey_B_1))+ , ((isoiec_9798_4_1_bdkey_B, ''TNA''),+ (KnownT isoiec_9798_4_1_bdkey_B_1))+ , ((isoiec_9798_4_1_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_4_1_bdkey_A_text_1))+ , ((isoiec_9798_4_1_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_4_1_bdkey_B_1))+ , ((isoiec_9798_4_1_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_4_1_bdkey_A_text_1))+ , ((isoiec_9798_4_1_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_4_1_bdkey_B_1))+ ]"++sublocale isoiec_9798_4_1_bdkey_state < isoiec_9798_4_1_bdkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_4_1_bdkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_4_1_bdkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_4_1_bdkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_1_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_bdkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_1_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_bdkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_1_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_bdkey_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_1_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_bdkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_1_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_bdkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_1_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_4_1_bdkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_4_1_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_4_1_bdkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_1_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_1_bdkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_1_bdkey_A &+ ( tid1, isoiec_9798_4_1_bdkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) |},+ LC ''isoiec_9798_4_1_ccf_1'', s(MV ''TNA'' tid0), s(AV ''B'' tid0),+ s(MV ''Text1'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_1_bdkey_A_1_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_4_2_bdkey_A+where "isoiec_9798_4_2_bdkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'', sMV ''Rb'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (MVar ''B'') |>,+ sC ''isoiec_9798_4_2_ccf_2'', sMV ''Rb'', sMV ''B'', sMV ''Text2''+ |>+ |>+ ]"++role isoiec_9798_4_2_bdkey_B+where "isoiec_9798_4_2_bdkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'', sN ''Rb'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_2_ccf_2'', sN ''Rb'', sAV ''B'', sMV ''Text2''+ |>+ |>+ ]"++protocol isoiec_9798_4_2_bdkey+where "isoiec_9798_4_2_bdkey =+{ isoiec_9798_4_2_bdkey_A, isoiec_9798_4_2_bdkey_B }"++locale restricted_isoiec_9798_4_2_bdkey_state = isoiec_9798_4_2_bdkey_state++type_invariant isoiec_9798_4_2_bdkey_msc_typing for isoiec_9798_4_2_bdkey+where "isoiec_9798_4_2_bdkey_msc_typing = mk_typing+ [ ((isoiec_9798_4_2_bdkey_A, ''B''), (KnownT isoiec_9798_4_2_bdkey_A_1))+ , ((isoiec_9798_4_2_bdkey_A, ''Rb''), (KnownT isoiec_9798_4_2_bdkey_A_1))+ , ((isoiec_9798_4_2_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_4_2_bdkey_A_1))+ , ((isoiec_9798_4_2_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_4_2_bdkey_B_text_1))+ , ((isoiec_9798_4_2_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_4_2_bdkey_A_text_2))+ , ((isoiec_9798_4_2_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_4_2_bdkey_B_2))+ , ((isoiec_9798_4_2_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_4_2_bdkey_A_text_2))+ , ((isoiec_9798_4_2_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_4_2_bdkey_B_2))+ ]"++sublocale isoiec_9798_4_2_bdkey_state < isoiec_9798_4_2_bdkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_4_2_bdkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_4_2_bdkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_4_2_bdkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_bdkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_4_2_bdkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_4_2_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_4_2_bdkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_2_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_2_bdkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_2_bdkey_A &+ ( tid1, isoiec_9798_4_2_bdkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(MV ''Rb'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''Rb'' tid0,+ s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_2_ccf_2'', LN ''Rb'' tid0, s(AV ''B'' tid0),+ s(MV ''Text2'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_2_bdkey_A_2_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_4_3_bdkey_A+where "isoiec_9798_4_3_bdkey_A =+ [ Send ''leak_A'' ( sN ''TNa'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''TNa'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_3_ccf_1'', sN ''TNa'', sAV ''B'', sMV ''Text1''+ |>+ |>+ , Recv ''2'' <| sAV ''B'', sAV ''A'', sMV ''TNb'', sMV ''Text4'',+ sMV ''Text3'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_3_ccf_2'', sMV ''TNb'', sAV ''A'', sMV ''Text3''+ |>+ |>+ ]"++role isoiec_9798_4_3_bdkey_B+where "isoiec_9798_4_3_bdkey_B =+ [ Send ''leak_B'' ( sN ''TNb'' )+ , Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''TNa'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', sKbd (MVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_3_ccf_1'', sMV ''TNa'', sAV ''B'', sMV ''Text1''+ |>+ |>+ , Recv ''text_2'' <| sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''B'', sMV ''A'', sN ''TNb'', sMV ''Text4'',+ sMV ''Text3'',+ PHash <| <| sC ''CCF'', sKbd (MVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_3_ccf_2'', sN ''TNb'', sMV ''A'', sMV ''Text3''+ |>+ |>+ ]"++protocol isoiec_9798_4_3_bdkey+where "isoiec_9798_4_3_bdkey =+{ isoiec_9798_4_3_bdkey_A, isoiec_9798_4_3_bdkey_B }"++locale restricted_isoiec_9798_4_3_bdkey_state = isoiec_9798_4_3_bdkey_state++type_invariant isoiec_9798_4_3_bdkey_msc_typing for isoiec_9798_4_3_bdkey+where "isoiec_9798_4_3_bdkey_msc_typing = mk_typing+ [ ((isoiec_9798_4_3_bdkey_B, ''A''), (KnownT isoiec_9798_4_3_bdkey_B_1))+ , ((isoiec_9798_4_3_bdkey_B, ''TNa''),+ (KnownT isoiec_9798_4_3_bdkey_B_1))+ , ((isoiec_9798_4_3_bdkey_A, ''TNb''),+ (KnownT isoiec_9798_4_3_bdkey_A_2))+ , ((isoiec_9798_4_3_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_4_3_bdkey_A_text_1))+ , ((isoiec_9798_4_3_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_4_3_bdkey_B_1))+ , ((isoiec_9798_4_3_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_4_3_bdkey_A_text_1))+ , ((isoiec_9798_4_3_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_4_3_bdkey_B_1))+ , ((isoiec_9798_4_3_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_4_3_bdkey_A_2))+ , ((isoiec_9798_4_3_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_4_3_bdkey_B_text_2))+ , ((isoiec_9798_4_3_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_4_3_bdkey_A_2))+ , ((isoiec_9798_4_3_bdkey_B, ''Text4''),+ (KnownT isoiec_9798_4_3_bdkey_B_text_2))+ ]"++sublocale isoiec_9798_4_3_bdkey_state < isoiec_9798_4_3_bdkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_4_3_bdkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_4_3_bdkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_4_3_bdkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_A_2_TNb t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_B_1_TNa t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_bdkey_B_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_4_3_bdkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_4_3_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_4_3_bdkey_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_3_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_3_bdkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_3_bdkey_B &+ ( tid1, isoiec_9798_4_3_bdkey_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), LN ''TNb'' tid1,+ s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNb'' tid0),+ s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_3_ccf_2'', s(MV ''TNb'' tid0), s(AV ''A'' tid0),+ s(MV ''Text3'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_3_bdkey_B_2_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_3_bdkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_3_bdkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_3_bdkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_3_bdkey_A &+ ( tid1, isoiec_9798_4_3_bdkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNa'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNa'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''B'' tid0) ) ( s(MV ''A'' tid0) ) |},+ LC ''isoiec_9798_4_3_ccf_1'', s(MV ''TNa'' tid0), s(AV ''B'' tid0),+ s(MV ''Text1'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_3_bdkey_A_1_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_4_4_bdkey_A+where "isoiec_9798_4_4_bdkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sN ''Ra'', sMV ''Text3'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (MVar ''B'') |>,+ sC ''isoiec_9798_4_4_ccf_2'', sN ''Ra'', sMV ''Rb'', sMV ''B'',+ sMV ''Text2''+ |>+ |>+ , Recv ''3'' <| sMV ''B'', sAV ''A'', sMV ''Text5'', sMV ''Text4'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (MVar ''B'') |>,+ sC ''isoiec_9798_4_4_ccf_3'', sMV ''Rb'', sN ''Ra'', sMV ''Text4''+ |>+ |>+ ]"++role isoiec_9798_4_4_bdkey_B+where "isoiec_9798_4_4_bdkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Ra'', sMV ''Text3'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_4_ccf_2'', sMV ''Ra'', sN ''Rb'', sAV ''B'',+ sMV ''Text2''+ |>+ |>+ , Recv ''text_3'' <| sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''B'', sAV ''A'', sMV ''Text5'', sMV ''Text4'',+ PHash <| <| sC ''CCF'', sKbd (AVar ''A'') (AVar ''B'') |>,+ sC ''isoiec_9798_4_4_ccf_3'', sN ''Rb'', sMV ''Ra'', sMV ''Text4''+ |>+ |>+ ]"++protocol isoiec_9798_4_4_bdkey+where "isoiec_9798_4_4_bdkey =+{ isoiec_9798_4_4_bdkey_A, isoiec_9798_4_4_bdkey_B }"++locale restricted_isoiec_9798_4_4_bdkey_state = isoiec_9798_4_4_bdkey_state++type_invariant isoiec_9798_4_4_bdkey_msc_typing for isoiec_9798_4_4_bdkey+where "isoiec_9798_4_4_bdkey_msc_typing = mk_typing+ [ ((isoiec_9798_4_4_bdkey_A, ''B''), (KnownT isoiec_9798_4_4_bdkey_A_1))+ , ((isoiec_9798_4_4_bdkey_B, ''Ra''), (KnownT isoiec_9798_4_4_bdkey_B_2))+ , ((isoiec_9798_4_4_bdkey_A, ''Rb''), (KnownT isoiec_9798_4_4_bdkey_A_1))+ , ((isoiec_9798_4_4_bdkey_A, ''Text1''),+ (KnownT isoiec_9798_4_4_bdkey_A_1))+ , ((isoiec_9798_4_4_bdkey_B, ''Text1''),+ (KnownT isoiec_9798_4_4_bdkey_B_text_1))+ , ((isoiec_9798_4_4_bdkey_A, ''Text2''),+ (KnownT isoiec_9798_4_4_bdkey_A_text_2))+ , ((isoiec_9798_4_4_bdkey_B, ''Text2''),+ (KnownT isoiec_9798_4_4_bdkey_B_2))+ , ((isoiec_9798_4_4_bdkey_A, ''Text3''),+ (KnownT isoiec_9798_4_4_bdkey_A_text_2))+ , ((isoiec_9798_4_4_bdkey_B, ''Text3''),+ (KnownT isoiec_9798_4_4_bdkey_B_2))+ , ((isoiec_9798_4_4_bdkey_A, ''Text4''),+ (KnownT isoiec_9798_4_4_bdkey_A_3))+ , ((isoiec_9798_4_4_bdkey_B, ''Text4''),+ (KnownT isoiec_9798_4_4_bdkey_B_text_3))+ , ((isoiec_9798_4_4_bdkey_A, ''Text5''),+ (KnownT isoiec_9798_4_4_bdkey_A_3))+ , ((isoiec_9798_4_4_bdkey_B, ''Text5''),+ (KnownT isoiec_9798_4_4_bdkey_B_text_3))+ ]"++sublocale isoiec_9798_4_4_bdkey_state < isoiec_9798_4_4_bdkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_4_4_bdkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_4_4_bdkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_4_4_bdkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_B_2_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_B_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_bdkey_B_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_bdkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_4_4_bdkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_4_4_bdkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_4_4_bdkey_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_4_bdkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_4_bdkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_4_bdkey_B &+ ( tid1, isoiec_9798_4_4_bdkey_B_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''Ra'' tid1), LN ''Rb'' tid1,+ s(MV ''Text2'' tid1), s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(MV ''Text2'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''A'' tid0) ) ( s(MV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_4_ccf_3'', s(MV ''Rb'' tid0), LN ''Ra'' tid0,+ s(MV ''Text4'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_bdkey_B_3_hash tid1) note_unified facts = this facts+ hence "Kbd ( s(AV ''A'' tid1) )+ ( s(AV ''B'' tid1) ) = Kbd ( s(AV ''A'' tid0) ) ( s(MV ''B'' tid0) )"+ by simp note facts = this facts+ thus ?thesis proof(cases rule: Kbd_cases)+ case noswap note_unified facts = this facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid1) ) |},+ LC ''isoiec_9798_4_4_ccf_2'', LN ''Ra'' tid0, LN ''Rb'' tid1,+ s(AV ''B'' tid1), s(MV ''Text2'' tid1)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_bdkey_A_2_hash tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ next+ case swapped note_unified facts = this facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''A'' tid0) ) ( s(AV ''A'' tid1) ) |},+ LC ''isoiec_9798_4_4_ccf_2'', LN ''Ra'' tid0, LN ''Rb'' tid1,+ s(AV ''A'' tid0), s(MV ''Text2'' tid1)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_bdkey_A_2_hash tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_4_bdkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_4_bdkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_4_bdkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_4_bdkey_A &+ ( tid1, isoiec_9798_4_4_bdkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra'' tid0),+ LN ''Rb'' tid0, s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', Kbd ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_4_ccf_2'', s(MV ''Ra'' tid0), LN ''Rb'' tid0,+ s(AV ''B'' tid0), s(MV ''Text2'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_bdkey_A_2_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++end
@@ -0,0 +1,874 @@+theory "isoiec-9798-4-udkey_cert_auto"+imports+ "../ESPLogic"+begin++role isoiec_9798_4_1_udkey_A+where "isoiec_9798_4_1_udkey_A =+ [ Send ''leak_A'' ( sN ''TNA'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''TNA'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', sK ''A'' ''B'' |>, sC ''isoiec_9798_4_1_ccf_1'',+ sN ''TNA'', sMV ''Text1''+ |>+ |>+ ]"++role isoiec_9798_4_1_udkey_B+where "isoiec_9798_4_1_udkey_B =+ [ Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''TNA'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', PSymK ( sMV ''A'' ) ( sAV ''B'' ) |>,+ sC ''isoiec_9798_4_1_ccf_1'', sMV ''TNA'', sMV ''Text1''+ |>+ |>+ ]"++protocol isoiec_9798_4_1_udkey+where "isoiec_9798_4_1_udkey =+{ isoiec_9798_4_1_udkey_A, isoiec_9798_4_1_udkey_B }"++locale restricted_isoiec_9798_4_1_udkey_state = isoiec_9798_4_1_udkey_state++type_invariant isoiec_9798_4_1_udkey_msc_typing for isoiec_9798_4_1_udkey+where "isoiec_9798_4_1_udkey_msc_typing = mk_typing+ [ ((isoiec_9798_4_1_udkey_B, ''A''), (KnownT isoiec_9798_4_1_udkey_B_1))+ , ((isoiec_9798_4_1_udkey_B, ''TNA''),+ (KnownT isoiec_9798_4_1_udkey_B_1))+ , ((isoiec_9798_4_1_udkey_A, ''Text1''),+ (KnownT isoiec_9798_4_1_udkey_A_text_1))+ , ((isoiec_9798_4_1_udkey_B, ''Text1''),+ (KnownT isoiec_9798_4_1_udkey_B_1))+ , ((isoiec_9798_4_1_udkey_A, ''Text2''),+ (KnownT isoiec_9798_4_1_udkey_A_text_1))+ , ((isoiec_9798_4_1_udkey_B, ''Text2''),+ (KnownT isoiec_9798_4_1_udkey_B_1))+ ]"++sublocale isoiec_9798_4_1_udkey_state < isoiec_9798_4_1_udkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_4_1_udkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_4_1_udkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_4_1_udkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_1_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_udkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_1_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_udkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_1_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_udkey_B_1_TNA t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_1_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_udkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_1_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_1_udkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_1_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_4_1_udkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_4_1_udkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_4_1_udkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_1_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_1_udkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_1_udkey_A &+ ( tid1, isoiec_9798_4_1_udkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNA'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNA'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_1_ccf_1'', s(MV ''TNA'' tid0), s(MV ''Text1'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_1_udkey_A_1_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_4_2_udkey_A+where "isoiec_9798_4_2_udkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sMV ''Text3'', sMV ''Rb'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', PSymK ( sAV ''A'' ) ( sMV ''B'' ) |>,+ sC ''isoiec_9798_4_2_ccf_2'', sMV ''Rb'', sMV ''Text2''+ |>+ |>+ ]"++role isoiec_9798_4_2_udkey_B+where "isoiec_9798_4_2_udkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Text3'', sN ''Rb'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', sK ''A'' ''B'' |>, sC ''isoiec_9798_4_2_ccf_2'',+ sN ''Rb'', sMV ''Text2''+ |>+ |>+ ]"++protocol isoiec_9798_4_2_udkey+where "isoiec_9798_4_2_udkey =+{ isoiec_9798_4_2_udkey_A, isoiec_9798_4_2_udkey_B }"++locale restricted_isoiec_9798_4_2_udkey_state = isoiec_9798_4_2_udkey_state++type_invariant isoiec_9798_4_2_udkey_msc_typing for isoiec_9798_4_2_udkey+where "isoiec_9798_4_2_udkey_msc_typing = mk_typing+ [ ((isoiec_9798_4_2_udkey_A, ''B''), (KnownT isoiec_9798_4_2_udkey_A_1))+ , ((isoiec_9798_4_2_udkey_A, ''Rb''), (KnownT isoiec_9798_4_2_udkey_A_1))+ , ((isoiec_9798_4_2_udkey_A, ''Text1''),+ (KnownT isoiec_9798_4_2_udkey_A_1))+ , ((isoiec_9798_4_2_udkey_B, ''Text1''),+ (KnownT isoiec_9798_4_2_udkey_B_text_1))+ , ((isoiec_9798_4_2_udkey_A, ''Text2''),+ (KnownT isoiec_9798_4_2_udkey_A_text_2))+ , ((isoiec_9798_4_2_udkey_B, ''Text2''),+ (KnownT isoiec_9798_4_2_udkey_B_2))+ , ((isoiec_9798_4_2_udkey_A, ''Text3''),+ (KnownT isoiec_9798_4_2_udkey_A_text_2))+ , ((isoiec_9798_4_2_udkey_B, ''Text3''),+ (KnownT isoiec_9798_4_2_udkey_B_2))+ ]"++sublocale isoiec_9798_4_2_udkey_state < isoiec_9798_4_2_udkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_4_2_udkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_4_2_udkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_4_2_udkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_2_udkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_2_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_4_2_udkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_4_2_udkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_4_2_udkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_2_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_2_udkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_2_udkey_A &+ ( tid1, isoiec_9798_4_2_udkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), s(MV ''Rb'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), LN ''Rb'' tid0,+ s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_2_ccf_2'', LN ''Rb'' tid0, s(MV ''Text2'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_2_udkey_A_2_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_4_3_udkey_A+where "isoiec_9798_4_3_udkey_A =+ [ Send ''leak_A'' ( sN ''TNa'' )+ , Recv ''text_1'' <| sMV ''Text1'', sMV ''Text2'' |>+ , Send ''1'' <| sAV ''A'', sAV ''B'', sN ''TNa'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', sK ''A'' ''B'' |>, sC ''isoiec_9798_4_3_ccf_1'',+ sN ''TNa'', sMV ''Text1''+ |>+ |>+ , Recv ''2'' <| sAV ''B'', sAV ''A'', sMV ''TNb'', sMV ''Text4'',+ sMV ''Text3'',+ PHash <| <| sC ''CCF'', sK ''A'' ''B'' |>, sC ''isoiec_9798_4_3_ccf_2'',+ sMV ''TNb'', sMV ''Text3''+ |>+ |>+ ]"++role isoiec_9798_4_3_udkey_B+where "isoiec_9798_4_3_udkey_B =+ [ Send ''leak_B'' ( sN ''TNb'' )+ , Recv ''1'' <| sMV ''A'', sAV ''B'', sMV ''TNa'', sMV ''Text2'',+ sMV ''Text1'',+ PHash <| <| sC ''CCF'', PSymK ( sMV ''A'' ) ( sAV ''B'' ) |>,+ sC ''isoiec_9798_4_3_ccf_1'', sMV ''TNa'', sMV ''Text1''+ |>+ |>+ , Recv ''text_2'' <| sMV ''Text3'', sMV ''Text4'' |>+ , Send ''2'' <| sAV ''B'', sMV ''A'', sN ''TNb'', sMV ''Text4'',+ sMV ''Text3'',+ PHash <| <| sC ''CCF'', PSymK ( sMV ''A'' ) ( sAV ''B'' ) |>,+ sC ''isoiec_9798_4_3_ccf_2'', sN ''TNb'', sMV ''Text3''+ |>+ |>+ ]"++protocol isoiec_9798_4_3_udkey+where "isoiec_9798_4_3_udkey =+{ isoiec_9798_4_3_udkey_A, isoiec_9798_4_3_udkey_B }"++locale restricted_isoiec_9798_4_3_udkey_state = isoiec_9798_4_3_udkey_state++type_invariant isoiec_9798_4_3_udkey_msc_typing for isoiec_9798_4_3_udkey+where "isoiec_9798_4_3_udkey_msc_typing = mk_typing+ [ ((isoiec_9798_4_3_udkey_B, ''A''), (KnownT isoiec_9798_4_3_udkey_B_1))+ , ((isoiec_9798_4_3_udkey_B, ''TNa''),+ (KnownT isoiec_9798_4_3_udkey_B_1))+ , ((isoiec_9798_4_3_udkey_A, ''TNb''),+ (KnownT isoiec_9798_4_3_udkey_A_2))+ , ((isoiec_9798_4_3_udkey_A, ''Text1''),+ (KnownT isoiec_9798_4_3_udkey_A_text_1))+ , ((isoiec_9798_4_3_udkey_B, ''Text1''),+ (KnownT isoiec_9798_4_3_udkey_B_1))+ , ((isoiec_9798_4_3_udkey_A, ''Text2''),+ (KnownT isoiec_9798_4_3_udkey_A_text_1))+ , ((isoiec_9798_4_3_udkey_B, ''Text2''),+ (KnownT isoiec_9798_4_3_udkey_B_1))+ , ((isoiec_9798_4_3_udkey_A, ''Text3''),+ (KnownT isoiec_9798_4_3_udkey_A_2))+ , ((isoiec_9798_4_3_udkey_B, ''Text3''),+ (KnownT isoiec_9798_4_3_udkey_B_text_2))+ , ((isoiec_9798_4_3_udkey_A, ''Text4''),+ (KnownT isoiec_9798_4_3_udkey_A_2))+ , ((isoiec_9798_4_3_udkey_B, ''Text4''),+ (KnownT isoiec_9798_4_3_udkey_B_text_2))+ ]"++sublocale isoiec_9798_4_3_udkey_state < isoiec_9798_4_3_udkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_4_3_udkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_4_3_udkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_4_3_udkey_A_text_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_A_text_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_A_2_TNb t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_A_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_A_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_B_1_A t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_B_1_TNa t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_B_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_B_1_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_B_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_3_udkey_B_text_2_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_3_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_4_3_udkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_4_3_udkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_4_3_udkey_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_3_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_3_udkey_A_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_3_udkey_B &+ ( tid1, isoiec_9798_4_3_udkey_B_2 ) : steps t &+ {| s(MV ''A'' tid1), s(AV ''B'' tid1), LN ''TNb'' tid1,+ s(MV ''Text3'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNb'' tid0),+ s(MV ''Text3'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_3_ccf_2'', s(MV ''TNb'' tid0), s(MV ''Text3'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_3_udkey_B_2_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_3_udkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_3_udkey_B"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "RLKR(s(MV ''A'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_3_udkey_B_1 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_3_udkey_A &+ ( tid1, isoiec_9798_4_3_udkey_A_1 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), LN ''TNa'' tid1,+ s(MV ''Text1'' tid1)+ |} = {| s(MV ''A'' tid0), s(AV ''B'' tid0), s(MV ''TNa'' tid0),+ s(MV ''Text1'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(MV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_3_ccf_1'', s(MV ''TNa'' tid0), s(MV ''Text1'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_3_udkey_A_1_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++role isoiec_9798_4_4_udkey_A+where "isoiec_9798_4_4_udkey_A =+ [ Recv ''1'' <| sMV ''B'', sAV ''A'', sMV ''Rb'', sMV ''Text1'' |>+ , Recv ''text_2'' <| sMV ''Text2'', sMV ''Text3'' |>+ , Send ''2'' <| sAV ''A'', sMV ''B'', sN ''Ra'', sMV ''Text3'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', PSymK ( sAV ''A'' ) ( sMV ''B'' ) |>,+ sC ''isoiec_9798_4_4_ccf_2'', sN ''Ra'', sMV ''Rb'', sMV ''Text2''+ |>+ |>+ , Recv ''3'' <| sMV ''B'', sAV ''A'', sMV ''Text5'', sMV ''Text4'',+ PHash <| <| sC ''CCF'', PSymK ( sAV ''A'' ) ( sMV ''B'' ) |>,+ sC ''isoiec_9798_4_4_ccf_3'', sMV ''Rb'', sN ''Ra'', sMV ''Text4''+ |>+ |>+ ]"++role isoiec_9798_4_4_udkey_B+where "isoiec_9798_4_4_udkey_B =+ [ Recv ''text_1'' ( sMV ''Text1'' )+ , Send ''1'' <| sAV ''B'', sAV ''A'', sN ''Rb'', sMV ''Text1'' |>+ , Recv ''2'' <| sAV ''A'', sAV ''B'', sMV ''Ra'', sMV ''Text3'',+ sMV ''Text2'',+ PHash <| <| sC ''CCF'', sK ''A'' ''B'' |>, sC ''isoiec_9798_4_4_ccf_2'',+ sMV ''Ra'', sN ''Rb'', sMV ''Text2''+ |>+ |>+ , Recv ''text_3'' <| sMV ''Text4'', sMV ''Text5'' |>+ , Send ''3'' <| sAV ''B'', sAV ''A'', sMV ''Text5'', sMV ''Text4'',+ PHash <| <| sC ''CCF'', sK ''A'' ''B'' |>, sC ''isoiec_9798_4_4_ccf_3'',+ sN ''Rb'', sMV ''Ra'', sMV ''Text4''+ |>+ |>+ ]"++protocol isoiec_9798_4_4_udkey+where "isoiec_9798_4_4_udkey =+{ isoiec_9798_4_4_udkey_A, isoiec_9798_4_4_udkey_B }"++locale restricted_isoiec_9798_4_4_udkey_state = isoiec_9798_4_4_udkey_state++type_invariant isoiec_9798_4_4_udkey_msc_typing for isoiec_9798_4_4_udkey+where "isoiec_9798_4_4_udkey_msc_typing = mk_typing+ [ ((isoiec_9798_4_4_udkey_A, ''B''), (KnownT isoiec_9798_4_4_udkey_A_1))+ , ((isoiec_9798_4_4_udkey_B, ''Ra''), (KnownT isoiec_9798_4_4_udkey_B_2))+ , ((isoiec_9798_4_4_udkey_A, ''Rb''), (KnownT isoiec_9798_4_4_udkey_A_1))+ , ((isoiec_9798_4_4_udkey_A, ''Text1''),+ (KnownT isoiec_9798_4_4_udkey_A_1))+ , ((isoiec_9798_4_4_udkey_B, ''Text1''),+ (KnownT isoiec_9798_4_4_udkey_B_text_1))+ , ((isoiec_9798_4_4_udkey_A, ''Text2''),+ (KnownT isoiec_9798_4_4_udkey_A_text_2))+ , ((isoiec_9798_4_4_udkey_B, ''Text2''),+ (KnownT isoiec_9798_4_4_udkey_B_2))+ , ((isoiec_9798_4_4_udkey_A, ''Text3''),+ (KnownT isoiec_9798_4_4_udkey_A_text_2))+ , ((isoiec_9798_4_4_udkey_B, ''Text3''),+ (KnownT isoiec_9798_4_4_udkey_B_2))+ , ((isoiec_9798_4_4_udkey_A, ''Text4''),+ (KnownT isoiec_9798_4_4_udkey_A_3))+ , ((isoiec_9798_4_4_udkey_B, ''Text4''),+ (KnownT isoiec_9798_4_4_udkey_B_text_3))+ , ((isoiec_9798_4_4_udkey_A, ''Text5''),+ (KnownT isoiec_9798_4_4_udkey_A_3))+ , ((isoiec_9798_4_4_udkey_B, ''Text5''),+ (KnownT isoiec_9798_4_4_udkey_B_text_3))+ ]"++sublocale isoiec_9798_4_4_udkey_state < isoiec_9798_4_4_udkey_msc_typing_state+proof -+ have "(t,r,s) : approx isoiec_9798_4_4_udkey_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF isoiec_9798_4_4_udkey_msc_typing.monoTyp, completeness_cases_rule])+ case (isoiec_9798_4_4_udkey_A_1_B t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_1_Rb t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_1_Text1 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_text_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_text_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_A_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_B_2_Ra t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_B_2_Text2 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_B_2_Text3 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_B_text_3_Text4 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (isoiec_9798_4_4_udkey_B_text_3_Text5 t r s tid0) note facts = this+ then interpret state: isoiec_9798_4_4_udkey_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ qed+ thus "isoiec_9798_4_4_udkey_msc_typing_state t r s" by unfold_locales auto+qed++text{* Prove secrecy of long-term keys. *}+context isoiec_9798_4_4_udkey_state begin++ (* This rule is unsafe in general, but OK here, + as we are only reasoning about static compromise. + *)+ lemma static_longterm_key_reveal[dest!]:+ "predOrd t (LKR a) e ==> RLKR a : reveals t"+ by (auto intro: compr_predOrdI)++ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "RLKR m ~: reveals t"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_sym_ud_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ shows "False"+ using facts by (sources "K m1 m2")++ lemma longterm_sym_bd_key_secrecy:+ assumes facts:+ "Kbd m1 m2 : knows t"+ "RLKR m1 ~: reveals t"+ "RLKR m2 ~: reveals t"+ "m1 : Agent"+ "m2 : Agent"+ shows "False"+ proof -+ from facts + have "KShr (agents {m1, m2}) : knows t"+ by (auto simp: Kbd_def)+ thus ?thesis using facts+ proof (sources "KShr (agents {m1, m2})")+ qed (auto simp: agents_def Agent_def)+ qed++ lemmas ltk_secrecy =+ longterm_sym_ud_key_secrecy+ longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]+ longterm_sym_bd_key_secrecy+ longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]++end++lemma (in restricted_isoiec_9798_4_4_udkey_state) A_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_4_udkey_A"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(MV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_4_udkey_A_3 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_4_udkey_B &+ ( tid1, isoiec_9798_4_4_udkey_B_3 ) : steps t &+ {| s(AV ''A'' tid1), s(AV ''B'' tid1), s(MV ''Ra'' tid1), LN ''Rb'' tid1,+ s(MV ''Text2'' tid1), s(MV ''Text4'' tid1)+ |} = {| s(AV ''A'' tid0), s(MV ''B'' tid0), LN ''Ra'' tid0,+ s(MV ''Rb'' tid0), s(MV ''Text2'' tid0), s(MV ''Text4'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(AV ''A'' tid0) ) ( s(MV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_4_ccf_3'', s(MV ''Rb'' tid0), LN ''Ra'' tid0,+ s(MV ''Text4'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_udkey_B_3_hash tid1) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid1) ) |},+ LC ''isoiec_9798_4_4_ccf_2'', LN ''Ra'' tid0, LN ''Rb'' tid1,+ s(MV ''Text2'' tid1)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_udkey_A_2_hash tid2) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+ qed (insert facts, fastsimp+)?+qed++lemma (in restricted_isoiec_9798_4_4_udkey_state) B_non_injective_agreement:+ assumes facts:+ "roleMap r tid0 = Some isoiec_9798_4_4_udkey_B"+ "RLKR(s(AV ''A'' tid0)) ~: reveals t"+ "RLKR(s(AV ''B'' tid0)) ~: reveals t"+ "( tid0, isoiec_9798_4_4_udkey_B_2 ) : steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some isoiec_9798_4_4_udkey_A &+ ( tid1, isoiec_9798_4_4_udkey_A_2 ) : steps t &+ {| s(AV ''A'' tid1), s(MV ''B'' tid1), LN ''Ra'' tid1, s(MV ''Rb'' tid1),+ s(MV ''Text2'' tid1)+ |} = {| s(AV ''A'' tid0), s(AV ''B'' tid0), s(MV ''Ra'' tid0),+ LN ''Rb'' tid0, s(MV ''Text2'' tid0)+ |})"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! "+ Hash {| {| LC ''CCF'', K ( s(AV ''A'' tid0) ) ( s(AV ''B'' tid0) ) |},+ LC ''isoiec_9798_4_4_ccf_2'', s(MV ''Ra'' tid0), LN ''Rb'' tid0,+ s(MV ''Text2'' tid0)+ |} ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest!: ltk_secrecy)+ next+ case (isoiec_9798_4_4_udkey_A_2_hash tid1) note_unified facts = this facts+ thus ?thesis by (fastsimp intro: event_predOrdI split: if_splits)+ qed (insert facts, fastsimp+)?+qed++end
@@ -0,0 +1,417 @@+/* + * Modeled from ISO/IEC 9798-2+ * Modeler: Cas Cremers, Dec. 2010+ * Ported to scyther-proof: Simon Meier, Feb. 2011+ *+ * Modeling notes:+ * - Variant of ISO/IEC 9798-2 with bidirectional keys k[A,B].+ * - time-variant-parameters, time-stamps, and sequence numbers are+ * modeled by nonces leaked to the adversary at the start of a role.+ * - The TextX fields are chosen by the adversary.+ */+theory isoiec_9798_2_bdkey begin+++/******************************************************************************+ * Protocol 1+ ******************************************************************************+ *+ * symmetric+ * one-pass+ * unilateral+ *+ * Note: the identity B may be ommitted, if+ * (a) the environment disallows such attacks, or+ * (b) a unidirectional key is used+ * (This formulation directly stems from the standard.)+ */+protocol isoiec_9798_2_1_bdkey+{+ leak_A. A -> : TNA++ text_1. -> A: Text1, Text2+ 1. A -> B: A, B, Text2, {'isoiec_9798_2_1_enc_1', TNA, B, Text1 }k[A,B]+}++property (of isoiec_9798_2_1_bdkey)+ B_non_injective_agreement: + niagree(B_1[A,B,TNA,Text1] -> A_1[A,B,TNA,Text1], {A, B})+++/******************************************************************************+ * Protocol 2+ ******************************************************************************+ *+ * symmetric+ * two-pass+ * unilateral+ *+ * Note: the identity B may be ommitted, if+ * (a) the environment disallows such attacks, or+ * (b) a unidirectional key is used+ */+protocol isoiec_9798_2_2_bdkey+{+ text_1. -> B: Text1+ 1. B -> A: B, A, RB, Text1++ text_2. -> A: Text2, Text3+ 2. A -> B: A, B, Text3, {'isoiec_9798_2_2_enc_2', RB, B, Text2}k[B,A]+}++property (of isoiec_9798_2_2_bdkey)+ B_non_injective_agreement: + niagree(B_2[A,B,RB,Text2] -> A_2[A,B,RB,Text2], {A, B})++++/******************************************************************************+ * Protocol 3+ ******************************************************************************+ *+ * symmetric+ * two-pass+ * mutual+ *+ * Note: the identities inside the encryptions may be ommitted, if+ * (a) the environment disallows such attacks, or+ * (b) a unidirectional key is used+ */+protocol isoiec_9798_2_3_bdkey+{+ leak_A. A -> : TNA+ leak_B. B -> : TNB++ text_1. -> A: Text1, Text2+ 1. A -> B: A, B, Text2, {'isoiec_9798_2_3_enc_1', TNA, B, Text1 }k[A,B]++ text_2. -> B: Text3, Text4+ 2. B -> A: B, A, Text4, {'isoiec_9798_2_3_enc_2', TNB, A, Text3 }k[B,A]+}++properties (of isoiec_9798_2_3_bdkey)+ A_non_injective_agreement: + niagree(A_2[A,B,TNB,Text3] -> B_2[A,B,TNB,Text3], {A, B})++ B_non_injective_agreement: + niagree(B_1[A,B,TNA,Text1] -> A_1[A,B,TNA,Text1], {A, B})+++/******************************************************************************+ * Protocol 4+ ******************************************************************************+ *+ * symmetric+ * three-pass+ * mutual+ *+ * Note: the identity B inside the encryption may be ommitted, if+ * (a) the environment disallows such attacks, or+ * (b) a unidirectional key is used+ *+ */+protocol isoiec_9798_2_4_bdkey+{+ text_1. -> B: Text1+ 1. B -> A: B, A, RB, Text1++ text_2. -> A: Text2, Text3+ 2. A -> B: A, B, Text3, {'isoiec_9798_2_4_enc_1', RA, RB, B, Text2 }k[A,B]++ text_3. -> B: Text4, Text5+ 3. B -> A: B, A, Text5, {'isoiec_9798_2_4_enc_2', RB, RA, Text4 }k[A,B]+}++properties (of isoiec_9798_2_4_bdkey)+ A_non_injective_agreement: + niagree(A_3[A,B,RA,RB,Text2,Text4] -> B_3[A,B,RA,RB,Text2,Text4], {A, B})++ B_non_injective_agreement: + niagree(B_2[A,B,RA,RB,Text2] -> A_2[A,B,RA,RB,Text2], {A, B})+++/******************************************************************************+ * Protocol 5+ ******************************************************************************+ *+ * symmetric+ * ttp+ * four-pass+ * mutual+ *+ * Modeling notes:+ * - The use of TNb in message 4, as specified by the ISO standard, is+ * different from other models, in which it was TNa.+ * - Added additional identity to messages in Step 2 to avoid identity swapping.+ * - We send identity P in Step 3 in order for B to be able to lookup key k(B,P)+ */+protocol isoiec_9798_2_5_bdkey+{+ leak_A. A -> : TVPa, TNa+ leak_B. B -> : TNb+ leak_P. P -> : TNp++ text_1. -> A: Text1+ 1. A -> P: A, P, TVPa, B, Text1++ text_2. -> P: Text2, Text3, Text4+ 2. P -> : P, A, Text4, { 'isoiec_9798_2_5_enc_2_1', TVPa, Kab, A, B, Text3 }k[A,P]+ , { 'isoiec_9798_2_5_enc_2_2', TNp , Kab, A, B, Text2 }k[B,P]+ -> A: P, A, Text4, { 'isoiec_9798_2_5_enc_2_1', TVPa, Kab, A, B, Text3 }k[A,P]+ , TokenPA_for_B++ text_3. -> A: Text5, Text6+ 3. A -> : A, B, Text6, P, TokenPA_for_B+ , { 'isoiec_9798_2_5_enc_3', TNa, B, Text5 }Kab+ -> B: A, B, Text6, P, { 'isoiec_9798_2_5_enc_2_2', TNp, Kab, A, B, Text2 }k[B,P]+ , { 'isoiec_9798_2_5_enc_3', TNa, B, Text5 }Kab++ text_4. -> B: Text7, Text8+ 4. B -> A: B, A, Text8, { 'isoiec_9798_2_5_enc_4', TNb, A, Text7 }Kab+}++properties (of isoiec_9798_2_5_bdkey)+ P_secret_Kab: secret(P, -, Kab, {A, B, P})+ A_secret_Kab: secret(A, 2, Kab, {A, B, P})+ B_secret_Kab: secret(B, 3, Kab, {A, B, P})++ // Agreement properties strengthened with respect to Cas Cremers' models:+ // (a) we also verify agreement on the freshness data TNa, TNb+ // (b) we also verify agreement with the trusted third party+ //+ A_non_injective_agreement_B: + niagree(A_4[A,B,P,Kab,TNa,Text5,TNb,Text7] -> B_4[A,B,P,Kab,TNa,Text5,TNb,Text7], {A, B, P})++ B_non_injective_agreement_A: + niagree(B_3[A,B,P,Kab,TNa,Text5] -> A_3[A,B,P,Kab,TNa,Text5], {A, B, P})++ A_non_injective_agreement_P: + niagree(A_2[A,B,P,Kab,TVPa,Text3] -> P_2[A,B,P,Kab,TVPa,Text3], {A, B, P})+ B_non_injective_agreement_P: + niagree(B_3[A,B,P,Kab,TNp,Text2] -> P_2[A,B,P,Kab,TNp,Text2], {A, B, P})+++/******************************************************************************+ * Protocol 6+ ******************************************************************************+ *+ * symmetric+ * ttp+ * five-pass+ * mutual+ *+ * Modeling notes:+ * - We send identity P in Step 4 in order for B to be able to lookup key k(B,P)+ * - Added additional identity to messages in Step 3 to avoid identity swapping.+ *+ * MPA Attack reported by Mathuria:+ * - Type flaw MPA when in parallel with Abadi-Needham protocol.+ */+protocol isoiec_9798_2_6_bdkey+{+ text_1. -> B: Text1+ 1. B -> A: B, A, Rb, Text1++ text_2. -> A: Text2+ 2. A -> P: A, P, Ra, Rb, B, Text2++ text_3. -> P: Text3, Text4, Text5+ 3. P -> : P, A, Text5, {'isoiec_9798_2_6_enc_3_1', Ra, Kab, A, B, Text4}k[A,P]+ , {'isoiec_9798_2_6_enc_3_2', Rb, Kab, A, B, Text3}k[B,P]+ -> A: P, A, Text5, {'isoiec_9798_2_6_enc_3_1', Ra, Kab, A, B, Text4}k[A,P]+ , TokenPA_for_B++ text_4. -> A: Text6, Text7 + 4. A -> : A, B, Text7, P, TokenPA_for_B+ , {'isoiec_9798_2_6_enc_4', Rpa, Rb, Text6}Kab+ -> B: A, B, Text7, P, {'isoiec_9798_2_6_enc_3_2', Rb, Kab, A, B, Text3}k[B,P]+ , {'isoiec_9798_2_6_enc_4', Rpa, Rb, Text6}Kab+ + text_5. -> B: Text8, Text9+ 5. B -> A: B, A, Text9, {'isoiec_9798_2_6_enc_5', Rb, Rpa, Text8}Kab+}++properties (of isoiec_9798_2_6_bdkey)+ P_secret_Kab: secret(P, -, Kab, {A, B, P})+ A_secret_Kab: secret(A, 3, Kab, {A, B, P})+ B_secret_Kab: secret(B, 4, Kab, {A, B, P})++ // Agreement properties strengthened with respect to Cas Cremers' models:+ // (a) we also verify agreement on the freshness data + // (b) we also verify agreement with the trusted third party+ //+ A_non_injective_agreement_B: + niagree(A_5[A,B,P,Kab,Rpa,Rb,Text6,Text8] -> B_5[A,B,P,Kab,Rpa,Rb,Text6,Text8], {A, B, P})++ B_non_injective_agreement_A: + niagree(B_4[A,B,P,Kab,Rpa,Rb,Text6] -> A_4[A,B,P,Kab,Rpa,Rb,Text6], {A, B, P})++ A_non_injective_agreement_P: + niagree(A_3[A,B,P,Ra,Kab,Text4] -> P_3[A,B,P,Ra,Kab,Text4], {A, B, P})++ B_non_injective_agreement_P: + niagree(B_4[A,B,P,Rb,Kab,Text3] -> P_3[A,B,P,Rb,Kab,Text3], {A, B, P})+++/******************************************************************************+ * Protocol 5 (with the assumption that the TTP does not play other roles)+ ******************************************************************************+ *+ * symmetric+ * ttp+ * four-pass+ * mutual+ *+ * Modeling notes:+ * - The use of TNb in message 4, as specified by the ISO standard, is+ * different from other models, in which it was TNa.+ * - We MUST assume that the trusted third party does not execute the A role.+ * Otherwise, some authentication properties break (see below).+ * - We send identity P in Step 3 in order for B to be able to lookup key k[B,P]+ */+protocol isoiec_9798_2_5_special_TTP_bdkey+{+ leak_A. A -> : TVPa, TNa+ leak_B. B -> : TNb+ leak_P. P -> : TNp++ text_1. -> A: Text1+ 1. A -> P: A, P, TVPa, B, Text1++ text_2. -> P: Text2, Text3, Text4+ 2. P -> : P, A, Text4, { 'isoiec_9798_2_5_special_TTP_enc_2_1', TVPa, Kab, B, Text3 }k[A,P]+ , { 'isoiec_9798_2_5_special_TTP_enc_2_2', TNp , Kab, A, Text2 }k[B,P]+ -> A: P, A, Text4, { 'isoiec_9798_2_5_special_TTP_enc_2_1', TVPa, Kab, B, Text3 }k[A,P]+ , TokenPA_for_B++ text_3. -> A: Text5, Text6+ 3. A -> : A, B, Text6, P, TokenPA_for_B+ , { 'isoiec_9798_2_5_special_TTP_enc_3', TNa, B, Text5 }Kab+ -> B: A, B, Text6, P, { 'isoiec_9798_2_5_special_TTP_enc_2_2', TNp, Kab, A, Text2 }k[B,P]+ , { 'isoiec_9798_2_5_special_TTP_enc_3', TNa, B, Text5 }Kab++ text_4. -> B: Text7, Text8+ 4. B -> A: B, A, Text8, { 'isoiec_9798_2_5_special_TTP_enc_4', TNb, A, Text7 }Kab+}++axiom (of isoiec_9798_2_5_special_TTP_bdkey) different_actors_A_P:+ premises+ "role(0) = A"+ "role(1) = P"+ "A#0 = P#1"+ imply+ "False"++properties (of isoiec_9798_2_5_special_TTP_bdkey)+ P_secret_Kab: secret(P, -, Kab, {A, B, P})+ A_secret_Kab: secret(A, 2, Kab, {A, B, P})+ B_secret_Kab: secret(B, 3, Kab, {A, B, P})++ // Agreement properties strengthened with respect to Cas Cremers' models:+ // (a) we also verify agreement on the freshness data TNa, TNb+ // (b) we also verify agreement with the trusted third party+ // + // Note: If no axiom dependency for a property below, then it can be proven+ // without the axiom.+ + A_non_injective_agreement_B: + niagree(A_4[A,B,P,Kab,TNa,Text5,TNb,Text7] -> B_4[A,B,P,Kab,TNa,Text5,TNb,Text7], {A, B, P})++ // depends on 'different_actors_A_P'+ B_non_injective_agreement_A: + niagree(B_3[A,B,P,Kab,TNa,Text5] -> A_3[A,B,P,Kab,TNa,Text5], {A, B, P})++ // depends on 'different_actors_A_P'+ A_non_injective_agreement_P: + niagree(A_2[A,B,P,Kab,TVPa,Text3] -> P_2[A,B,P,Kab,TVPa,Text3], {A, B, P})++ B_non_injective_agreement_P: + niagree(B_3[A,B,P,Kab,TNp,Text2] -> P_2[A,B,P,Kab,TNp,Text2], {A, B, P})+++/******************************************************************************+ * Protocol 6 (with the assumption that the TTP does not play other roles)+ ******************************************************************************+ *+ * symmetric+ * ttp+ * five-pass+ * mutual+ *+ * Modeling notes:+ * - We send identity P in Step 4 in order for B to be able to lookup key k[B,P]+ * - We MUST assume that the trusted third party does not execute any of the+ * other roles. Otherwise, some authentication properties break (see below).+ *+ * MPA Attack reported by Mathuria:+ * - Type flaw MPA when in parallel with Abadi-Needham protocol.+ */+protocol isoiec_9798_2_6_special_TTP_bdkey+{+ text_1. -> B: Text1+ 1. B -> A: B, A, Rb, Text1++ text_2. -> A: Text2+ 2. A -> P: A, P, Ra, Rb, B, Text2++ text_3. -> P: Text3, Text4, Text5+ 3. P -> : P, A, Text5, {'isoiec_9798_2_6_special_TTP_enc_3_1', Ra, Kab, B, Text4}k[A,P]+ , {'isoiec_9798_2_6_special_TTP_enc_3_2', Rb, Kab, A, Text3}k[B,P]+ -> A: P, A, Text5, {'isoiec_9798_2_6_special_TTP_enc_3_1', Ra, Kab, B, Text4}k[A,P]+ , TokenPA_for_B++ text_4. -> A: Text6, Text7 + 4. A -> : A, B, Text7, P, TokenPA_for_B+ , {'isoiec_9798_2_6_special_TTP_enc_4', Rpa, Rb, Text6}Kab+ -> B: A, B, Text7, P, {'isoiec_9798_2_6_special_TTP_enc_3_2', Rb, Kab, A, Text3}k[B,P]+ , {'isoiec_9798_2_6_special_TTP_enc_4', Rpa, Rb, Text6}Kab+ + text_5. -> B: Text8, Text9+ 5. B -> A: B, A, Text9, {'isoiec_9798_2_6_special_TTP_enc_5', Rb, Rpa, Text8}Kab+}++axiom (of isoiec_9798_2_6_special_TTP_bdkey) different_actors_A_P:+ premises+ "role(0) = A"+ "role(1) = P"+ "A#0 = P#1"+ imply+ "False"++axiom (of isoiec_9798_2_6_special_TTP_bdkey) different_actors_B_P:+ premises+ "role(0) = B"+ "role(1) = P"+ "B#0 = P#1"+ imply+ "False"++properties (of isoiec_9798_2_6_special_TTP_bdkey)+ P_secret_Kab: secret(P, -, Kab, {A, B, P})+ A_secret_Kab: secret(A, 3, Kab, {A, B, P})+ B_secret_Kab: secret(B, 4, Kab, {A, B, P})++ // Agreement properties strengthened with respect to Cas Cremers' models:+ // (a) we also verify agreement on the freshness data + // (b) we also verify agreement with the trusted third party+ // + // Note: If no axiom dependency for a property below, then it can be proven+ // without the axiom.++ // depends on 'different_actors_B_P' and 'different_actors_A_P'+ A_non_injective_agreement_B: + niagree(A_5[A,B,P,Kab,Rpa,Rb,Text6,Text8] -> B_5[A,B,P,Kab,Rpa,Rb,Text6,Text8], {A, B, P})++ // depends on 'different_actors_B_P' and 'different_actors_A_P'+ B_non_injective_agreement_A: + niagree(B_4[A,B,P,Kab,Rpa,Rb,Text6] -> A_4[A,B,P,Kab,Rpa,Rb,Text6], {A, B, P})++ // depends on 'different_actors_A_P+ A_non_injective_agreement_P: + niagree(A_3[A,B,P,Ra,Kab,Text4] -> P_3[A,B,P,Ra,Kab,Text4], {A, B, P})++ // depends on 'different_actors_B_P+ B_non_injective_agreement_P: + niagree(B_4[A,B,P,Rb,Kab,Text3] -> P_3[A,B,P,Rb,Kab,Text3], {A, B, P})++end
@@ -0,0 +1,248 @@+/* + * Modeled from ISO/IEC 9798-2+ * Modeler: Cas Cremers, Dec. 2010+ * Ported to scyther-proof: Simon Meier, Feb. 2011+ *+ * Modeling notes:+ * - Variant of ISO/IEC 9798-2 with unidirectional keys k(A,B) and all+ * optional identities dropped.+ * - time-variant-parameters, time-stamps, and sequence numbers are+ * modeled by nonces leaked to the adversary at the start of a role.+ * - The TextX fields are chosen by the adversary.+ */+theory isoiec_9798_2_bdkey begin+++/******************************************************************************+ * Protocol 1+ ******************************************************************************+ *+ * symmetric+ * one-pass+ * unilateral+ *+ * Note: the identity B is ommitted because a unidirectional key is used+ */+protocol isoiec_9798_2_1_udkey+{+ leak_A. A -> : TNA++ text_1. -> A: Text1, Text2+ 1. A -> B: A, B, Text2, {'isoiec_9798_2_1_enc_1', TNA, Text1 }k(A,B)+}++property (of isoiec_9798_2_1_udkey)+ B_non_injective_agreement: + niagree(B_1[A,B,TNA,Text1] -> A_1[A,B,TNA,Text1], {A, B})+++/******************************************************************************+ * Protocol 2+ ******************************************************************************+ *+ * symmetric+ * two-pass+ * unilateral+ *+ * Note: the identity is ommitted because a unidirectional key is used+ */+protocol isoiec_9798_2_2_udkey+{+ text_1. -> B: Text1+ 1. B -> A: B, A, RB, Text1++ text_2. -> A: Text2, Text3+ 2. A -> B: A, B, Text3, {'isoiec_9798_2_2_enc_2', RB, Text2}k(A,B)+}++property (of isoiec_9798_2_2_udkey)+ B_non_injective_agreement: + niagree(B_2[A,B,RB,Text2] -> A_2[A,B,RB,Text2], {A, B})++++/******************************************************************************+ * Protocol 3+ ******************************************************************************+ *+ * symmetric+ * two-pass+ * mutual+ *+ * Note: the identities are ommitted because a unidirectional key is used+ */+protocol isoiec_9798_2_3_udkey+{+ leak_A. A -> : TNA+ leak_B. B -> : TNB++ text_1. -> A: Text1, Text2+ 1. A -> B: A, B, Text2, {'isoiec_9798_2_3_enc_1', TNA, Text1 }k(A,B)++ text_2. -> B: Text3, Text4+ 2. B -> A: B, A, Text4, {'isoiec_9798_2_3_enc_2', TNB, Text3 }k(B,A)+}++properties (of isoiec_9798_2_3_udkey)+ A_non_injective_agreement: + niagree(A_2[A,B,TNB,Text3] -> B_2[A,B,TNB,Text3], {A, B})++ B_non_injective_agreement: + niagree(B_2[A,B,TNA,Text1] -> A_1[A,B,TNA,Text1], {A, B})++++/******************************************************************************+ * Protocol 4+ ******************************************************************************+ *+ * symmetric+ * three-pass+ * mutual+ *+ * Note: the identities are ommitted because a unidirectional key is used+ *+ * In case (b), modeled here, the second key is reversed and the identities are+ * omitted in the ciphertexts.+ */+protocol isoiec_9798_2_4_udkey+{+ text_1. -> B: Text1+ 1. B -> A: B, A, RB, Text1++ text_2. -> A: Text2, Text3+ 2. A -> B: A, B, Text3, {'isoiec_9798_2_4_enc_1', RA, RB, Text2 }k(A,B)++ text_3. -> B: Text4, Text5+ 3. B -> A: B, A, Text5, {'isoiec_9798_2_4_enc_2', RB, RA, Text4 }k(B,A)+}++properties (of isoiec_9798_2_4_udkey)+ A_non_injective_agreement: + niagree(A_3[A,B,RA,RB,Text2,Text4] -> B_3[A,B,RA,RB,Text2,Text4], {A, B})++ B_non_injective_agreement: + niagree(B_2[A,B,RA,RB,Text2] -> A_2[A,B,RA,RB,Text2], {A, B})+++/******************************************************************************+ * Protocol 5+ ******************************************************************************+ *+ * symmetric+ * ttp+ * four-pass+ * mutual+ *+ * Modeling notes:+ * - The use of TNb in message 4, as specified by the ISO standard, is+ * different from other models, in which it was TNa.+ * - We send identity P in Step 3 in order for B to be able to lookup key k(B,P)+ */+protocol isoiec_9798_2_5_udkey+{+ leak_A. A -> : TVPa, TNa+ leak_B. B -> : TNb+ leak_P. P -> : TNp++ text_1. -> A: Text1+ 1. A -> P: A, P, TVPa, B, Text1++ text_2. -> P: Text2, Text3, Text4+ 2. P -> : P, A, Text4, { 'isoiec_9798_2_5_enc_2_1', TVPa, Kab, B, Text3 }k(A,P)+ , { 'isoiec_9798_2_5_enc_2_2', TNp , Kab, A, Text2 }k(B,P)+ -> A: P, A, Text4, { 'isoiec_9798_2_5_enc_2_1', TVPa, Kab, B, Text3 }k(A,P)+ , TokenPA_for_B++ text_3. -> A: Text5, Text6+ 3. A -> : A, B, Text6, P, TokenPA_for_B+ , { 'isoiec_9798_2_5_enc_3', TNa, B, Text5 }Kab+ -> B: A, B, Text6, P, { 'isoiec_9798_2_5_enc_2_2', TNp, Kab, A, Text2 }k(B,P)+ , { 'isoiec_9798_2_5_enc_3', TNa, B, Text5 }Kab++ text_4. -> B: Text7, Text8+ 4. B -> A: B, A, Text8, { 'isoiec_9798_2_5_enc_4', TNb, A, Text7 }Kab+}++properties (of isoiec_9798_2_5_udkey)+ P_secret_Kab: secret(P, -, Kab, {A, B, P})+ A_secret_Kab: secret(A, 2, Kab, {A, B, P})+ B_secret_Kab: secret(B, 3, Kab, {A, B, P})++ // Agreement properties strengthened with respect to Cas Cremers' models:+ // (a) we also verify agreement on the freshness data TNa, TNb+ // (b) we also verify agreement with the trusted third party+ //+ A_non_injective_agreement_B: + niagree(A_4[A,B,P,Kab,TNa,Text5,TNb,Text7] -> B_4[A,B,P,Kab,TNa,Text5,TNb,Text7], {A, B, P})++ B_non_injective_agreement_A: + niagree(B_3[A,B,P,Kab,TNa,Text5] -> A_3[A,B,P,Kab,TNa,Text5], {A, B, P})++ A_non_injective_agreement_P: + niagree(A_2[A,B,P,Kab,TVPa,Text3] -> P_2[A,B,P,Kab,TVPa,Text3], {A, B, P})+ B_non_injective_agreement_P: + niagree(B_3[A,B,P,Kab,TNp,Text2] -> P_2[A,B,P,Kab,TNp,Text2], {A, B, P})+++/******************************************************************************+ * Protocol 6+ ******************************************************************************+ *+ * symmetric+ * ttp+ * five-pass+ * mutual+ *+ * Modeling notes:+ * - We send identity P in Step 4 in order for B to be able to lookup key k(B,P)+ *+ * MPA Attack reported by Mathuria:+ * - Type flaw MPA when in parallel with Abadi-Needham protocol.+ */+protocol isoiec_9798_2_6_udkey+{+ text_1. -> B: Text1+ 1. B -> A: B, A, Rb, Text1++ text_2. -> A: Text2+ 2. A -> P: A, P, Ra, Rb, B, Text2++ text_3. -> P: Text3, Text4, Text5+ 3. P -> : P, A, Text5, {'isoiec_9798_2_6_enc_3_1', Ra, Kab, B, Text4}k(A,P)+ , {'isoiec_9798_2_6_enc_3_2', Rb, Kab, A, Text3}k(B,P)+ -> A: P, A, Text5, {'isoiec_9798_2_6_enc_3_1', Ra, Kab, B, Text4}k(A,P)+ , TokenPA_for_B++ text_4. -> A: Text6, Text7 + 4. A -> : A, B, Text7, P, TokenPA_for_B+ , {'isoiec_9798_2_6_enc_4', Rpa, Rb, Text6}Kab+ -> B: A, B, Text7, P, {'isoiec_9798_2_6_enc_3_2', Rb, Kab, A, Text3}k(B,P)+ , {'isoiec_9798_2_6_enc_4', Rpa, Rb, Text6}Kab+ + text_5. -> B: Text8, Text9+ 5. B -> A: B, A, Text9, {'isoiec_9798_2_6_enc_5', Rb, Rpa, Text8}Kab+}++properties (of isoiec_9798_2_6_udkey)+ P_secret_Kab: secret(P, -, Kab, {A, B, P})+ A_secret_Kab: secret(A, 3, Kab, {A, B, P})+ B_secret_Kab: secret(B, 4, Kab, {A, B, P})++ // Agreement properties strengthened with respect to Cas Cremers' models:+ // (a) we also verify agreement on the freshness data + // (b) we also verify agreement with the trusted third party+ //+ A_non_injective_agreement_B: + niagree(A_5[A,B,P,Kab,Rpa,Rb,Text6,Text8] -> B_5[A,B,P,Kab,Rpa,Rb,Text6,Text8], {A, B, P})++ B_non_injective_agreement_A: + niagree(B_4[A,B,P,Kab,Rpa,Rb,Text6] -> A_4[A,B,P,Kab,Rpa,Rb,Text6], {A, B, P})++ A_non_injective_agreement_P: + niagree(A_3[A,B,P,Ra,Kab,Text4] -> P_3[A,B,P,Ra,Kab,Text4], {A, B, P})++ B_non_injective_agreement_P: + niagree(B_4[A,B,P,Rb,Kab,Text3] -> P_3[A,B,P,Rb,Kab,Text3], {A, B, P})++end
@@ -0,0 +1,525 @@+/*+ * Modeled from ISO/IEC 9798+ * Modeler: Cas Cremers, Dec. 2010+ * Adapted for scyther-proof: Simon Meier, Feb. 2011+ *+ * Modeling notes:+ * - We allow the adversary to choose the content of all TextX fields.+ * - time-variant-parameters, time-stamps, and sequence numbers are+ * modeled by nonces leaked to the adversary at the start of a role.+ * - Given some pattern 'pkA', then the signature pattern 'sign{m}pkA' is+ * translated to the message '(m, {m}inv(pkA))' upon execution. + */+theory isoiec_9798_3 begin++/****************************************************************************+ * Protocol 1+ ****************************************************************************+ *+ * signature+ * one-pass+ * unilateral+ *+ * Modeling notes:+ * - we assume that pk(A) is already known to B+ */+++protocol isoiec_9798_3_1+{+ leak_A. A -> : TNA++ text_1. -> A: Text1, Text2+ 1. A -> B: A, B, Text2, + sign{'isoiec_9798_3_1_sig_1', TNA, B, Text1 }pk(A)+}++properties (of isoiec_9798_3_1)+ B_non_injective_agreement: + niagree(B_1[A,B,TNA,Text1] -> A_1[A,B,TNA,Text1], {A})+++/****************************************************************************+ * Protocol 2+ ****************************************************************************+ *+ * signature+ * two-pass+ * unilateral+ *+ * Modeling notes:+ * - we assume that pk(A) is already known to B+ */+protocol isoiec_9798_3_2+{+ text_1. -> B: Text1+ 1. B -> A: B, A, Rb, Text1++ text_2. -> A: Text2, Text3+ 2. A -> B: A, B, Text3, + sign{'isoiec_9798_3_2_sig_2', Ra, Rb, B, Text2 }pk(A)+}++properties (of isoiec_9798_3_2)+ // Note: for this agreement property the identity B must not be dropped+ B_non_injective_agreement: + niagree(B_2[A,B,Ra,Rb,Text2] -> A_2[A,B,Ra,Rb,Text2], {A})+++/****************************************************************************+ * Protocol 3+ ****************************************************************************+ *+ * signature+ * two-pass+ * mutual+ * parallel+ *+ * Modeling notes:+ * - Here we only verify a sequential model of the protocol.+ * - We assume that the public keys are already predistributed.+ */+protocol isoiec_9798_3_3+{+ leak_A. A -> : TNA+ leak_B. B -> : TNB+ + text_1. -> A: Text1, Text2+ 1. A -> B: A, B, Text2, + sign{'isoiec_9798_3_3_sig_1', TNA, B, Text1 }pk(A)++ text_2. -> B: Text3, Text4+ 2. B -> A: A, B, Text4, + sign{'isoiec_9798_3_3_sig_2', TNB, A, Text3 }pk(B)+}++properties (of isoiec_9798_3_3)+ A_non_injective_agreement: + niagree(A_2[A,B,TNB,Text3] -> B_2[A,B,TNB,Text3], {B})++ B_non_injective_agreement: + niagree(B_1[A,B,TNA,Text1] -> A_1[A,B,TNA,Text1], {A})+++/****************************************************************************+ * Protocol 4+ ****************************************************************************+ *+ * signature+ * three-pass+ * mutual+ *+ * Modeling notes:+ * - We assume that the public keys are already predistributed.+ */+protocol isoiec_9798_3_4+{+ text_1. -> B: Text1+ 1. B -> A: B, A, RB, Text1++ text_2. -> A: Text2, Text3+ 2. A -> B: A, B, Text3, + sign{'isoiec_9798_3_4_sig_1', RA, RB, B, Text2 }pk(A)++ text_3. -> B: Text4, Text5+ 3. B -> A: B, A, Text5, + sign{'isoiec_9798_3_4_sig_2', RB, RA, A, Text4 }pk(B)+}++properties (of isoiec_9798_3_4)+ // The identity A in Step 3 is required for this property to hold.+ A_non_injective_agreement: + niagree(A_3[A,B,RA,RB,Text2,Text4] -> B_3[A,B,RA,RB,Text2,Text4], {A,B})++ // The identity B in Step 2 is required for this property to hold.+ B_non_injective_agreement: + niagree(B_2[A,B,RA,RB,Text2] -> A_2[A,B,RA,RB,Text2], {A})+++/****************************************************************************+ * Protocol 5+ ****************************************************************************+ *+ * signature+ * two-pass+ * mutual+ * parallel+ *+ * Modeling notes:+ * - unnecessary sequentialization in the model.+ * - we assume that the public keys are already predistributed.+ */+protocol isoiec_9798_3_5+{+ text_1. -> A: Text1+ 1. A -> B: A, B, RA, Text1++ text_2. -> B: Text2+ 2. B -> A: B, A, RB, Text2++ text_3. -> B: Text5, Text6+ 3. B -> A: B, A, Text6, + sign{'isoiec_9798_3_5_sig_1', RB, RA, A, Text5 }pk(B)++ text_4. -> A: Text3, Text4+ 4. A -> B: A, B, Text4, + sign{'isoiec_9798_3_5_sig_2', RA, RB, B, Text3 }pk(A)+}++properties (of isoiec_9798_3_5)+ // The identity A in Step 3 is required for this property to hold.+ A_non_injective_agreement: + niagree(A_3[A,B,RA,RB,Text5] -> B_3[A,B,RA,RB,Text5], {B})++ // The identity B in Step 4 is required for this property to hold.+ B_non_injective_agreement: + niagree(B_4[A,B,RA,RB,Text3,Text5] -> A_4[A,B,RA,RB,Text3,Text5], {A,B})+++/****************************************************************************+ * Protocol 6 (Option 1)+ ****************************************************************************+ *+ * signature+ * ttp+ * five-pass+ * mutual+ *+ * A initiates and also communicates with T+ *+ * Modeling notes:+ * - We model the case where T sends the public keys instead of just verifying+ * the certificates; i.e., 'ResA = (A, pk(A))' and 'ResB = (B, pk(B))'.+ * - Option 1 and Option 2 must not share tags!+ */+protocol isoiec_9798_3_6_1+{+ text_1. -> A: Text1+ 1. A -> B: A, B, Ra, Text1 + + text_2. -> B: Text2, Text3+ 2. B -> : A, B, Ra, Rb, Text3,+ sign{'isoiec_9798_3_6_opt_1_sig_2', B, Ra, Rb, A, Text2}pk(B)++ -> A: A, B, Ra, Rb, Text3, + TokenBA++ text_3. -> A: Text4+ 3. A -> T: A, T, Rpa, Rb, B, Text4++ text_4. -> T: Text5, Text6, Text7+ 4. T -> : T, A, Text7, A, pk(A), B, pk(B),+ sign{'isoiec_9798_3_6_opt_1_sig_4_1', Rpa, B, pk(B), Text6}pk(T), + sign{'isoiec_9798_3_6_opt_1_sig_4_2', Rb, A, pk(A), Text5}pk(T)++ -> A: T, A, Text7, A, pk(A), B, pkB,+ sign{'isoiec_9798_3_6_opt_1_sig_4_1', Rpa, B, pkB, Text6}pk(T), + TokenTA_for_B++ // Here, A checks TokenBA against the public key pkB received from T.+ // As we lack support for additionally checked equalities, A sends a message+ // to itself encrypted with a fresh nonce to emulate the equality check.+ check_4_out. A -> : {'check_4', + TokenBA+ }check_nonce_4+ check_4_in. -> A: {'check_4', + sign{'isoiec_9798_3_6_opt_1_sig_2', B, Ra, Rb, A, Text2}pkB + }check_nonce_4++ // Note: we additionally send T such that B knows which key to use for+ // checking TokenTA_for_B+ text_5. -> A: Text8, Text9+ 5. A -> : A, B, Text9, T,+ TokenTA_for_B, + sign{'isoiec_9798_3_6_opt_1_sig_5', Rb, Ra, B, A, Text8}pk(A)++ -> B: A, B, Text9, T,+ sign{'isoiec_9798_3_6_opt_1_sig_4_2', Rb, A, pkA, Text5}pk(T),+ // Note: the standard does not require to check that 'Ra5 = Ra'!+ sign{'isoiec_9798_3_6_opt_1_sig_5', Rb, Ra5, B, A, Text8}pkA+}++properties (of isoiec_9798_3_6_1)+ A_non_injective_agreement: + niagree(A_5[A,B,Ra,Rb,Text2] -> B_2[A,B,Ra,Rb,Text2], {B, T})++ // Possible authentication FLAW:+ // We do NOT get agreement on Ra because the standard does not require B to+ // check its occurence in the signature from Step 5 to be equal with the+ // one in Step 2.+ //+ // FIXME: What are the consequences?+ B_non_injective_agreement: + niagree(B_5[A,B,Ra5,Rb,Text8] -> A_5[A,B,Ra,Rb,Text8], {A, T})++ // We additionally verify agreement of A and B with the TTP T.+ A_non_injective_agreement_T: + niagree(A_5[B,T,Rpa,pkB ,Text6] -> + T_4[B,T,Rpa,pk(B),Text6], {T})++ B_non_injective_agreement_T: + niagree(B_5[A,T,Rb,pkA ,Text5] -> + T_4[A,T,Rb,pk(A),Text5], {T})++++/****************************************************************************+ * Protocol 6 (Option 2)+ ****************************************************************************+ *+ * signature+ * ttp+ * five-pass+ * mutual+ *+ * A initiates and also communicates with T+ *+ * Modeling notes:+ * - Option 1 and Option 2 must not share tags!+ * - We model the case where T sends the public keys instead of just verifying+ * the certificates; i.e., 'ResA = (A, pk(A))' and 'ResB = (B, pk(B))'.++ FIXME: Compare equality checks done here to what is prescribed in the+ standard. We probably do a few more => there may be attacks on the+ standard.++ We probably also shouldn't check the public keys delivered by T.++ */+protocol isoiec_9798_3_6_2+{+ text_1. -> A: Text1+ 1. A -> B: A, B, Ra, Text1 + + text_2. -> B: Text2, Text3+ 2. B -> : A, B, Ra, Rb, Text3,+ sign{'isoiec_9798_3_6_opt_2_sig_2', B, Ra, Rb, A, Text2}pk(B)++ -> A: A, B, Ra, Rb, Text3, + TokenBA++ text_3. -> A: Text4+ 3. A -> T: A, T, Rpa, Rb, B, Text4++ // Note: Text6 is not used in Option 2+ text_4. -> T: Text5, Text7 + 4. T -> : T, A, Text7, A, pk(A), B, pk(B),+ sign{ 'isoiec_9798_3_6_opt_2_sig_4', + Rpa, Rb, A, pk(A), B, pk(B), Text5 }pk(T)+ -> A: T, A, Text7, A, pk(A), B, pkB,+ TokenTA++ // Here, A first checks TokenTA and then checks TokenBA against the public+ // key received from T. As we lack support for additionally checked+ // equalities, A sends a message to itself encrypted with a fresh nonce to+ // emulate the equality check.+ check_4_out. A -> : {'check_4', + TokenTA,+ TokenBA+ }check_nonce_4+ check_4_in. -> A: {'check_4', + sign{'isoiec_9798_3_6_opt_2_sig_4', + Rpa, Rb, A, pkA, B, pkB, Text5 }pk(T),+ sign{'isoiec_9798_3_6_opt_2_sig_2', B, Ra, Rb, A, Text2}pkB+ }check_nonce_4++ // Note: we additionally send T such that B knows which key to use for+ // checking TokenTA+ text_5. -> A: Text8, Text9+ 5. A -> : A, B, Rpa, Text9, T, + TokenTA,+ sign{'isoiec_9798_3_6_opt_2_sig_5', Rb, Ra, B, A, Text8}pk(A)++ -> B: A, B, Rpa, Text9, T,+ sign{'isoiec_9798_3_6_opt_2_sig_4', + Rpa, Rb, A, pkA, B, pkB, Text5 }pk(T), + // Note: the standard does not require to check that 'Ra5 = Ra'!+ sign{'isoiec_9798_3_6_opt_2_sig_5', Rb, Ra5, B, A, Text8}pkA+}++properties (of isoiec_9798_3_6_2)+ // Note that we do not get agreement on T!+ A_non_injective_agreement: + niagree(A_5[A,B,Ra,Rb,Text2] -> B_2[A,B,Ra,Rb,Text2], {B, T})++ // Possible authentication FLAW:+ // We do NOT get agreement on Ra because the standard does not require B to+ // check its occurence in the signature from Step 5 to be equal with the+ // one in Step 2.+ //+ // FIXME: What are the consequences?+ B_non_injective_agreement: + niagree(B_5[A,B,Ra5,Rb,Text8] -> A_5[A,B,Ra,Rb,Text8], {A, T})++ // We additionally verify agreement of A and B with the TTP T+ A_non_injective_agreement_T: + niagree(A_5[A,B,T,Rpa,Rb,pkA ,pkB ,Text5] -> + T_4[A,B,T,Rpa,Rb,pk(A),pk(B),Text5], {T})++ B_non_injective_agreement_T: + niagree(B_5[A,B,T,Rpa,Rb,pkA ,pkB ,Text5] -> + T_4[A,B,T,Rpa,Rb,pk(A),pk(B),Text5], {T})++++/****************************************************************************+ * Protocol 7 (Option 1)+ ****************************************************************************+ *+ * signature+ * ttp+ * five-pass+ * mutual+ *+ * B initiates and A communicates with T+ *+ * Modeling notes:+ * - Option 1 and Option 2 must not share tags!+ * - We model the case where T sends the public keys instead of just verifying+ * the certificates; i.e., 'ResA = (A, pk(A))' and 'ResB = (B, pk(B))'.++ FIXME: Compare equality checks done here to what is prescribed in the+ standard. We probably do a few more => there may be attacks on the+ standard.++ */+protocol isoiec_9798_3_7_1+{+ text_1. -> B: Text1+ 1. B -> A: B, A, Rb, Text1 + + text_2. -> A: Text2+ 2. A -> T: A, T, Rpa, Rb, A, B, Text2 ++ text_3. -> T: Text3, Text4, Text5 + 3. T -> : T, A, Text5, A, pk(A), B, pk(B),+ sign{ 'isoiec_9798_3_7_opt_1_sig_3_1', Rpa, B, pk(B), Text4 }pk(T),+ sign{ 'isoiec_9798_3_7_opt_1_sig_3_2', Rb, A, pk(A), Text3 }pk(T)+ -> A: T, A, Text5, A, pk(A), B, pkB,+ sign{ 'isoiec_9798_3_7_opt_1_sig_3_1', Rpa, B, pkB, Text4 }pk(T),+ TokenTA_for_B++ // Note: we additionally send T such that B knows which key to use for+ // checking TokenTA+ text_4. -> A: Text6, Text7+ 4. A -> : A, B, Rpa, Text7, T, + TokenTA_for_B,+ sign{'isoiec_9798_3_7_opt_1_sig_4', Rb, Ra, B, A, Text6}pk(A)++ -> B: A, B, Rpa, Text9, T,+ sign{'isoiec_9798_3_7_opt_1_sig_3_2', Rb, A, pkA, Text3}pk(T), + sign{'isoiec_9798_3_7_opt_1_sig_4', Rb, Ra, B, A, Text6}pkA++ text_5. -> B: Text8, Text9+ 5. B -> : A, B, Ra, Rb, Text9,+ sign{'isoiec_9798_3_7_opt_1_sig_5', Ra, Rb, A, B, Text8}pk(B)++ -> A: A, B, Ra, Rb, Text9, + sign{'isoiec_9798_3_7_opt_1_sig_5', Ra, Rb, A, B, Text8}pkB++}++properties (of isoiec_9798_3_7_1)+ // Note that we do not get agreement on T!+ A_non_injective_agreement: + niagree(A_5[A,B,Ra,Rb,Text8] -> B_5[A,B,Ra,Rb,Text8], {B, T})++ B_non_injective_agreement: + niagree(B_4[A,B,Ra,Rb,Text6] -> A_4[A,B,Ra,Rb,Text6], {A, T})++ // We additionally verify agreement of A and B with the TTP T+ A_non_injective_agreement_T: + niagree(A_3[B,T,Rpa,pkB,Text4] -> T_3[B,T,Rpa,pk(B),Text4], {T})+ B_non_injective_agreement_T: + niagree(B_4[A,T,Rb,pkA,Text3] -> T_3[A,T,Rb,pk(A),Text3], {T})++++/****************************************************************************+ * Protocol 7 (Option 2)+ ****************************************************************************+ *+ * signature+ * ttp+ * five-pass+ * mutual+ *+ * B initiates and A communicates with T+ *+ * Modeling notes:+ * - Option 1 and Option 2 must not share tags!+ * - We model the case where T sends the public keys instead of just verifying+ * the certificates; i.e., 'ResA = (A, pk(A))' and 'ResB = (B, pk(B))'.++ FIXME: Compare equality checks done here to what is prescribed in the+ standard. We probably do a few more => there may be attacks on the+ standard.++ */+protocol isoiec_9798_3_7_2+{+ text_1. -> B: Text1+ 1. B -> A: B, A, Rb, Text1 + + text_2. -> A: Text2+ 2. A -> T: A, T, Rpa, Rb, A, B, Text2 ++ // Note: Text4 is not used in Option 2+ text_3. -> T: Text3, Text5 + 3. T -> : T, A, Text5, A, pk(A), B, pk(B),+ sign{ 'isoiec_9798_3_7_opt_2_sig_3', + Rpa, Rb, A, pk(A), B, pk(B), Text3 }pk(T)+ -> A: T, A, Text5, A, pk(A), B, pkB,+ TokenTA++ // Here, A checks TokenTA. As we lack support for additionally checked+ // equalities, A sends a message to itself encrypted with a fresh nonce to+ // emulate the equality check.+ check_3_out. A -> : {'check_4', + TokenTA+ }check_nonce_4+ check_3_in. -> A: {'check_4', + sign{'isoiec_9798_3_7_opt_2_sig_3', + Rpa, Rb, A, pkA, B, pkB, Text3 }pk(T)+ }check_nonce_4++ // Note: we additionally send T such that B knows which key to use for+ // checking TokenTA+ text_4. -> A: Text6, Text7+ 4. A -> : A, B, Rpa, Text7, T, + TokenTA,+ sign{'isoiec_9798_3_7_opt_2_sig_4', Rb, Ra, B, A, Text6}pk(A)++ -> B: A, B, Rpa, Text9, T,+ sign{'isoiec_9798_3_7_opt_2_sig_3', + Rpa, Rb, A, pkA, B, pkB, Text3 }pk(T), + sign{'isoiec_9798_3_7_opt_2_sig_4', Rb, Ra, B, A, Text6}pkA++ text_5. -> B: Text8, Text9+ 5. B -> : A, B, Ra, Rb, Text9,+ sign{'isoiec_9798_3_7_opt_2_sig_5', Ra, Rb, A, B, Text8}pk(B)++ -> A: A, B, Ra, Rb, Text9, + sign{'isoiec_9798_3_7_opt_2_sig_5', Ra, Rb, A, B, Text8}pkB++}++properties (of isoiec_9798_3_7_2)+ A_non_injective_agreement: + niagree(A_5[A,B,Ra,Rb,Text8] -> B_5[A,B,Ra,Rb,Text8], {B, T})++ B_non_injective_agreement: + niagree(B_4[A,B,Ra,Rb,Text6] -> A_4[A,B,Ra,Rb,Text6], {A, T})++ // We additionally verify agreement of A and B with the TTP T+ A_non_injective_agreement_T: + niagree(A_4[A,B,T,Rpa,Rb,pkA ,pkB ,Text3] -> + T_3[A,B,T,Rpa,Rb,pk(A),pk(B),Text3], {T})++ B_non_injective_agreement_T: + niagree(B_4[A,B,T,Rpa,Rb,pkA ,pkB ,Text3] -> + T_3[A,B,T,Rpa,Rb,pk(A),pk(B),Text3], {T})++++end
@@ -0,0 +1,122 @@+/*+ * Modeled from ISO/IEC 9798-4+ * Modeler: Cas Cremers, Dec. 2010, Feb. 2011.+ * Ported to scyther-proof: Simon Meier, Feb. 2011.+ *+ * Modeling notes:+ * - Variant of ISO/IEC 9798-4 with bidirectional keys k[A,B].+ * - time-variant-parameters, time-stamps, and sequence numbers are+ * modeled by nonces leaked to the adversary at the start of a role.+ * - The TextX fields are chosen by the adversary.+ * - The keyed CCF (f_kab(x)) is modeled as h(('CCF', k[a,b]), x)+ *+ */+theory isoiec_9798_4_bdkey begin+++/******************************************************************************+ * Protocol 1+ ******************************************************************************+ *+ * ccf+ * unilateral+ * one-pass+ */+protocol isoiec_9798_4_1_bdkey+{+ leak_A. A -> : TNA++ text_1. -> A: Text1, Text2+ 1. A -> B: A, B, TNA, Text2, Text1, + h(('CCF', k[A,B]), ('isoiec_9798_4_1_ccf_1', TNA, B, Text1))+}++properties (of isoiec_9798_4_1_bdkey)+ B_non_injective_agreement:+ niagree(B_1[A,B,TNA,Text1] -> A_1[A,B,TNA,Text1], {A, B})+++/******************************************************************************+ * Protocol 2+ ******************************************************************************+ *+ * ccf+ * unilateral+ * two-pass+ */+protocol isoiec_9798_4_2_bdkey+{+ text_1. -> B: Text1+ 1. B -> A: B, A, Rb, Text1++ text_2. -> A: Text2, Text3+ 2. A -> B: A, B, Text3, Rb, Text2, + h(('CCF', k[A,B]), ('isoiec_9798_4_2_ccf_2', Rb, B, Text2))+}++properties (of isoiec_9798_4_2_bdkey)+ B_non_injective_agreement:+ niagree(B_2[A,B,Rb,Text2] -> A_2[A,B,Rb,Text2], {A, B})+++/******************************************************************************+ * Protocol 3+ ******************************************************************************+ *+ * ccf+ * mutual+ * two-pass+ */+protocol isoiec_9798_4_3_bdkey+{+ leak_A. A -> : TNa+ leak_B. B -> : TNb++ text_1. -> A: Text1, Text2+ 1. A -> B: A, B, TNa, Text2, Text1, + h(('CCF', k[A,B]), ('isoiec_9798_4_3_ccf_1', TNa, B, Text1))++ text_2. -> B: Text3, Text4+ 2. B -> A: B, A, TNb, Text4, Text3, + h(('CCF', k[A,B]), ('isoiec_9798_4_3_ccf_2', TNb, A, Text3))+}++properties (of isoiec_9798_4_3_bdkey)+ A_non_injective_agreement:+ niagree(A_2[A,B,TNb,Text3] -> B_2[A,B,TNb,Text3], {A, B})++ B_non_injective_agreement:+ niagree(B_1[A,B,TNa,Text1] -> A_1[A,B,TNa,Text1], {A, B})+++/******************************************************************************+ * Protocol 4+ ******************************************************************************+ *+ * ccf+ * mutual+ * three-pass+ */+protocol isoiec_9798_4_4_bdkey+{+ text_1. -> B: Text1+ 1. B -> A: B, A, Rb, Text1++ text_2. -> A: Text2, Text3+ 2. A -> B: A, B, Ra, Text3, Text2, + h(('CCF', k[A,B]), ('isoiec_9798_4_4_ccf_2', Ra, Rb, B, Text2))++ text_3. -> B: Text4, Text5+ 3. B -> A: B, A, Text5, Text4,+ h(('CCF', k[A,B]), ('isoiec_9798_4_4_ccf_3', Rb, Ra, Text4))+}++properties (of isoiec_9798_4_4_bdkey)+ A_non_injective_agreement:+ niagree(A_3[A,B,Ra,Rb,Text2,Text4] -> B_3[A,B,Ra,Rb,Text2,Text4], {A, B})++ B_non_injective_agreement:+ niagree(B_2[A,B,Ra,Rb,Text2] -> A_2[A,B,Ra,Rb,Text2], {A, B})+++end
@@ -0,0 +1,121 @@+/*+ * Modeled from ISO/IEC 9798-4+ * Modeler: Cas Cremers, Dec. 2010, Feb. 2011.+ * Ported to scyther-proof: Simon Meier, Feb. 2011.+ *+ * Modeling notes:+ * - Variant of ISO/IEC 9798-4 with unidirectional keys k(A,B) and + * identities dropped if possible.+ * - time-variant-parameters, time-stamps, and sequence numbers are+ * modeled by nonces leaked to the adversary at the start of a role.+ * - The TextX fields are chosen by the adversary.+ * - The keyed CCF (f_kab(x)) is modeled as h(('CCF', k(a,b)), x)+ */+theory isoiec_9798_4_udkey begin+++/******************************************************************************+ * Protocol 1+ ******************************************************************************+ *+ * ccf+ * unilateral+ * one-pass+ */+protocol isoiec_9798_4_1_udkey+{+ leak_A. A -> : TNA++ text_1. -> A: Text1, Text2+ 1. A -> B: A, B, TNA, Text2, Text1, + h(('CCF', k(A,B)), ('isoiec_9798_4_1_ccf_1', TNA, Text1))+}++properties (of isoiec_9798_4_1_udkey)+ B_non_injective_agreement:+ niagree(B_1[A,B,TNA,Text1] -> A_1[A,B,TNA,Text1], {A, B})+++/******************************************************************************+ * Protocol 2+ ******************************************************************************+ *+ * ccf+ * unilateral+ * two-pass+ */+protocol isoiec_9798_4_2_udkey+{+ text_1. -> B: Text1+ 1. B -> A: B, A, Rb, Text1++ text_2. -> A: Text2, Text3+ 2. A -> B: A, B, Text3, Rb, Text2, + h(('CCF', k(A,B)), ('isoiec_9798_4_2_ccf_2', Rb, Text2))+}++properties (of isoiec_9798_4_2_udkey)+ B_non_injective_agreement:+ niagree(B_2[A,B,Rb,Text2] -> A_2[A,B,Rb,Text2], {A, B})+++/******************************************************************************+ * Protocol 3+ ******************************************************************************+ *+ * ccf+ * mutual+ * two-pass+ */+protocol isoiec_9798_4_3_udkey+{+ leak_A. A -> : TNa+ leak_B. B -> : TNb++ text_1. -> A: Text1, Text2+ 1. A -> B: A, B, TNa, Text2, Text1, + h(('CCF', k(A,B)), ('isoiec_9798_4_3_ccf_1', TNa, Text1))++ text_2. -> B: Text3, Text4+ 2. B -> A: B, A, TNb, Text4, Text3, + h(('CCF', k(A,B)), ('isoiec_9798_4_3_ccf_2', TNb, Text3))+}++properties (of isoiec_9798_4_3_udkey)+ A_non_injective_agreement:+ niagree(A_2[A,B,TNb,Text3] -> B_2[A,B,TNb,Text3], {A, B})++ B_non_injective_agreement:+ niagree(B_1[A,B,TNa,Text1] -> A_1[A,B,TNa,Text1], {A, B})+++/******************************************************************************+ * Protocol 4+ ******************************************************************************+ *+ * ccf+ * mutual+ * three-pass+ */+protocol isoiec_9798_4_4_udkey+{+ text_1. -> B: Text1+ 1. B -> A: B, A, Rb, Text1++ text_2. -> A: Text2, Text3+ 2. A -> B: A, B, Ra, Text3, Text2, + h(('CCF', k(A,B)), ('isoiec_9798_4_4_ccf_2', Ra, Rb, Text2))++ text_3. -> B: Text4, Text5+ 3. B -> A: B, A, Text5, Text4,+ h(('CCF', k(A,B)), ('isoiec_9798_4_4_ccf_3', Rb, Ra, Text4))+}++properties (of isoiec_9798_4_4_udkey)+ A_non_injective_agreement:+ niagree(A_3[A,B,Ra,Rb,Text2,Text4] -> B_3[A,B,Ra,Rb,Text2,Text4], {A, B})++ B_non_injective_agreement:+ niagree(B_2[A,B,Ra,Rb,Text2] -> A_2[A,B,Ra,Rb,Text2], {A, B})++end
@@ -0,0 +1,592 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<head> + + <title>Security Protocol Proof Visualization</title> + <script type="text/javascript" src="js/jquery.js"></script> + <script type="text/javascript" src="js/ui/jquery.ui.core.js"></script> + <script type="text/javascript" src="js/ui/jquery.ui.widget.js"></script> + <script type="text/javascript" src="js/ui/jquery.ui.mouse.js"></script> + <script type="text/javascript" src="js/ui/jquery.ui.draggable.js"></script> + <script type="text/javascript" src="js/ui/jquery.ui.tabs.js"></script> + <script type="text/javascript" src="js/ui/jquery.effects.core.js"></script> + <script type="text/javascript" src="js/jquery.layout.js"></script> + + <script src="js/tooltip/lib/jquery.bgiframe.js" type="text/javascript"></script> + <script src="js/tooltip/lib/jquery.dimensions.js" type="text/javascript"></script> + <script src="js/tooltip/jquery.tooltip.js" type="text/javascript"></script> + + <script type="text/javascript" src="js/json_parse.js"></script> + <script type="text/javascript" src="theory.js"></script> + + <link rel="stylesheet" href="js/tooltip/jquery.tooltip.css" /> + <link rel="stylesheet" href="css/ui-lightness/jquery.ui.all.css" /> + <link rel="stylesheet" href="css/scyther-proof.css" /> + + <script type="text/javascript"> + // a single global variable holding the ScytherP info + var scytherP = undefined; + + // Isolating the translation of indices to the corresponding textual + // representations. + function graphRef(refIdx) { return "graphRef_" + refIdx; } + function caseRef(refIdx) { return "caseRef_" + refIdx; } + function thmRef(refIdx) { return "thmRef_" + refIdx; } + function explRef(refIdx) { return "explRef_" + refIdx; } + function graphFileName (graphIdx) { return "img/graph_" + graphIdx + ".png"; } + + // corresponding selection functions + function selectGraphRef (refIdx) { return $("#"+graphRef(refIdx)); } + function selectCaseRef(refIdx) { return $("#"+caseRef(refIdx)); } + function selectThmRef(refIdx) { return $("#"+thmRef(refIdx)); } + function selectExplRef(refIdx) { return $("[name="+explRef(refIdx)+"]"); } + + // Using the displays + function hideAllDisplays () { + $("#ui-pane-explanation").addClass("hidden"); + $("#ui-sequent-display").addClass("hidden"); + $("#ui-case-display").addClass("hidden"); + $("#ui-graph-display").addClass("hidden"); + } + + function displayGraph(graphIdx) { + hideAllDisplays(); + $("#ui-graph-display").removeClass("hidden"); + $("#graph-img").attr("src", graphFileName(graphIdx)); + } + + function displaySequent(premIdx, conclIdx) { + hideAllDisplays(); + $("#ui-sequent-display").removeClass("hidden"); + $("#prem-img").attr("src", graphFileName(premIdx)); + $("#concl-img").attr("src", graphFileName(conclIdx)); + } + + function displayCase(c) { + // switch displays + hideAllDisplays(); + $("#ui-case-display").removeClass("hidden"); + // attach images + var mkImage = function(name, graphIdx) { + return '<img src="' + graphFileName(graphIdx) + '" title="' + name + '"/>'; + }; + var mkNamedImage = function(name, graphIdx) { + var img = mkImage(name, graphIdx); + var name_div = '<div>case: ' + name + '</div>'; + return '<div class="named-image">' + name_div + img + '</div>'; + }; + $("#ui-case-display .original") + .empty().append(mkImage('Original', c[0])); + var nonTrivial = $("#ui-case-display .non-trivial").empty(); + var trivial = $("#ui-case-display .trivial").empty(); + jQuery.each(c[1], function(i, subcase) { + var display = undefined; + if (subcase[0][1]) + display = trivial; + else + display = nonTrivial; + display.append(mkNamedImage(subcase[0][0], subcase[1])); + }); + } + + // Detecting if shift key is held + var shiftIsDown; + + function installShiftDownHandler() { + shiftIsDown = false; + + $(document).keydown(function(e) { + if (e.which == 16) + shiftIsDown = true; + }); + + $(document).keyup(function(e) { + if (e.which == 16) + shiftIsDown = false; + }); + } + + function ifShiftDown (fun, arg) { + if (shiftIsDown) + fun(arg); + } + + // rollover effect for highlighting clickable items + // (obj must be a jQuery object denoting the elements that should be marked) + function installHighlightClickable (obj, info) { + obj.attr('title', info); + obj.hover( + function(e) { + //$(this).css('backgroundColor', '#e0e0ee'); + $(this).stop().animate({backgroundColor: '#e9e9f9'}, 'fast'); + } + , function(e) { + //$(this).css('backgroundColor', 'white'); + $(this).stop().animate({backgroundColor: 'white'}, 'fast'); + } + ); + } + + // Highlighting references to proof states and case distinctions. + function undoHighlights () { + if (scytherP.removeHighlights != undefined) + scytherP.removeHighlights(); + } + + function highlightElem (selector) { + selector().addClass("highlighted"); + scytherP.removeHighlights = function(){ + selector().removeClass("highlighted"); + } + } + + function highlightGraphRef (refIdx) { + undoHighlights(); + var seq = scytherP.proofstates[refIdx][1]; + //displaySequent(seq[0], seq[1]); + displayGraph(seq); + highlightElem( function() { return selectGraphRef(refIdx); } ); + } + + function highlightCaseRef (refIdx) { + undoHighlights(); + var c = scytherP.cases[refIdx][1]; + displayCase(c); + highlightElem( function() { return selectCaseRef(refIdx); } ); + } + + function highlightExplRef (refIdx) { + // undoHighlights(); + var expl = scytherP.explanations[refIdx][1]; + displayExplanation(expl); + // highlightElem( function() { return selectCaseRef(refIdx); } ); + } + + // displaying additional explanations + function displayExplanation (explanation) { + $("#ui-explanation-display").html(explanation); + } + + // building the generation info + function installGenerationInfo (info) { + var mkLink = function(file) { + return ('<a href="' + file[1] +'" target="new">' + file[0] + '</a>'); + }; + $("#gen-info-header").html(info.header); + $("#gen-info-time").html(info.time); + $("#gen-info-system").html(info.system); + $("#gen-info-input-file").html(mkLink(info.inputFile)); + $("#gen-info-proof-script").html(mkLink(info.proofScript)); + $("#gen-info-command-line").html(info.commandLine); + var certStatus = info.certificateStatus; + if (info.logFile != undefined) + certStatus += ' (' + mkLink(info.logFile) + ')'; + $("#gen-info-certificate-status").html(certStatus); + } + + // reference for the layout. + var myLayout; + + $(document).ready(function () { + // install layout + myLayout = $('body').layout(); + //myLayout.toggle("north"); + //myLayout.toggle("east"); + myLayout.sizePane("west", 400); + + // initialize tabs in east pane + $('#ui-tabs-east').tabs(); + + // install shift-down handler + installShiftDownHandler(); + + // parse json info + scytherP = json_parse(scytherP_theory_JSON); + scytherP.curRefIdx = ""; + // install inner html + $("#proof").html(scytherP.theory); + // install generation info + installGenerationInfo(scytherP.generationInfo); + // install event handlers for sequent references + jQuery.each(scytherP.proofstates, function(idx, assoc){ + var refIdx =assoc[0]; + var obj = selectGraphRef(refIdx); + obj.bind("click", function(e){ + highlightGraphRef(refIdx); + }); + obj.bind("mouseover", function(e){ + ifShiftDown(highlightGraphRef, refIdx); + }); + installHighlightClickable(obj, 'click to show visualization'); + }); + + // install event handlers for case references + jQuery.each(scytherP.cases, function(idx, assoc){ + var refIdx = assoc[0]; + var obj = selectCaseRef(refIdx); + obj.bind("mouseover", function(e){ + ifShiftDown(highlightCaseRef, refIdx); + }); + obj.bind("click", function(e){ + highlightCaseRef(refIdx); + }); + installHighlightClickable(obj, 'click to show case distinction'); + }); + + // install event handlers for explanation references + jQuery.each(scytherP.explanations, function(idx, assoc){ + var refIdx = assoc[0]; + var obj = selectExplRef(refIdx); + obj.bind("mouseover", function(e){ + ifShiftDown(highlightExplRef, refIdx); + }); + obj.bind("click", function(e){ + highlightExplRef(refIdx); + }); + }); + + // install event handlers for theorem references + jQuery.each(scytherP.theoremRefs, function(idx, assoc){ + var refIdx =assoc[0]; + selectThmRef(refIdx) + .tooltip({ + track: true, + delay: 200, + fade: 100, + opacity: .7, + bodyHandler: function() { + return $("<img/>").attr("src", graphFileName(assoc[1])) + .addClass("sequent-tooltip"); + } + }); + }); + + // hide all displays except pane explanation + hideAllDisplays(); + $("#ui-pane-explanation").removeClass("hidden"); + }); + </script> +</head> +<body> + +<div class="ui-layout-north"> + <div id="gen-info"> + <p id="gen-info-header" class="header"></p> + <table> + <tr> + <td class="topic">Generation date:</td> + <td id="gen-info-time"></td> + </tr> + <tr> + <td class="topic">Input file:</td> + <td id="gen-info-input-file" class="file"></td> + </tr> + <tr> + <td class="topic">Isabelle/HOL certificate:</td> + <td id="gen-info-proof-script" class="file"> + <a href="files/CR_talk_cert_auto.thy" target="new">CR_talk_cert_auto.thy</a> + </td> + </tr> + <tr> + <td/> + <td id="gen-info-certificate-status"></td> + </tr> + <tr> + <td class="topic">System information:</td> + <td id="gen-info-system"></td> + </tr> + <tr> + <td class="topic">Command line:</td> + <td id="gen-info-command-line"></td> + </tr> + </table> + </div> +</div> + +<div class="ui-layout-west"> + <div id="proof">Failed to load 'theory.js'. JavaScript needs to be + enabled for the visualization to work.</div> +</div> + +<div class="ui-layout-east"> + <div id="ui-tabs-east" class="ui-tabs"> + <ul> + <li><a href="#help-tab"><span>Help</span></a></li> + <li><a href="#debug-tab"><span>Debug Info</span></a></li> + </ul> + <div id="help-tab"> + <h1>Overview</h1> + <p> + This HTML page is a visualization of a security protocol + correctness proof. The underlying theory (i.e. protocol model, + verification theory, and verification algorithm) is described in + the paper <a href="http://www.inf.ethz.ch/personal/meiersi/publications/index.html#strong_invariants">Strong + Invariants for the Efficient Construction of Machine-Checked + Protocol Security Proofs</a> by Meier, Cremers, and Basin. + </p> + + <p> + The page was generated automatically and you can find additional + information about the the generation process in the top pane. If + you need more space to investigate the proofs and visualizations, + you can adjust the layout by moving the splitters. + </p> + + <h1>Security Protocol Theories</h1> + <p> + In the left pane, you find a pretty-printed version of the security + protocol theory that was verified. A security protocol theory is a + sequence of protocol definitions and security properties that these + protocols (should) satisfy. Each property that is satisfied is + accompanied by a proof. Most elements of the left pane can be + visualized. Just click on them to display their visualization in + the center pane. + </p> + + <h2>Protocol Definitions</h2> + + A protocol is a set of roles where each role is a list of send + and receive steps, which use pattern matching for sending and + receiving messages. The labels of send and receive steps have no + operational meaning. However, they are used for referencing these + steps in the properties and proofs. Patterns are constructed + using the following syntax. + <table> + <tr> + <td>'c' + </td> + <td>A global constant named <span class="math">c</span>. + </td> + </tr> + <tr> + <td>~n + </td> + <td>A freshly generated value (e.g., a nonce) named <span class="math">n</span>. + </td> + </tr> + <tr> + <td>?v + </td> + <td>A message variable named <span class="math">v</span>. + </td> + </tr> + <tr> + <td>a + </td> + <td>An agent variable named <span class="math">a</span>; i.e. "no-prefix" marks agent variables. + </td> + </tr> + <tr> + <td>h(m) + </td> + <td>The hash of the pattern <span class="math">m</span>. + </td> + </tr> + <tr> + <td>{m}k + </td> + <td>The encryption of the pattern <span class="math">m</span> with the key <span class="math">k</span>. + </td> + </tr> + <tr> + <td>sign{m}k + </td> + <td>A signature of the pattern <span class="math">m</span> that can be <em>verified</em> with the key <span class="math">k</span>. + </td> + </tr> + <tr> + <td>x1,..,xn + </td> + <td>The left-associative tuple <span class="math">(..((x1,x2),x3),..,xn)</span> of the patterns <span class="math">x1,..,xn</span>. + </td> + </tr> + <tr> + <td>pk(a) + </td> + <td>The long-term public key of <span class="math">a</span>. + </td> + </tr> + <tr> + <td>sk(a) + </td> + <td>The long-term private key of <span class="math">a</span>. + </td> + </tr> + <tr> + <td>k(a,b) + </td> + <td>The long-term shared key between <span class="math">a</span> and <span class="math">b</span>. + </td> + </tr> + </table> + Please see our paper for additional information. + + + <h2>Protocol Properties</h2> + <p> + There are two types of properties that can be proven + automatically: (1) Type invariants are required to make the case + distinction on the possible sources of a message finite despite + the untyped model we are working with. (2) Security properties + like secrecy and authentication. + </p> + + <span class="paragraph">Type invariants</span> + state for each message variable of every role of + the protocol what its possible contents can be in a reachable + state of the protocol. In the paper referenced above, we only + describe a single type invariant; namely that every message + variable is either instantiated with a nonce or something the + intruder knows before the variable was instantiated. We have + generalized this construction such that the "type" of a variable + can be specified more precisely. Types denote sets of messages + parametrized over the system state and a thread i. They are built + according to the following syntax. + <table> + <tr> + <td>Known@R_l + </td> + <td>All messages known before thread i executed step l of role R. + </td> + </tr> + <tr> + <td>n@R + </td> + <td>A nonce named n generated by some thread j executing role R. + </td> + </tr> + <tr> + <td>ty1 | ty2 + </td> + <td>The union of the messages denoted by ty1 and ty2. + </td> + </tr> + <tr> + <td>... + </td> + <td>Standard cryptographic constructors as for patterns. + </td> + </tr> + </table> + + + <p><span class="paragraph">Security properties</span> + are specified in the form of sequents (called judgments in the + paper) where all thread identifiers in the premise are universally + quantified and all additional thread identifiers in the conclusion + are existentially quantified. Thread identifiers are prefixed with + '#'. Local variables and actual freshly generated values are + denoted by their corresponding patterns suffixed with the + identifier of the thread that they are local to. Apart from these + constructions the syntax of messages and the predicates used in the + security property specifications should self-explanatory. + </p> + + <h2>Proofs</h2> + <p> + Proofs are trees consisting of nested case distinctions, + resolutions with already proven theorems, and triviality + justifications. The calculus employed is described in the paper + referenced above. The syntax for the proofs was inspired the + Isabelle's proof language ISAR. For the actual proof script that + can be machine-checked using Isabelle/HOL together with our + formalization of the verification theory, see the reference in the + top pane. + </p> + + <p> + Note that for properties <em>not</em> satisfied by the protocol, the + proof may contain missing branches. In these cases, the + corresponding proof script is not accepted by Isabelle/HOL. Moreover, + the proof state is likely to indicate an attack. + </p> + + <p> + All non-trivial elements of the proofs can be visualized by + clicking on them. For a case distinction on the possible sources of a + message m, we also highlight this message in the visualization by a + double border. + </p> + + <h2>Visualization</h2> + + There are three types of nodes: + <ol> + <li>Red colored ellipses list messages the intruder is supposed to know. + </li> + <li> + Colored rectangles list information about threads. They either + just denote that a role step was executed by the given thread + or they list additional equalities or compromisedness + information about the given thread. The quantification of + thread identifiers is denoted by the prefix "some" in the box + with the additional information. + </li> + <li> + Gray rectangles list logical facts that cannot be associated to + a fixed thread. + </li> + </ol> + The nodes are connected by edges denoting the required ordering + with respect to the reachable state in whose context we are + conducting the proof. Edges from the additional thread information + boxes to the first step executed by that thread have no logical + meaning in our verification theory. They could however be seen as + "thread creation" events. + + + <h1>Further Information</h1> + <p> + All of the work present here is work in progress. Both our + implementation of the proof-generation tool as well as the + Isabelle/HOL theories are scheduled to be open-sourced. If you + would like to have a preliminary snapshot or if you have + further questions, ideas, suggestions, ... please don't hesitate to + write a mail to <a + href="mailto:simon.meier@inf.ethz.ch">simon.meier@inf.ethz.ch</a>. + </p> + </div> + <div id="debug-tab"> + <p id="test-animate" class="debug">Debug information for the last selected item providing it:</p> + <pre id="ui-explanation-display"></pre> + </div> + </div> +</div> + +<div class="ui-layout-center"> + <div id="ui-pane-explanation"> + <table> + <tr><td></td><td></td><td style="text-align: center">^^</td><td></td><td></td></tr> + <tr><td></td><td></td><td>Top pane: information about proof generation and checking</td><td></td><td></td></tr> + <tr><td><<</td><td>Left Pane: proof script (select proof states by clicking)</td><td></td><td>Right pane: help and debug info </td><td>>></td></tr> + <tr><td></td><td></td><td><br><br><br><br>Center pane: visualization display</td><td></td><td></td></tr> + </table> + </div> + <div id="ui-sequent-display" style="width: 100%"> + <div id="outer-prem" class="outer" style="width: 50%"> + <div id="inner-prem" class="inner"> + <img id="prem-img" width="100%" title="" alt="Premise" /> + </div> + </div> + <div id="outer-concl" class="outer" style="width: 50%"> + <div id="inner-concl" class="inner"> + <img id="concl-img" width="100%" title="" alt="Conclusion" /> + </div> + </div> + </div> + <div id="ui-graph-display" style="width: 100%; height: 100%"> + <img id="graph-img"/> + </div> + <div id="ui-case-display" style="width: 100%; height: 100%"> + <h3>Case distinction performed on:</h3> + <div class="original"></div> + <h3>Non-trivial cases:</h3> + <div class="non-trivial"></div> + <h3>Trivial cases:</h3> + <div class="trivial"></div> + </div> +</div> + +</body> +</html> +
@@ -0,0 +1,5 @@+Simon Meier <meiersi@inf.ethz.ch>++Student contributor:+---------------------+Martin Schaub (extension of Isabelle theories to compromising adversaries)
@@ -0,0 +1,31 @@++## targets++default: ESPL+images: ESPL+test: ++all: images test+++## global settings++SRC = $(ISABELLE_HOME)/src+OUT = $(ISABELLE_OUTPUT)+LOG = $(OUT)/log++USEDIR = $(ISABELLE_TOOL) usedir -v true -i true ## -d pdf ## -D generated+++## ESPL++ESPL: $(OUT)/ESPL++$(OUT)/ESPL: ## ROOT.ML document/root.tex src/*.thy src/ESPLogic/*.thy src/ESPLogic/*.ML+ @$(USEDIR) -b -P http://isabelle.in.tum.de/library HOL ESPL+++## clean++clean:+ @rm -f $(OUT)/ESPL
@@ -0,0 +1,37 @@+# GNU Makefile for ScytherP and the Isabelle Embedded Security Protocol Logic+#+# Author: Simon Meier <simon.meier@inf.ethz.ch>+# Date: 13.1.2010+# Modified: 23.6.2010 - Renaming of scytherP to scyther-proof ++++# The following commands require+#+# a working GHC installation (tested with GHC 6.12.1)+# cabal-install (http://hackage.haskell.org/package/cabal-install)+#+# The easiest way to satisfy these requirements is to install the Haskell+# Platform (http://hackage.haskell.org/platform/).+#++# install the 'scyther-proof' executable.+scyther-proof-install:+ cd ScytherP; cabal install++# build the developer documentation (see the console output for its location).+scyther-proof-doc:+ cd ScytherP; cabal haddock --executables+++# The following commands require+#+# a working installation of Isabelle2009-1+# (http://www.cl.cam.ac.uk/research/hvg/Isabelle/).+#++# build an image of the ESPL formalization in Isabelle. This is required for+# the 'scyther-proof --isabelle' switch to work.+espl-image:+ isabelle make clean+ isabelle make
@@ -0,0 +1,165 @@+======================================================================+README for the scyther-proof security protocol verification tool+======================================================================++Author: Simon Meier <simon.meier@inf.ethz.ch>++Creation Date: 13/05/2011+++1. Introduction+===============++ Every distribution of the scyther-proof tool contains a copy of the+ Isabelle/HOL theories formalizing its verification theory and a copy of the+ protocol models that were verified using scyther-proof. In particular, these+ examples include models for all of our repaired versions of the protocols+ from the ISO/IEC-9798 authentication standard. (In the source distribution+ of scyther-proof they can be found at 'data/examples/iso9798'.)++ In the following sections, we give step by step instructions to get the+ whole system working and we explain the usage of our tools and provide+ further information (e.g., building documentation).+++2. Installation instructions+============================++2.1 Installing scyther-proof+----------------------------++ You need a working Haskell environment that provides GHC 7 and the 'cabal+ install' tool. The simplest way to get such an environment is to download and+ install the Haskell Platform package for your OS. + + http://hackage.haskell.org/platform/+ + Then call++ cabal install++ in the root directory of this source code package. This will use the+ Haskell's deployment tool 'cabal-install' to download all missing libraries+ from Hackage, the central Haskell library repository and install the+ 'scyther-proof' executable in the default installation location of+ cabal-install. The installation location is printed at the end of the build+ process.++ Call + + scyther-proof++ without any arguments to get an overview of the arguments supported and the+ paths to the examples and the Isabelle/HOL theories.+++3.2 Installing the Isabelle/HOL theories+----------------------------------------++ Download and install full Isabelle2009-1 according to the installation+ instructions at++ http://isabelle.in.tum.de/website-Isabelle2009-1/download_x86-linux.html++ The first time you call 'scyther-proof' with the '--isabelle' flag it will+ build the logic image of the Isabelle/HOL theories formalizing the security+ protocol verification theory underlying scyther-proof.++ For enabling interactive processing of theory files based using our+ extensions to Isabelle's ISAR proof language use one of the following two+ variants.++ Variant a: Brute Force+ ----------------------++ Overwrite the standard Emacs keywords file+ + $ISABELLE_HOME/etc/isar-keywords.el+ + with the Emacs keywords file provided with the ESPL distribution.+ + $SCYTHER_PROOF_HOME/isabelle/src/isar-keywords.el++ This is needed in order to make the new ISAR keywords "role",+ "protocol", "sources", and "prefix_close" available in the Emacs+ frontend.+++ Variant b: Elegance+ -------------------++ A more elegant way is to copy the keywords file provided with our+ distribution to++ $ISABELLE_HOME/etc/isar-keywords-ESPL.el++ and start Isabelle using the -k switch as follows.++ isabelle emacs -k ESPL <your-theory-file.thy>++ ++3. Usage+========+++3.1 scyther-proof+------------+++ Usage Example+ -------------++ You can now execute the 'scyther-proof' binary without any arguments to get a+ list of the available flags. A simple example usage is (assuming+ 'scyther-proof' is in the PATH).++ scyther-proof $EXAMPLE_DIR/classic/NS_Public.spthy --shortest++ This will parse the NSL protocol modeled in the 'nsl.spthy' file and output+ all specified security properties together with the proof with the fewest+ number of chain rule applications to stdout.++ In order to generate an Isabelle proof script two additional options need to+ be added++ scyther-proof $EXAMPLE_DIR/classic/NS_Public.spthy --shortest --output=nsl_cert.thy --ASCII++ The first one specifies the output file and the second one instructs+ scyther-proof to use Isabelle's ASCII notation as the output format.+++ To build the source code documentation you can use the call++ cabal configure; cabal haddock++ which will use cabal-install and Haskell's source code documentation tool+ 'haddock' to build the source code documentation. The location of this+ documentation is again output on the command line.+++3.2 The Isabelle/HOL theories+-----------------------------++ In the directory output by scyther-proof, load the Tutorial on interactive+ proof construction using the following commands++ cd <theory-dir-output-by-scytherproof>/src+ isabelle emacs Tutorial.thy++ or if you've chosen the elegant variant++ isabelle emacs -k ESPL Tutorial.thy++ Note that in many case the easiest way to start with constructing+ machine-checked proofs interactively is to use a proof script generated by+ scyther-proof.+++***+* Happy Proving :-)+*+* In case of questions do not hesistate to contact me at+* simon.meier@inf.ethz.ch+***+
@@ -0,0 +1,1 @@+use_thy "src/ESPLogic"
@@ -0,0 +1,63 @@+\documentclass[11pt,a4paper]{article}+\usepackage{isabelle,isabellesym}++% further packages required for unusual symbols (see also+% isabellesym.sty), use only when needed++%\usepackage{amssymb}+ %for \<leadsto>, \<box>, \<diamond>, \<sqsupset>, \<mho>, \<Join>,+ %\<lhd>, \<lesssim>, \<greatersim>, \<lessapprox>, \<greaterapprox>,+ %\<triangleq>, \<yen>, \<lozenge>++%\usepackage[greek,english]{babel}+ %option greek for \<euro>+ %option english (default language) for \<guillemotleft>, \<guillemotright>++%\usepackage[latin1]{inputenc}+ %for \<onesuperior>, \<onequarter>, \<twosuperior>, \<onehalf>,+ %\<threesuperior>, \<threequarters>, \<degree>++%\usepackage[only,bigsqcap]{stmaryrd}+ %for \<Sqinter>++%\usepackage{eufrak}+ %for \<AA> ... \<ZZ>, \<aa> ... \<zz> (also included in amssymb)++%\usepackage{textcomp}+ %for \<cent>, \<currency>++% this should be the last package used+\usepackage{pdfsetup}++% urls in roman style, theory text in math-similar italics+\urlstyle{rm}+\isabellestyle{it}++% for uniform font size+%\renewcommand{\isastyle}{\isastyleminor}+++\begin{document}++\title{ESPL}+\author{By simon}+\maketitle++\tableofcontents++% sane default for proof documents+\parindent 0pt\parskip 0.5ex++% generated text of all theories+\input{session}++% optional bibliography+%\bibliographystyle{abbrv}+%\bibliography{root}++\end{document}++%%% Local Variables:+%%% mode: latex+%%% TeX-master: t+%%% End:
@@ -0,0 +1,27 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+theory ESPLogic+imports+ "ESPLogic/Capabilities"+ "ESPLogic/InferenceRules"+ "ESPLogic/WeakTyping"+ "ESPLogic/Automation"+ "ESPLogic/Syntax"+ "ESPLogic/Unify"+begin++text{* This is the top-level theory node to be imported by+ users of the embedded security protocol logic.+*}++end
@@ -0,0 +1,387 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+theory Automation+imports+ Syntax+ InferenceRules+ WeakTyping+uses+ espl_definitions+ espl_methods+begin++section{* Automation *}++subsection{* Setup of ISAR commands *}++setup{* ESPL_Definitions.KnowsCasesCache.setup *}++method_setup sources =+ {* ESPL_Methods.sourcesP >> + (fn ((minimal, msg_t), opt_rule) => fn ctxt =>+ METHOD_CASES (fn facts => + Seq.DETERM (HEADGOAL (+ ESPL_Methods.sources_tac ctxt + minimal msg_t opt_rule facts))))+ *}+ "enumerate the possible sources of a term known to the intruder"++attribute_setup completeness_cases_rule = + {* Scan.succeed (Thm.rule_attribute + ESPL_Methods.completeness_cases_attrib) *}+ "conversion to a completeness cases rule"++attribute_setup type_elim_rule = + {* Scan.succeed (Thm.declaration_attribute + (fn th => fn ctxt =>+ if member Thm.eq_thm (ESPL_Definitions.TypeElimRulesData.get ctxt) th+ then ctxt+ else ESPL_Definitions.TypeElimRulesData.map (fn ths => th::ths) ctxt)) *}+ "marks a theorem as a rule that should be used for type information eliminitation"++declare (in typed_state) decrChain_SumT_KnownTE[type_elim_rule]+declare (in typed_state) decrChain_KnownTE[type_elim_rule]+declare (in typed_state) decrChain_AgentTE[type_elim_rule]++++subsection{* Setting up Isabelle built-in Tools *}++text{*+ The unification based on ordered rewritting is somewhat fragile.+ We have to see what equations we still have to add to avoid+ looping in the simplifier.+*}+lemma tid_eq_commute [simp]: "((i1::tid) = i2) = (i2 = i1)"+ by (rule eq_commute)++lemma all_imp_insert [simp]: + "(\<forall> a. (a = x \<longrightarrow> P a) \<and> Q a) = (P x \<and> (\<forall> a. Q a))"+ by(auto)++lemma all2_imp_insert [simp]: + "(\<forall> a b. ((a = x \<and> b = y) \<longrightarrow> P a b) \<and> Q a b) = (P x y \<and> (\<forall> a b. Q a b))"+ by fast+++lemma ball_Un_pairParts [iff]:+ "(\<forall> im \<in> pairParts x \<union> pairParts y. P im) =+ ((\<forall> im \<in> pairParts x. P im) \<and> (\<forall> im \<in> pairParts y. P im))"+ by fast++lemma ball_pairParts_Rep_subst_Var [dest!]:+ "\<forall> im \<in> pairParts (Rep_subst s (EVar v i)). P im \<Longrightarrow>+ P (Rep_subst s (EVar v i))"+ by fast++lemma (in reachable_state) decrChain_Rep_subst_AVar [iff]:+ "from \<noteq> {} \<Longrightarrow> + \<not> decrChain path t from (s (AVar v, i)) m"+ using inst_AVar_cases[of v i] + by (auto simp: Agent_def)++lemma (in reachable_state) remove_trivial_predOrd [dest!]:+ "Ln (Lit (EConst c)) \<prec> y \<Longrightarrow> True"+ "Ln (s (AVar v, i)) \<prec> y \<Longrightarrow> True"+ "Ln (Lit (EAgent a)) \<prec> y \<Longrightarrow> True"+ "Ln (Lit (EveNonce n)) \<prec> y \<Longrightarrow> True"+ "Ln (PK m) \<prec> y \<Longrightarrow> True"+ by auto++(* FIXME: Remove this lemma, automation should cope otherwise *)+lemma (in reachable_state) extract_knows_hyps:+ "Ln m \<prec> St e \<Longrightarrow> m \<in> knows t"+ "St e \<prec> Ln m \<Longrightarrow> m \<in> knows t"+ "LKR a \<prec> Ln m \<Longrightarrow> m \<in> knows t"+ "Ln m \<prec> LKR a \<Longrightarrow> m \<in> knows t"+ "Ln m \<prec> Ln m' \<Longrightarrow> m \<in> knows t \<and> m' \<in> knows t"+ by (auto intro: event_predOrdI)++declare (in reachable_state) conjE[OF split_before, elim!]+declare (in reachable_state) conjE[OF split_knows, elim!]++lemma (in reachable_state) reorient_store_eqs [iff]:+ "(Lit l' = s l) = (s l = Lit l')"+ "(Lit l' \<noteq> s l) = (s l \<noteq> Lit l')"+ "(Tup x y = s l) = (s l = Tup x y)"+ "(Enc m k = s l) = (s l = Enc m k)"+ "(Hash m = s l) = (s l = Hash m)"+ "(K a b = s l) = (s l = K a b)"+ "(PK a = s l) = (s l = PK a)"+ "(SK a = s l) = (s l = SK a)"+ by auto++lemma (in reachable_state) reorient_store_eq_store_fixed [simp]: + "(s (AV a i) = s (MV v j)) = (s (MV v j) = s (AV a i))"+ "(s (AV a i) = s (AV v j)) = (s (AV v j) = s (AV a i))"+ "(s (MV a i) = s (MV v j)) = (s (MV v j) = s (MV a i))"+ by auto++text{* Required by \verb|note_unified| *}+lemma (in reachable_state) reorient_store_eq_store: + "(s x = s y) = (s y = s x)"+ by auto++text{* Removes all impossible cases for lkreveals and LKR*}+lemma (in reachable_state) remove_predOrd_LKR [dest!]:+ "(LKR (Tup x y)) \<prec> e \<Longrightarrow> False"+ "e \<prec> (LKR (Tup x y)) \<Longrightarrow> False"+ "(LKR (Enc m k)) \<prec> e \<Longrightarrow> False"+ "e \<prec> (LKR (Enc m k)) \<Longrightarrow> False"+ "(LKR (Hash m)) \<prec> e \<Longrightarrow> False"+ "e \<prec> (LKR (Hash m)) \<Longrightarrow> False"+ "(LKR (K a b)) \<prec> e \<Longrightarrow> False"+ "e \<prec> (LKR (K a b)) \<Longrightarrow> False"+ "(LKR (SK a)) \<prec> e \<Longrightarrow> False"+ "e \<prec> (LKR (SK a)) \<Longrightarrow> False" + "(LKR (PK a)) \<prec> e \<Longrightarrow> False"+ "e \<prec> (LKR (PK a)) \<Longrightarrow> False"+ "(LKR (Lit (EConst i))) \<prec> e \<Longrightarrow> False"+ "e \<prec> (LKR (Lit (EConst i))) \<Longrightarrow> False"+ "(LKR (Lit (ENonce i j))) \<prec> e \<Longrightarrow> False"+ "e \<prec> (LKR (Lit (ENonce i j))) \<Longrightarrow> False"+ "(LKR (Lit (EveNonce i))) \<prec> e \<Longrightarrow> False"+ "e \<prec> (LKR (Lit (EveNonce i))) \<Longrightarrow> False"+by(auto dest: predOrd_LKR_agent1 predOrd_LKR_agent2)+++subsection{* Testing the Infrastructure *}+++(*+text{*+ Commented out because new ISAR syntax comes only active after+ the theory file that defines them.+*}++role C+where "C =+ [ Send ''1'' ( PEnc ( sN ''k'' ) ( sPK ''S'' ) )+ , Recv ''2'' ( PHash ( sN ''k'' ) )+ , Note ''3'' SessKey (sN ''k'')+ ]"++role S+where "S =+ [ Recv ''1'' ( PEnc ( sMV ''k'' ) ( sPK ''S'' ) )+ , Send ''2'' ( PHash ( sMV ''k'' ) )+ ]"++protocol CR+where "CR = { C, S }"++locale restricted_CR_state = CR_state++type_invariant auto_msc_typing for CR+where "auto_msc_typing = mk_typing+ [ ((S, ''k''), (SumT (KnownT S_1) (NonceT C ''k'')))+ ]"+++lemma additional_reveal_order:+ assumes facts:+ "predOrd t (LKR a) c"+ shows + "a \<in> lkreveals t \<and> predOrd t (LKR a) c"+using facts+by(auto intro: event_predOrdI)++sublocale CR_state < auto_msc_typing_state+proof -+ have "(t,r,s) : approx auto_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF auto_msc_typing.monoTyp, completeness_cases_rule])+ case (S_1_k t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc ( s(MV ''k'' tid0) ) ( PK ( s(AV ''S'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ qed+ thus "auto_msc_typing_state t r s" by unfold_locales auto+qed++lemma (in restricted_CR_state) C_k_order_raw:+ assumes facts:+ "roleMap r tid0 = Some C"+ shows+ "LN ''k'' tid0 \<in> knows t \<longrightarrow>+ (LKR (s(AV ''S'' tid0))) \<prec> (Ln (LN ''k'' tid0)) \<or> + (St (tid0, C_3) \<prec> (Ln (LN ''k'' tid0)))" + (is "?knows \<longrightarrow> ?order")+proof+ assume "?knows"+ thus "?order" using facts+ proof (sources "LN ''k'' tid0")+ case C_1_k+ thus ?thesis+ by (sources "SK (s (AV ''S'' tid0))") (fastsimp intro: event_predOrdI)++ qed auto+qed++(*+lemmas (in restricted_CR_state) C_k_order = C_k_order_raw[rule_format, THEN additional_reveal_order]+*)++lemma (in restricted_CR_state) C_k_secrecy:+ assumes facts:+ "roleMap r tid0 = Some C"+ "s(AV ''S'' tid0) ~: lkreveals t"+ "(tid0, C_3) \<notin> steps t"+ "LN ''k'' tid0 : knows t"+ shows "False"+using facts +by(fastsimp dest: C_k_order_raw[rule_format] + intro: event_predOrdI)+++*)+++(*+text{*+ Commented out because new ISAR syntax comes only active after+ the theory file that defines them.+*}++text{* Testing the role definition command *}+role I+where "I \<equiv> + [ Send ''0'' (PEnc \<langle>sLC ''0'', sAV ''I'', sN ''ni''\<rangle> (sPK ''R''))+ , Recv ''1'' (PEnc \<langle>sLC ''1'', sAV ''R'', sN ''ni'', sMV ''nr''\<rangle> (sPK ''I''))+ , Send ''2'' (PEnc \<langle>sLC ''2'', sMV ''nr''\<rangle> (sPK ''R''))+ ]"++text{* A few of the proven theorems: *}+thm I.weakly_atomic_convs+thm I_def+thm I.unfold+thm I.wf_role+thm I.distinct_steps+thm I.in_set_conv+thm I.zip_conv+thm I.prefixClose_convs++thm I_1_def+thm I_1.unfold+thm I_1_pt_def+thm I_1.inst_conv+thm I_1.sendStep_conv+thm I_1.stepPat_conv+thm I_1.FV_conv+thm I_1.FMV_conv++text{* + Note that you should not need to use these theorems manually as the + simplifier and the classical reasoner are already setup such that+ they are used when appropriate.++ The general design idea behind the rules is such that wherever possible+ constants are not unfolded, as this simplifies proof states.+*}++text{* An additional role for testing purposes. *}+role R+where "R \<equiv>+ [ Recv ''0'' (PEnc \<langle>sLC ''0'', sLAV ''I'', sLMV ''ni''\<rangle> (sPK ''R''))+ , Send ''1'' (PEnc \<langle>sLC ''1'', sLAV ''R'', sLMV ''ni'', sLN ''nr''\<rangle> (sPK ''I''))+ , Recv ''2'' (PEnc \<langle>sLC ''2'', sLN ''nr''\<rangle> (sPK ''R''))+ ]"++thm R.weakly_atomic_convs++protocol nsl+where "nsl = {I, R}"++text{* Testing the protocol definition command; the generated theorems: *}+thm nsl_def+thm nsl.unfold+thm nsl.wf_proto+thm nsl.distinct_roles+thm nsl.in_set_conv++type_invariant typed_nsl for nsl+where "typed_nsl = mk_typing+ [ ((R, ''ni''), (SumT (KnownT R_0) (NonceT I ''ni'')))+ , ((I, ''nr''), (SumT (KnownT I_1) (NonceT R ''nr'')))+ ]"+++sublocale nsl_state \<subseteq> typed_nsl_state+proof -+ have "(t,r,s) \<in> approx typed_nsl"+ proof(cases rule: reachable_in_approxI_ext+ [OF typed_nsl.monoTyp, completeness_cases_rule])+ case (I_1_nr t r s i)+ then interpret state: typed_nsl_state t r s+ by unfold_locales auto+ show ?case using I_1_nr+ proof(sources "inst s i I_1_pt")+ qed (fastsimp intro: event_predOrdI split: if_splits)++ next+ case (R_0_ni t r s i)+ then interpret state: typed_nsl_state t r s+ by unfold_locales auto+ show ?case using R_0_ni+ proof(sources "inst s i R_0_pt")+ qed (fastsimp intro: event_predOrdI split: if_splits)++ qed+ thus "typed_nsl_state t r s" by unfold_locales auto+qed++context nsl_state begin+ lemma longterm_private_key_secrecy:+ assumes facts:+ "SK m : knows t"+ "m ~: Compromised"+ shows "False"+ using facts by (sources "SK m")++ lemma longterm_shared_key_secrecy:+ assumes facts:+ "K m1 m2 : knows t"+ "m1 ~: Compromised"+ "m2 ~: Compromised"+ shows "False"+ using facts by (sources "K m1 m2")++ lemmas ltk_secrecy =+ longterm_shared_key_secrecy+ longterm_shared_key_secrecy[OF in_knows_predOrd1]+ longterm_private_key_secrecy+ longterm_private_key_secrecy[OF in_knows_predOrd1]+end++lemma (in nsl_state) I_ni_secrecy:+ assumes facts:+ "roleMap r i = Some I"+ "LN ''ni'' i \<in> knows t"+ "s (AV ''I'' i) \<notin> lkreveals t"+ "s (AV ''R'' i) \<notin> lkreveals t" + shows "False"+using facts proof(sources " LN ''ni'' tid0 ")+ case I_0_ni thus ?thesis by (fastsimp dest!: ltk_secrecy)+next+ case (R_1_ni tid1) thus ?thesis + proof(sources "inst s tid1 R_0_pt")+ case I_0_enc thus ?thesis + by (fastsimp dest!: ltk_secrecy)+ qed (insert facts, (((clarsimp, order?) | order))+)?+qed+++*)+++end
@@ -0,0 +1,258 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+theory Capabilities+imports+ ExplicitModel+ InferenceRules+begin++chapter{* Compromising Adversary Capability *}++section{* Partnering *}+types partnering = "state \<Rightarrow> (tid \<times> tid) set"+++definition unionPart :: "partnering \<Rightarrow> partnering \<Rightarrow> partnering" (infix "UNP" 65)+where+ "unionPart P1 P2 q = P1 q \<union> P2 q" ++notation (xsymbols)+ unionPart (infix "\<union>\<^isub>P" 65)++lemma union_unionPart_conv:+ "(a \<in> ((P1 \<union>\<^isub>P P2) q)) = (a \<in> (P1 q \<union> P2 q))"+by (fastsimp simp add: unionPart_def)+++definition mk_partnering :: "role \<Rightarrow> role \<Rightarrow> (pattern \<times> pattern \<times> rolestep) set \<Rightarrow> partnering"+where+ "mk_partnering R1 R2 conds q = (case q of (t,r,s) \<Rightarrow>+ {(i,j) | i j. roleMap r i = Some R1 \<and> roleMap r j = Some R2 \<and> + (\<forall> (p1,p2,st) \<in> conds. (j,st) \<in> steps t \<longrightarrow> (inst s i p1) = (inst s j p2)) })"++lemma mk_partnering_conv:+ "((i,j) \<in> mk_partnering R1 R2 conds (t,r,s)) = + (roleMap r i = Some R1 \<and> roleMap r j = Some R2 \<and> + (\<forall> (p1,p2,st) \<in> conds. (j,st) \<in> steps t \<longrightarrow> (inst s i p1) = (inst s j p2)))"+by (fastsimp simp add: mk_partnering_def)++lemma setEqImpTupleIn: "(X = Y) \<Longrightarrow> ((i,j) \<in> X) = ((i,j) \<in> Y)"+by fastsimp++lemma uniquePartner: + assumes facts:+ "(i,j) \<in> mk_partnering R1 R2 conds (t,r,s)"+ "(pt1,pt2,st) \<in> conds"+ "(j,st) \<in> steps t"+ "pt2 = PFresh n"+ shows+ "\<forall> j'. (i,j') \<in> mk_partnering R1 R2 conds (t,r,s) \<and> (j',st) \<in> steps t \<longrightarrow> j' = j"+proof -+ have "inst s i pt1 = inst s j pt2"+ using facts by (fastsimp simp add: mk_partnering_conv)+ moreover + hence "\<forall> j'. j' \<noteq> j \<longrightarrow> inst s j pt2 \<noteq> inst s j' pt2"+ using facts by fastsimp+ ultimately + have "\<forall> j'. j' \<noteq> j \<longrightarrow> inst s i pt1 \<noteq> inst s j' pt2"+ by fastsimp+ hence "\<forall> j'. (j' \<noteq> j \<and> (j',st) \<in> steps t) \<longrightarrow> (i,j') \<notin> mk_partnering R1 R2 conds (t,r,s)"+ using facts by (fastsimp simp add: mk_partnering_conv)+ thus ?thesis+ by auto+qed++lemma mk_partneringRole:+ assumes facts:+ "(i,j) \<in> mk_partnering R1 R2 conds (t,r,s)"+ shows+ "roleMap r i = Some R1 \<and> roleMap r j = Some R2"+using facts+by (fastsimp simp add: mk_partnering_conv)++section{* Capabilities *}++types capability = "state \<Rightarrow> reveal set"++subsection{* Helper Functions *}+definition interCap :: "capability \<Rightarrow> capability \<Rightarrow> capability" (infix "INC" 65)+where+ "interCap C1 C2 = (\<lambda> q. C1 q \<inter> C2 q)"++notation (xsymbols)+ interCap (infix "\<inter>\<^isub>C" 65)++definition unionCap :: "capability \<Rightarrow> capability \<Rightarrow> capability" (infix "UNC" 65)+where+ "unionCap C1 C2 = (\<lambda> q. C1 q \<union> C2 q)" ++notation (xsymbols)+ unionCap (infix "\<union>\<^isub>C" 65)++lemma union_unionCap_conv:+ "(a \<in> ((C1 \<union>\<^isub>C C2) q)) = (a \<in> (C1 q \<union> C2 q))"+by (fastsimp simp add: unionCap_def)++lemma inter_interCap_conv:+ "(a \<in> ((C1 \<inter>\<^isub>C C2) q)) = (a \<in> (C1 q \<inter> C2 q))"+by (fastsimp simp add: interCap_def)+++subsection{* Adversary-Compromise Model *}++definition acm :: "capability set \<Rightarrow> state set"+where+ "acm caps = { (t,r,s) | t r s. \<forall> reveal \<in> reveals t. \<exists> cap \<in> caps. reveal \<in> cap (t,r,s) }"++lemma acm_to_caps:+"\<lbrakk> + (t,r,s) \<in> acm caps ; + reveal \<in> reveals t + \<rbrakk> \<Longrightarrow> \<exists> cap \<in> caps. reveal \<in> cap (t,r,s)"+by(fastsimp simp add: acm_def)+++lemma acm_monotone:+"\<lbrakk> (t,r,s) \<in> acm caps \<rbrakk> + \<Longrightarrow> (t,r,s) \<in> acm (caps \<union> caps')"+by(fastsimp simp add: acm_def)++subsection{* Implementation of Capabilities and Dot-Mapping *}++subsubsection{* Long Term Key Reveals *}+fun LKRprotected :: "tid \<Rightarrow> varid set \<Rightarrow> capability"+where+ "LKRprotected i pAVars (t,r,s) = {RLKR a | a. \<forall> pAVar \<in> pAVars. s (pAVar, i) \<noteq> a}"++fun LKRafterStep :: "tid \<Rightarrow> rolestep \<Rightarrow> capability"+where+ "LKRafterStep i step (t,r,s) = {RLKR a | a. predOrd t (St (i,step)) (LKR a)}"++fun LKRbeforeStep :: "tid \<Rightarrow> rolestep \<Rightarrow> capability"+where+ "LKRbeforeStep i step (t,r,s) = {RLKR a | a. predOrd t (LKR a) (St (i, step))}"++fun LKRactor :: "tid \<Rightarrow> varid \<Rightarrow> capability"+where+ "LKRactor i actor (t,r,s) = {RLKR (s (actor, i))} \<inter> + {a. \<exists> R. roleMap r i = Some R \<and> a \<in> LKRprotected i ((aVars R) - {actor}) (t,r,s)}"++fun LKRpeers :: "tid \<Rightarrow> varid \<Rightarrow> capability"+where+ "LKRpeers i actor (t,r,s) = {a. \<exists> R. roleMap r i = Some R \<and> a \<in> LKRprotected i (aVars R - {actor}) (t,r,s)}"++fun LKRothers :: "tid \<Rightarrow> capability"+where+ "LKRothers i (t,r,s) = {a. \<exists> R. roleMap r i = Some R \<and> a \<in> LKRprotected i (aVars R) (t,r,s)}"++fun LKRafter :: "tid \<Rightarrow> capability"+where + "LKRafter i (t,r,s) = {a. \<exists> R st. roleMap r i = Some R \<and> lastComStep R = Some st \<and> a \<in> LKRafterStep i st (t,r,s)}"++fun LKRbefore :: "tid \<Rightarrow> capability"+where + "LKRbefore i (t,r,s) = {a. \<exists> R st. roleMap r i = Some R \<and> firstComStep R = Some st \<and> a \<in> LKRbeforeStep i st (t,r,s)}"++fun LKRduring :: "tid \<Rightarrow> capability"+where+ "LKRduring i q = {a. a \<notin> LKRafter i q \<and> a \<notin> LKRbefore i q}"++text{* The partnering definition used in this capability must ensure, that + if two threads are partners, they their transcript match, i.e. they + have matching histories. That means all variables must be included! *}+fun LKRafterCorrect :: "tid \<Rightarrow> partnering \<Rightarrow> capability"+where + "LKRafterCorrect i ps (t,r,s) = + {a. \<exists> R st. roleMap r i = Some R \<and> lastComStep R = Some st \<and> a \<in> LKRafterStep i st (t,r,s) \<and> + (\<exists> (i,j) \<in> ps (t,r,s). (\<exists> R' st'. roleMap r j = Some R' \<and> lastComStep R' = Some st' \<and> a \<in> LKRafterStep j st' (t,r,s) ))}"+++lemma imposs_lkr_caps[iff]:+ "RCompr a b \<notin> LKRprotected i vars (t,r,s)"+ "RCompr a b \<notin> LKRothers i (t,r,s)"+ "RCompr a b \<notin> LKRactor i c (t,r,s)"+ "RCompr a b \<notin> LKRafter i (t,r,s)"+ "RCompr a b \<notin> LKRafterCorrect i ps(t,r,s)"+by(fastsimp)++++subsubsection{* Compromises *}++definition RNR :: "capability"+where+ "RNR _ = {RCompr RandGen j| j. True}"++definition SKs :: "capability"+where+ "SKs _ = {RCompr SessKey j| j. True}"++definition otherData :: "capability"+where+ "otherData _ = {RCompr State j| j. True}"+++definition comprOthers :: "tid \<Rightarrow> partnering \<Rightarrow> capability"+where+ "comprOthers i ps q = {RCompr State j| j. (i,j) \<notin> ps q} \<union>+ {RCompr SessKey j| j. (i,j) \<notin> ps q} \<union>+ {RCompr RandGen j| j. (i,j) \<notin> ps q}"++definition comprPartners :: "tid \<Rightarrow> partnering \<Rightarrow> capability"+where+ "comprPartners i ps q = UNIV - comprOthers i ps q"++definition SkR :: "tid \<Rightarrow> partnering \<Rightarrow> capability"+where+ "SkR i ps q = {RCompr SessKey j | j. (i,j) \<notin> ps q \<and> j \<noteq> i}"+++definition StR :: "tid \<Rightarrow> partnering \<Rightarrow> capability"+where+ "StR i ps q = {RCompr State j | j. (i,j) \<notin> ps q \<and> j \<noteq> i}"++lemma imposs_compr_caps[iff]:+ "RLKR a \<notin> StR i ps q"+ "RLKR a \<notin> SkR i ps q"+ "RLKR a \<notin> RNR q"+ "RCompr SessKey j \<notin> StR i ps q"+ "RCompr RandGen j \<notin> StR i ps q"+ "RCompr State j \<notin> SkR i ps q"+ "RCompr RandGen j \<notin> SkR i ps q"+ "RCompr State j \<notin> RNR q"+ "RCompr SessKey j \<notin> RNR q"+by(fastsimp simp add: StR_def SkR_def RNR_def)++++lemma SkR_conv[simp]:+ "c \<in> SkR i ps (t,r,s) = (\<exists> j. (c = RCompr SessKey j) \<and> (i,j) \<notin> ps (t,r,s) \<and> j \<noteq> i )"+by(fastsimp simp add: SkR_def)++lemma RNR_conv[simp]:+ "c \<in> RNR (t,r,s) = (\<exists> j. (c = RCompr RandGen j))"+by(fastsimp simp add: RNR_def)++lemma StR_conv[simp]:+ "c \<in> StR i ps (t,r,s) = (\<exists> j. (c = RCompr State j) \<and> (i,j) \<notin> ps (t,r,s) \<and> j \<noteq> i )"+by(fastsimp simp add: StR_def)+++lemma (in reachable_state) LKRafterTrans:+ "\<lbrakk>+ roleMap r i = Some R;+ lastComStep R = Some st;+ RLKR a \<in> LKRafter i (t,r,s);+ LKR a \<prec> St (i,st)+ \<rbrakk> \<Longrightarrow> False"+by(fastsimp)++end
@@ -0,0 +1,225 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+theory DistinctList+imports Main+begin++chapter{* Preliminaries *}++section{* Splitting Lists *}+++fun splits :: "'a list \<Rightarrow> ('a list \<times> 'a list) list"+where+ "splits [] = [([],[])]"+| "splits (x#xs) = ([],x#xs) # map (\<lambda>(pre,suf). (x#pre,suf)) (splits xs)"++lemma in_set_splits_conv: + "((ys,zs) \<in> set (splits xs)) = (xs = ys @ zs)"+by(induct xs arbitrary: ys zs) (auto simp: Cons_eq_append_conv)+++section{* Distinct Lists *}++lemma distinct_in_set_decomp: + assumes "x \<in> set xs" and "distinct xs"+ shows "\<exists> ys zs. xs = ys@ x # zs \<and> + x \<notin> set ys \<and> x \<notin> set zs \<and> set ys \<inter> set zs = {}"+ (is "\<exists> ys zs. ?split xs ys zs")+using assms+proof(induct xs)+ case (Cons a xs)+ hence "x = a \<or> x \<in> set xs" (is "?hd \<or> ?tl") by simp+ moreover+ { assume ?hd + hence "?split (a#xs) [] xs" using Cons by auto+ hence ?case by fast+ }+ moreover+ { assume ?tl then + obtain ys zs where "?split xs ys zs" using Cons by auto+ with Cons have "?split (a#xs) (a#ys) zs" by auto+ hence ?case by fast+ }+ ultimately show ?case by fast+ next+qed simp+++subsection{* Direct Predecessors *}++fun "nextRel" :: "'a list \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"+where+ "nextRel [] a b = False"+| "nextRel [x] a b = False"+| "nextRel (x#y#xs) a b = ((a = x \<and> b = y) \<or> (nextRel (y#xs) a b))"++lemma nextRelI: "xs = ys@x#y#zs \<Longrightarrow> nextRel xs x y"+ by (induct xs x y arbitrary: ys rule: nextRel.induct)+ (auto simp: Cons_eq_append_conv)++lemma nextRelD:+ "nextRel xs x y \<Longrightarrow> (\<exists> ys zs. xs = ys@x#y#zs)"+ by (induct xs x y arbitrary: ys rule: nextRel.induct)+ (auto simp: Cons_eq_append_conv)++lemma nextRel_conv:+ "(nextRel xs x y) = (\<exists> ys zs. xs = ys@x#y#zs)"+ by(auto intro: nextRelI nextRelD)++lemma in_set_nextRel1: "nextRel xs x y \<Longrightarrow> x \<in> set xs"+ by(auto simp: nextRel_conv)++lemma in_set_nextRel2: "nextRel xs x y \<Longrightarrow> y \<in> set xs"+ by(auto simp: nextRel_conv)++lemma nextRel_rev:+ "nextRel (rev xs) x y = nextRel xs y x"+unfolding nextRel_conv+proof+ assume "\<exists>ys zs. xs = ys @ y # x # zs" then+ obtain ys zs where "xs = ys @ y # x # zs" by fast+ then have "rev xs = rev (ys @ y # x # zs)" by (rule arg_cong)+ then show "\<exists>ys zs. rev xs = ys @ x # y # zs" by auto+next+ assume "\<exists>ys zs. rev xs = ys @ x # y # zs" then+ obtain ys zs where "rev xs = ys @ x # y # zs" by fast+ then have "rev (rev xs) = rev (ys @ x # y # zs)" by (rule arg_cong)+ then show "\<exists>ys zs. xs = ys @ y # x # zs" by auto+qed+++text{* Specialized instances of nextRel_rev for Snoc appends *}+lemma nextRel_Snoc_simps:+ "nextRel (xs@[a]) x y = nextRel (a#rev xs) y x"+ "nextRel (xs@[a,b]) x y = nextRel (b#a#rev xs) y x"+ by(subst nextRel_rev[symmetric], simp)+++lemma nextRel_Cons_simps:+ "x \<noteq> y \<Longrightarrow> nextRel (x#xs) y z = nextRel xs y z"+ "x' \<noteq> z \<Longrightarrow> nextRel (x#x'#xs) y z = nextRel (x'#xs) y z"+ by (cases xs) simp+++lemmas nextRel_simps [simp] = + nextRel_rev nextRel_Snoc_simps nextRel_Cons_simps+ +lemma nextRelI_direct [simp,intro!]: "nextRel (xs@x#y#ys) x y"+ by(auto simp: nextRel_conv)++lemma nextRel_appendI1:+ "nextRel xs x y \<Longrightarrow> nextRel (xs@ys) x y"+ by(induct xs x y rule: nextRel.induct) auto++++subsection{* Predecessors *}++fun listOrd :: "'a list \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"+where+ "listOrd [] a b = False"+| "listOrd (x#xs) a b = ((a = x \<and> b \<in> set xs) \<or> listOrd xs a b)"++lemma in_set_listOrd1: "listOrd xs x y \<Longrightarrow> x \<in> set xs"+ by(induct xs, auto)++lemma in_set_listOrd2: "listOrd xs x y \<Longrightarrow> y \<in> set xs"+ by(induct xs, auto)++lemma listOrd_append [simp]: + "listOrd (xs@ys) a b = + (listOrd xs a b \<or> listOrd ys a b \<or> (a \<in> set xs \<and> b \<in> set ys))"+ by(induct xs, auto)++lemma listOrd_rev [simp]: "listOrd (rev xs) x y = listOrd xs y x"+ by(induct xs, auto)++lemma nextRel_imp_listOrd: "nextRel xs x y \<Longrightarrow> listOrd xs x y"+ by(induct xs x y rule: nextRel.induct) auto++lemma listOrd_filter: "listOrd (filter p xs) x y \<Longrightarrow> listOrd xs x y"+ by(induct xs) (auto split: if_splits)++lemma listOrd_takeWhile: "listOrd (takeWhile p xs) x y \<Longrightarrow> listOrd xs x y"+proof(induct xs)+case Nil+ thus ?case by auto+next+case (Cons a xs)+ thus ?case by(auto split: if_splits dest: set_takeWhileD)+qed ++lemma list_Ord_singleton[simp]: "listOrd [a] x y \<Longrightarrow> False"+ by auto++lemma listOrd_distinct_irr [simp]: "distinct xs \<Longrightarrow> \<not>listOrd xs x x"+ by(induct xs, auto)++lemma listOrd_distinct_trans: + "\<lbrakk> listOrd xs x y; listOrd xs y z; distinct xs \<rbrakk> + \<Longrightarrow> listOrd xs x z"+ by (induct xs) (auto dest: in_set_listOrd1 in_set_listOrd2)++lemma listOrd_distinct_asymD: + "\<lbrakk> listOrd xs x y; distinct xs \<rbrakk> \<Longrightarrow> \<not> listOrd xs y x"+ by (induct xs) (auto dest: in_set_listOrd1 in_set_listOrd2)++lemma listOrd_distinct_cases: + "\<lbrakk> x \<in> set xs; y \<in> set xs; distinct xs \<rbrakk> + \<Longrightarrow> x = y \<or> listOrd xs x y \<or> listOrd xs y x"+ by(induct xs, auto)++definition listEqOrd :: "'a list \<Rightarrow> 'a \<Rightarrow> 'a \<Rightarrow> bool"+ where "listEqOrd xs x y \<equiv> (x = y) \<or> listOrd xs x y"+++subsection{* List Order *}++locale distinct_list = + fixes xs :: "'a list"+ assumes distinct [simp,intro!]: "distinct xs"+begin+ abbreviation "next" (infixl "\<prec>\<^sub>1" 50) where "next \<equiv> nextRel xs"+ abbreviation pred (infixl "\<prec>" 50) where "pred \<equiv> listOrd xs"+ abbreviation predEq (infixl "\<preceq>" 50) where "predEq \<equiv> listEqOrd xs"+end++text{* Aquiring the order properties *}++sublocale distinct_list \<subseteq> order "predEq" "pred"+ by unfold_locales+ (auto simp: listEqOrd_def+ dest: listOrd_distinct_asymD + intro: listOrd_distinct_trans)+++text{* Relating @{term next} to the order *}++context distinct_list begin++lemma next_imp_less: "x \<prec>\<^sub>1 y \<Longrightarrow> x \<prec> y"+ by(auto simp: listEqOrd_def + dest!: nextRel_imp_listOrd)++lemma next_imp_le: "x \<prec>\<^sub>1 y \<Longrightarrow> x \<preceq> y"+ by(auto dest: next_imp_less)++lemma in_set_less1: "x \<prec> y \<Longrightarrow> x \<in> set xs"+ by(simp add: pred_def in_set_listOrd1)++lemma in_set_less2: "x \<prec> y \<Longrightarrow> y \<in> set xs"+ by(simp add: pred_def in_set_listOrd2)++lemmas in_set_next1 = in_set_less1[OF next_imp_less, rule_format]+lemmas in_set_next2 = in_set_less2[OF next_imp_less, rule_format]+++end+++end
@@ -0,0 +1,496 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+theory ExecMessage+imports + Protocol+begin++subsection{* Execution Messages *}++typedef tid = "UNIV :: nat set" by blast++datatype execlit = EConst id+ | EAgent id+ | ENonce id tid+ | EveNonce id++datatype execmsg = Lit execlit+ | Tup execmsg execmsg+ | Enc execmsg execmsg+ | Hash execmsg+ | K execmsg execmsg+ | KShr "id set" (* a set of agent sharing this key *)+ | PK execmsg+ | SK execmsg+++text{*Concrete syntax: messages appear as {|A,B,NA|}, etc...*}+syntax+ "@MTuple" :: "['a, args] => 'a * 'b" ("(2{|_,/ _|})")++syntax (xsymbols)+ "@MTuple" :: "['a, args] => 'a * 'b" ("(2\<lbrace>_,/ _\<rbrace>)")++translations+ "{|x, y, z|}" == "{|x, {|y, z|}|}"+ "{|x, y|}" == "Tup x y"+++text{* + A shallow reference to bi-directional keys between two agents.+ Used only in proofs, but not in specifications. Hence, it can+ be ignored for soundness.+*}+definition Agent :: "execmsg set"+where "Agent \<equiv> { Lit (EAgent a) | a. True}"++definition agents :: "execmsg set \<Rightarrow> id set"+where "agents M = {a. Lit (EAgent a) \<in> M}"++definition Kbd :: "execmsg \<Rightarrow> execmsg \<Rightarrow> execmsg"+where "Kbd a b = (if (a \<in> Agent \<and> b \<in> Agent) + then KShr (agents {a, b}) + else undefined)"++lemma Kbd_commute [simp]: + "Kbd x y = Kbd y x"+ by (auto simp: Kbd_def agents_def)++lemma size_Kbd [simp]: + "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> size (Kbd a b) = 0"+ by ( auto simp: Kbd_def)++lemma Kbd_free [simp]:+ "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> Kbd a b \<noteq> Lit l"+ "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> Kbd a b \<noteq> Tup x y"+ "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> Kbd a b \<noteq> Enc x y"+ "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> Kbd a b \<noteq> Hash x"+ "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> Kbd a b \<noteq> K x y"+ "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> Kbd a b \<noteq> PK x"+ "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> Kbd a b \<noteq> SK x"+ by (auto simp: Kbd_def)++declare Kbd_free[symmetric, simp]++lemma Kbd_split_inj:+ "\<lbrakk> a \<in> Agent; b \<in> Agent; x \<in> Agent; y \<in> Agent \<rbrakk> \<Longrightarrow>+ (Kbd a b = Kbd x y) = (a = x \<and> b = y \<or> a = y \<and> b = x)"+ apply(clarsimp simp: Kbd_def Agent_def agents_def expand_set_eq) + apply(rule iffI)+ apply(rename_tac a b x y)+ apply(safe)+ apply(drule_tac x="a" in spec)+ apply(simp)+ apply(drule_tac x="y" in spec)+ apply(simp)+ apply(drule_tac x="x" in spec)+ apply(simp)+ apply(drule_tac x="b" in spec)+ apply(simp)+ done++lemma Kbd_non_split_inj [simp]:+ "\<lbrakk> a \<in> Agent; b \<in> Agent; x \<in> Agent \<rbrakk>+ \<Longrightarrow> (Kbd a b = Kbd x b) = (a = x)"+ "\<lbrakk> a \<in> Agent; b \<in> Agent; x \<in> Agent \<rbrakk>+ \<Longrightarrow> (Kbd a b = Kbd b x) = (a = x)"+ "\<lbrakk> a \<in> Agent; b \<in> Agent; x \<in> Agent \<rbrakk>+ \<Longrightarrow> (Kbd b a = Kbd x b) = (a = x)"+ "\<lbrakk> a \<in> Agent; b \<in> Agent; x \<in> Agent \<rbrakk>+ \<Longrightarrow> (Kbd b a = Kbd b x) = (a = x)"+ "\<lbrakk> a \<in> Agent; y \<in> Agent; x \<in> Agent \<rbrakk>+ \<Longrightarrow> (Kbd a a = Kbd x y) = (a = y \<and> x = y)"+ "\<lbrakk> a \<in> Agent; b \<in> Agent; x \<in> Agent \<rbrakk>+ \<Longrightarrow> (Kbd a b = Kbd x x) = (a = x \<and> b = x)"+ by (auto simp: Kbd_split_inj)++lemma Kbd_cases [ consumes 1+ , case_names Agent_a Agent_b Agent_x Agent_y noswap swapped]:+ "\<lbrakk> Kbd a b = Kbd x y;+ a \<in> Agent; b \<in> Agent; + x \<in> Agent; y \<in> Agent; + \<lbrakk> a = x; b = y \<rbrakk> \<Longrightarrow> R; + \<lbrakk> a = y; b = x \<rbrakk> \<Longrightarrow> R+ \<rbrakk> \<Longrightarrow> R"+ by (auto simp: Kbd_split_inj)++subsection{* Operations *}++types store = "varid \<times> tid \<Rightarrow> execmsg"++fun inv :: "execmsg \<Rightarrow> execmsg"+where+ "inv (PK m) = SK m"+| "inv (SK m) = PK m"+| "inv m = m"++lemma inv_Kbd [simp]: + "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> inv (Kbd a b) = Kbd a b"+ by(auto simp: Kbd_def)++(* TODO: Move *)+fun opt_map2 :: "('a \<Rightarrow> 'b \<Rightarrow> 'c) \<Rightarrow> 'a option \<Rightarrow> 'b option \<Rightarrow> 'c option"+where+ "opt_map2 f (Some x) (Some y) = Some (f x y)"+| "opt_map2 f _ _ = None"++lemma Some_opt_map2 [simp]:+ "(Some x = opt_map2 f a b) =+ (\<exists> y z. x = f y z \<and> Some y = a \<and> Some z = b)"+ "(opt_map2 f a b = Some x) =+ (\<exists> y z. x = f y z \<and> Some y = a \<and> Some z = b)"+ by (cases a, simp, cases b, simp_all add: eq_commute)+++lemma Some_if_pushL [simp]:+ "(Some x = (if b then Some y else None)) = (b \<and> x = y)"+ "((if b then Some y else None) = Some x) = (b \<and> x = y)"+ by (auto split: if_splits)++lemma Some_if_pushR [simp]:+ "(Some x = (if b then None else Some y)) = (\<not>b \<and> x = y)"+ "((if b then None else Some y) = Some x) = (\<not>b \<and> x = y)"+ by (auto split: if_splits)++lemma Some_Option_map [simp]:+ "(Some x = Option.map f a) = (\<exists>y. x = f y \<and> Some y = a)"+ "(Option.map f a = Some x) = (\<exists>y. x = f y \<and> Some y = a)"+ by (cases a, auto)+++fun inst :: "store \<Rightarrow> tid \<Rightarrow> pattern \<Rightarrow> execmsg option"+where+ "inst s i (PConst c) = Some (Lit (EConst c))"+| "inst s i (PFresh n) = Some (Lit (ENonce n i))"+| "inst s i (PVar v) = Some (s (v, i))"+| "inst s i (PTup x y) = opt_map2 Tup (inst s i x) (inst s i y)"+| "inst s i (PEnc m k) = opt_map2 Enc (inst s i m) (inst s i k)"+| "inst s i (PSign m k) = + opt_map2 Tup (inst s i m) + (opt_map2 Enc (inst s i m) (Option.map inv (inst s i k)))"+| "inst s i (PHash m) = Option.map Hash (inst s i m)"+| "inst s i (PSymK a b) = opt_map2 K (inst s i a) (inst s i b)"+| "inst s i (PAsymPK a) = Option.map PK (inst s i a)"+| "inst s i (PAsymSK a) = Option.map SK (inst s i a)"+| "inst s i (PShrK V) = + (if (\<forall> v \<in> V. s (v, i) \<in> Agent)+ then Some (KShr (agents {s (v, i) | v. v \<in> V})) + else None)"++text{* We assume that recipients making use of shared keys look them up+ in a table. This lookup only succeeds if agent identities are + given.+*}++lemma Some_inst_sKbd [simp]:+ "(Some m = inst s i (sKbd a b)) = + (m = Kbd (s (a, i)) (s (b, i)) \<and> + s (a, i) \<in> Agent \<and> s (b, i) \<in> Agent+ )"+ by (auto simp: sKbd_def Kbd_def Agent_def agents_def)+++fun unpair :: "execmsg \<Rightarrow> execmsg set"+where+ "unpair (Tup x y) = unpair x \<union> unpair y"+| "unpair m = {m}"+++text{* + We do not use neither subterms nor parts in our reasoning + infrastructure. However it used to formulate a few lemmas+ illustrating the relation between Paulsons' approach and ours.+*}++fun subterms :: "execmsg \<Rightarrow> execmsg set"+where+ "subterms (Lit l) = {Lit l}"+| "subterms (Tup x y) = insert (Tup x y) (subterms x \<union> subterms y)"+| "subterms (Enc m k) = insert (Enc m k) (subterms m \<union> subterms k)"+| "subterms (Hash m) = insert (Hash m) (subterms m)"+| "subterms (K a b) = insert (K a b) (subterms a \<union> subterms b)"+| "subterms (PK a) = insert (PK a) (subterms a)"+| "subterms (SK a) = insert (SK a) (subterms a)"+| "subterms (KShr A) = insert (KShr A) {Lit (EAgent a) | a. a \<in> A}"++fun parts :: "execmsg \<Rightarrow> execmsg set"+where+ "parts (Lit l) = {Lit l}"+| "parts (Tup x y) = insert (Tup x y) (parts x \<union> parts y)"+| "parts (Enc m k) = insert (Enc m k) (parts m)"+| "parts (Hash m) = {Hash m}"+| "parts (K a b) = {K a b}"+| "parts (PK a) = {PK a}"+| "parts (SK a) = {SK a}"+| "parts (KShr A) = {KShr A}"+++fun pairParts :: "execmsg \<Rightarrow> execmsg set"+where+ "pairParts (Tup x y) = + insert (Tup x y) (pairParts x \<union> pairParts y)"+| "pairParts m = {m}"++lemma pairParts_Kbd [simp]: + "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> pairParts (Kbd a b) = {Kbd a b}"+ by (auto simp: Kbd_def)++inductive_set+ infer :: "execmsg set \<Rightarrow> execmsg set"+ for M :: "execmsg set"+where+ Inj [simp,intro]: "m \<in> M \<Longrightarrow> m \<in> infer M"+| Tup: "\<lbrakk> x \<in> infer M; y \<in> infer M \<rbrakk> \<Longrightarrow> Tup x y \<in> infer M"+| Fst: "Tup x y \<in> infer M \<Longrightarrow> x \<in> infer M"+| Snd: "Tup x y \<in> infer M \<Longrightarrow> y \<in> infer M"+| Hash: "m \<in> infer M \<Longrightarrow> Hash m \<in> infer M"+| Enc: "\<lbrakk> m \<in> infer M; k \<in> infer M \<rbrakk> \<Longrightarrow> Enc m k \<in> infer M"+| Dec: "\<lbrakk> Enc m k \<in> infer M; inv k \<in> infer M \<rbrakk> \<Longrightarrow> m \<in> infer M"+ ++subsection{* Properties *}++subsubsection{* Agents *}++lemma notin_Agent [iff]:+ "Lit (EConst x) \<notin> Agent"+ "Lit (EAgent x) \<in> Agent"+ "Lit (ENonce x i) \<notin> Agent"+ "Lit (EveNonce x) \<notin> Agent"+ "Tup m1 m2 \<notin> Agent"+ "Enc m1 m2 \<notin> Agent"+ "Hash m1 \<notin> Agent"+ "K m1 m2 \<notin> Agent"+ "KShr V \<notin> Agent"+ "PK m1 \<notin> Agent"+ "SK m1 \<notin> Agent"+ "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> Kbd a b \<notin> Agent"+ by (auto simp: Kbd_def Agent_def)+++subsubsection{* Unification modulo key-inversion *}++lemma size_inv [simp]: "size (inv x) = size x"+ by (cases x) auto++lemma inv_eqs [iff]:+ "(inv x = Lit m) = (x = Lit m)"+ "(inv x = Tup m1 m2) = (x = Tup m1 m2)"+ "(inv x = Enc m1 m2) = (x = Enc m1 m2)"+ "(inv x = Hash m1) = (x = Hash m1)"+ "(inv x = K m1 m2) = (x = K m1 m2)"+ "(inv x = PK m1) = (x = SK m1)"+ "(inv x = SK m1) = (x = PK m1)"+ "(Lit m = inv x) = (x = Lit m)"+ "(Tup m1 m2 = inv x) = (x = Tup m1 m2)"+ "(Enc m1 m2 = inv x) = (x = Enc m1 m2)"+ "(Hash m1 = inv x) = (x = Hash m1)"+ "(K m1 m2 = inv x) = (x = K m1 m2)"+ "(PK m1 = inv x) = (x = SK m1)"+ "(SK m1 = inv x) = (x = PK m1)"+ "(KShr A = inv x) = (x = KShr A)"+ "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> + (Kbd a b = inv x) = (x = Kbd a b)"+ by (auto) (induct x, simp+)+++lemma inv_inj [iff]:+ "(inv x = inv y) = (x = y)"+ by (auto) (induct x, auto)+++++subsubsection{* @{term subterms} *}++lemma subterms_trans: + "\<lbrakk> x \<in> subterms y; y \<in> subterms z \<rbrakk> \<Longrightarrow> x \<in> subterms z"+ by(induct z, auto)++lemma unpair_subset_subterms: + "unpair m \<subseteq> subterms m"+ by(induct m, auto)++lemmas unpair_subtermsD = + subsetD[OF unpair_subset_subterms, rule_format]+++subsubsection{* @{term infer} *}++text{* Monotonicity *}++lemma infer_mono [trans]: "M \<subseteq> N \<Longrightarrow> infer M \<subseteq> infer N"+ by(auto, erule infer.induct, auto intro: infer.intros)++lemma infer_increasing: "M \<subseteq> infer M"+ by(blast)+++text{* Converse fails: A message composed from subterms of both+ sets is not in the union of the individual inferable sets. *}+lemma infer_Un: "infer M \<union> infer N \<subseteq> infer (M \<union> N)"+ by(intro Un_least infer_mono Un_upper1 Un_upper2)++lemmas infer_UnD = subsetD[OF infer_Un, rule_format]++lemma infer_insert: "insert x (infer M) \<subseteq> infer (insert x M)"+ by(blast intro: infer_mono[THEN [2] rev_subsetD])+++text{* Idempotence and transitivity *}++lemma infer_inferD [dest!]: "x \<in> infer (infer M) \<Longrightarrow> x \<in> infer M"+ by (induct rule: infer.induct) (auto intro: infer.intros)++lemma infer_idem [iff]: "infer (infer M) = infer M"+ by blast++lemma infer_subset_iff [simp]: + "(infer M \<subseteq> infer N) = (M \<subseteq> infer N)" (is "?lhs = ?rhs")+proof+ assume ?lhs+ have "M \<subseteq> infer M" by(rule infer_increasing)+ also note `?lhs`+ finally show ?rhs .+next+ assume ?rhs+ hence "infer M \<subseteq> infer (infer N)" by(rule infer_mono)+ thus ?lhs by simp+qed++lemma infer_trans: "\<lbrakk> x \<in> infer M; M \<subseteq> infer N \<rbrakk> \<Longrightarrow> x \<in> infer N"+by (drule infer_mono, blast)++text{*Cut; Lemma 2 of Lowe*}+lemma infer_cut: + "\<lbrakk> y \<in> infer (insert x M); x \<in> infer M \<rbrakk> \<Longrightarrow> y \<in> infer M"+ by (erule infer_trans, blast)+++lemma Tup_in_infer [simp]: + "Tup x y \<in> infer M = (x \<in> infer M \<and> y \<in> infer M)"+ by(blast intro: infer.intros)++lemma infer_insert_Tup [simp]:+ "infer (insert (Tup x y) M) = infer (insert x (insert y M))"+ by(safe, (erule infer.induct, auto intro: infer.intros)+)++lemma infer_insertI [intro]: "x \<in> infer M \<Longrightarrow> x \<in> infer (insert y M)"+ by(erule rev_subsetD[OF _ infer_mono], blast)++lemma infer_finite_support: + assumes "m \<in> infer M"+ shows "\<exists> N. N \<subseteq> M \<and> finite N \<and> m \<in> infer N" (is "\<exists> N. ?support m N")+using assms+proof(induct rule: infer.induct)+ case (Inj m)+ hence "?support m {m}" by fast+ thus ?case by blast+next+ case (Hash m)+ then obtain Nm where "?support m Nm" by blast+ hence "?support (Hash m) Nm" by (blast intro: infer.intros)+ thus ?case by blast+next+ case (Tup x y) note IH = this+ obtain Nx where "?support x Nx" using IH by blast+ moreover obtain Ny where "?support y Ny" using IH by blast+ ultimately have "?support (Tup x y) (Nx \<union> Ny)" + by (blast intro: infer.intros infer_UnD)+ thus ?case by blast+next+ case (Fst x y)+ then obtain Nxy where "?support \<lbrace>x, y\<rbrace> Nxy" by blast+ hence "?support x Nxy" by (blast intro: infer.intros)+ thus ?case by blast+next+ case (Snd x y)+ then obtain Nxy where "?support \<lbrace>x, y\<rbrace> Nxy" by blast+ hence "?support y Nxy" by (blast intro: infer.intros)+ thus ?case by blast+next+ case (Enc m k) note IH = this+ obtain Nm where "?support m Nm" using IH by blast+ moreover obtain Nk where "?support k Nk" using IH by blast+ ultimately have "?support (Enc m k) (Nm \<union> Nk)" + by (blast intro: infer.intros infer_UnD)+ thus ?case by blast+next+ case (Dec m k) note IH = this+ obtain Nmk where "?support (Enc m k) Nmk" using IH by blast+ moreover obtain Nk where "?support (inv k) Nk" using IH by blast+ ultimately have "?support m (Nmk \<union> Nk)" + by (blast intro: infer.intros infer_UnD)+ thus ?case by blast+qed++++subsubsection{* @{term pairParts} *}++lemma pairParts_mono [iff]: "m \<in> pairParts m"+ by(induct m rule: pairParts.induct, auto)++lemma pairParts_idem: + "m' \<in> pairParts m \<Longrightarrow> pairParts m' \<subseteq> pairParts m"+ by(induct m, auto)++lemmas pairParts_idemD = + subsetD[OF pairParts_idem, rule_format]++lemma pairParts_in_infer:+ "\<lbrakk> x \<in> pairParts m; m \<in> infer M \<rbrakk> \<Longrightarrow> x \<in> infer M"+ by(induct m arbitrary: x, auto)++lemma unpair_subset_pairParts: "unpair m \<subseteq> pairParts m"+ by(induct m, auto)++lemmas unpair_subset_pairPartsD =+ subsetD[OF unpair_subset_pairParts, rule_format]+++subsection{* Initial Intruder Knowledge *}+++definition IK0 :: "execmsg set"+where "IK0 \<equiv> + { Lit (EConst c) | c. True} \<union>+ { Lit (EveNonce a) | a. True} \<union>+ { Lit (EAgent a) | a. True} \<union>+ { PK (Lit (EAgent a)) | a. True} \<union> + { KShr {} }"++lemma IK0_unpair_inv: "m \<in> IK0 \<Longrightarrow> unpair m = {m}"+ by(auto simp: IK0_def image_def)++lemma in_IK0_by_unpair: + "\<lbrakk> m \<in> unpair m'; m' \<in> IK0 \<rbrakk> \<Longrightarrow> m \<in> IK0"+ by(frule IK0_unpair_inv, auto)++lemma notin_IK0 [iff]:+ "SK a \<notin> IK0"+ "K a b \<notin> IK0"+ "Enc m k \<notin> IK0"+ "Hash m \<notin> IK0"+ "Lit (ENonce n i) \<notin> IK0"+ "Tup x y \<notin> IK0"+ "A \<noteq> {} \<Longrightarrow> KShr A \<notin> IK0"+ "\<lbrakk> a \<in> Agent; b \<in> Agent \<rbrakk> \<Longrightarrow> Kbd a b \<notin> IK0"+ by (auto simp: IK0_def Kbd_def agents_def Agent_def)++lemma in_IK0_simps [iff]:+ "Lit (EConst c) \<in> IK0"+ "Lit (EveNonce n) \<in> IK0"+ "Lit (EAgent a) \<in> IK0"+ "PK (Lit (EAgent a)) \<in> IK0"+ "KShr {} \<in> IK0"+ by(auto simp: IK0_def)++end
@@ -0,0 +1,1693 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+theory ExplicitModel+imports+ HOL_ext+ Hints+ Protocol+ ExecMessage+begin++++chapter{* Security Proofs *}++section{* Explicit Execution Model *}++datatype rawevent = + Step "tid \<times> rolestep"+ | Learns "execmsg set"+ | LKReveal id+++datatype reveal = + RCompr notetype tid+| RLKR execmsg++types explicit_trace = "rawevent list"+types execstep = "tid \<times> rolestep"+types threadpool = "tid \<rightharpoonup> (rolestep list \<times> rolestep list \<times> rolestep set)"++fun knows :: "explicit_trace \<Rightarrow> execmsg set"+where+ "knows [] = {}"+| "knows (Learns M # t) = M \<union> knows t"+| "knows (Step estep # t) = knows t"+| "knows (LKReveal a # t) = knows t"++fun steps :: "explicit_trace \<Rightarrow> execstep set"+where+ "steps [] = {}"+| "steps (Learns M # t) = steps t"+| "steps (Step estep # t) = insert estep (steps t)"+| "steps (LKReveal a # t) = steps t"++fun reveals :: "explicit_trace \<Rightarrow> reveal set"+where+ "reveals (Step (i, s) # xs) = + (if (noteStep s) then+ insert (RCompr (noteType s) i) (reveals xs)+ else+ reveals xs)"+| "reveals (Learns m # xs) = reveals xs"+| "reveals (LKReveal a # xs) = insert (RLKR (Lit (EAgent a))) (reveals xs)"+| "reveals [] = {}"++fun lkreveals :: "explicit_trace \<Rightarrow> execmsg set"+where+ "lkreveals [] = {}"+| "lkreveals (Learns M # t) = lkreveals t"+| "lkreveals (Step estep # t) = lkreveals t"+| "lkreveals (LKReveal a # t) = insert (Lit (EAgent a)) (lkreveals t)"++definition longTermKeys :: "id \<Rightarrow> execmsg set"+where+ "longTermKeys a = { SK (Lit (EAgent a)) } \<union>+ { K (Lit (EAgent a)) b | b. b \<in> Agent } \<union> + { K b (Lit (EAgent a)) | b. b \<in> Agent } \<union> + { KShr A | A. a \<in> A }"+ +lemma SK_in_longTermKeys [iff]:+ "(SK x \<in> longTermKeys a) = (x = (Lit (EAgent a)))"+ by (auto simp: longTermKeys_def)++lemma K_in_longTermKeys [iff]:+ "(K x y \<in> longTermKeys a) = + ( (x = (Lit (EAgent a)) \<and> y \<in> Agent) \<or> + (y = (Lit (EAgent a)) \<and> x \<in> Agent) + )"+ by (auto simp: longTermKeys_def)++lemma KShr_in_longTermKeys [iff]:+ "(KShr A \<in> longTermKeys a) = (a \<in> A)"+ by (auto simp: longTermKeys_def)++lemma notin_longTermKeys [iff]:+ "Hash m \<notin> longTermKeys a"+ "Tup x y \<notin> longTermKeys a"+ "Enc m k \<notin> longTermKeys a"+by (auto simp: longTermKeys_def)++lemma longTermKeys_conv: + "(m \<in> longTermKeys a) = + ( (m = SK (Lit (EAgent a))) \<or> + (\<exists> b \<in> Agent. m = K (Lit (EAgent a)) b \<or> + m = K b (Lit (EAgent a))+ ) \<or> + (\<exists> A. m = KShr A \<and> a \<in> A)+ )"+ by (auto simp: longTermKeys_def)+++types state = "explicit_trace \<times> threadpool \<times> store"++inductive_set + reachable :: "proto \<Rightarrow> state set" + for P :: "proto"+where+ init: "\<lbrakk> \<forall> i done todo skipped. r i = Some (done,todo,skipped) \<longrightarrow> done = [] \<and> skipped = {} \<and> todo \<in> P;+ \<forall> a i. s (AVar a, i) \<in> Agent+ \<rbrakk>+ \<Longrightarrow> ([Learns IK0], r, s) \<in> reachable P"+ +| compr: "\<lbrakk> (t, r, s) \<in> reachable P;+ r i = Some (done, Note l ty pt # todo, skipped);+ Some m = inst s i pt+ \<rbrakk>+ \<Longrightarrow> (t @ [Step (i,Note l ty pt), Learns (pairParts m - knows t)], r(i \<mapsto> (done @ [Note l ty pt], todo, skipped)), s) \<in> reachable P"++| skip: "\<lbrakk> (t, r, s) \<in> reachable P;+ r i = Some (done, Note l ty pt # todo, skipped)+ \<rbrakk> + \<Longrightarrow> (t, r(i \<mapsto> (done @ [Note l ty pt], todo, insert (Note l ty pt) skipped)), s) \<in> reachable P"++| lkr: "\<lbrakk> (t, r, s) \<in> reachable P;+ LKReveal a \<notin> set t+ \<rbrakk>+ \<Longrightarrow> (t @ [LKReveal a, Learns (longTermKeys a - knows t)], r, s) \<in> reachable P"++| send: "\<lbrakk> (t, r, s) \<in> reachable P;+ r i = Some (done, Send l pt # todo, skipped);+ Some m = inst s i pt+ \<rbrakk>+ \<Longrightarrow> (t @ [Step (i, Send l pt), Learns (pairParts m - knows t)], r(i \<mapsto> (done @ [Send l pt], todo, skipped)), s) \<in> reachable P"+ +| recv: "\<lbrakk> (t, r, s) \<in> reachable P;+ r i = Some (done, Recv l pt # todo, skipped);+ Some m = inst s i pt;+ m \<in> knows t+ \<rbrakk>+ \<Longrightarrow> (t @ [Step (i, Recv l pt)], r(i \<mapsto> (done @ [Recv l pt], todo, skipped)), s) \<in> reachable P"++| hash: "\<lbrakk> (t, r, s) \<in> reachable P;+ m \<in> knows t;+ Hash m \<notin> knows t+ \<rbrakk>+ \<Longrightarrow> (t @ [Learns {Hash m}], r, s) \<in> reachable P"++| tuple: "\<lbrakk> (t, r, s) \<in> reachable P;+ x \<in> knows t;+ y \<in> knows t;+ Tup x y \<notin> knows t+ \<rbrakk>+ \<Longrightarrow> (t @ [Learns {Tup x y}], r, s) \<in> reachable P"++| encr: "\<lbrakk> (t, r, s) \<in> reachable P;+ m \<in> knows t;+ k \<in> knows t;+ Enc m k \<notin> knows t+ \<rbrakk>+ \<Longrightarrow> (t @ [Learns {Enc m k}], r, s) \<in> reachable P"+++| decr: "\<lbrakk> (t, r, s) \<in> reachable P;+ Enc m k \<in> knows t;+ inv k \<in> knows t+ \<rbrakk>+ \<Longrightarrow> (t @ [Learns (pairParts m - knows t)], r, s) \<in> reachable P"++locale reachable_state = wf_proto ++ fixes t :: explicit_trace+ and r :: threadpool+ and s :: store+ assumes reachable [simp,intro!]: "(t,r,s) \<in> reachable P"+begin+ text{* A local variant of the induction rule of @{term "reachable"}. *}+ lemmas reachable_induct = reachable.induct+ [ OF reachable+ , rule_format+ , consumes 0+ , case_names init compr skip lkr send recv hash tuple encr decr+ ]+end++text{* An extension of the reachable state locale denoting+ an individual thread and its state. *}++locale reachable_thread = reachable_state ++ fixes i :: "tid"+ and "done" :: "rolestep list"+ and todo :: "rolestep list"+ and skipped :: "rolestep set" + assumes thread_exists: "r i = Some (done, todo, skipped)"+begin++text{* The thread state is built such that @{term "done @ todo"} is+ always a role of @{term P}. *}++lemma role_in_P: "done @ todo \<in> P"+using thread_exists+proof (induct arbitrary: i "done" todo skipped rule: reachable_induct)+qed (fastsimp split: if_splits)+++end++text{* Importing all lemmas of the wellformed role locale for+the term @{term "done @ todo"}. *}+sublocale reachable_thread \<subseteq> wf_role "done @ todo"+ by (rule wf_roles[OF role_in_P])++++subsection{* Basic Properties *}++lemma knowsI: "\<lbrakk> Learns M \<in> set t; m \<in> M \<rbrakk> \<Longrightarrow> m \<in> knows t"+ by(induct t rule: knows.induct, auto)++lemma knowsD: "m \<in> knows t \<Longrightarrow> \<exists> M. Learns M \<in> set t \<and> m \<in> M"+ by(induct t rule: steps.induct, auto)++lemma knows_append [simp]: + "knows (xs@ys) = knows xs \<union> knows ys"+ by(induct xs rule: knows.induct, auto)++lemma stepsI: "Step estep \<in> set t \<Longrightarrow> estep \<in> steps t"+ by(induct t rule: steps.induct, auto)++lemma stepsD: "estep \<in> steps t \<Longrightarrow> Step estep \<in> set t"+ by(induct t rule: steps.induct, auto)++lemma Step_in_set_conv [simp]: + "(Step estep \<in> set t) = (estep \<in> steps t)"+ by(auto intro!: stepsI stepsD)++lemma steps_append [simp]: + "steps (t@t') = steps t \<union> steps t'"+ by(induct t rule: steps.induct, auto)++lemma lkrevealsI: "LKReveal a \<in> set t \<Longrightarrow> (Lit (EAgent a)) \<in> lkreveals t"+ by(induct t rule: lkreveals.induct, auto)++lemma lkrevealsD: "(Lit (EAgent a)) \<in> lkreveals t \<Longrightarrow> LKReveal a \<in> set t"+ by(induct t rule: lkreveals.induct, auto)++lemma Lkr_in_set_conv [simp]: + "(LKReveal a \<in> set t) = ((Lit (EAgent a)) \<in> lkreveals t)"+ by(auto intro!: lkrevealsI lkrevealsD)++lemma lkreveals_append [simp]: + "lkreveals (t@t') = lkreveals t \<union> lkreveals t'"+ by(induct t rule: lkreveals.induct, auto)++lemma lkreveals_agent: + "a \<in> lkreveals t \<Longrightarrow> \<exists> b. a = (Lit (EAgent b))"+ by(induct t rule: lkreveals.induct, auto)++subsection{* Thread Execution *}++lemma (in reachable_state) step_in_dom: + "(i, step) \<in> steps t \<Longrightarrow> i \<in> dom r"+proof (induct rule: reachable_induct) qed auto++lemma reveals_Nil[dest!]:+ "a \<in> reveals [] \<Longrightarrow> False"+by (auto)++lemma reveals_append [simp]:+ "reveals (xs@ys) = reveals xs \<union> reveals ys"+by(induct xs rule: reveals.induct, auto)++lemma RLKR_lkreveals_conv:+ "(RLKR a \<in> reveals t) = (a \<in> lkreveals t)"+proof(induct t rule: reveals.induct)+ case (1 i s xs)+ thus ?case by force+qed auto++lemma steps_to_reveals:+ "(i, Note l ty pt) \<in> steps t \<Longrightarrow> RCompr ty i \<in> reveals t"+by(induct t rule: reveals.induct) (auto)++lemma reveals_to_steps:+ "RCompr ty i \<in> reveals t \<Longrightarrow> \<exists> l pt. (i, Note l ty pt) \<in> steps t"+proof(induct t rule: reveals.induct)+ case (1 i' s xs)+ thus ?case by (cases s) auto+qed auto++lemma RCompr_steps_conv:+ "RCompr ty i \<in> reveals t = (\<exists> l pt. (i, Note l ty pt) \<in> steps t)"+by (fastsimp intro: reveals_to_steps steps_to_reveals)++context reachable_thread+begin++lemma in_dom_r [iff]: "i \<in> dom r" + by (auto intro!: thread_exists)++lemma distinct_done [iff]: "distinct done"+ using distinct by auto++lemma skipped_in_done: + "step \<in> skipped \<Longrightarrow> step \<in> set done"+using thread_exists+proof (induct arbitrary: i "done" skipped todo rule: reachable_induct)+qed (auto split: if_splits)+++lemma distinct_todo [iff]: "distinct todo"+using distinct by auto+++(*+ + Proofs of the relationship between steps, skipped and done ++ ********************************************************************************************)++lemma note_in_skipped: + "\<lbrakk> step \<in> skipped \<rbrakk> \<Longrightarrow> + \<exists> l ty pt. (step = (Note l ty pt))"+using thread_exists+proof(induct arbitrary: i "done" todo skipped rule: reachable_induct)+ case init+ thus "?case" by fastsimp+qed( auto split: if_splits)+++lemma send_notin_skipped [iff]: + "Send l pt \<notin> skipped"+ by (auto dest!: note_in_skipped)++lemma recv_notin_skipped [iff]: + "Recv l pt \<notin> skipped"+ by (auto dest!: note_in_skipped)++lemma in_steps_conv_done_skipped:+ "(i, step) \<in> steps t = + (step \<in> set done \<and> step \<notin> skipped)"+using thread_exists+using distinct+proof(induct arbitrary: i "done" todo skipped rule: reachable_induct)+ case init thus ?case by fastsimp+next + case (send t r s i "done" l pt todo skipped m i' done' todo' skipped')+ thus ?case+ proof(cases "i = i'")+ case True+ then interpret thread: + reachable_thread P t r s i "done" "Send l pt # todo" skipped'+ using send by unfold_locales auto+ thus ?thesis + using send `i = i'` by fastsimp + qed auto+next+ case (recv t r s i "done" l pt todo skipped m i' done' todo' skipped')+ thus ?case+ proof(cases "i = i'")+ case True+ then interpret thread: + reachable_thread P t r s i "done" "Recv l pt # todo" skipped'+ using recv by unfold_locales auto+ thus ?thesis + using recv `i = i'` by fastsimp + qed auto+next+ case (compr t r s i "done" l ty pt todo skipped m i' done' todo' skipped') + thus ?case+ proof(cases "i = i'")+ case True+ thus ?thesis using compr `i = i'`+ proof(cases "step = Note l ty pt")+ case True+ interpret thread:+ reachable_thread P t r s i "done" "Note l ty pt # todo" skipped'+ using compr `i = i'` by unfold_locales auto+ thus ?thesis using compr `i = i'` `step = Note l ty pt` by (fastsimp dest: thread.skipped_in_done )+ qed fastsimp+ qed auto+next+ case(skip t r s i "done" l ty pt todo skipped i' done' todo' skipped')+ thus ?case+ proof(cases "i = i'")+ case True+ thus ?thesis using skip `i = i'`+ proof(cases "step = Note l ty pt")+ case True+ interpret thread:+ reachable_thread P t r s i "done" "Note l ty pt # todo" skipped+ using skip `i = i'` by unfold_locales auto+ thus ?thesis using skip `i = i'` `step = Note l ty pt` by fastsimp+ qed fastsimp+ qed auto+qed auto++lemma in_steps_recv:+ "((Recv l pt) \<in> set done) = ((i,Recv l pt) \<in> steps t)"+using thread_exists+proof(induct arbitrary: i "done" todo skipped rule rule: reachable_induct)+ case init+ thus "?case" by fastsimp+qed ((unfold map_upd_Some_unfold)?, auto)+++lemma in_steps_send:+ "((Send l pt) \<in> set done) = ((i,Send l pt) \<in> steps t)"+using thread_exists+proof(induct arbitrary: i "done" todo skipped rule rule: reachable_induct)+ case init+ thus "?case" by fastsimp+qed ((unfold map_upd_Some_unfold)?, auto)+++lemmas send_steps_in_done [elim!] = iffD1[OF in_steps_send, rule_format]+lemmas send_done_in_steps [elim!] = iffD2[OF in_steps_send, rule_format]+lemmas recv_steps_in_done [elim!] = iffD1[OF in_steps_recv, rule_format]+lemmas recv_done_in_steps [elim!] = iffD2[OF in_steps_recv, rule_format]+++lemma in_steps_eq_in_done:+ "step \<notin> skipped \<Longrightarrow> ((i, step) \<in> steps t) = (step \<in> set done)" +using thread_exists+by(auto simp add: in_steps_conv_done_skipped)++lemma todo_notin_doneD:+ "step \<in> set todo \<Longrightarrow> step \<notin> set done"+using distinct+using role_in_P+by(auto)++lemma done_notin_todoD:+ "step \<in> set done \<Longrightarrow> step \<notin> set todo"+using distinct+using role_in_P+by(auto)++lemma todo_notin_skippedD:+ "step \<in> set todo \<Longrightarrow> step \<notin> skipped"+using distinct+using role_in_P+by(fastsimp dest: skipped_in_done)++lemma skipped_notin_todoD:+ "step \<in> skipped \<Longrightarrow> step \<notin> set todo"+using distinct+using role_in_P+by(fastsimp dest: skipped_in_done)++lemma notin_steps_notin_trace:+ "(i, step) \<notin> steps t \<Longrightarrow> (Step (i, step)) \<notin> set t"+by(auto)++lemma in_steps_in_done:+ assumes inSteps:+ "(i, step) \<in> steps t"+ shows + "step \<in> set done"+proof(cases step)+ case (Send l pt)+ thus ?thesis using inSteps by (fastsimp dest: in_steps_send[THEN iffD2])+next+ case (Recv l pt)+ thus ?thesis using inSteps by (fastsimp dest: in_steps_recv[THEN iffD2])+next+ case (Note l ty pt)+ thus ?thesis using inSteps by (fastsimp simp add: in_steps_conv_done_skipped)+qed+++lemma step_notin_skippedD [dest]:+ "\<lbrakk> step \<in> skipped; (i, step) \<in> steps t \<rbrakk> \<Longrightarrow> False"+by(auto simp add: in_steps_conv_done_skipped)++lemma notin_skipped_notin_steps [dest]:+ "\<lbrakk> step \<in> set done; (i, step) \<notin> steps t; step \<notin> skipped \<rbrakk> \<Longrightarrow> False"+by(auto simp add: in_steps_conv_done_skipped)++lemma[dest]:+ "\<lbrakk> step \<in> set todo; step \<in> set done \<rbrakk> \<Longrightarrow> False"+by(fastsimp dest: todo_notin_doneD)++lemma[dest]:+ "\<lbrakk> step \<in> set todo; step \<in> skipped \<rbrakk> \<Longrightarrow> False"+by(auto dest: todo_notin_skippedD)++lemma[dest]:+ "\<lbrakk> (i, step) \<notin> steps t; (Step (i, step)) \<in> set t \<rbrakk> \<Longrightarrow> False"+by(auto)++lemma[dest]:+ "\<lbrakk> (i, step) \<in> steps t; (Step (i, step)) \<notin> set t \<rbrakk> \<Longrightarrow> False"+by(auto)++lemma listOrd_done_imp_listOrd_trace:+ assumes facts:+ "listOrd done prev step"+ "prev \<notin> skipped"+ "step \<notin> skipped" + shows stepOrd:+ "listOrd t (Step (i, prev)) (Step (i, step))"+using thread_exists+using facts+proof(induct arbitrary: i "done" todo skipped rule: reachable_induct)+ case (init r s i "done" todo) + thus ?case+ by fastsimp+next+ case (send t r s i "done" l msg todo skipped m i' done' todo' skipped')+ thus ?case using send + proof(cases "i = i'")+ case True+ interpret this_thread:+ reachable_thread P t r s i' "done" "Send l msg # todo'" skipped'+ using send `i = i'` by unfold_locales auto+ thus ?thesis using send `i = i'`+ by fastsimp+ qed fastsimp+next+ case (recv t r s i "done" l msg todo skipped m i' done' todo' skipped')+ from recv show ?case + proof(cases "i = i'")+ case True+ interpret this_thread:+ reachable_thread P t r s i' "done" "Recv l msg # todo'" skipped'+ using recv `i = i'` by unfold_locales auto+ thus ?thesis using recv `i = i'`+ by fastsimp+ qed fastsimp+next+ case (compr t r s i "done" l ty msg todo skipped m i' done' todo' skipped')+ from compr show ?case + proof(cases "i = i'")+ case True+ interpret this_thread:+ reachable_thread P t r s i' "done" "Note l ty msg # todo'" skipped'+ using compr `i = i'` by unfold_locales auto+ thus ?thesis using compr `i = i'`+ by fastsimp+ qed fastsimp+next+ case (skip t r s i "done" l ty msg todo skipped i' done' todo' skipped') + from skip show ?case + proof(cases "i = i'")+ case True+ then interpret this_thread:+ reachable_thread P t r s i "done" "Note l ty msg # todo" skipped+ using skip `i = i'` by unfold_locales auto+ thus ?thesis using skip `i = i'`+ by fastsimp+ qed fastsimp+qed auto++lemma listOrd_recv_role_imp_listOrd_trace:+ assumes facts:+ "(i, step) \<in> steps t"+ "listOrd (done @ todo) (Recv l pt) step"+ shows rtOrd:+ "listOrd t (Step (i, Recv l pt)) (Step (i, step))" +using distinct+using facts+by(auto dest: in_set_listOrd1 todo_notin_doneD listOrd_done_imp_listOrd_trace in_set_listOrd2 listOrd_append[THEN iffD1] in_steps_conv_done_skipped[THEN iffD1])++lemma listOrd_send_role_imp_listOrd_trace:+ assumes facts:+ "(i, step) \<in> steps t"+ "listOrd (done @ todo) (Send l pt) step"+ shows stOrd:+ "listOrd t (Step (i, Send l pt)) (Step (i, step))" +using distinct+using facts+by(auto dest: in_set_listOrd1 todo_notin_doneD listOrd_done_imp_listOrd_trace in_set_listOrd2 listOrd_append[THEN iffD1] in_steps_conv_done_skipped[THEN iffD1])++lemma roleOrd_notSkipped_imp_listOrd_trace:+ assumes facts:+ "(i, step) \<in> steps t"+ "step' \<notin> skipped"+ "listOrd (done @ todo) step' step"+ shows+ "listOrd t (Step (i, step')) (Step (i, step))"+using distinct+using facts+by(auto dest: in_set_listOrd1 todo_notin_doneD listOrd_done_imp_listOrd_trace in_set_listOrd2 listOrd_append[THEN iffD1] in_steps_conv_done_skipped[THEN iffD1])++end+++subsection{* Variable Substitutions *}++context reachable_state+begin++lemma inst_AVar_cases: + "s (AVar v, i) \<in> Agent"+ by (induct rule: reachable_induct, auto)++lemma inst_AVar_in_IK0: + "s (AVar v, i) \<in> IK0"+using inst_AVar_cases[of v i] +by (auto simp: IK0_def Agent_def)++lemma knows_IK0: "m \<in> IK0 \<Longrightarrow> m \<in> knows t"+ by(induct rule: reachable_induct, auto)++lemma inst_AVar_in_knows [iff]:+ "s (AVar a, i) \<in> knows t"+ by (rule knows_IK0[OF inst_AVar_in_IK0])++end (* reachable_state *)++lemma (in reachable_state) send_step_FV:+ assumes thread_exists: "r i = Some (done, Send l msg # todo, skipped)"+ and FV: "MVar n \<in> FV msg"+ shows "\<exists> l' msg'. (i, Recv l' msg') \<in> steps t \<and> MVar n \<in> FV msg'"+proof -+ interpret this_thread: reachable_thread P t r s i "done" "Send l msg # todo" skipped+ using thread_exists by unfold_locales auto+ let ?role = "done @ Send l msg # todo"+ have "Send l msg \<in> set ?role" by simp+ then obtain l' msg' + where "listOrd ?role (Recv l' msg') (Send l msg)"+ and "MVar n \<in> FV msg'"+ using FV by(fast dest!: this_thread.Send_FV)+ thus ?thesis using this_thread.distinct+ by(auto dest: in_set_listOrd1 in_set_listOrd2)+qed++lemma (in reachable_state) note_step_FV:+ assumes thread_exists: "r i = Some (done, Note l ty msg # todo, skipped)"+ and FV: "MVar n \<in> FV msg"+ shows "\<exists> l' msg'. (i, Recv l' msg') \<in> steps t \<and> MVar n \<in> FV msg'"+proof -+ interpret this_thread: reachable_thread P t r s i "done" "Note l ty msg # todo" skipped+ using thread_exists by unfold_locales auto+ let ?role = "done @ Note l ty msg # todo"+ have "Note l ty msg \<in> set ?role" by simp+ then obtain l' msg' + where "listOrd ?role (Recv l' msg') (Note l ty msg)"+ and "MVar n \<in> FV msg'"+ using FV by(fast dest!: this_thread.Note_FV)+ thus ?thesis using this_thread.distinct+ by(auto dest: in_set_listOrd1 in_set_listOrd2)+qed+++subsubsection{* The Effect of a Step on the Intruder Knowledge *}+++context reachable_state+begin++lemma SendD: + "(i, Send lbl pt) \<in> steps t \<Longrightarrow> + (\<exists> m. Some m = inst s i pt \<and> m \<in> knows t)"+proof(induct rule: reachable_induct)+qed auto++end+++subsection{* Almost Distinct Traces *}++fun distinct' :: "explicit_trace \<Rightarrow> bool"+where+ "distinct' [] = True"+| "distinct' (Learns M # t) =+ ((\<forall> m \<in> M. m \<notin> knows t) \<and> distinct' t)"+| "distinct' (Step estep # t) =+ ((estep \<notin> steps t) \<and> distinct' t)"+| "distinct' (LKReveal a # t) =+ (((Lit (EAgent a)) \<notin> lkreveals t) \<and> distinct' t)"+++lemma distinct'_append [simp]:+ "distinct' (t@t') = + (distinct' t \<and> distinct' t' \<and> + (knows t \<inter> knows t' = {}) \<and> (steps t \<inter> steps t' = {}) \<and>+ (lkreveals t \<inter> lkreveals t') = {})"+proof (induct t rule: distinct'.induct)+qed (auto intro!: knowsI)++lemma distinct'_singleton [iff]: "distinct' [x]"+by (cases x) auto++lemma (in reachable_state) distinct'_trace [iff]:+ "distinct' t"+proof(induct arbitrary: i "done" todo skipped rule: reachable_induct)+ case (recv t r s i "done" l msg todo skipped)+ then interpret this_thread: + reachable_thread P t r s i "done" "Recv l msg # todo" skipped+ by unfold_locales auto+ show ?case using `distinct' t` this_thread.distinct+ by(fastsimp dest: this_thread.in_steps_in_done)+next+ case (send t r s i "done" l msg todo skipped m)+ then interpret this_thread: + reachable_thread P t r s i "done" "Send l msg # todo" skipped+ by unfold_locales auto+ show ?case using `distinct' t` and this_thread.distinct+ by(fastsimp dest: this_thread.in_steps_in_done)+next+ case (compr t r s i "done" l ty msg todo skipped m)+ then interpret this_thread: + reachable_thread P t r s i "done" "Note l ty msg # todo" skipped+ by unfold_locales auto+ show ?case using `distinct' t` and this_thread.distinct+ by(fastsimp dest: this_thread.in_steps_in_done)+next+ case (skip t r s i "done" l ty msg todo skipped)+ then interpret this_thread: + reachable_thread P t r s i "done" "Note l ty msg # todo" skipped+ by unfold_locales auto+ show ?case using `distinct' t` and this_thread.distinct+ by(auto)+qed auto+++subsection{* Happens-Before Order *}++datatype event = St "tid \<times> rolestep" | Ln execmsg | LKR execmsg++fun predOrd :: "explicit_trace \<Rightarrow> event \<Rightarrow> event \<Rightarrow> bool"+where+ "predOrd [] x y = False"+| "predOrd (Learns M # xs) x y =+ ((x \<in> Ln ` M \<and> (y \<in> Ln ` knows xs \<or> y \<in> St ` steps xs \<or> y \<in> LKR ` lkreveals xs)) \<or>+ predOrd xs x y)"+| "predOrd (Step estep # xs) x y =+ ((x = St estep \<and> (y \<in> Ln ` knows xs \<or> y \<in> St ` steps xs \<or> y \<in> LKR ` lkreveals xs)) \<or>+ predOrd xs x y)"+| "predOrd (LKReveal a # xs) x y = + ((x = LKR (Lit (EAgent a)) \<and> (y \<in> Ln ` knows xs \<or> y \<in> St ` steps xs \<or> y \<in> LKR ` lkreveals xs)) \<or>+ predOrd xs x y)"++definition predEqOrd :: "explicit_trace \<Rightarrow> event \<Rightarrow> event \<Rightarrow> bool"+where "predEqOrd t x y = ((x = y) \<or> predOrd t x y)"+++lemma predOrd_singleton [simp]: "\<not> predOrd [a] x y"+by (cases a) auto++lemma in_knows_predOrd1: "predOrd t (Ln x) y \<Longrightarrow> x \<in> knows t"+proof (induct t)+ case (Cons e t) thus ?case by (cases e) auto+qed auto++lemma in_knows_predOrd2: "predOrd t x (Ln y) \<Longrightarrow> y \<in> knows t"+proof (induct t)+ case (Cons e t) thus ?case by (cases e) auto+qed auto++lemma in_steps_predOrd1: "predOrd t (St x) y \<Longrightarrow> x \<in> steps t"+proof (induct t)+ case (Cons e t) thus ?case by (cases e) auto+qed auto++lemma in_steps_predOrd2: "predOrd t x (St y) \<Longrightarrow> y \<in> steps t"+proof (induct t)+ case (Cons e t) thus ?case by (cases e) auto+qed auto++lemma in_lkreveals_predOrd1: "predOrd t (LKR x) y \<Longrightarrow> x \<in> lkreveals t"+proof (induct t)+ case (Cons e t) thus ?case by (cases e) auto+qed auto++lemma in_lkreveals_predOrd2: "predOrd t x (LKR y) \<Longrightarrow> y \<in> lkreveals t"+proof (induct t)+ case (Cons e t) thus ?case by (cases e) auto+qed auto++lemma in_reveals_predOrd1:+ assumes facts: "predOrd t (St (i, st)) e"+ "noteStep st"+ shows "RCompr (noteType st) i \<in> reveals t"+using facts+by(force dest: noteStepD intro: RCompr_steps_conv[THEN iffD2] in_steps_predOrd1)++lemma in_reveals_predOrd2:+ assumes facts: "predOrd t e (St (i, st))"+ "noteStep st"+ shows "RCompr (noteType st) i \<in> reveals t"+using facts+by(force dest: noteStepD intro: RCompr_steps_conv[THEN iffD2] in_steps_predOrd2)++lemma note_in_reveals_predOrd1:+ assumes facts: "predOrd t (St (i, Note l ty pt)) e"+ shows "RCompr ty i \<in> reveals t"+using facts+by(force dest: noteStepD intro: RCompr_steps_conv[THEN iffD2] in_steps_predOrd1)++lemma note_in_reveals_predOrd2:+ assumes facts: "predOrd t e (St (i, Note l ty pt))"+ shows "RCompr ty i \<in> reveals t"+using facts+by(force dest: noteStepD intro: RCompr_steps_conv[THEN iffD2] in_steps_predOrd2)++lemma lkr_in_reveals_predOrd1:+ "predOrd t (LKR a) e \<Longrightarrow> RLKR a \<in> reveals t"+by(force intro: RLKR_lkreveals_conv[THEN iffD2] in_lkreveals_predOrd1)++lemma lkr_in_reveals_predOrd2:+ "predOrd t e (LKR a) \<Longrightarrow> RLKR a \<in> reveals t"+by(force intro: RLKR_lkreveals_conv[THEN iffD2] in_lkreveals_predOrd2)+++lemmas event_predOrdI = + in_knows_predOrd1 in_knows_predOrd2 + in_steps_predOrd1 in_steps_predOrd2++lemmas compr_predOrdI =+ lkr_in_reveals_predOrd1 lkr_in_reveals_predOrd2 + note_in_reveals_predOrd1 note_in_reveals_predOrd2++lemma event_predOrdE:+ "\<lbrakk>predOrd t (Ln x) (Ln y); \<lbrakk> x \<in> knows t; y \<in> knows t \<rbrakk> \<Longrightarrow> R \<rbrakk> \<Longrightarrow> R"+ "\<lbrakk>predOrd t (Ln x) (St b); \<lbrakk> x \<in> knows t; b \<in> steps t \<rbrakk> \<Longrightarrow> R \<rbrakk> \<Longrightarrow> R"+ "\<lbrakk>predOrd t (St a) (Ln y); \<lbrakk> a \<in> steps t; y \<in> knows t \<rbrakk> \<Longrightarrow> R \<rbrakk> \<Longrightarrow> R"+ "\<lbrakk>predOrd t (St a) (St b); \<lbrakk> a \<in> steps t; b \<in> steps t \<rbrakk> \<Longrightarrow> R \<rbrakk> \<Longrightarrow> R"+ "\<lbrakk>predOrd t (LKR c) (Ln y); \<lbrakk> RLKR c \<in> reveals t; y \<in> knows t \<rbrakk> \<Longrightarrow> R \<rbrakk> \<Longrightarrow> R"+ "\<lbrakk>predOrd t (LKR c) (St b); \<lbrakk> RLKR c \<in> reveals t; b \<in> steps t \<rbrakk> \<Longrightarrow> R \<rbrakk> \<Longrightarrow> R"+ "\<lbrakk>predOrd t (St a) (LKR d); \<lbrakk> a \<in> steps t; RLKR d \<in> reveals t \<rbrakk> \<Longrightarrow> R \<rbrakk> \<Longrightarrow> R"+ "\<lbrakk>predOrd t (Ln x) (LKR d); \<lbrakk> x \<in> knows t; RLKR d \<in> reveals t \<rbrakk> \<Longrightarrow> R \<rbrakk> \<Longrightarrow> R"+ "\<lbrakk>predOrd t (LKR c) (LKR d); \<lbrakk> RLKR c \<in> reveals t; RLKR d \<in> reveals t \<rbrakk> \<Longrightarrow> R \<rbrakk> \<Longrightarrow> R"+ by(fastsimp intro: event_predOrdI compr_predOrdI)++++lemma predOrd_LKR_agent1:+ "predOrd t (LKR a) b \<Longrightarrow> \<exists> c. a = (Lit (EAgent c))"+by(auto dest!: lkreveals_agent RLKR_lkreveals_conv[THEN iffD1] dest: compr_predOrdI )++lemma predOrd_LKR_agent2:+ "predOrd t b (LKR a) \<Longrightarrow> \<exists> c. a = (Lit (EAgent c))"+by(auto dest!: lkreveals_agent RLKR_lkreveals_conv[THEN iffD1] dest: compr_predOrdI )++lemma in_set_predOrd1: + "predOrd t x y \<Longrightarrow> x \<in> Ln ` knows t \<or> x \<in> St ` steps t \<or> x \<in> LKR ` lkreveals t"+by (induct t x y rule: predOrd.induct) auto++lemma in_set_predOrd2: + "predOrd t x y \<Longrightarrow> y \<in> Ln ` knows t \<or> y \<in> St ` steps t \<or> y \<in> LKR ` lkreveals t"+by (induct t x y rule: predOrd.induct) auto++lemma listOrd_imp_predOrd:+ "listOrd t (Step e) (Step e') \<Longrightarrow> predOrd t (St e) (St e')"+by (induct t rule: steps.induct) (auto dest!: stepsI)++lemma predOrd_append [simp]:+ "predOrd (xs@ys) x y = + (predOrd xs x y \<or> predOrd ys x y \<or>+ ((x \<in> Ln ` knows xs \<or> x \<in> St ` steps xs \<or> x \<in> LKR ` lkreveals xs) \<and> + (y \<in> Ln ` knows ys \<or> y \<in> St ` steps ys \<or> y \<in> LKR ` lkreveals ys)))"+ apply(induct xs x y rule: predOrd.induct)+ apply(simp_all)+ apply(blast+)+ done++lemma predOrd_distinct'_irr [simp]: + "distinct' t \<Longrightarrow> \<not>predOrd t x x"+ apply(induct t, auto)+ apply(case_tac x, auto)+ apply(case_tac a, auto)+ apply(case_tac a, auto)+ apply(case_tac a, auto)+ done++lemma predOrd_distinct'_trans: + "\<lbrakk> predOrd t x y; predOrd t y z; distinct' t \<rbrakk> + \<Longrightarrow> predOrd t x z"+ apply(induct t x y rule: predOrd.induct)+ apply(auto dest: in_set_predOrd1 in_set_predOrd2)+ done++lemma predOrd_distinct'_asymD: + "\<lbrakk> predOrd t x y; distinct' t \<rbrakk> \<Longrightarrow> \<not> predOrd t y x"+ apply(induct t x y rule: predOrd.induct)+ apply(auto dest: in_set_predOrd1 in_set_predOrd2)+ done+++sublocale reachable_state \<subseteq> beforeOrd: order "predEqOrd t" "predOrd t"+ apply(unfold_locales)+ apply(auto simp: predEqOrd_def+ dest: predOrd_distinct'_asymD + intro: predOrd_distinct'_trans)+ done++abbreviation (in reachable_state)+ "pred'" (infixl "\<prec>" 50) where "pred' \<equiv> predOrd t"++abbreviation (in reachable_state) + "predEq'" (infixl "\<preceq>" 50) where "predEq' \<equiv> predEqOrd t"++lemma predOrd_conv:+ "predOrd xs x y = + (\<exists> ys zs. xs = ys @ zs \<and> + (x \<in> Ln ` knows ys \<or> x \<in> St ` steps ys \<or> x \<in> LKR ` lkreveals ys) \<and>+ (y \<in> Ln ` knows zs \<or> y \<in> St ` steps zs \<or> y \<in> LKR ` lkreveals zs))"+ (is "?pred xs = (\<exists> ys zs. ?decomp xs ys zs)")+proof -+ { assume "?pred xs"+ hence "\<exists> ys zs. ?decomp xs ys zs"+ proof (induct xs)+ case Nil thus ?case by simp+ next+ case (Cons e xs) thus ?case+ proof(cases e)+ case (Step st) thus ?thesis+ proof(cases "x = St st")+ case True hence "?decomp (e#xs) [e] xs" + using Step Cons by auto+ thus ?thesis by blast+ next+ case False+ hence "predOrd xs x y"+ using Step Cons by auto+ then obtain ys zs where "?decomp xs ys zs"+ using Cons by blast+ hence "?decomp (e#xs) (e#ys) zs"+ using Step Cons by auto+ thus ?thesis by blast+ qed+ next+ case (Learns M) thus ?thesis+ proof(cases "\<exists> m \<in> M. x = Ln m")+ case True + then obtain m where "m \<in> M" and "x = Ln m"+ by auto+ hence "?decomp (e#xs) [e] xs" + using Learns Cons by auto+ thus ?thesis by blast+ next+ case False+ hence "predOrd xs x y"+ using Learns Cons by auto+ then obtain ys zs where "?decomp xs ys zs"+ using Cons by blast+ hence "?decomp (e#xs) (e#ys) zs"+ using Learns Cons by auto+ thus ?thesis by blast+ qed+ next+ case (LKReveal a) thus ?thesis+ proof(cases "x = LKR (Lit (EAgent a))")+ case True hence "?decomp (e#xs) [e] xs"+ using LKReveal Cons by auto+ thus ?thesis by blast+ next+ case False hence "predOrd xs x y"+ using LKReveal Cons by auto+ then obtain ys zs where "?decomp xs ys zs"+ using Cons by blast+ hence "?decomp (e#xs) (e#ys) zs"+ using LKReveal Cons by auto+ thus ?thesis by blast+ qed+ qed+ qed+ }+ moreover+ { assume "\<exists> ys zs. ?decomp xs ys zs"+ hence "?pred xs"+ proof (induct xs)+ case Nil thus ?case by simp+ next+ case (Cons e xs)+ then obtain ys zs where decomp1: "?decomp (e#xs) ys zs"+ by blast+ hence "ys = [] \<and> e # xs = zs \<or> (\<exists>ys'. e # ys' = ys \<and> xs = ys' @ zs)"+ (is "?nil \<or> ?non_nil")+ by (simp add: Cons_eq_append_conv)+ moreover+ { assume ?nil hence ?case using decomp1 by auto }+ moreover+ { assume ?non_nil+ then obtain ys' where decomp2: "ys = e # ys'" and "xs = ys' @ zs"+ by auto+ hence ?case+ proof(cases e)+ case (Step st) thus ?thesis+ proof(cases "x = St st")+ case True thus ?thesis+ using Step decomp1 decomp2 by auto+ next+ case False+ hence "?decomp xs ys' zs"+ using Step decomp1 decomp2 by auto+ hence "predOrd xs x y"+ using Cons by auto+ thus ?thesis+ using Step by auto+ qed+ next+ case (Learns M) thus ?thesis+ proof(cases "\<exists> m \<in> M. x = Ln m")+ case True thus ?thesis+ using Learns decomp1 decomp2 by auto+ next+ case False+ hence "?decomp xs ys' zs"+ using Learns decomp1 decomp2 by auto+ hence "predOrd xs x y"+ using Cons by auto+ thus ?thesis+ using Learns by auto+ qed+ next+ case (LKReveal a) thus ?thesis+ proof(cases "x = LKR (Lit (EAgent a))")+ case True thus ?thesis+ using LKReveal decomp1 decomp2 by auto+ next+ case False+ hence "?decomp xs ys' zs"+ using LKReveal decomp1 decomp2 by auto+ hence "predOrd xs x y"+ using Cons by auto+ thus ?thesis + using LKReveal by auto+ qed+ qed+ }+ ultimately show ?case by fast+ qed+ }+ ultimately show ?thesis by fast+qed+++subsection{* Input Terms *}+++context reachable_state+begin++lemma knows_pairParts_closed:+ "m \<in> knows t \<Longrightarrow> pairParts m \<subseteq> knows t"+proof(induct arbitrary: m rule: reachable_induct)+ case init thus ?case by(auto simp: IK0_def) +next+ case send thus ?case by(auto dest: pairParts_idemD)+next+ case decr thus ?case by(auto dest: pairParts_idemD)+next+ case tuple thus ?case by fastsimp+next+ case lkr thus ?case by(auto simp: longTermKeys_def)+next+ case compr thus ?case by(auto dest: pairParts_idemD)+qed auto+++lemmas knows_pairParts_closedD =+ subsetD[OF knows_pairParts_closed, rule_format]++lemmas rev_knows_pairParts_closedD =+ rev_subsetD[OF _ knows_pairParts_closed, rule_format]+++lemma pairParts_before:+ "\<lbrakk> predOrd t (Ln m) y; m' \<in> pairParts m \<rbrakk> \<Longrightarrow>+ predOrd t (Ln m') y"+proof(induct rule: reachable_induct)+ case (hash t r s msg)+ then interpret s1: reachable_state P t r s+ by unfold_locales+ from hash show ?case+ by (fastsimp dest: s1.rev_knows_pairParts_closedD)+next+ case (encr t r s msg key)+ then interpret s1: reachable_state P t r s+ by unfold_locales+ from encr show ?case+ by (fastsimp dest: s1.rev_knows_pairParts_closedD)+next+ case (tuple t r s msg1 msg2)+ then interpret s1: reachable_state P t r s+ by unfold_locales+ from tuple show ?case+ by (fastsimp dest: s1.rev_knows_pairParts_closedD)+next+ case (decr t r s msg key)+ then interpret s1: reachable_state P t r s+ by unfold_locales+ from decr show ?case+ by (fastsimp dest: s1.rev_knows_pairParts_closedD)+next+ case (send t r s i "done" l msg todo msg)+ then interpret s1: reachable_state P t r s+ by unfold_locales+ from send show ?case+ by (fastsimp dest: s1.rev_knows_pairParts_closedD)+next+ case (recv t r s i "done" l msg todo)+ then interpret s1: reachable_state P t r s+ by unfold_locales+ from recv show ?case+ by (fastsimp dest: s1.rev_knows_pairParts_closedD)+next+ case (init r s) thus ?case by simp+next+ case (lkr t r s a)+ then interpret s1: reachable_state P t r s+ by unfold_locales+ from lkr show ?case+ by (fastsimp dest: s1.rev_knows_pairParts_closedD)+next+ case (skip t r s i "done" l ty pt todo)+ then interpret s1: reachable_state P t r s + by unfold_locales+ from skip show ?case+ by(fastsimp dest: s1.rev_knows_pairParts_closedD)+next+ case (compr t r s i "done" l ty pt todo skipped m)+ then interpret s1: reachable_state P t r s+ by unfold_locales+ from compr show ?case+ by(fastsimp dest: s1.rev_knows_pairParts_closedD)+qed++lemma Ln_before_inp:+ "(i, Recv l pt) \<in> steps t \<Longrightarrow> + \<exists> m. Some m = inst s i pt \<and> Ln m \<prec> St (i, Recv l pt)"+ by (induct arbitrary: i l pt rule: reachable_induct) fastsimp+++lemma Ln_before_inpE:+ "\<lbrakk> (i, Recv l pt) \<in> steps t;+ \<And> m. \<lbrakk> Some m = inst s i pt; Ln m \<prec> St (i, Recv l pt) \<rbrakk>+ \<Longrightarrow> Q+ \<rbrakk> \<Longrightarrow> Q"+ by (auto dest!: Ln_before_inp)++(*+lemmas knows_inp = in_knows_predOrd1[OF Ln_before_inp, rule_format]+*)++text{* Three of the lemmas for the reasoning technique. *}+lemmas Input = Ln_before_inp++lemma split_before:+ "Ln (Tup m m') \<prec> y \<Longrightarrow> Ln m \<prec> y \<and> Ln m' \<prec> y"+ by (fastsimp intro: pairParts_before)++lemma split_knows:+ "Tup m m' \<in> knows t \<Longrightarrow> m \<in> knows t \<and> m' \<in> knows t"+ by (fastsimp intro: knows_pairParts_closedD)+end++subsection{* Case Distinction on Learning Messages *}++text{* Note that the hints are logically equal to true. Thus they have no logical+ content. However they are placed here to track the individual cases when + computing the decryption chains for a concrete message and protocol.+*}++fun decrChain :: "string \<Rightarrow> explicit_trace \<Rightarrow> event set \<Rightarrow> execmsg \<Rightarrow> execmsg \<Rightarrow> bool"+where+ "decrChain path t from (Enc msg key) m = + ( ( m = Enc msg key \<and> (\<forall> f \<in> from. predOrd t f (Ln m)) \<and> + hint ''decrChainPath'' path+ ) \<or>+ ( (\<forall> f \<in> from. predOrd t f (Ln (Enc msg key))) \<and> + decrChain (path@''E'') t {Ln (Enc msg key), Ln (inv key)} msg m )+ )"+| "decrChain path t from (Tup x y) m = + ( ( m = Tup x y \<and> (\<forall> f \<in> from. predOrd t f (Ln m)) \<and>+ hint ''decrChainPath'' path+ ) \<or>+ decrChain (path@''L'') t from x m \<or>+ decrChain (path@''R'') t from y m+ )"+| "decrChain path t from msg m =+ ( m = msg \<and> (\<forall> f \<in> from. predOrd t f (Ln m)) \<and>+ hint ''decrChainPath'' path+ )"++lemma decrChain_append:+ "decrChain path t from msg m \<Longrightarrow> decrChain path (t@t') from msg m"+ by (induct path t "from" msg m rule: decrChain.induct) auto++lemma decrChain_unpair:+ "\<lbrakk> m' \<in> pairParts m; m' \<in> M;+ \<forall> f \<in> from. f \<in> Ln ` knows t \<or> f \<in> St ` steps t+ \<rbrakk> \<Longrightarrow> decrChain path (t@[Learns M]) from m m'"+by (induct m arbitrary: path M) (auto simp: remove_hints)++lemma decrChain_decrypt:+ "\<lbrakk> decrChain path t from msg (Enc m k);+ Enc m k \<in> knows t; inv k \<in> knows t;+ m' \<in> pairParts m; m' \<notin> knows t \<rbrakk> \<Longrightarrow>+ decrChain path' (t @ [Learns (pairParts m - knows t)]) from msg m'"+proof(induct msg arbitrary: path path' "from")+ case (Enc msg key)+ hence from_before [simp]: + "\<forall>f\<in>from. predOrd t f (Ln (Enc msg key))" by auto+ have "m = msg \<and> k = key \<or> + decrChain (path@''E'') t {Ln (Enc msg key), Ln (inv key)} msg (Enc m k)"+ (is "?here \<or> ?nested")+ using Enc by auto+ moreover+ { assume "?here"+ hence "?case"+ proof(cases "m' = Enc m k")+ case True thus ?thesis+ using `?here` Enc by fastsimp+ next+ case False thus ?thesis+ using `?here` Enc+ by(auto intro!: decrChain_unpair)+ qed+ }+ moreover+ { assume "?nested"+ hence "?case" using Enc+ by (fastsimp dest!: Enc(2))+ }+ ultimately show ?case by fast+qed auto+++lemma (in reachable_state) knows_cases_raw:+ assumes knows: "m' \<in> knows t"+ shows + "(m' \<in> IK0) \<or>+ (\<exists> m. m' = Hash m \<and> Ln m \<prec> Ln (Hash m)) \<or>+ (\<exists> m k. m' = Enc m k \<and> Ln m \<prec> Ln (Enc m k) \<and> Ln k \<prec> Ln (Enc m k)) \<or>+ (\<exists> x y. m' = Tup x y \<and> Ln x \<prec> Ln (Tup x y) \<and> Ln y \<prec> Ln (Tup x y)) \<or>+ (\<exists> i done todo skipped. r i = Some (done, todo, skipped) \<and> + (\<exists> l pt m. + Send l pt \<in> set done \<and> Some m = inst s i pt \<and> + decrChain [] t {St (i, Send l pt)} m m'+ )+ ) \<or>+ (\<exists> i done todo skipped. r i = Some (done, todo, skipped) \<and> + (\<exists> l ty pt m. + Note l ty pt \<in> set done \<and> Note l ty pt \<notin> skipped \<and> + Some m = inst s i pt \<and> + decrChain [] t {St (i, Note l ty pt)} m m'+ )+ ) \<or>+ (\<exists> a. m' = SK a \<and> LKR a \<prec> Ln m') \<or>+ (\<exists> a b. m' = K a b \<and> LKR a \<prec> Ln m') \<or>+ (\<exists> a b. m' = K a b \<and> LKR b \<prec> Ln m') \<or> + (\<exists> A. \<exists> a \<in> A. m' = KShr A \<and> LKR (Lit (EAgent a)) \<prec> Ln m')+ "+ (is "?cases m' t r s")+proof -+ --{* Prove cases transfer lemma for trace extension *}+ { fix m' t t' r s+ let ?thesis = "?cases m' (t@t') r s"+ assume "?cases m' t r s" + (is "?ik0 \<or> ?hash \<or> ?enc \<or> ?tup \<or> ?chain t r s \<or> ?note t r s \<or> ?keys")+ moreover+ { assume "?ik0" hence "?thesis" by blast } moreover+ { assume "?hash" hence "?thesis" by fastsimp } moreover+ { assume "?enc" hence "?thesis" by fastsimp } moreover+ { assume "?tup" hence "?thesis" by fastsimp } moreover+ { assume "?chain t r s"+ hence "?chain (t@t') r s" + by (fastsimp intro!: decrChain_append)+ hence "?thesis" by blast+ } moreover+ { assume "?note t r s"+ hence "?note (t@t') r s" + by (fastsimp intro!: decrChain_append)+ hence "?thesis" by blast+ } moreover+ { assume "?keys" hence "?thesis" by auto }+ ultimately have ?thesis by fast+ }+ note cases_appendI_trace = this++ --{* Prove actual thesis *}+ from knows show ?thesis+ proof (induct arbitrary: m' rule: reachable_induct)+ case init thus ?case by simp+ next+ case (hash t r s m)+ let ?t' = "t @ [Learns {Hash m}]"+ note IH = hash(2)+ have "m' \<in> knows t \<or> m' = Hash m" (is "?old \<or> ?new")+ using hash by fastsimp+ moreover+ { assume "?new" hence ?case + using `m \<in> knows t` by fastsimp + }+ moreover+ { assume "?old" + hence ?case by (fastsimp intro!: IH cases_appendI_trace)+ }+ ultimately show ?case by fast+ next+ case (encr t r s m k)+ let ?t' = "t @ [Learns {Enc m k}]"+ note IH = encr(2)+ have "m' \<in> knows t \<or> m' = Enc m k" (is "?old \<or> ?new")+ using encr by fastsimp+ moreover+ { assume "?new" hence ?case + using `m \<in> knows t` and `k \<in> knows t` by fastsimp + }+ moreover+ { assume "?old" + hence ?case by (fast intro!: IH cases_appendI_trace)+ }+ ultimately show ?case by fast+ next+ case (tuple t r s x y)+ let ?t' = "t @ [Learns {Tup x y}]"+ note IH = tuple(2)+ have "m' \<in> knows t \<or> m' = Tup x y" (is "?old \<or> ?new")+ using tuple by fastsimp+ moreover+ { assume "?new" hence ?case + using `x \<in> knows t` and `y \<in> knows t` by fastsimp + }+ moreover+ { assume "?old" + hence ?case by (fast intro!: IH cases_appendI_trace)+ }+ ultimately show ?case by fast+ next+ case (recv t r s i "done" l pt todo skipped)+ hence "?cases m' t r s" + (is "?ik0 \<or> ?hash \<or> ?enc \<or> ?tup \<or> ?chain t r s \<or> ?note t r s \<or> ?keys")+ by clarsimp+ moreover+ { assume "?ik0" hence "?case" by blast } moreover+ { assume "?hash" hence "?case" by fastsimp } moreover+ { assume "?enc" hence "?case" by fastsimp } moreover+ { assume "?keys" hence "?case" by fastsimp } moreover+ { assume "?tup" hence "?case" by fastsimp } moreover+ { let ?t' = "t@[Step (i, Recv l pt)]"+ and ?r' = "r(i \<mapsto> (done @ [Recv l pt], todo, skipped))"+ assume "?chain t r s" then+ obtain i' done' todo' l' pt' skipped' m+ where thread': "r i' = Some (done', todo', skipped')"+ and send: "Send l' pt' \<in> set done'"+ and msg: "Some m = inst s i' pt'"+ and chain:"decrChain [] t {St (i', Send l' pt')} m m'"+ by auto+ then interpret th1: reachable_thread P t r s i' done' todo' skipped'+ using recv by unfold_locales auto+ moreover+ obtain done'' todo'' skipped''+ where "Send l' pt' \<in> set done''"+ and "?r' i' = Some (done'', todo'', skipped'')"+ using `r i = Some (done, Recv l pt # todo, skipped)` thread' send+ by (cases "i = i'") (fastsimp+)+ ultimately+ have "?chain ?t' ?r' s"+ using chain msg+ by (fast intro!: decrChain_append)+ hence "?case" by auto+ } moreover+ { let ?t' = "t@[Step (i, Recv l pt)]"+ and ?r' = "r(i \<mapsto> (done @ [Recv l pt], todo, skipped))"+ assume "?note t r s" then+ obtain i' done' todo' skipped' l' ty' pt' m+ where thread': "r i' = Some (done', todo', skipped')"+ and inDone: "Note l' ty' pt' \<in> set done'"+ and notSkipped: "Note l' ty' pt' \<notin> skipped'"+ and msg: "Some m = inst s i' pt'"+ and chain: "decrChain [] t {St (i', Note l' ty' pt')} m m'"+ by auto+ then interpret th1: reachable_thread P t r s i' done' todo' skipped'+ using recv by unfold_locales auto+ moreover+ obtain done'' todo'' skipped''+ where "Note l' ty' pt' \<in> set done''"+ and "Note l' ty' pt' \<notin> skipped'' "+ and "?r' i' = Some (done'', todo'', skipped'')"+ using `r i = Some (done, Recv l pt # todo, skipped)` thread' inDone notSkipped+ by (cases "i = i'") (fastsimp+)+ ultimately+ have "?note ?t' ?r' s" using msg chain notSkipped inDone+ by (fast intro!: decrChain_append)+ hence "?case" by auto+ }+ ultimately show ?case by fastsimp+ next+ case (send t r s i "done" l pt todo skipped m)+ then interpret th1: + reachable_thread P t r s i "done" "Send l pt # todo" skipped+ by unfold_locales+ let ?r' = "r(i \<mapsto> (done @ [Send l pt], todo, skipped))"+ let ?t' = "(t @ [Step (i, Send l pt)]) @ [Learns (pairParts m - knows t)]"+ have "m' \<in> knows t \<or> m' \<in> pairParts m \<and> m' \<notin> knows t \<and> Some m = inst s i pt" + (is "?old \<or> ?new")+ using send by fastsimp+ moreover+ { assume "?new"+ hence "decrChain [] ?t' {St (i, Send l pt)} m m'"+ by (fastsimp intro!: decrChain_unpair)+ moreover+ have "?r' i = Some (done @ [Send l pt], todo, skipped)"+ using th1.thread_exists by auto+ ultimately+ have ?case using `Some m = inst s i pt`+ apply-+ apply(rule disjI2)+ apply(rule disjI2)+ apply(rule disjI2)+ apply(rule disjI2)+ apply(rule disjI1)+ apply(fastsimp)+ done+ }+ moreover+ { assume "?old" + hence "?cases m' t r s" + (is "?ik0 \<or> ?hash \<or> ?enc \<or> ?tup \<or> ?chain t r s \<or> ?note t r s \<or> ?keys")+ using send by clarsimp+ moreover+ { assume "?ik0" hence "?case" by blast } moreover+ { assume "?hash" hence "?case" by fastsimp } moreover+ { assume "?enc" hence "?case" by fastsimp } moreover+ { assume "?keys" hence "?case" by fastsimp } moreover+ { assume "?tup" hence "?case" by fastsimp } moreover+ { assume "?chain t r s" then+ obtain i' done' todo' l' pt' skipped' m+ where thread': "r i' = Some (done', todo',skipped')"+ and send: "Send l' pt' \<in> set done'"+ and msg: "Some m = inst s i' pt'"+ and chain: "decrChain [] t {St (i', Send l' pt')} m m'"+ by auto+ obtain done'' todo'' skipped''+ where "Send l' pt' \<in> set done''"+ and "(r(i \<mapsto> (done @ [Send l pt], todo, skipped))) i' = Some (done'', todo'',skipped'')"+ using `r i = Some (done, Send l pt # todo, skipped)` thread' send+ by (cases "i = i'") (fastsimp+)+ hence "?chain ?t' ?r' s"+ using chain msg+ by (fast intro!: decrChain_append)+ hence "?case" by auto+ } moreover+ { assume "?note t r s" then+ obtain i' done' todo' skipped' l' ty' pt' m+ where thread': "r i' = Some (done', todo', skipped')"+ and inDone: "Note l' ty' pt' \<in> set done'"+ and notSkipped: "Note l' ty' pt' \<notin> skipped'"+ and msg: "Some m = inst s i' pt'"+ and chain: "decrChain [] t {St (i', Note l' ty' pt')} m m'"+ by auto+ obtain done'' todo'' skipped''+ where "Note l' ty' pt' \<in> set done''"+ and "Note l' ty' pt' \<notin> skipped'' "+ and "?r' i' = Some (done'', todo'', skipped'')"+ using `r i = Some (done, Send l pt # todo, skipped)` thread' inDone notSkipped+ by (cases "i = i'") (fastsimp+)+ hence "?note ?t' ?r' s" using chain notSkipped inDone msg+ by(fast intro!: decrChain_append)+ hence "?case" by auto+ }+ ultimately have ?case by fast+ }+ ultimately show ?case by fast+ next+ case (decr t r s m k)+ then interpret s1: reachable_state P t r s+ by unfold_locales+ let ?t' = "t @ [Learns (pairParts m - knows t)]"+ note IH = decr(2)+ have "m' \<in> knows t \<or> m' \<in> pairParts m \<and> m' \<notin> knows t" + (is "?old \<or> ?new")+ using decr by fastsimp+ moreover+ { assume "?new"+ hence "m' \<in> pairParts m" and "m' \<notin> knows t" by auto+ hence + "(predOrd t (Ln m) (Ln (Enc m k)) \<and> predOrd t (Ln k) (Ln (Enc m k))) \<or>+ ((\<exists>i done todo skipped. r i = Some (done, todo,skipped) \<and>+ (\<exists>l pt ms. Send l pt \<in> set done \<and> Some ms = inst s i pt \<and> + decrChain [] t {St (i, Send l pt)} ms (Enc m k)))) \<or>+ ((\<exists>i done todo skipped. r i = Some (done, todo,skipped) \<and>+ (\<exists>l ty pt ms. Note l ty pt \<in> set done \<and> Note l ty pt \<notin> skipped \<and>+ Some ms = inst s i pt \<and> + decrChain [] t {St (i, Note l ty pt)} ms (Enc m k))))"+ (is "?fake_enc \<or> ?decchain t (Enc m k) \<or> ?notechain t (Enc m k)")+ using IH[OF `Enc m k \<in> knows t`] by auto+ moreover+ { assume "?fake_enc"+ hence "?case" using `?new`+ by (auto dest!: in_knows_predOrd1 s1.rev_knows_pairParts_closedD)+ }+ moreover+ { assume "?decchain t (Enc m k)" then+ obtain i' done' todo' l' pt' skipped' ms+ where thread': "r i' = Some (done', todo',skipped')"+ and send: "Send l' pt' \<in> set done'"+ and msg: "Some ms = inst s i' pt'"+ and chain: "decrChain [] t {St (i', Send l' pt')} ms (Enc m k)"+ by auto+ moreover+ hence "decrChain [] ?t' {St (i', Send l' pt')} ms m'"+ using `?new` `Enc m k \<in> knows t` `inv k \<in> knows t`+ by (fastsimp intro!: decrChain_decrypt)+ ultimately+ have "?decchain ?t' m'" by fastsimp+ hence "?case" by blast+ }+ moreover+ { assume "?notechain t (Enc m k)" then+ obtain i' done' todo' l' ty' pt' skipped' ms+ where thread': "r i' = Some (done', todo',skipped')"+ and inDone: "Note l' ty' pt' \<in> set done'"+ and notSkipped: "Note l' ty' pt' \<notin> skipped'"+ and msg: "Some ms = inst s i' pt'"+ and chain: "decrChain [] t {St (i', Note l' ty' pt')} ms (Enc m k)"+ by auto+ moreover+ hence "decrChain [] ?t' {St (i', Note l' ty' pt')} ms m'"+ using `?new` `Enc m k \<in> knows t` `inv k \<in> knows t`+ by (fastsimp intro!: decrChain_decrypt)+ ultimately+ have "?notechain ?t' m'" by fastsimp+ hence "?case" by blast+ }+ ultimately have ?case by fast+ }+ moreover+ { assume "?old" + hence ?case by (fast intro!: IH cases_appendI_trace)+ }+ ultimately show ?case by fast thm decr+ next+ case(lkr t r s a)+ then interpret s1: reachable_state P t r s+ by unfold_locales+ let ?t' = "t @ [ LKReveal a, Learns (longTermKeys a - knows t)]"+ note IH = lkr(2)+ have "m' \<in> knows t \<or> m' \<in> longTermKeys a \<and> m' \<notin> knows t" + (is "?old \<or> ?new")+ using lkr by fastsimp+ moreover + {+ assume "?old"+ hence "?case" by (fast intro!: IH cases_appendI_trace)+ }+ moreover+ {+ assume "?new"+ hence ?case by (auto simp: longTermKeys_def)+ }+ ultimately show "?case" by fast+ next+ case (skip t r s i "done" l ty pt todo skipped)+ then interpret this_thread: reachable_thread P t r s i "done" "Note l ty pt # todo" skipped by unfold_locales+ let ?r' = "r(i \<mapsto> (done @ [Note l ty pt], todo, insert (Note l ty pt) skipped))"+ have "m' \<in> knows t" using skip by fastsimp+ hence "?cases m' t r s" + (is "?ik0 \<or> ?hash \<or> ?enc \<or> ?tup \<or> ?chain t r s \<or> ?note t r s \<or> ?keys")+ using skip by clarsimp+ moreover+ { assume "?ik0" hence "?case" by blast } moreover+ { assume "?hash" hence "?case" by fastsimp } moreover+ { assume "?enc" hence "?case" by fastsimp } moreover+ { assume "?keys" hence "?case" by fastsimp } moreover+ { assume "?tup" hence "?case" by fastsimp } moreover+ { assume "?chain t r s" then+ obtain i' done' todo' l' pt' skipped' m+ where thread': "r i' = Some (done', todo',skipped')"+ and send: "Send l' pt' \<in> set done'"+ and msg: "Some m = inst s i' pt'"+ and chain: "decrChain [] t {St (i', Send l' pt')} m m'"+ by auto+ obtain done'' todo'' skipped''+ where "Send l' pt' \<in> set done''"+ and "?r' i' = Some (done'', todo'',skipped'')"+ using skip(3) thread' send+ by (cases "i = i'") (fastsimp+)+ hence "?chain t ?r' s"+ using chain msg by fast+ hence "?case" by auto+ }+ moreover+ { assume "?note t r s" then+ obtain i' done' todo' skipped' l' ty' pt' m+ where thread': "r i' = Some (done', todo', skipped')"+ and inDone: "Note l' ty' pt' \<in> set done'"+ and notSkipped: "Note l' ty' pt' \<notin> skipped'"+ and msg: "Some m = inst s i' pt'"+ and chain: "decrChain [] t {St (i', Note l' ty' pt')} m m'"+ by auto+ obtain done'' todo'' skipped''+ where "Note l' ty' pt' \<in> set done''"+ and "Note l' ty' pt' \<notin> skipped'' "+ and "?r' i' = Some (done'', todo'', skipped'')"+ using `r i = Some (done, Note l ty pt # todo, skipped)` thread' inDone notSkipped+ by (cases "i = i'") (force dest: this_thread.done_notin_todoD)++ hence "?note t ?r' s" + using chain notSkipped inDone msg+ by fast+ hence "?case" by auto+ } moreover+ { assume "?keys" hence "?case" by fastsimp }+ ultimately + show "?case" by fastsimp+ next+ case(compr t r s i "done" l ty pt todo skipped m m')+ then interpret th1: + reachable_thread P t r s i "done" "Note l ty pt # todo" skipped+ by unfold_locales+ let ?r' = "r(i \<mapsto> (done @ [Note l ty pt], todo, skipped))"+ let ?t' = "(t @ [Step (i, Note l ty pt)]) @ [Learns (pairParts m - knows t)]"+ have "m' \<in> knows t \<or> m' \<in> pairParts m \<and> m' \<notin> knows t \<and> Some m = inst s i pt" + (is "?old \<or> ?new")+ using compr by fastsimp+ moreover+ { assume "?new"+ (*+ hence "m' \<in> pairParts (inst s i pt)" and "m' \<notin> knows t" using `m = inst s i pt` + by auto+*)+ hence "decrChain [] ?t' {St (i, Note l ty pt)} m m'" + by (fastsimp intro!: decrChain_unpair)+ moreover+ have "?r' i = Some (done @ [Note l ty pt], todo, skipped)" + using th1.thread_exists by auto+ moreover+ have "Note l ty pt \<in> set (Note l ty pt # todo)" + using th1.thread_exists by auto+ hence "Note l ty pt \<notin> skipped" + by (fastsimp dest: th1.todo_notin_skippedD)+ ultimately+ have ?case using `Some m = inst s i pt`+ apply-+ apply(rule disjI2)+ apply(rule disjI2)+ apply(rule disjI2)+ apply(rule disjI2)+ apply(rule disjI2)+ apply(rule disjI1)+ by force+ }+ moreover+ { assume "?old" + hence "?cases m' t r s" + (is "?ik0 \<or> ?hash \<or> ?enc \<or> ?tup \<or> ?chain t r s \<or> ?note t r s \<or> ?keys")+ using compr by clarsimp+ moreover+ { assume "?ik0" hence "?case" by blast } moreover+ { assume "?hash" hence "?case" by fastsimp } moreover+ { assume "?enc" hence "?case" by fastsimp } moreover+ { assume "?keys" hence "?case" by fastsimp } moreover+ { assume "?tup" hence "?case" by fastsimp } moreover+ { assume "?chain t r s" then+ obtain i' done' todo' l' pt' skipped' m+ where thread': "r i' = Some (done', todo',skipped')"+ and send: "Send l' pt' \<in> set done'"+ and msg: "Some m = inst s i' pt'"+ and chain: "decrChain [] t {St (i', Send l' pt')} m m'"+ by auto+ obtain done'' todo'' skipped''+ where "Send l' pt' \<in> set done''"+ and "(r(i \<mapsto> (done @ [Note l ty pt], todo, skipped))) i' = Some (done'', todo'',skipped'')"+ using compr(3) thread' send+ by (cases "i = i'") (fastsimp+)+ hence "?chain ?t' ?r' s" using chain msg+ by(fast intro!: decrChain_append)+ hence "?case" by auto+ } moreover+ { assume "?note t r s" then+ obtain i' done' todo' skipped' l' ty' pt' m+ where thread': "r i' = Some (done', todo', skipped')"+ and inDone: "Note l' ty' pt' \<in> set done'"+ and notSkipped: "Note l' ty' pt' \<notin> skipped'"+ and msg: "Some m = inst s i' pt'"+ and chain: "decrChain [] t {St (i', Note l' ty' pt')} m m'"+ by auto+ obtain done'' todo'' skipped''+ where "Note l' ty' pt' \<in> set done''"+ and "Note l' ty' pt' \<notin> skipped'' "+ and "?r' i' = Some (done'', todo'', skipped'')"+ using `r i = Some (done, Note l ty pt # todo, skipped)` thread' inDone notSkipped+ by (cases "i = i'") (fastsimp+)+ hence "?note ?t' ?r' s"+ using chain notSkipped inDone msg+ by(fast intro!: decrChain_append)+ hence "?case" by auto+ }+ ultimately have ?case by fast+ }+ ultimately show ?case by fast+ qed+qed++end
@@ -0,0 +1,248 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+(* Extensions to the standard HOL library *)+theory HOL_ext+imports+ Main+begin+++section{* Maps *}++lemma dom_upd [simp]: + "dom (\<lambda> a. if a = x then Some y else m a) = insert x (dom m)"+ by(fastsimp simp: dom_if)++lemma map_leD: "\<lbrakk> m \<subseteq>\<^sub>m m'; m x = Some y \<rbrakk> \<Longrightarrow> m' x = Some y"+ by(force simp: map_le_def)++lemma rev_map_leD: "\<lbrakk> m x = Some y; m \<subseteq>\<^sub>m m' \<rbrakk> \<Longrightarrow> m' x = Some y"+ by(force simp: map_le_def)++lemma map_leI: + "\<lbrakk> \<And> x y. m x = Some y \<Longrightarrow> m' x = Some y \<rbrakk> \<Longrightarrow> m \<subseteq>\<^sub>m m'"+ by(force simp: map_le_def)++section{* Finite Sets *}++text{* + Automating the simplification of differences of finite sets. +*}+lemma eq_conj_neq: + "y \<noteq> z \<Longrightarrow> (x = y \<and> x \<noteq> z) = (x = y)"+ "y \<noteq> z \<Longrightarrow> (x = y \<and> (x \<noteq> z \<and> P)) = ((x = y) \<and> P)"+ "y \<noteq> z \<Longrightarrow> (x = y \<and> (P \<and> x \<noteq> z)) = ((x = y) \<and> P)"+ "y \<noteq> z \<Longrightarrow> (x \<noteq> z \<and> x = y) = (x = y)"+ "y \<noteq> z \<Longrightarrow> ((x \<noteq> z \<and> P) \<and> x = y) = ((x = y) \<and> P)"+ "y \<noteq> z \<Longrightarrow> ((P \<and> x \<noteq> z) \<and> x = y) = ((x = y) \<and> P)"+ by(auto)++lemmas finite_setdiff_compute =+ conj_disj_distribL + conj_disj_distribR + ex_disj_distrib+ eq_conj_neq+ disj_ac+++subsection{* Extensions to ML infrastructure for HOL *}++lemma HOL_concl_revcut_rl:+ "\<lbrakk> PROP V; PROP V \<Longrightarrow> W \<rbrakk> \<Longrightarrow> W"+ by simp+++ML{*+signature HOL_EXT =+sig+ (* Gather bound variables *)+ val add_bound_list : term -> int list -> int list++ (* Permutations of all quantifiers *)+ val invert_perm : int list -> int list+ val forall_permute : Proof.context -> int list -> cterm -> thm+ val forall_permute_conv : Proof.context -> int list -> cterm -> thm++ (* Theorem modifications *)+ val beta_norm_thm : thm -> thm+ val make_HOL_elim : thm -> thm+ val protect_concl : thm -> thm+ val lift_ground_thm_mod + : Proof.context -> (Proof.context -> thm -> thm) -> thm -> thm++ (* Applying tactics to theorems *)+ val rule_by_tactic + : Proof.context -> (Proof.context -> thm -> thm Seq.seq) -> thm -> thm+ val refine_rule + : Proof.context -> (Proof.context -> thm -> thm Seq.seq) -> thm -> thm+ val track_HOL_term + : Proof.context -> term -> (thm * (thm -> thm)) * Proof.context+end;++*}++ML{*++structure HOL_Ext: HOL_EXT =+struct++(* gather a list of bound variables *)+val add_bound_list =+ (fn f => rev o f) o fold_aterms (fn Bound i => (fn is => i::is) | _ => I);+++(* invert a permutation *)+fun invert_perm p =+ p ~~ (0 upto (length p - 1))+ |> sort (int_ord o pairself fst)+ |> map snd+++(* Prove the permutation of the outermost all quantifiers:+ + !!x0 .. x(n-1). A |- !!x[p0] .. x[p(n-1)]. A++ PRE: No meta-variables in the given cterm.+*)+fun forall_permute ctxt p ct =+ let+ val cert = Thm.cterm_of (ProofContext.theory_of ctxt);+ fun mk_cv (_, ty) n = cert (Free (n, ty));+ val string_of_perm = commas o map string_of_int;+ fun err msg = raise CTERM+ ( "forall_permute: " ^ msg ^ " [" ^ string_of_perm p ^ "]"+ , [ct] );++ val t = Thm.term_of ct;+ val n = length p;+ val vs = t |> Term.strip_all_vars |> #1 o chop n;++ val () = if n <> length vs+ then err "too many variables referenced"+ else ();++ val (vns', _) = Variable.variant_fixes (map fst vs) ctxt;+ val cvs' = map2 mk_cv vs vns';+ val cpvs' = + map (nth cvs') p+ handle Subscript => err "wrong subscript in permutation";+ in+ ct+ |> Thm.assume+ |> forall_elim_list cvs'+ |> forall_intr_list cpvs'+ end++(* Prove the conversion permuting the variables:++ (!!x0 .. x(n-1). A) == (!!x[p0] .. x[p(n-1)]. A)+*)+fun forall_permute_conv ctxt p ct =+ let+ val lr = forall_permute ctxt p ct;+ val ct' = Thm.cprop_of lr;+ val rl = forall_permute ctxt (invert_perm p) ct';+ in+ Thm.equal_intr (Thm.implies_intr ct lr) + (Thm.implies_intr ct' rl)+ end;+++(* Beta-normal form of a theorem *)+fun beta_norm_thm th =+ Thm.equal_elim (Thm.beta_conversion true (Thm.cprop_of th)) th++(* make an elim rule with a "Trueprop ?R" concluion *)+fun make_HOL_elim rl = + zero_var_indexes (rl RS @{thm HOL_concl_revcut_rl})+++(*+ A ==> ... ==> C+ ---------------- (protect_concl)+ A ==> ... ==> #C+*)+fun protect_concl th = + Drule.comp_no_flatten (th, Thm.nprems_of th) 1 Drule.protectI;+++(* Modify a theorem using a function thm -> thm that requires the theorem+ to contain no schematic variables.+*)+fun lift_ground_thm_mod ctxt f th =+ let+ val ((_, [th']), ctxt') = Variable.import true [th] ctxt;+ in+ f ctxt' th'+ |> singleton (Variable.export ctxt' ctxt)+ |> zero_var_indexes+ end;+++(*Makes a rule by applying a tactic to an existing rule.++ Copied from 'tactic.ML' and fixed such that the current context+ is taken as an argument to avoid clashes with free variables referenced + by facts used by the tactic.+*)+fun rule_by_tactic ctxt tac rl =+ lift_ground_thm_mod ctxt + (fn ctxt' => fn st => + case Seq.pull (tac ctxt' st) of+ NONE => raise THM ("rule_by_tactic", 0, [rl])+ | SOME (st', _) => st')+ rl;++(* Apply a tactic to the premises of an elim rule *)+fun refine_rule ctxt tac =+ Goal.conclude o rule_by_tactic ctxt tac o protect_concl+++(* Returns a theorem of the for "Q x |- Q x" together with+ a removal function that can be used to eliminate the "Q x"+ assumption by replacing it with (\y. x = y). The given+ theorem can be used to track the conversions of "x" that+ happen when using automatic tools. Just insert the given+ theorem.+*)+fun track_HOL_term ctxt x_t =+ let+ val thy = ProofContext.theory_of ctxt;+ val cert = Thm.cterm_of thy;++ val x_ty = Term.fastype_of x_t; ++ val ([Q_n],ctxt') = Variable.variant_fixes ["Q"] ctxt;+ val Q_ty = x_ty --> HOLogic.boolT;+ val Q_t = Free (Q_n, Q_ty);+ + val Q_ct = cert Q_t;+ val Qx_ct = cert (HOLogic.mk_Trueprop (Q_t $ x_t));+ val eq_x_ct = cert + (Abs ("y", x_ty, + Const (@{const_name "op ="}, x_ty --> x_ty --> HOLogic.boolT)+ $ x_t $ Bound 0));++ fun remove_tracking th' =+ th' + |> Thm.implies_intr Qx_ct + |> Thm.forall_intr Q_ct+ |> Thm.forall_elim eq_x_ct+ |> curry (op RS) @{thm refl}+ |> beta_norm_thm+ in+ ((Thm.assume Qx_ct, remove_tracking), ctxt')+ end;+++end;+*}+++end
@@ -0,0 +1,92 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+theory Hints+imports+ Main+uses+ espl_utils+begin++section{* A Theory of Hints for Marking Intermediate Results *}+++definition hint :: "string \<Rightarrow> 'a \<Rightarrow> bool"+where "hint lbl data = True"++text{* + Simplify with the rule below to remove all hints in your + current subgoal.+*}+lemmas remove_hints = hint_def++lemma hintI: "hint lbl data"+ by (simp add: remove_hints)+++subsection{*ML Interface for working with hints*}++ML{*+signature HINTS =+sig+ val dest_hint: term -> string * term+ val mk_hint: string -> term -> term+ val mk_hint_thm: theory -> string -> term -> thm+ val gather: (string * term -> bool) -> term list -> (string * term) list+ val gather_by_name: string -> term list -> term list+ val remove_all_hints_tac: int -> tactic+end;+*}++ML{*++structure Hints: HINTS =+struct ++open ESPL_Utils;++(* Destructs a hint *)+fun dest_hint (Const (@{const_name hint}, _) $ lbl $ data) = (HOLogic.dest_string lbl, data)+ | dest_hint t = raise TERM ("dest_hint", [t]);++(* gather the hints in the premises matching the predicate *)+fun gather p = filter p o gather_props dest_hint+ +(* gather the hints matching the name *) +fun gather_by_name name = map snd o gather (equal name o fst)++(* A tactic removing all hints in the given subgoal *)+val remove_all_hints_tac = full_simp_tac (HOL_ss addsimps @{thms remove_hints})++(* create a hint term *)+fun mk_hint name t =+ let+ val name_t = HOLogic.mk_string name;+ val hint_ty = @{typ string} --> Term.fastype_of t --> HOLogic.boolT;+ in+ Const (@{const_name hint}, hint_ty) $ name_t $ t+ end;++(* create a hint theorem *)+fun mk_hint_thm thy name t =+ let+ val hint_ct = mk_hint name t |> HOLogic.mk_Trueprop+ |> Thm.cterm_of thy;+ in+ Goal.prove_internal [] hint_ct (K (ALLGOALS remove_all_hints_tac))+ end;++end;++*}++end
@@ -0,0 +1,481 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+theory InferenceRules+imports+ HOL_ext+ Hints+ ExplicitModel+begin+++section{* Inference Rules *}++subsection{* Role Order *}++definition roleMap :: "threadpool \<Rightarrow> tid \<rightharpoonup> role"+where "roleMap pool \<equiv> (\<lambda>(done,todo,skipped). Some (done @ todo)) \<circ>\<^sub>m pool"++lemma roleMap_empty [simp]: "roleMap empty = empty"+ by(simp add: roleMap_def)++lemma dom_roleMap [simp]: "dom (roleMap r) = dom r"+ by(auto simp: dom_def roleMap_def map_comp_def + split: option.splits)++lemma roleMap_upd [simp]:+ "roleMap (pool(i \<mapsto> (done,todo,skipped))) = + (roleMap pool)(i \<mapsto> (done@todo))"+ by(rule ext, simp add: roleMap_def map_comp_def)++lemma roleMap_SomeD:+ "roleMap r i = Some R \<Longrightarrow> + \<exists> todo done skipped. r i = Some (done, todo, skipped) \<and> R = done@todo"+ by(auto simp: roleMap_def map_comp_def split: option.splits)++lemma roleMap_SomeI:+ "\<lbrakk> r i = Some (done, todo, skipped); R = done @ todo \<rbrakk> \<Longrightarrow>+ roleMap r i = Some R"+ by(auto simp: roleMap_def map_comp_def split: option.splits)++lemma roleMap_SomeE:+ assumes role_exists: "roleMap r i = Some R"+ obtains "done" todo skipped+ where "r i = Some (done, todo, skipped)" and "R = done @ todo"+using role_exists+by (auto simp: roleMap_def map_comp_def split: option.splits)++lemma roleMap_le_roleMapI [intro!]:+ assumes roleMap_leD: + "\<And> i done todo skipped. r i = Some (done, todo, skipped) \<Longrightarrow> + \<exists> done' todo' skipped'. r' i = Some (done', todo', skipped') \<and> done@todo = done'@todo'"+ shows "roleMap r \<subseteq>\<^sub>m roleMap r'"+by(auto simp: roleMap_def map_comp_def split: option.splits+ intro!: map_leI dest!: roleMap_leD)++lemma (in reachable_thread) roleMap: + "roleMap r i = Some (done@todo)"+ by(fast intro!: thread_exists roleMap_SomeI)++subsection{* Prefix Close *}+++definition prefixClose :: "store \<Rightarrow> explicit_trace \<Rightarrow> role \<Rightarrow> rolestep \<Rightarrow> tid \<Rightarrow> bool"+where+"prefixClose s t R step i = + (\<forall> st st'. + (nextRel (filter (\<lambda> x. \<not> (noteStep x)) (takeWhile (\<lambda> x. x \<noteq> step) R) @ [step]) st st') \<longrightarrow>+ ((recvStep st \<longrightarrow> (\<exists> m. Some m = inst s i (stepPat st) \<and> predOrd t (Ln m) (St (i, st)))) \<and>+ predOrd t (St (i, st)) (St (i, st')))+ )"++context reachable_state begin++lemma note_filtered_done[iff]:+ "Note l ty pt \<notin> set (filter (\<lambda> x. \<not> (noteStep x)) done)"+by auto++lemma take_while_is_done:+ assumes facts:+ "r i = Some(done, step # todo, skipped)"+ "roleMap r i = Some R"+ shows isDone:+ "(takeWhile (\<lambda> x. x \<noteq> step) R) = done"+using facts+proof -+ interpret reachable_thread P t r s i "done" "step#todo" skipped+ using facts by unfold_locales auto+ hence "step \<in> set (step # todo)" by auto+ hence "step \<notin> set done" using facts by (fastsimp dest!: todo_notin_doneD)+ hence "(takeWhile (\<lambda> x. x \<noteq> step) done) = done" by auto+ hence "(takeWhile (\<lambda> x. x \<noteq> step) (done @ (step # todo))) = done" by auto+ moreover+ have "R = (done @ (step # todo))" using facts by (fastsimp dest: roleMap_SomeD)+ ultimately show ?thesis by auto+qed++lemma note_filtered_role:+ "Note l ty pt \<in> set (filter (\<lambda> x. \<not> (noteStep x)) (takeWhile (\<lambda> x. x \<noteq> step) R) @ [step]) \<Longrightarrow> step = (Note l ty pt)"+by auto++lemma note_filtered_revRole:+"Note l ty pt \<in> set (step# rev (filter (\<lambda> x. \<not> (noteStep x)) (takeWhile (\<lambda> x. x \<noteq> step) R))) \<Longrightarrow> step = (Note l ty pt)"+by auto++lemma filtered_role_conv:+ assumes filtered:+ "st \<in> set (filter (\<lambda> x. \<not> (noteStep x)) (takeWhile (\<lambda> x. x \<noteq> step) R) @ [step])"+ shows "(st \<in> set R \<and> st \<noteq> (Note l ty pt)) \<or> (st = step)"+proof -+ have "st \<in> set (filter (\<lambda> x. \<not> (noteStep x)) (takeWhile (\<lambda> x. x \<noteq> step) R)) \<or> (st = step)" using filtered by auto+ moreover {+ assume inFilter: "st \<in> set (filter (\<lambda> x. \<not> (noteStep x)) (takeWhile (\<lambda> x. x \<noteq> step) R)) \<and> (st \<noteq> step)"+ hence "st \<in> set (takeWhile (\<lambda> x. x \<noteq> step) R) \<and> (st \<noteq> step)" by auto+ hence "st \<in> set R \<and> (st \<noteq> step)" by (auto dest: set_takeWhileD)+ hence "st \<in> set R" by auto+ moreover+ have "st \<noteq> (Note l ty pt)" using inFilter by (auto dest: note_filtered_role)+ ultimately have ?thesis by auto+ }+ ultimately show ?thesis by auto+qed++lemma filtered_done_conv:+ assumes isThread:+ "r i = Some(done, step # todo, skipped)"+ "roleMap r i = Some R"+ and filtered:+ "st \<in> set (filter (\<lambda> x. \<not> (noteStep x)) (takeWhile (\<lambda> x. x \<noteq> step) R) @ [step])"+ shows+ "(st \<in> set done \<and> st \<noteq> (Note l ty pt)) \<or> (st = step)"+proof -+ have "(st \<in> set R \<and> st \<noteq> (Note l ty pt)) \<or> (st = step)" using filtered by (fastsimp dest: filtered_role_conv)+ moreover+ have "(takeWhile (\<lambda> x. x \<noteq> step) R) = done" using isThread by (fastsimp dest: take_while_is_done)+ ultimately show ?thesis using isThread and filtered by fastsimp+qed++lemma filtered_in_done:+ assumes step: "(i, step) \<in> steps t"+ and role_exists: "roleMap r i = Some R \<and> r i = Some(done, todo, skipped)"+ and inFiltered: "st \<in> set (filter (\<lambda> x. \<not> (noteStep x)) (takeWhile (\<lambda> x. x \<noteq> step) R) @ [step])"+ shows "st \<in> set done"+proof -+ interpret this_thread:+ reachable_thread P t r s i "done" todo skipped+ using role_exists by unfold_locales auto+ hence "step \<in> set done"+ using step by (auto dest: this_thread.in_steps_in_done)+ moreover+ then obtain prefix suffix + where done_split: "done = prefix @ step # suffix \<and> step \<notin> set prefix"+ by (auto dest!: split_list_first)+ hence "takeWhile (\<lambda>x. x \<noteq> step) (prefix@step#suffix@todo) = prefix"+ by (subst takeWhile_append2) auto+ hence "takeWhile (\<lambda>x. x \<noteq> step) R = prefix"+ using role_exists done_split by (auto elim!: roleMap_SomeE) + moreover {+ assume "st \<noteq> step \<and> takeWhile (\<lambda>x. x \<noteq> step) R = prefix"+ hence "st \<in> set prefix" using inFiltered + by auto+ hence ?thesis using done_split by fastsimp+ }+ moreover {+ assume "st = step \<and> step \<in> set done"+ hence ?thesis by auto+ }+ ultimately show ?thesis by auto+qed+++lemma recv_roleOrd_imp_predOrd:+ assumes step: "(i, step) \<in> steps t"+ and role_exists: "roleMap r i = Some R"+ and role_ord: "listOrd R (Recv l pt) step"+ shows "St (i, (Recv l pt)) \<prec> St (i, step)"+proof -+ from role_exists+ obtain "done" todo skipped+ where "R = done @ todo"+ and "r i = Some (done, todo, skipped)"+ by (auto elim!: roleMap_SomeE)+ then interpret this_thread:+ reachable_thread P t r s i "done" todo skipped+ by unfold_locales auto+ show ?thesis using step role_ord `R = done @ todo`+ by (fast intro!: listOrd_imp_predOrd+ this_thread.listOrd_recv_role_imp_listOrd_trace)+qed+++lemma send_roleOrd_imp_predOrd:+ assumes step: "(i, step) \<in> steps t"+ and role_exists: "roleMap r i = Some R"+ and role_ord: "listOrd R (Send l pt) step"+ shows "St (i, (Send l pt)) \<prec> St (i, step)"+proof -+ from role_exists+ obtain "done" todo skipped+ where "R = done @ todo"+ and "r i = Some (done, todo, skipped)"+ by (auto elim!: roleMap_SomeE)+ then interpret this_thread:+ reachable_thread P t r s i "done" todo skipped+ by unfold_locales auto+ show ?thesis using step role_ord `R = done @ todo`+ by (fast intro!: listOrd_imp_predOrd+ this_thread.listOrd_send_role_imp_listOrd_trace)+qed++lemmas roleOrd_imp_predOrd' =+ send_roleOrd_imp_predOrd[OF in_steps_predOrd1, rule_format]+ recv_roleOrd_imp_predOrd[OF in_steps_predOrd1, rule_format]++lemmas roleOrd_imp_step =+ in_steps_predOrd1[OF send_roleOrd_imp_predOrd, rule_format]+ in_steps_predOrd1[OF recv_roleOrd_imp_predOrd, rule_format]++lemmas roleOrd_imp_step' =+ roleOrd_imp_step[OF in_steps_predOrd1, rule_format]++lemma prefixClose_rawI:+ assumes "\<And> st st'. + \<lbrakk> nextRel (filter (\<lambda> x. \<not> (noteStep x)) (takeWhile (\<lambda> x. x \<noteq> step) R) @ [step]) st st';+ recvStep st+ \<rbrakk> \<Longrightarrow> \<exists> m. Some m = inst s i (stepPat st) \<and> Ln m \<prec> St (i, st)"+ and "\<And> st st'. + \<lbrakk> nextRel (filter (\<lambda> x. \<not> (noteStep x)) (takeWhile (\<lambda> x. x \<noteq> step) R) @ [step]) st st'+ \<rbrakk> \<Longrightarrow> St (i, st) \<prec> St (i, st')"+ shows "prefixClose s t R step i"+using prems by (auto simp: prefixClose_def)++lemma prefixCloseI:+ assumes step: "(i, step) \<in> steps t"+ and role_exists: "roleMap r i = Some R"+ shows "prefixClose s t R step i"+proof -+ from role_exists+ obtain "done" todo skipped+ where R_split: "R = done @ todo"+ and "r i = Some (done, todo,skipped)"+ by (auto elim!: roleMap_SomeE)+ moreover+ then interpret this_thread:+ reachable_thread P t r s i "done" todo skipped+ by unfold_locales auto+ + from step have "step \<in> set done"+ by (rule this_thread.in_steps_in_done)+ then obtain prefix suffix + where done_split: "done = prefix @ step # suffix \<and> step \<notin> set prefix"+ by (auto dest!: split_list_first)+ moreover+ hence "takeWhile (\<lambda>x. x \<noteq> step) (prefix@step#suffix@todo) = prefix"+ by (subst takeWhile_append2) auto+ moreover+ { fix st st'+ assume nextRel: "nextRel (step#rev (filter (\<lambda> x. \<not> (noteStep x)) prefix)) st' st"++ hence in_nextRel: "st' \<in> set (step#rev (filter (\<lambda> x. \<not> (noteStep x)) prefix)) \<and>+ st \<in> set (step#rev (filter (\<lambda> x. \<not> (noteStep x)) prefix))"+ by(auto dest: in_set_nextRel1 in_set_nextRel2)+ hence "st \<in> set done" and "st' \<in> set done"+ using done_split step role_exists nextRel+ by (auto dest: in_set_nextRel1 in_set_nextRel2 filtered_in_done)+ hence "st \<in> set done \<and> st \<notin> skipped" and "st' \<in> set done \<and> st' \<notin> skipped"+ using step in_nextRel+ apply -+ apply(rule conjI, assumption)+ apply(case_tac "st = step")+ apply(fastsimp dest: this_thread.in_steps_conv_done_skipped[THEN iffD1])+ apply(fastsimp dest!: this_thread.note_in_skipped note_filtered_revRole)++ apply(rule conjI, assumption)+ apply(case_tac "st' = step")+ apply(fastsimp dest: this_thread.in_steps_conv_done_skipped[THEN iffD1])+ by(fastsimp dest!: this_thread.note_in_skipped note_filtered_revRole)+ hence steps: "(i, st) \<in> steps t" "(i, st') \<in> steps t"+ by(auto dest: this_thread.in_steps_conv_done_skipped[THEN iffD1])+ { assume "recvStep st" then+ obtain l pt where "st = Recv l pt" by (cases st) auto+ hence "\<exists> m. Some m = inst s i (stepPat st) \<and> Ln m \<prec> St (i, st)"+ using steps by(auto intro!: Ln_before_inp)+ }+ note input = this++ have "listOrd R st st'" + using nextRel and R_split and done_split+ by(fastsimp dest: nextRel_imp_listOrd listOrd_rev[THEN iffD1] listOrd_filter)+ hence "St (i, st) \<prec> St (i, st')"+ using role_exists steps R_split+ apply -+ apply(drule this_thread.in_steps_conv_done_skipped[THEN iffD1])+ by(fastsimp dest!: this_thread.roleOrd_notSkipped_imp_listOrd_trace dest:listOrd_imp_predOrd)++ note input and this+ }+ ultimately show ?thesis+ by (auto simp: prefixClose_def)+qed++text{* Support for the "prefix\_close" command. *}++lemma ext_prefixClose: + "\<lbrakk> (i, step) \<in> steps t; roleMap r i = Some R \<rbrakk> \<Longrightarrow>+ prefixClose s t R step i \<and> + (recvStep step \<longrightarrow> (\<exists> m. Some m = inst s i (stepPat step) \<and> Ln m \<prec> St (i, step)))"+ by (cases step) (fastsimp intro!: prefixCloseI Ln_before_inp)+++text{* + Used for prefix closing assumptions corresponding to a case of+ an annotation completeness induction proof.+*}+lemma thread_prefixClose: + assumes thread_exists: "r i = Some (step#done, todo, skipped)"+ and not_skipped: "step \<notin> skipped"+ shows + "(\<forall> st st'. nextRel (step # (filter (\<lambda> x. \<not> (noteStep x)) done)) st st' \<longrightarrow>+ ((recvStep st \<longrightarrow> + (\<exists> m. Some m = inst s i (stepPat st) \<and> predOrd t (Ln m) (St (i, st)))+ ) \<and>+ predOrd t (St (i, st)) (St (i, st')))+ ) \<and>+ (recvStep (last (step#done)) \<longrightarrow>+ (\<exists> m. Some m = inst s i (stepPat (last (step#done))) \<and> + predOrd t (Ln m) (St (i, (last (step#done))))+ )+ )"+ (is "?prefix \<and> ?inp_last")+proof -+ interpret this_thread: reachable_thread P t r s i "step#done" todo skipped+ using thread_exists by unfold_locales auto+ {+ assume recv: "recvStep (last (step#done))"+ hence last_step: "(i, last (step#done)) \<in> steps t"+ proof+ obtain l pt+ where recv_eq: "(Recv l pt) = (last (step # done))"+ using recv by (fastsimp dest!: recvStepD)+ hence "Recv l pt \<in> set (step # done)" by auto+ thus ?thesis+ using thread_exists recv_eq+ by(fastsimp dest!: this_thread.in_steps_recv[THEN iffD1])+ qed+ hence "?inp_last"+ by (cases "last (step # done)") (fastsimp dest!: Ln_before_inp)++ }+ moreover+ { + fix st st'+ assume "nextRel (step # (filter (\<lambda> x. \<not> (noteStep x)) done)) st st'"+ hence listOrd: "listOrd (step # [x\<leftarrow>done . \<not> noteStep x]) st st'"+ by (auto dest: nextRel_imp_listOrd)+ hence skipped: "st \<notin> skipped \<and> st' \<notin> skipped"+ proof(cases "st = step \<and> st' \<in> set done \<and> \<not> noteStep st'")+ case True+ thus "?thesis" using listOrd not_skipped by (fastsimp dest: this_thread.note_in_skipped)+ next+ case False+ note falseAsms = this+ thus ?thesis using falseAsms listOrd + by (cases "listOrd [x\<leftarrow>done . \<not> noteStep x] st st'") + (auto simp add: dest: this_thread.note_in_skipped in_set_listOrd1 in_set_listOrd2 )+ qed+ hence "st \<notin> skipped" "st' \<notin> skipped" by auto++ hence step_ord: "predOrd t (St (i, st)) (St (i, st'))"+ proof(cases "st = step \<and> st' \<in> set [x\<leftarrow>done . \<not> noteStep x]")+ case True+ hence "st' \<in> set done" by auto+ thus ?thesis using listOrd skipped True+ apply -+ apply(drule conjunct1,+ drule_tac ?P = "st = step" and ?Q = "st' \<in> set done" in conjI,+ assumption)+ apply(drule_tac ?Q = "listOrd done st st'" and ?P = "st = step \<and> st' \<in> set done" in disjI1)+ apply(drule listOrd.simps(2)[THEN iffD2])+ by(fastsimp dest: listOrd_imp_predOrd this_thread.listOrd_done_imp_listOrd_trace)+ next+ case False+ note assms = this+ thus ?thesis+ proof(cases "listOrd [x\<leftarrow>done . \<not> noteStep x] st st'")+ case False+ thus ?thesis using assms listOrd by auto+ next+ case True + thus ?thesis using assms listOrd skipped+ apply -+ apply(drule listOrd_filter)+ apply(drule_tac ?Q = "listOrd done st st'" and ?P = "st = step \<and> st' \<in> set done" in disjI2)+ apply(drule listOrd.simps(2)[THEN iffD2])+ by (fastsimp dest: listOrd_imp_predOrd this_thread.listOrd_done_imp_listOrd_trace)+ qed+ qed+ hence recv: "recvStep st \<Longrightarrow> + \<exists> m. Some m = inst s i (stepPat st) \<and> predOrd t (Ln m) (St (i, st))"+ using this_thread.roleMap+ by (cases st) (auto intro!: Ln_before_inp dest: in_steps_predOrd1)+ note step_ord recv+ }+ ultimately+ show ?thesis by fast+qed++end++text{* + TODO: Find the right place for this lemma. It is used only in+ the "prefix\_close" command.+*}+lemma steps_in_steps: "(i,step) \<in> steps t \<Longrightarrow> (i,step) \<in> steps t"+ by auto+++subsection{* Additional Lemmas on Learning Messages *}+++context reachable_state+begin++(* TODO: Move *)+lemma nothing_before_IK0: "m \<in> IK0 \<Longrightarrow> \<not> y \<prec> Ln m"+proof(induct arbitrary: y rule: reachable_induct)+ case (send t r s i "done" l pt todo m y)+ then interpret this_state: reachable_state P t r s by unfold_locales+ show ?case using send+ by(fastsimp dest: this_state.knows_IK0)+next+ case (decr t r s m k y)+ then interpret this_state: reachable_state P t r s by unfold_locales+ show ?case using decr+ by(fastsimp dest: this_state.knows_IK0)+next + case (lkr t r s a)+ then interpret this_state: reachable_state P t r s by unfold_locales+ show ?case using lkr+ by(fastsimp dest: this_state.knows_IK0)+next + case (compr t r s "done" l ty pt todo skipped m y)+ then interpret this_state: reachable_state P t r s by unfold_locales+ show ?case using compr+ by(fastsimp dest: this_state.knows_IK0)+qed auto++lemmas nothing_before_IK0_iffs [iff] = in_IK0_simps[THEN nothing_before_IK0]++end (* rechable_state *)++subsubsection{* Resoning about Variable Contents *}++context reachable_state+begin++lemma inst_AVar_ineqs [iff]:+ "s (AVar v, i) \<noteq> Tup x y"+ "s (AVar v, i) \<noteq> Enc m k"+ "s (AVar v, i) \<noteq> Hash m"+ "s (AVar v, i) \<noteq> PK a"+ "s (AVar v, i) \<noteq> SK a"+ "s (AVar v, i) \<noteq> K a b"+ "s (AVar v, i) \<noteq> KShr A"+ "s (AVar v, i) \<noteq> Lit (ENonce n i')"+ "s (AVar v, i) \<noteq> Lit (EConst c)"+ "s (AVar v, i) \<noteq> Lit (EveNonce n)"+ by (insert inst_AVar_cases[of v i]) + (auto simp: Agent_def)++declare inst_AVar_cases[iff]+declare inst_AVar_ineqs[symmetric, iff]++end++end
@@ -0,0 +1,354 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+theory Protocol+imports + DistinctList+begin++section{* Protocol Specifications *}++subsection{* Types and Operations *}++subsubsection{* Patterns *}++types id = string++datatype varid = AVar id | MVar id++datatype pattern = + PConst id+ | PFresh id+ | PVar varid+ | PHash pattern+ | PTup pattern pattern + | PEnc pattern pattern + | PSign pattern pattern+ | PSymK pattern pattern + | PShrK "varid set" (* variables denoting a set of agents sharing a key *)+ | PAsymPK pattern + | PAsymSK pattern ++(* bi-directional keys between two agents referenced by variables *)+definition sKbd :: "varid \<Rightarrow> varid \<Rightarrow> pattern"+where "sKbd a b = PShrK {a, b}"++text{* Free variables *}+fun FV :: "pattern \<Rightarrow> varid set"+where + "FV (PVar v) = {v}"+| "FV (PHash m) = FV m"+| "FV (PTup x y) = FV x \<union> FV y"+| "FV (PEnc m k) = FV m \<union> FV k"+| "FV (PSign m k) = FV m \<union> FV k"+| "FV (PSymK a b) = FV a \<union> FV b"+| "FV (PShrK A) = A"+| "FV (PAsymPK a) = FV a"+| "FV (PAsymSK a) = FV a"+| "FV (_) = {}"++lemma FV_sKbd [simp]: "FV (sKbd a b) = {a, b}"+ by (auto simp: sKbd_def)+++text{* Free message variables *}+fun FMV :: "pattern \<Rightarrow> id set"+where + "FMV (PVar (MVar v)) = {v}"+| "FMV (PHash m) = FMV m"+| "FMV (PTup x y) = FMV x \<union> FMV y"+| "FMV (PEnc m k) = FMV m \<union> FMV k"+| "FMV (PSign m k) = FMV m \<union> FMV k"+| "FMV (PSymK a b) = FMV a \<union> FMV b"+| "FMV (PShrK A) = {v. MVar v \<in> A}"+| "FMV (PAsymPK a) = FMV a"+| "FMV (PAsymSK a) = FMV a"+| "FMV (_) = {}"++lemma FMV_sKbd [simp]: + "FMV (sKbd a b) = {v. MVar v = a \<or> MVar v = b}"+ by (auto simp: sKbd_def)+++fun FAV :: "pattern \<Rightarrow> id set"+where+ "FAV (PVar (AVar a)) = {a}"+| "FAV (PHash m) = FAV m"+| "FAV (PTup x y) = FAV x \<union> FAV y"+| "FAV (PEnc m k) = FAV m \<union> FAV k"+| "FAV (PSign m k) = FAV m \<union> FAV k"+| "FAV (PSymK a b) = FAV a \<union> FAV b"+| "FAV (PShrK A) = {v. AVar v \<in> A}"+| "FAV (PAsymPK a) = FAV a"+| "FAV (PAsymSK a) = FAV a"+| "FAV (_) = {}"++lemma FAV_sKbd [simp]: + "FAV (sKbd a b) = {v. AVar v = a \<or> AVar v = b}"+ by (auto simp: sKbd_def)+++subsubsection{* Roles *}++text{*+ Roles are non-empty lists of unique send and receive steps + such that no long-term keys are used in message texts and all + nonce variables are received before they are sent.++ The labels allow to make steps with identical message unique.+ They are currently defaulted to strings, but could be anything.+*}++types lbl = string++datatype notetype = RandGen | State | SessKey++datatype rolestep = Send lbl pattern | Recv lbl pattern | Note lbl notetype pattern++fun stepPat :: "rolestep \<Rightarrow> pattern"+where+ "stepPat (Send lbl msg) = msg"+| "stepPat (Recv lbl msg) = msg"+| "stepPat (Note lbl ty msg) = msg"++fun noteType :: "rolestep \<Rightarrow> notetype"+where+ "noteType (Note l ty pt) = ty"++fun sendStep :: "rolestep \<Rightarrow> bool"+where+ "sendStep (Send lbl msg) = True"+| "sendStep (Recv lbl msg) = False"+| "sendStep (Note lbl ty msg) = False"++fun noteStep :: "rolestep \<Rightarrow> bool"+where+ "noteStep (Send lbl msg) = False"+| "noteStep (Recv lbl msg) = False"+| "noteStep (Note lbl ty msg) = True"+++abbreviation recvStep where "recvStep x \<equiv> \<not>sendStep x \<and> \<not> noteStep x"++lemma sendStepD [simp]:+ assumes inStep: "sendStep step"+ shows "\<exists> l pt. step = (Send l pt)"+using inStep+proof(cases step)+qed auto++lemma recvStepD [simp]:+ assumes inStep: "recvStep step"+ shows "\<exists> l pt. step = (Recv l pt)"+using inStep+proof(cases step)+qed auto++lemma noteStepD [simp]:+ assumes inStep: "noteStep step"+ shows "\<exists> l ty pt. step = (Note l ty pt)"+using inStep+proof(cases step)+qed auto+++types "role" = "rolestep list"++fun recv_before :: "id set \<Rightarrow> role \<Rightarrow> bool"+where+ "recv_before bound [] = True"+| "recv_before bound (Recv _ msg # xs) = + recv_before (bound \<union> FMV msg) xs"+| "recv_before bound (Note _ _ msg # xs) =+ ((\<forall> v. v \<in> FMV msg \<longrightarrow> v \<in> bound) \<and> recv_before bound xs)"+| "recv_before bound (Send _ msg # xs) =+ ((\<forall> v. v \<in> FMV msg \<longrightarrow> v \<in> bound) \<and> recv_before bound xs)"+++locale wf_role =+ distinct_list R for R :: "role" ++ assumes recv_msgVar_first [iff]: "recv_before {} R"++ +subsubsection{* Protocols *}++types proto = "role set"++locale wf_proto =+ fixes P :: proto+ assumes wf_roles: "R \<in> P \<Longrightarrow> wf_role R"+++subsection{* Properties *}++subsubsection{* Well-Formed Roles *}++lemma recv_before_sent_distinct_Send_FV:+ "\<lbrakk> recv_before V (R@ Send lbl pt # R'); + distinct (R @ Send lbl pt # R');+ v \<in> FMV pt; v \<notin> V + \<rbrakk> \<Longrightarrow>+ \<exists> lbl' pt'. Recv lbl' pt' \<in> set R \<and> v \<in> FMV pt'"+proof(induct R arbitrary: V)+ case (Cons step R) note IH = this show ?case+ proof(cases step)+ case (Send lbl pt) thus ?thesis using IH by auto+ next+ case (Recv lbl pt) thus ?thesis using IH by (auto, fast)+ next+ case (Note lbl ty pt) thus ?thesis using IH by auto+ qed+qed simp++lemma recv_before_note_distinct_Note_FV:+ "\<lbrakk> recv_before V (R@ Note lbl ty pt # R'); + distinct (R @ Note lbl ty pt # R');+ v \<in> FMV pt; v \<notin> V + \<rbrakk> \<Longrightarrow>+ \<exists> lbl' pt'. Recv lbl' pt' \<in> set R \<and> v \<in> FMV pt'"+proof(induct R arbitrary: V)+ case (Cons Note R) + note IH = this show ?case+ proof(cases Note)+ case (Send lbl pt) thus ?thesis using IH by auto+ next+ case (Recv lbl pt) thus ?thesis using IH by (auto, fast)+ next+ case (Note lbl ty pt) thus ?thesis using IH by auto+ qed+qed simp+++lemma (in wf_role) Send_FV:+ assumes Send: "Send lbl pt \<in> set R" (is "?send \<in> set R")+ and FV: "v \<in> FMV pt"+ shows "\<exists> lbl' pt'. listOrd R (Recv lbl' pt') (Send lbl pt) \<and> v \<in> FMV pt'" +using Send +proof -+ let ?send = "Send lbl pt"+ and "\<exists> lbl' pt'. ?received lbl' pt'" = ?thesis+ assume "?send \<in> set R" then+ obtain ys zs + where split: "R = ys @ ?send # zs" by (blast dest!: split_list)+ moreover have "distinct R" and "recv_before {} R" by auto+ ultimately obtain lbl' pt' where "Recv lbl' pt' \<in> set ys" + and "v \<in> FMV pt'"+ by (fastsimp dest!: recv_before_sent_distinct_Send_FV intro!: FV)+ hence "?received lbl' pt'" using split by auto+ thus ?thesis by blast+qed+++lemma (in wf_role) Note_FV:+ assumes Note: "Note lbl ty pt \<in> set R" (is "?note \<in> set R")+ and FV: "v \<in> FMV pt"+ shows "\<exists> lbl' pt'. listOrd R (Recv lbl' pt') (Note lbl ty pt) \<and> v \<in> FMV pt'" +using Note+proof -+ let ?send = "Note lbl ty pt"+ and "\<exists> lbl' pt'. ?received lbl' pt'" = ?thesis+ assume "?note \<in> set R" then+ obtain ys zs + where split: "R = ys @ ?note # zs" by (blast dest!: split_list)+ moreover have "distinct R" and "recv_before {} R" by auto+ ultimately obtain lbl' pt' where "Recv lbl' pt' \<in> set ys" + and "v \<in> FMV pt'"+ by (fastsimp dest!: recv_before_note_distinct_Note_FV intro!: FV)+ hence "?received lbl' pt'" using split by auto+ thus ?thesis by blast+qed++lemma FV_FAV_conv[iff]:+ "(a \<in> FAV pt) = ((AVar a) \<in> FV pt)"+proof(induct pt)+ case (PVar vid)+ thus ?case+ by(cases vid) auto+qed auto++lemma FV_FMV_conv[iff]:+ "(v \<in> FMV pt) = ((MVar v) \<in> FV pt)"+proof(induct pt)+ case (PVar vid)+ thus ?case+ by(cases vid) auto+qed auto++++definition aVars:: "role \<Rightarrow> varid set"+where+ "aVars role = foldr (\<lambda> st se. (AVar ` FAV (stepPat st)) \<union> se) role {}"++lemma aVars_singleton[iff]:+ "AVar a \<notin> aVars []"+by(fastsimp simp add: aVars_def)++lemma aVars_Nil [iff]: "aVars [] = {}"+ by (auto simp: aVars_def)++lemma aVars_Cons [simp]: "aVars (s#xs) = (AVar ` FAV (stepPat s) \<union> aVars xs)"+ by (auto simp: aVars_def)++lemma aVars_FAV_conv:+ "(AVar a \<in> aVars R) = (\<exists> s \<in> set R. \<exists> pt. (stepPat s = pt \<and> a \<in> FAV pt))"+by (induct R rule: foldr.induct) ( fastsimp simp add: aVars_def)++++definition lastComStep :: "role \<rightharpoonup> rolestep"+where+ "lastComStep rs = (case (filter (\<lambda> s. \<not> (noteStep s)) rs) of + (x#xs) \<Rightarrow> Some (last (x#xs))+ |([]) \<Rightarrow> None)"++definition firstComStep :: "role \<rightharpoonup> rolestep"+where+ "firstComStep rs = (case (filter (\<lambda> s. \<not> (noteStep s)) rs) of + (x#xs) \<Rightarrow> Some x+ |([]) \<Rightarrow> None)"+++lemma lastComStep_Nil [iff]: "lastComStep [] = None"+ by (auto simp: lastComStep_def)++lemma lastComStep_Cons [simp]: + "lastComStep (x#xs) =+ (let + s = lastComStep xs+ in+ if (noteStep x) then+ s+ else+ if (s = None) then+ Some x+ else+ s+ )"+proof (cases "[s\<leftarrow>xs . \<not> noteStep s]")+qed (fastsimp simp add: lastComStep_def)+++lemma firstComStep_Nil [iff]: "firstComStep [] = None"+ by (auto simp: firstComStep_def)++lemma firstComStep_Cons [simp]: "firstComStep (x#xs) =+ ( if (noteStep x) then+ firstComStep xs+ else+ Some x+ )"+proof (cases "[s\<leftarrow>xs . \<not> noteStep s]")+qed (fastsimp simp add: firstComStep_def)+ +++++end
@@ -0,0 +1,80 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+(* 6th Generation: Adapt Syntax to make it more readable, also in ASCII notation ++ Adapted to paper.+*)+theory Syntax+imports+ ExplicitModel+begin++section{* User Level Syntax *}++text{*+ The syntax adaption is currently done in a separate file and AFTER all developments of+ the logic, because it is not fixed yet.+*}+++subsubsection{* General Cryptographic Messages *}++notation (xsymbols) ExecMessage.inv ("[_]\<^isup>-\<^isup>1" [60] 58)+++subsubsection{* Specification Messages *}++abbreviation "sC" where "sC x \<equiv> PConst x"+abbreviation "sN" where "sN x \<equiv> PFresh x"+abbreviation "sMV" where "sMV x \<equiv> PVar (MVar x)"+abbreviation "sAV" where "sAV x \<equiv> PVar (AVar x)"++text{* + Note the following abbreviations are kept for + backwards compatibility. They are deprecated for + new developments.+*}+abbreviation "sLC" where "sLC x \<equiv> PConst x"+abbreviation "sLN" where "sLN x \<equiv> PFresh x"+abbreviation "sLMV" where "sLMV x \<equiv> PVar (MVar x)"+abbreviation "sLAV" where "sLAV x \<equiv> PVar (AVar x)"++abbreviation "sPK" where "sPK x \<equiv> PAsymPK (sAV x)"+abbreviation "sSK" where "sSK x \<equiv> PAsymSK (sAV x)"+abbreviation "sK" where "sK x y \<equiv> PSymK (sAV x) (sAV y)"+abbreviation "sShrK" where "sShrK A \<equiv> PShrK A"++syntax+ "@PTuple" :: "['a, args] => 'a * 'b" ("(2<|_,/ _|>)")++syntax (xsymbols)+ "@PTuple" :: "['a, args] => 'a * 'b" ("(2\<langle>_,/ _\<rangle>)")++translations+ "<|x, y, z|>" == "<|x, <|y, z|> |>"+ "<|x, y|>" == "PTup x y"+++subsubsection{* Execution Messages *}++abbreviation "C" where "C \<equiv> EConst"+abbreviation "N" where "N \<equiv> ENonce"+abbreviation "MV" where "MV x i \<equiv> (MVar x, i)"+abbreviation "AV" where "AV x i \<equiv> (AVar x, i)"++abbreviation "LC" where "LC x \<equiv> Lit (C x)"+abbreviation "LN" where "LN x i \<equiv> Lit (N x i)"++abbreviation "LAg" where "LAg x \<equiv> Lit (EAgent x)"++end
@@ -0,0 +1,652 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+theory Unify+imports + HOL_ext+ InferenceRules+ WeakTyping+ (* referenced because we use espl_definitions.ML and+ espl_methods.ML. With a uses clause it would be+ loaded twice, which may result in strange effects.+ *)+ Automation +begin++section{* Explicit unification of sets of equality theorems *}++text{* Specialized to the use cases of our ESPL *}++text{* Additional required lemmas *}+lemma eq_imp_size_eq: "x = y \<Longrightarrow> size x = size y"+ by (rule arg_cong)++ML{*++(*+ Strategy: Per theorem++ 1. check that it is an unconditional equality+ 2. rewrite using current simpset+ 3. if false then stop and return theorem false+ otherwise split conjunctions and add to + current simpset++ NOTE: We have to maintain the invariant that the simpset+ is non-looping. Hence, we may have to rebuild it several + times. Probably whenever a thread identifier equality + occurs.+*)+++(* Utilities + ************)++(* apply a function 'f' to a list and return the partition of+ all elements left unchanged by 'f' w.r.t. the given order+ and the changed elements.+*)+fun partition_changed ord f xs =+ let+ fun go unchanged changed [] = (rev unchanged, rev changed)+ | go unchanged changed (y::ys) = + let + val y' = f y+ in + case ord (y, y') of+ EQUAL => go (y::unchanged) changed ys+ | _ => go unchanged (y'::changed) ys+ end+ in + go [] [] xs + end++(* Remove an outer Trueprop if there is any *)+fun remove_Trueprop t = + the_default t (try HOLogic.dest_Trueprop t)++(* Destruct a symbolic representation of the contents+ of a protocol variable. +*)+fun dest_MVar_store_lookup t = + case ESPL_Definitions.dest_variable_store_lookup t of+ (s, (@{const MVar} $ v, tid)) => (s, (v, tid))+ | _ => raise TERM ("dest_MVar_store_lookup: no MVar",[t])++val is_variable_store_lookup = can ESPL_Definitions.dest_variable_store_lookup+val is_MVar_store_lookup = can dest_MVar_store_lookup +++(* Check if a term is a roleMap application *)+fun is_roleMap (@{const roleMap} $ _ $ _) = true+ | is_roleMap _ = false++(* Check if a term is a key inversion *)+fun is_key_inversion (@{term "ExecMessage.inv :: execmsg \<Rightarrow> execmsg"} $ _) = true+ | is_key_inversion _ = false+++(* If the given theorem is a HOL equality it gets reoriented+ such that the lhs is guaranteed to be smaller than the + right-hand side with respect to the given order. Note that+ reflexive equalities are dropped!+*)+fun reorient_HOL_eq ord th =+ (case th |> Thm.concl_of + |> HOLogic.dest_Trueprop+ |> HOLogic.dest_eq+ |> ord+ of+ GREATER => SOME (th RS @{thm sym})+ | LESS => SOME th+ | EQUAL => NONE+ ) handle + TERM _ => SOME th + | THM (name,k,info) => + raise THM ("reorient_HOL_eq:" ^ name, k,info)++*}++ML{*++(* The term order we use for orienting the unification equalities:+ 1. s x is smaller than any other non-store term+ 2. roleMap x y is smaller than any other non-roleMap term+ 2. otherwise the standard term order is used.++ TODO: This could possibly be implemented using the+ lexicographic path ordering.++ Moreover, think about situations involving 'inv'.+ (We probably don't want to have 'inv' on the lhs.)+*)+fun unify_term_ord (lhs,rhs) =+ let fun proj t = (not (is_variable_store_lookup t)+ , (not (is_MVar_store_lookup t)+ , (not (is_roleMap t), t)+ ) )++ in (prod_ord bool_ord + (prod_ord bool_ord + (prod_ord bool_ord TermOrd.term_ord)))+ (proj lhs, proj rhs) + end++fun old_unify_term_ord (arg as (lhs,rhs)) = + if (is_variable_store_lookup lhs) then + if (is_variable_store_lookup rhs) then+ TermOrd.term_ord arg+ else+ LESS+ else+ if (is_variable_store_lookup rhs) then+ GREATER+ else+ if (is_roleMap lhs) then+ if (is_roleMap rhs) then+ TermOrd.term_ord arg+ else+ LESS+ else+ if (is_roleMap rhs) then+ GREATER+ else+ TermOrd.term_ord arg;+ +*}++(*+context reachable_state begin++ML{*++fun both t = (unify_term_ord t, old_unify_term_ord t);++both (@{term "s (MV a b)"}, @{term "LN x i"});+both (@{term "s (MV a b)"}, @{term "s (MV c d)"});+both (swap (@{term "s (MV a b)"}, @{term "s (AV c d)"}));+both (@{term "roleMap r i"}, @{term "Some R"});+both (swap (@{term "roleMap r i"}, @{term "Some R"}));+ ++*}+*)++ML{*++structure UnifyDest = Named_Thms+ (val name ="unify_dest"+ val description = "Destruction rules to be used in note_unified")++*}++setup{* UnifyDest.setup *}++declare (in reachable_state) split_before[unify_dest]+declare (in reachable_state) split_knows[unify_dest]++ML{*++(* Tries to derive 'False' from equality of sizes of equated terms.+*)+fun inequal_sizes ss eq_th =+ let+ val opt_size_eq = + SOME (simplify ss (eq_th RS @{thm eq_imp_size_eq}))+ handle THM _ => NONE+ in+ case opt_size_eq of+ SOME size_eq =>+ (case size_eq |> Thm.concl_of |> remove_Trueprop of+ @{term False} => SOME size_eq+ | _ => NONE)+ | NONE => NONE+ end++(* Unify the equalities in the given list of theorems + using rewriting with the simpset of the given context. +*)+fun unify do_occurs_check ctxt ths =+ let+ (* TODO: Remove hack by using Named_Thms data functor. *)+ val thm_by_name = ProofContext.get_thm ctxt;+ val ss = simpset_of ctxt + delsimps map thm_by_name ["tid_eq_commute", "reorient_store_eq_store"];++ (* substitute an equality theorem in the given list of 'done' and + 'todo' theorems. The changed theorems from 'done' are readded+ to the output 'todo' list (the second component of the result).+ *)+ fun subst_eq (done, todo) eq_th =+ let+ val apply = simplify (ss addsimps [eq_th]);+ val (doneUc, doneC) = partition_changed Thm.thm_ord apply done;+ in+ (eq_th::doneUc, doneC @ map apply todo)+ end;++ (* occurence check: tries to prove 'False' from size equality *)+ fun occurs_check eq_th =+ if do_occurs_check then+ inequal_sizes ss eq_th+ else+ NONE++ (* solve a single unification equation *)+ fun solve1 (done, [] ) = done+ | solve1 (done, th::todo) = + if (member Thm.eq_thm done th) then+ solve1 (done, todo)+ else if not (Thm.no_prems th) then+ solve1 (th::done, todo)+ else+ (case remove_Trueprop (Thm.concl_of th) of+ (@{const True}) => solve1 (done, todo)+ | (@{const False}) => [th]+ | (@{const "op &"} $ _ $ _) =>+ solve1 ( done + , (th RS @{thm conjunct1}) ::+ (th RS @{thm conjunct2}) :: todo+ )+ | (Const (@{const_name "op ="},_) $ _ $ _) => + (case reorient_HOL_eq unify_term_ord th of+ NONE => solve1 (done, todo)+ | SOME th' =>+ (case occurs_check th' of+ SOME th_false => [th_false]+ | NONE => solve1 (subst_eq (done,todo) th')+ )+ )+ | _ => (case map_filter (try (curry (op RS) th)) (UnifyDest.get ctxt) of+ [] => solve1 (th::done, todo)+ | ths => solve1 (done, ths @ todo)+ )+ ) + in+ solve1 ([], map (simplify ss) ths)+ end++*}++++ML{*++(* Note a set of theorems modified by a function ++ 'f:: Proof.Context -> thm list -> thm list'.++ This should be supported by attributes. However,+ currently we resort to the following hack. ++ We do a normal note_theoerms and the retrieve+ the bound theorems, modify them, and store them+ again WITHOUT any attributes being applied.++ This is fragile. However, I couldn't see a better+ way with the current framework.+*)+fun note_modified_thmss f args =+ let+ (* copied from Pure/Isar/proof.ML *)+ fun map_context_result f state =+ f (Proof.context_of state) + ||> (fn ctxt => Proof.map_context (K ctxt) state);++ val bindings = map (fst o fst) args;++ fun modify_bound_thms ctxt b =+ let+ val ths = ProofContext.get_thms ctxt (ProofContext.full_name ctxt b);+ in+ ((b,[]), [(f ctxt ths,[])])+ end;++ fun modify_and_renote state =+ state+ |> map_context_result + (fn ctxt => ctxt |>+ (ProofContext.note_thmss "" + (map (modify_bound_thms ctxt) bindings))+ )+ |> (fn (named_thss, state') =>+ state'+ |> Proof.put_facts (SOME (maps snd named_thss))+ )+ in+ modify_and_renote o Proof.note_thmss args+ end++*}++ML{*+local+ structure K = OuterKeyword;+ structure T = Toplevel;++ fun define_cmd name info f =+ OuterSyntax.command name info (K.tag_proof K.prf_decl)+ (SpecParse.name_facts >> (T.print oo (T.proof o (note_modified_thmss f))));+in+ val _ = + define_cmd "note_prefix_closed" + "prefix close facts and store them under the given name"+ ESPL_Methods.prefix_close_thms;++ val _ = + define_cmd "note_unified" + "unify equality facts and store them under the given name"+ (unify true);++ (* TODO: Implement this command - currently it is just notes. *)+ val _ = + define_cmd "note_cyclic" + "try to derive a cyclicity violation from the given facts and store them under the given name"+ (K I);++end+*}+++(*++lemma (in reachable_state) test : "X"+proof -+ fix tid\<^isub>1 tid\<^isub>2 tid\<^isub>3+ assume "s (MV ''ni'' tid\<^isub>1) = LN ''ni'' tid\<^isub>3"+ and"s (MV ''ni'' tid\<^isub>1) = LN ''ni'' tid\<^isub>2"+ML_prf{*+ unify true @{context} @{thms this}+ handle THM (_,_,ths) => ths++*}+ note_unified facts = this++lemma++*)++(*++ML{* @{const predOrd} *}+ML{* @{term "predOrd t (Ln \<lbrace>LN ''ni'' i, x\<rbrace>) (Ln y)"} *}+ML{*++case @{term "predOrd t (Ln \<lbrace>LN ''ni'' i, x\<rbrace>) (Ln y)"} of+ (@{const predOrd} $ _ $ (@{const Ln} $ (Const (@{const_name Tup},_) $ _ $ _)) $ _) =>+ Const ("YES 1", TFree ("blah",["blih"]))+ | (Const (@{const_name predOrd}, _) $ _ $ _ $ _ ) =>+ Const ("YES 2", TFree ("blah",["blih"]))+ | (x $ _ $ _ $ _ ) =>+ x+ | _ => Const ("no", TFree ("blah",["blih"]))++*}++lemma test: + assumes facts:+ "Enc x y = Enc t v"+ "x = v"+ shows "False"+proof -+ note_unified this = facts+ thm this+oops+++text{* Testing the role definition command *}+role nslXInit+where "nslXInit \<equiv> + [ Send ''0'' (PEnc \<langle>sC ''0'', sAV ''I'', sN ''ni''\<rangle> (sPK ''R''))+ , Recv ''1'' (PEnc \<langle>sC ''1'', sAV ''R'', sN ''ni'', sMV ''nr''\<rangle> (sPK ''I''))+ , Send ''2'' (PEnc \<langle>sC ''2'', sMV ''nr''\<rangle> (sPK ''R''))+ ]"++text{* An additional role for testing purposes. *}+role nslXResp+where "nslXResp \<equiv>+ [ Recv ''0'' (PEnc \<langle>sC ''0'', sLAV ''I'', sLMV ''ni''\<rangle> (sPK ''R''))+ , Send ''1'' (PEnc \<langle>sC ''1'', sLAV ''R'', sLMV ''ni'', sLN ''nr''\<rangle> (sPK ''I''))+ , Recv ''2'' (PEnc \<langle>sC ''2'', sLN ''nr''\<rangle> (sPK ''R''))+ ]"++protocol nslX+where "nslX = {nslXInit, nslXResp}"++locale atomic_nslX_state = typed_state nslX _ _ _ "weakly_atomic"++lemma (in atomic_nslX_state) SK_from_IK0:+ assumes facts:+ "SK a \<in> knows t"+ shows "a \<in> Compromised"+using facts+proof(sources "SK a")+qed clarsimp++lemma (in atomic_nslX_state) I_sec_ni:+ assumes facts:+ "roleMap r i = Some nslXInit"+ "Ln (Tup (LN ''ni'' i) x) \<prec> Ln y"+ "s(AV ''I'' i) \<notin> Compromised"+ "s(AV ''R'' i) \<notin> Compromised" + shows "False"+using facts+proof(sources! "LN ''ni'' i")+ case nslXInit_0_ni+ note_unified facts = facts this+thm split_before[OF `Ln \<lbrace>LN ''ni'' i, x\<rbrace> \<prec> Ln y`]+ML_prf{*+@{term "Ln \<lbrace>LN ''ni'' i, x\<rbrace> \<prec> Ln y"}+*}+ thus ?thesis+ proof(sources! "SK (s (AV ''R'' i))")+ case ik0+ note_unified facts = facts this+ thus ?thesis by clarsimp+ qed+next+ case (nslXInit_2_nr i1)+ note_unified facts = facts this+ thus ?thesis+ proof(sources! "inst s i1 nslXInit_1_pt")+ case fake+ note_unified facts = facts this+ thus ?thesis by order+ next+ case (nslXResp_1_enc r1)+ note_unified facts = facts this+ thus ?thesis .+ qed+next+ case (nslXResp_1_ni r1)+ note_unified facts = facts this+ thus ?thesis+ proof(sources "inst s r1 nslXResp_0_pt")+ case fake+ note_unified facts = facts this+ thus ?thesis by order+ next+ case (nslXInit_0_enc i2)+ note_unified facts = facts this+ thus ?thesis+ proof(sources! "SK (s (AV ''I'' i))")+ case ik0+ note_unified facts = facts this+ thus ?thesis by clarsimp+ qed+ qed+qed++++++(* OLD TEST INFRASTRUCTURE+++ML{*++val th1 = Thm.assume @{cterm "Trueprop (s (AV ''a'' i) = x)"};+val th2 = Thm.assume @{cterm "Trueprop (PK (s (AV ''a'' i)) = inv (y))"};+val th3 = Thm.assume @{cterm "Trueprop (Enc (LN ''a'' i) (PK (s (AV ''a'' j))) = + Enc (LN ''a'' j) (PK (s (AV ''b'' i))))"};+val th4 = Thm.assume @{cterm "Trueprop ((b::nat) < c)"};+val th5 = Thm.assume @{cterm "Trueprop ((x::execmsg) = Enc (Tup y (PK x)) z)"};+++*}+++ML{*++unify true @{context} [th1,th2,th3,th5,th1,th2,th3,th5,th1,th2,th3,th5,th1,th2,th3,th5]++*}++subsection{* Redefining the notes command *}++text{*+ note[prefix_closed] this = facts+ note[unified] this = facts++^ preferred version++ note this[unified] = facts++*}++ML{*++Proof.note_thmss+*}++ML{* ++ProofContext.note_thmss+*}++note_prefix_closed+note_unified+note_cyclic++ML{*++local + structure P = OuterParse;+ structure S = SpecParse;++ fun bling ctxt =+ let val _ = Output.warning "test";+ in ctxt end;++ fun modifier (name, f) = P.$$$ name >> K f;+ val modifiers = [("test", (K bling)),("unified",unify true)];+in+ val thms_mod = Scan.first (map modifier modifiers @ [Scan.succeed (K I)]);+ val mod_name_facts = thms_mod -- S.name_facts+end+*}+ +++lemma test: "blah"+proof -+ note_prefix_closed unified = sym allI+ and blah = ballI+ thm this+ thm blah+ thm unified+ ++++++*)++role C+where "C =+ [ Send ''1'' ( PEnc ( sN ''k'' ) ( sPK ''S'' ) )+ , Recv ''2'' ( PHash ( sN ''k'' ) ) + ]" ++role S+where "S =+ [ Recv ''1'' ( PEnc ( sMV ''k'' ) ( sPK ''S'' ) )+ , Send ''2'' ( PHash ( sMV ''k'' ) ) + ]" ++protocol CR+where "CR = { C, S }"++locale atomic_CR_state = atomic_state CR+locale CR_state = reachable_state CR++lemma (in atomic_CR_state) C_secret_k:+ assumes facts:+ "roleMap r i\<^isub>0 = Some C"+ "s(AV ''S'' i\<^isub>0) \<notin> Compromised"+ "LN ''k'' i\<^isub>0 \<in> knows t"+ shows "False"+using facts proof(sources! " LN ''k'' i\<^isub>0 ")+ case C_1_k note_unified facts = this facts+ thus ?thesis proof(sources! " SK ( s(AV ''S'' i\<^isub>0) ) ")+ qed (insert facts, ((clarsimp, order?))+)?+qed++lemma (in CR_state) weak_atomicity:+ "complete (t,r,s) atomicAnn"+proof (cases rule: complete_atomicAnnI[completeness_cases_rule])+ case (S_1_k t r s i\<^isub>0) note facts = this+ then interpret state: atomic_state CR t r s+ by unfold_locales assumption++ show ?case using facts+ proof(sources! "+ Enc ( s(MV ''k'' i\<^isub>0) ) ( PK ( s(AV ''S'' i\<^isub>0) ) ) ")+ qed (insert facts, ((fastsimp simp: atomicAnn_def dest: state.extract_knows_hyps))+)?+qed++lemma (in atomic_CR_state) C_ni_synch:+ assumes facts:+ "roleMap r i\<^isub>1 = Some C"+ "s(AV ''S'' i\<^isub>1) \<notin> Compromised"+ "(i\<^isub>1, C_2) \<in> steps t"+ shows+ "\<exists>i\<^isub>2.+ roleMap r i\<^isub>2 = Some S &+ s(AV ''S'' i\<^isub>2) = s(AV ''S'' i\<^isub>1) &+ s(MV ''k'' i\<^isub>2) = LN ''k'' i\<^isub>1 &+ St(i\<^isub>1, C_1) \<prec> St(i\<^isub>1, C_2) &+ St(i\<^isub>1, C_1) \<prec> St(i\<^isub>2, S_1) &+ St(i\<^isub>2, S_2) \<prec> St(i\<^isub>1, C_2) &+ St(i\<^isub>2, S_1) \<prec> St(i\<^isub>2, S_2)"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources! " Hash ( LN ''k'' i\<^isub>1 ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: C_secret_k intro: event_predOrdI)+ next+ case (S_2_hash i\<^isub>2) note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc ( LN ''k'' i\<^isub>1 ) ( PK ( s(AV ''S'' i\<^isub>2) ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis by (fastsimp dest: C_secret_k intro: event_predOrdI)+ next+ case C_1_enc note_unified facts = this facts+ thus ?thesis by force+ qed+ qed+qed++*)++end
@@ -0,0 +1,1150 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+theory WeakTyping+imports+ InferenceRules+ Syntax+begin++section{* A Shallow Embedding of a Message Type System *}++subsection{* Introduction *}++text{*+ The goal of this theory is to develop a simple way for specifying+ type invariants for the message variables of a protocol. A message+ type is a set of messages that depends on the thread and the + system state that this message type is interpreted relative to.+ + A typing is then a function assigning to each combination of a+ role and an identifier of a message variable in this role a + message type. ++ Each typing approximates the set of states where all instantiated+ message variables are instantiated with a message corresponding + to their type.+*}++types msgtype = "tid \<Rightarrow> state \<Rightarrow> execmsg set"++types typing = "(role \<times> id) \<Rightarrow> msgtype"++definition approx :: "typing \<Rightarrow> state set"+where "approx typing q \<equiv> case q of (t,r,s) \<Rightarrow>+ \<forall> (i,step) \<in> steps t. + \<forall> R. roleMap r i = Some R \<longrightarrow>+ (\<forall> n. MVar n \<in> FV (stepPat step) \<longrightarrow>+ s (MVar n, i) \<in> typing (R, n) i (t,r,s)+ )"++locale typed_state = reachable_state++ fixes typing :: "typing"+ assumes approximates: "(t,r,s) \<in> approx typing"++locale typed_thread = reachable_thread++ fixes typing :: "typing"+ assumes approximates: "(t,r,s) \<in> approx typing"++sublocale typed_thread \<subseteq> typed_state+ using approximates by unfold_locales+++lemma approx_unfold:+ "((t,r,s) \<in> approx typing) = + (\<forall> (i,step) \<in> steps t. + \<forall> R. roleMap r i = Some R \<longrightarrow>+ (\<forall> n. MVar n \<in> FV (stepPat step) \<longrightarrow>+ s (MVar n, i) \<in> typing (R, n) i (t,r,s)))"+by (auto simp: approx_def mem_def)++lemma in_approxI:+ assumes all_vars:+ "\<And> i step R n.+ \<lbrakk> (i,step) \<in> steps t;+ roleMap r i = Some R;+ MVar n \<in> FV (stepPat step)+ \<rbrakk>+ \<Longrightarrow> s (MV n i) \<in> typing (R, n) i (t,r,s)"+ shows "(t,r,s) \<in> approx typing"+by (auto simp: approx_unfold dest!: all_vars)++lemma in_approxD:+ assumes approx: "(t,r,s) \<in> approx typing"+ and asms: "(i,step) \<in> steps t"+ "roleMap r i = Some R"+ "MVar n \<in> FV (stepPat step)"+ shows "s (MV n i) \<in> typing (R, n) i (t,r,s)"+using approx asms+by (auto simp: approx_unfold)+++subsection{* A Combinator Language for Message Types *}++subsubsection{* Structural Types *}++text{*+ Structural message types specify the structure of a message.+ Their interpretation is independent of the thread that they+ are interpreted in. All of them except the type for nonces of+ a specific role are also independent of the state that they+ are interpreted in.+*}++definition ConstT :: "id \<Rightarrow> msgtype"+where "ConstT c i q \<equiv> { LC c }"++definition AgentT :: msgtype+where "AgentT i q \<equiv> Agent"++definition NonceT :: "role \<Rightarrow> id \<Rightarrow> msgtype"+where "NonceT R n i q \<equiv> case q of + (t,r,s) \<Rightarrow> { LN n i' | i'. roleMap r i' = Some R }"++definition SomeNonceT :: "msgtype"+where "SomeNonceT q i = {Lit (ENonce n' i') | n' i'. True}"++definition HashT :: "msgtype \<Rightarrow> msgtype"+where "HashT ty i q \<equiv> { Hash m | m. m \<in> ty i q }"++definition TupT :: "msgtype \<Rightarrow> msgtype \<Rightarrow> msgtype"+where "TupT ty1 ty2 i q \<equiv> + { \<lbrace>x, y\<rbrace> | x y. x \<in> ty1 i q \<and> y \<in> ty2 i q }"++definition EncT :: "msgtype \<Rightarrow> msgtype \<Rightarrow> msgtype"+where "EncT tym tyk i q \<equiv> + { Enc m k | m k. m \<in> tym i q \<and> k \<in> tyk i q }"++definition PKT :: "msgtype \<Rightarrow> msgtype"+where "PKT ty i q \<equiv> { PK m | m. m \<in> ty i q }"++definition SKT :: "msgtype \<Rightarrow> msgtype"+where "SKT ty i q \<equiv> { SK m | m. m \<in> ty i q }"++definition KT :: "msgtype \<Rightarrow> msgtype \<Rightarrow> msgtype"+where "KT ty1 ty2 i q \<equiv> + { K m1 m2 | m1 m2. m1 \<in> ty1 i q \<and> m2 \<in> ty2 i q }"++definition KShrT :: "msgtype"+where "KShrT i q \<equiv> { KShr A | A. True }" +++text{* TODO: Make this syntax abbreviation work. *}+syntax+ "@TTuple" :: "['a, args] => 'a * 'b" ("(2{$_,/ _$})")++syntax (xsymbols)+ "@TTuple" :: "['a, args] => 'a * 'b" ("(2\<lbrace>$_,/ _$\<rbrace>)")++translations+ "{$x, y, z$}" == "{$x, {$y, z$}$}" + "{$x, y$}" == "WeakTyping.TupT x y"+++subsubsection{* Special Types *}++text{* + The empty type denotes that a variable is never instantiated.+ The sum type denotes the union of two message types, while+ the intersection type denotes the intersection of the two + message types.+*}++definition EmptyT :: "msgtype"+where "EmptyT i q \<equiv> {}"++definition SumT :: "msgtype \<Rightarrow> msgtype \<Rightarrow> msgtype"+where "SumT ty1 ty2 i q \<equiv> ty1 i q \<union> ty2 i q"++definition InterT :: "msgtype \<Rightarrow> msgtype \<Rightarrow> msgtype"+where "InterT ty1 ty2 i q \<equiv> ty1 i q \<inter> ty2 i q"+++text{*+ The known before a specific role step type captures the+ interaction of the intruder with the execution of a protocol.+ If the intruder fakes a message being received, then the+ variables are instantiated with messages known to the intruder+ \emph{before} the receive step was executed.+*}++definition KnownT :: "rolestep \<Rightarrow> msgtype"+where "KnownT step i q \<equiv> case q of (t,r,s) \<Rightarrow> + { m | m. predOrd t (Ln m) (St (i,step)) }"++text{*+ The idea behind the secrecy type is that this denotes a variable+ whose content is guaranteed to be secret, if a given set of+ agent variables are instantiated with uncompromised agents. However,+ in our current execution model this does not work, as the intruder is+ not required to learn the contents of an encryption he has the keys+ for. Hence, we won't be able to prove that a message variable is + either known to the intruder or secret.++ TODO: Investigate how a complete forcing could be+ formalized will retaining the event order and the + decrytption-chain reasoning techniqe.+*}+++subsubsection{* Constructing Type Invariants *}++text{*+ The following function converts a list of type assignments to a+ typing. It will be used to specify the type invariants of specific+ protocols.+*}++definition mk_typing :: "((role \<times> id) \<times> msgtype) list \<Rightarrow> typing"+where "mk_typing tyeqs \<equiv> + foldr (\<lambda>(x, ty) typing. typing(x:=ty)) tyeqs (\<lambda>x. EmptyT)"+++subsection{* Proving Well-Typedness *}++text{*+ A protocol is well-typed with respect to a typing iff+ all its reachable state are approximated by the typing.++ We specialize the induction scheme that we get from the definition+ of the set of reachable states to a ``type checking'' induction+ scheme. It works for message typings that are monotoneous with+ respect to state updates.+*}++definition monoTyp :: "typing \<Rightarrow> bool" +where "monoTyp typ \<equiv> + (\<forall> x i t r s t' r'.+ roleMap r \<subseteq>\<^sub>m roleMap r' \<longrightarrow>+ typ x i (t,r,s) \<subseteq> typ x i (t@t',r',s)+ )"++lemma monoTypI:+ "\<lbrakk> \<And> x i t r s t' r' s' m. + \<lbrakk> roleMap r \<subseteq>\<^sub>m roleMap r'; m \<in> typ x i (t,r,s) \<rbrakk>+ \<Longrightarrow> m \<in> typ x i (t@t',r',s)+ \<rbrakk> \<Longrightarrow> monoTyp typ"+ by(auto simp: monoTyp_def)++lemma monoTypD:+ "\<lbrakk> monoTyp typ;+ m \<in> typ x i (t,r,s);+ roleMap r \<subseteq>\<^sub>m roleMap r'+ \<rbrakk> \<Longrightarrow>+ m \<in> typ x i (t@t',r',s)"+ unfolding monoTyp_def by blast++lemma monoTyp_freeD:+ "\<lbrakk> monoTyp typ;+ m \<in> typ x i (t,r,s);+ roleMap r \<subseteq>\<^sub>m roleMap r';+ t' = t@t''+ \<rbrakk> \<Longrightarrow>+ m \<in> typ x i (t',r',s)"+ unfolding monoTyp_def by blast++lemma monoTyp_appendD:+ "\<lbrakk> monoTyp typ;+ m \<in> typ x i (t,r,s)+ \<rbrakk> \<Longrightarrow>+ m \<in> typ x i (t@t',r,s)"+ by (rule monoTyp_freeD) auto+++lemma (in reachable_state) reachable_in_approxI:+ assumes monoTyp: "monoTyp typing"+ and recv_case:+ "\<And> t r s i done todo skipped m R step n.+ \<lbrakk> R \<in> P; + roleMap r i = Some R;+ (done, step # todo) \<in> set (splits R);+ recvStep step;+ MVar n \<in> FV (stepPat step);+ \<forall> step' \<in> set done. MVar n \<notin> FV (stepPat step');+ hint ''completenessCase'' (step, n);+ + (t,r,s) \<in> reachable P;+ (t,r,s) \<in> approx typing;+ r i = Some (done, step # todo, skipped);+ Some m = inst s i (stepPat step);+ m \<in> knows t+ \<rbrakk> \<Longrightarrow> + s (MV n i) \<in> typing (R, n) i (t @ [Step (i, step)], r(i \<mapsto> (done @ [step], todo, skipped)), s)"+ shows "(t,r,s) \<in> approx typing"+proof -+ { fix i step "done" todo skipped n+ have+ "\<lbrakk> r i = Some (done, todo, skipped);+ (i,step) \<in> steps t;+ MVar n \<in> FV (stepPat step)+ \<rbrakk> \<Longrightarrow> s (MV n i) \<in> typing (done@todo, n) i (t,r,s)"+ proof(induct arbitrary: i "done" todo step n skipped rule: reachable_induct)+ case (send t r s i "done" l pt todo skipped m i' done' todo' step n skipped')+ then interpret th1: + reachable_thread P t r s i "done" "Send l pt # todo" skipped+ by unfold_locales auto+ from send + have "(i', step) \<in> steps t \<or> (i' = i) \<and> step = Send l pt"+ (is "?old \<or> ?new") by auto+ moreover+ { assume ?old+ hence "s(MV n i') \<in> typing (done'@todo', n) i' (t,r,s)"+ using send by (auto split: if_splits)+ hence ?case+ proof(rule monoTyp_freeD[OF monoTyp])+ qed (auto simp: th1.thread_exists)+ }+ moreover+ { let ?role = "done @ Send l pt # todo"+ note IH = send(2)+ assume "?new"+ hence "MVar n \<in> FV pt"+ using send by auto+ then obtain l' msg' + where "(i, Recv l' msg') \<in> steps t" + "MVar n \<in> FV msg'"+ by (fastsimp dest!: th1.send_step_FV[OF th1.thread_exists])+ hence typed: "s (MV n i) \<in> typing (?role, n) i (t, r, s)"+ by (auto dest: IH[OF th1.thread_exists])+ have "done'@todo' = ?role"+ using send `?new` by auto+ hence ?case using `?new`+ apply -+ apply(rule monoTyp_freeD[OF monoTyp])+ by (auto intro!: typed simp: th1.thread_exists)+ }+ ultimately show ?case by fast+ next+ case (recv t r s i "done" l pt todo skipped m i' done' todo' step n skipped') then+ interpret th1: + reachable_thread P t r s i "done" "Recv l pt # todo" skipped+ by unfold_locales auto+ from recv+ have "(i', step) \<in> steps t \<or> (i' = i) \<and> step = Recv l pt"+ (is "?old \<or> ?new") by auto+ moreover+ { assume ?old+ hence "s(MV n i') \<in> typing (done'@todo', n) i' (t,r,s)"+ using recv by (auto split: if_splits)+ hence ?case using `?old`+ apply -+ apply(rule monoTyp_freeD[OF monoTyp])+ apply(auto simp: th1.thread_exists)+ done+ }+ moreover+ { let ?role = "done @ Recv l pt # todo"+ note IH = recv(2)+ assume "?new"+ hence cur_thread: "?role = done' @ todo'" "i = i'" + using recv by auto+ have ?case+ proof(cases "\<exists> step' \<in> set done. MVar n \<in> FV (stepPat step')")+ case True+ with recv+ obtain step'' + where FV: "MVar n \<in> FV (stepPat step'')" + and step'': "step'' \<in> set done"+ by auto+ thus ?thesis + proof(cases "step'' \<in> skipped")+ case False+ then obtain step' + where FV: "MVar n \<in> FV (stepPat step')" + and notinSkipped: "step' \<notin> skipped"+ and step': "(i,step') \<in> steps t"+ using FV step''+ by(auto simp add: th1.in_steps_conv_done_skipped)+ hence "s (MV n i) \<in> typing (?role, n) i (t, r, s)"+ by (auto intro!: IH th1.thread_exists)+ hence "s (MV n i') \<in> typing (done'@todo', n) i' (t, r, s)"+ using cur_thread by simp+ thus ?thesis+ apply -+ apply(rule monoTyp_freeD[OF monoTyp])+ apply(auto simp: th1.thread_exists)+ done+ next+ case True+ then obtain step'+ where FV: "MVar n \<in> FV (stepPat step')" + and inSkipped: "step' \<in> skipped"+ and inDone: "step' \<in> set done"+ using FV step''+ by auto+ then obtain l' ty' pt'+ where noteEq: "(Note l' ty' pt') = step'"+ by(auto dest!: th1.note_in_skipped)++ hence "\<exists> l'' pt''. listOrd ?role (Recv l'' pt'') (Note l' ty' pt') \<and> MVar n \<in> FV (stepPat (Recv l'' pt''))"+ using FV inSkipped inDone + apply -+ apply(drule FV_FMV_conv[THEN iffD2])+ apply(subgoal_tac "Note l' ty' pt' \<in> set ?role")+ apply(drule th1.Note_FV)+ by (auto dest: FV_FMV_conv[THEN iffD1])+ then obtain l'' pt''+ where roleBefore: "listOrd ?role (Recv l'' pt'') (Note l' ty' pt')"+ and varOfRecv: "MVar n \<in> FV (stepPat (Recv l'' pt''))"+ by auto+ hence "Recv l'' pt'' \<in> set done" + using inDone noteEq+ apply -+ apply(drule listOrd_append[THEN iffD1])+ apply(case_tac "listOrd done (Recv l'' pt'') (Note l' ty' pt')")+ apply(fastsimp dest: in_set_listOrd1)+ apply(case_tac "listOrd (Recv l pt # todo) (Recv l'' pt'') (Note l' ty' pt')")+ apply(fastsimp dest: in_set_listOrd2 th1.done_notin_todoD)+ apply(case_tac "Recv l'' pt'' \<in> set done \<and> Note l' ty' pt' \<in> set (Recv l pt # todo)")+ by(auto dest: th1.done_notin_todoD)+ hence "(i, Recv l'' pt'') \<in> steps t" by auto++ hence "s (MV n i) \<in> typing (?role, n) i (t, r, s)"+ using varOfRecv by (auto intro!: IH th1.thread_exists)+ hence "s (MV n i') \<in> typing (done'@todo', n) i' (t, r, s)"+ using cur_thread by simp+ thus ?thesis+ apply -+ apply(rule monoTyp_freeD[OF monoTyp])+ apply(auto simp: th1.thread_exists)+ done+ qed+ next+ case False+ moreover have "(t, r, s) \<in> approx typing"+ by (auto simp: approx_unfold dest!: IH roleMap_SomeD)+ moreover have "MVar n \<in> FV pt" + using `MVar n \<in> FV (stepPat step)` `?new` by auto+ moreover note `Some m = inst s i pt`+ moreover note `m \<in> knows t`+ moreover note cur_thread[symmetric]+ + ultimately show ?thesis+ apply -+ apply(clarsimp simp del: fun_upd_apply)+ apply(rule recv_case)+ apply(simp_all add: th1.role_in_P th1.roleMap th1.thread_exists + in_set_splits_conv remove_hints)+ done+ qed+ }+ ultimately show ?case by fastsimp+ next+ case (compr t r s i "done" l ty pt todo skipped m i' done' todo' step n skipped')+ then interpret th1: + reachable_thread P t r s i "done" "Note l ty pt # todo" skipped+ by unfold_locales auto+ from compr+ have "(i', step) \<in> steps t \<or> (i' = i) \<and> step = Note l ty pt"+ (is "?old \<or> ?new") by auto+ moreover+ { assume ?old+ hence "s(MV n i') \<in> typing (done'@todo', n) i' (t,r,s)"+ using compr by (auto split: if_splits)+ hence ?case+ proof(rule monoTyp_freeD[OF monoTyp])+ qed (auto simp: th1.thread_exists)+ }+ moreover+ { let ?role = "done @ Note l ty pt # todo"+ note IH = compr(2)+ assume "?new"+ hence "MVar n \<in> FV pt"+ using compr by auto+ then obtain l' msg' + where "(i, Recv l' msg') \<in> steps t" + "MVar n \<in> FV msg'"+ by (fastsimp dest!: th1.note_step_FV[OF th1.thread_exists])+ hence typed: "s (MV n i) \<in> typing (?role, n) i (t, r, s)"+ by (auto dest: IH[OF th1.thread_exists])+ have "done'@todo' = ?role"+ using compr `?new` by auto+ hence ?case using `?new`+ apply -+ apply(rule monoTyp_freeD[OF monoTyp])+ by (auto intro!: typed simp: th1.thread_exists)+ }+ ultimately show ?case by fast+ next+ case (skip t r s i "done" l ty pt todo skipped i' done' todo' step n skipped')+ then interpret th1: + reachable_thread P t r s i "done" "Note l ty pt # todo" skipped+ by unfold_locales auto+ from skip+ have "(i', step) \<in> steps t" (is "?old") by auto+ hence "s(MV n i') \<in> typing (done'@todo', n) i' (t,r,s)"+ using skip by (auto split: if_splits)+ thus ?case+ proof(rule monoTyp_freeD[OF monoTyp])+ qed (auto simp: th1.thread_exists)+ qed (auto intro: monoTyp_appendD[OF monoTyp])+ }+ thus ?thesis unfolding approx_unfold by(auto elim!: roleMap_SomeE)+qed++text{*+ We prove a variant of the above lemma, which is suitable for+ automation. The difference is the description of the variables+ that need to be checked. Here, it is done such that Isabelle's+ simplifier gets a finite set that it can rewrite into normal+ form.+*}+lemma (in reachable_state) reachable_in_approxI_ext:+ assumes monoTyp: "monoTyp typing"+ and recv_case:+ "\<And> t r s i done todo skipped m R step n.+ \<lbrakk> R \<in> P; + roleMap r i = Some R;+ (done, step # todo) \<in> set (splits R);+ recvStep step;+ MVar n \<in> foldl (\<lambda> fv step'. fv - FV (stepPat step')) (FV (stepPat step)) done;+ hint ''completenessCase'' (step, n);+ + (t,r,s) \<in> reachable P;+ (t,r,s) \<in> approx typing;+ r i = Some (done, step # todo ,skipped);+ Some m = inst s i (stepPat step);+ m \<in> knows t+ \<rbrakk> \<Longrightarrow> + s (MV n i) \<in> typing (R, n) i ( t @ [Step (i, step)], r(i \<mapsto> (done @ [step], todo, skipped)), s)"+ shows "(t,r,s) \<in> approx typing"+proof(induct rule: reachable_in_approxI[OF monoTyp])+ case (1 t r s i "done" todo skipped m R step n)+ { fix v V+ assume "v \<in> V"+ and "\<forall>step'\<in>set done. v \<notin> FV (stepPat step')"+ hence "v \<in> foldl (\<lambda> fv step'. fv - FV (stepPat step')) V done"+ by (induct "done" arbitrary: V) auto+ }+ hence "MVar n \<in> foldl (\<lambda> fv step'. fv - FV (stepPat step')) (FV (stepPat step)) done"+ using 1 by auto+ thus ?case using 1+ apply(subgoal_tac "True")+ apply(clarsimp)+ apply(rule recv_case)+ by(assumption | simp add: remove_hints)++qed++text{* Proving typing monotonicity *}++subsubsection{* Monotonicity Proofs *}++definition monoMsgTyp :: "msgtype \<Rightarrow> bool"+where "monoMsgTyp ty \<equiv>+ (\<forall>i t r s t' r'.+ roleMap r \<subseteq>\<^sub>m roleMap r' \<longrightarrow>+ ty i (t, r, s) \<subseteq> ty i (t @ t', r', s))"++lemma monoMsgTypD:+ "\<lbrakk> monoMsgTyp ty;+ m \<in> ty i (t,r,s);+ roleMap r \<subseteq>\<^sub>m roleMap r'+ \<rbrakk> \<Longrightarrow>+ m \<in> ty i (t@t',r',s)"+ unfolding monoMsgTyp_def by blast+++lemma monoMsgTyp_SumTI[intro!]:+ assumes ty1: "monoMsgTyp ty1"+ and ty2: "monoMsgTyp ty2"+ shows "monoMsgTyp (SumT ty1 ty2)"+ by(auto simp: monoMsgTyp_def SumT_def + dest: monoMsgTypD[OF ty1] monoMsgTypD[OF ty2])++lemma monoMsgTyp_InterTI[intro!]:+ assumes ty1: "monoMsgTyp ty1"+ and ty2: "monoMsgTyp ty2"+ shows "monoMsgTyp (InterT ty1 ty2)"+ by(auto simp: monoMsgTyp_def InterT_def + dest: monoMsgTypD[OF ty1] monoMsgTypD[OF ty2])++lemma monoMsgTyp_KnownTI[iff]:+ shows "monoMsgTyp (KnownT step)"+ by(auto simp: monoMsgTyp_def KnownT_def )+ +lemma monoMsgTyp_NonceTI[iff]:+ shows "monoMsgTyp (NonceT R n)"+ by(auto simp: monoMsgTyp_def NonceT_def dest: map_leD)++lemma monoMsgTyp_ConstTI[iff]:+ shows "monoMsgTyp (ConstT c)"+ by(auto simp: monoMsgTyp_def ConstT_def dest: map_leD)++lemma monoMsgTyp_AgentTI[iff]:+ shows "monoMsgTyp AgentT"+ by(auto simp: monoMsgTyp_def AgentT_def dest: map_leD)++lemma monoMsgTyp_EncTI[intro!]:+ assumes ty1: "monoMsgTyp ty1"+ and ty2: "monoMsgTyp ty2"+ shows "monoMsgTyp (EncT ty1 ty2)"+ by(auto simp: monoMsgTyp_def EncT_def + dest: monoMsgTypD[OF ty1] monoMsgTypD[OF ty2])++lemma monoMsgTyp_KTI[intro!]:+ assumes ty1: "monoMsgTyp ty1"+ and ty2: "monoMsgTyp ty2"+ shows "monoMsgTyp (KT ty1 ty2)"+ by(auto simp: monoMsgTyp_def KT_def + dest: monoMsgTypD[OF ty1] monoMsgTypD[OF ty2])++lemma monoMsgTyp_KShrTI[intro!]:+ shows "monoMsgTyp KShrT"+ by(auto simp: monoMsgTyp_def KShrT_def)++lemma monoMsgTyp_TupTI[intro!]:+ assumes ty1: "monoMsgTyp ty1"+ and ty2: "monoMsgTyp ty2"+ shows "monoMsgTyp (TupT ty1 ty2)"+ by(auto simp: monoMsgTyp_def TupT_def + dest: monoMsgTypD[OF ty1] monoMsgTypD[OF ty2])++lemma monoMsgTyp_HashTI[intro!]:+ assumes ty: "monoMsgTyp ty"+ shows "monoMsgTyp (HashT ty)"+ by(auto simp: monoMsgTyp_def HashT_def + dest: monoMsgTypD[OF ty])++lemma monoMsgTyp_PKTI[intro!]:+ assumes ty: "monoMsgTyp ty"+ shows "monoMsgTyp (PKT ty)"+ by(auto simp: monoMsgTyp_def PKT_def + dest: monoMsgTypD[OF ty])++lemma monoMsgTyp_SKTI[intro!]:+ assumes ty: "monoMsgTyp ty"+ shows "monoMsgTyp (SKT ty)"+ by(auto simp: monoMsgTyp_def SKT_def + dest: monoMsgTypD[OF ty])++lemma monoTyp_mk_typing[intro!]:+ assumes monoMsgTyp: + "\<And> pos ty. (pos, ty) \<in> set tyeqs \<Longrightarrow> monoMsgTyp ty"+ shows "monoTyp (mk_typing tyeqs)"+using monoMsgTyp+proof(induct tyeqs)+ case Nil thus ?case+ by(auto intro!: monoTypI simp: mk_typing_def EmptyT_def)+next+ case (Cons tyeq tyeqs) + thus ?case+ proof(cases tyeq)+ case (Pair pos' ty') + have mk_typing_Cons [simp]:+ "mk_typing ((pos',ty')#tyeqs) = (mk_typing tyeqs)(pos' := ty')"+ by (simp add: mk_typing_def)+ with Pair show ?thesis+ apply(auto intro!: monoTypI)+ apply(auto intro: monoTypD[OF Cons(1), OF Cons(2)]+ monoMsgTypD[OF Cons(2)]+ simp: Pair)+ done+ qed+qed++subsection{* Automation *}+++subsubsection{* ACI of Sum and Intersection Types *}++lemma SumT_absorb [simp]: "SumT ty ty = ty"+ by (rule ext, rule ext) (auto simp: SumT_def)++lemma SumT_left_absorb: "SumT ty1 (SumT ty1 ty2) = SumT ty1 ty2"+ by (rule ext, rule ext) (auto simp: SumT_def)++lemma SumT_commute: "SumT ty1 ty2 = SumT ty1 ty2"+ by (rule ext, rule ext) (auto simp: SumT_def)++lemma SumT_left_commute: "SumT ty1 (SumT ty2 ty3) = SumT ty2 (SumT ty1 ty3)"+ by (rule ext, rule ext) (auto simp: SumT_def)++lemma SumT_assoc: "SumT (SumT ty1 ty2) ty3 = SumT ty1 (SumT ty2 ty3)"+ by (rule ext, rule ext) (auto simp: SumT_def)++lemmas SumT_ac = SumT_assoc SumT_left_absorb SumT_commute SumT_left_commute+ -- {* Type sum is an AC-operator *}++lemma InterT_absorb [simp]: "InterT ty ty = ty"+ by (rule ext, rule ext) (auto simp: InterT_def)++lemma InterT_left_absorb: "InterT ty1 (InterT ty1 ty2) = InterT ty1 ty2"+ by (rule ext, rule ext) (auto simp: InterT_def)++lemma InterT_commute: "InterT ty1 ty2 = InterT ty1 ty2"+ by (rule ext, rule ext) (auto simp: InterT_def)++lemma InterT_left_commute: "InterT ty1 (InterT ty2 ty3) = InterT ty2 (InterT ty1 ty3)"+ by (rule ext, rule ext) (auto simp: InterT_def)++lemma InterT_assoc: "InterT (InterT ty1 ty2) ty3 = InterT ty1 (InterT ty2 ty3)"+ by (rule ext, rule ext) (auto simp: InterT_def)+++lemmas InterT_ac = InterT_assoc InterT_left_absorb InterT_commute InterT_left_commute+ -- {* Type intersection is an AC-operator *}+++subsubsection{* Type Membership *}+++text{* Special types *}++lemma notin_EmptyT[iff]:+ "m \<notin> EmptyT i q"+ by (simp add: EmptyT_def)++text{* The rules for SumT are special, as their usage currently+depends on the combination of SumT and KnownT.+*}+lemma in_SumTE:+ "\<lbrakk> m \<in> SumT ty1 ty2 i q; m \<in> ty1 i q \<Longrightarrow> R; m \<in> ty2 i q \<Longrightarrow> R + \<rbrakk> \<Longrightarrow> R"+ by(auto simp: SumT_def)++lemma notin_SumTE [elim!]: + "\<lbrakk> m \<notin> SumT ty1 ty2 i q; + \<lbrakk> m \<notin> ty1 i q; m \<notin> ty2 i q \<rbrakk> \<Longrightarrow> R+ \<rbrakk> \<Longrightarrow> R"+ by(auto simp: SumT_def)++lemma notin_KnownT_append_StepE [dest!]:+ "m \<notin> KnownT step i (t@ [Step (i, step)], r, s) \<Longrightarrow>+ m \<notin> knows t"+ by(auto simp: KnownT_def)++++text{* Atomic types *}++lemma in_ConstT [iff]:+ "(m \<in> ConstT c i q) = (m = LC c)"+ by(auto simp: ConstT_def)++lemma notin_AgentT [iff]:+ "LN n nTid \<notin> AgentT i q"+ "Hash m \<notin> AgentT i q"+ "Tup x y \<notin> AgentT i q"+ "Enc m k \<notin> AgentT i q"+ "SK x \<notin> AgentT i q"+ "PK x \<notin> AgentT i q"+ "K x y \<notin> AgentT i q"+ by(auto simp: AgentT_def Agent_def)++text{* To be used together with if\_splits in a well-typedness+proof *}+lemma in_NonceT [simp]: + "(LN n i \<in> NonceT R n i' (t,r,s)) = (roleMap r i = Some R)"+ by(simp add: NonceT_def)++lemma in_NonceTE [elim!]:+ "\<lbrakk> m \<in> NonceT R n i (t,r,s); + \<And> nTid. \<lbrakk> m = LN n nTid; roleMap r nTid = Some R \<rbrakk> \<Longrightarrow> Q + \<rbrakk> \<Longrightarrow> Q"+ by(auto simp: NonceT_def)++lemma notin_NonceT_thenonceE [elim!]:+ "\<lbrakk> LN n nTid \<notin> NonceT nR n i (t, r(i \<mapsto> (done,todo,skipped)), s);+ nTid = i \<Longrightarrow> Q;+ \<lbrakk> nTid \<noteq> i; roleMap r nTid \<noteq> Some nR \<rbrakk> \<Longrightarrow> Q+ \<rbrakk> \<Longrightarrow> Q"+ by(auto simp: NonceT_def split: if_splits)+++text{* These rules ensure that type information is exploited+when a match impossible without intruder activity happening.+*}+lemma Tup_in_SumT_KnownT_NonceTD [dest!]:+ "Tup x y \<in> SumT (KnownT step) (NonceT R n) i (t, r, s)+ \<Longrightarrow> predOrd t (Ln (Tup x y)) (St (i, step))"+ by(auto simp: KnownT_def SumT_def)++lemma Hash_in_SumT_KnownT_NonceTD [dest!]:+ "Hash x \<in> SumT (KnownT step) (NonceT R n) i (t, r, s)+ \<Longrightarrow> predOrd t (Ln (Hash x)) (St (i, step))"+ by(auto simp: KnownT_def SumT_def)++lemma Enc_in_SumT_KnownT_NonceTD [dest!]:+ "Enc x y \<in> SumT (KnownT step) (NonceT R n) i (t, r, s)+ \<Longrightarrow> predOrd t (Ln (Enc x y)) (St (i, step))"+ by(auto simp: KnownT_def SumT_def)++text{* TODO: Extend these lemmas for further combinations. This requires+some more thinking. However, for a well-designed protocols the message+structure is not required for disambiguation because the encryptions+contain tags that identify them.+*}++lemma in_SomeNonceTE [elim!]:+ "\<lbrakk> m \<in> SomeNonceT i q;+ \<And> n' i'. m = LN n' i' \<Longrightarrow> Q+ \<rbrakk> \<Longrightarrow> Q"+ by(auto simp: SomeNonceT_def)++lemma Nonce_in_SomeNonceT [simp]:+ "LN n' i' \<in> SomeNonceT i q"+ by(simp add: SomeNonceT_def)++text{* Removes trivial statements from the premises *}+lemma Nonce_in_SumT_KnownT_SomeNonceTE [iff]:+ "LN n i \<in> SumT (KnownT step) SomeNonceT i' (t, r, s)"+ by (auto simp: SumT_def)+++text{* Structural types *}++text{* The following rules are used in well-typedness proofs *}+lemma Hash_in_HashT [simp]: + "(Hash x \<in> HashT ty i q) = (x \<in> ty i q)"+ by (simp add: HashT_def)++lemma Tup_in_TupT [simp]: + "(Tup x y \<in> TupT ty1 ty2 i q) = (x \<in> ty1 i q \<and> y \<in> ty2 i q)"+ by (simp add: TupT_def)++lemma Enc_in_EncT [simp]: + "(Enc x y \<in> EncT ty1 ty2 i q) = (x \<in> ty1 i q \<and> y \<in> ty2 i q)"+ by (simp add: EncT_def)++lemma PK_in_PKT [simp]: "(PK x \<in> PKT ty i q) = (x \<in> ty i q)"+ by (simp add: PKT_def)++lemma SK_in_SKT [simp]: "(SK x \<in> SKT ty i q) = (x \<in> ty i q)"+ by (simp add: SKT_def)++lemma K_in_KT [simp]: + "(K x y \<in> KT ty1 ty2 i q) = (x \<in> ty1 i q \<and> y \<in> ty2 i q)"+ by (simp add: KT_def)++++text{* The following rules ensure that messages are expanded+automatically in when applying the sources rule.+*}++lemma in_HashTE [elim!]:+ "\<lbrakk> m \<in> HashT ty i q;+ \<And> x. \<lbrakk> m = Hash x; x \<in> ty i q \<rbrakk> \<Longrightarrow> Q+ \<rbrakk> \<Longrightarrow> Q"+ by(auto simp: HashT_def)++lemma in_EncTE [elim!]:+ "\<lbrakk> m \<in> EncT ty1 ty2 i q;+ \<And> x k. \<lbrakk> m = Enc x k; x \<in> ty1 i q; k \<in> ty2 i q \<rbrakk> \<Longrightarrow> Q+ \<rbrakk> \<Longrightarrow> Q"+ by(auto simp: EncT_def)++lemma in_TupTE [elim!]:+ "\<lbrakk> m \<in> TupT ty1 ty2 i q;+ \<And> x y. \<lbrakk> m = \<lbrace> x, y \<rbrace>; x \<in> ty1 i q; y \<in> ty2 i q \<rbrakk> \<Longrightarrow> Q+ \<rbrakk> \<Longrightarrow> Q"+ by(auto simp: TupT_def)++lemma in_KTE [elim!]:+ "\<lbrakk> m \<in> KT ty1 ty2 i q;+ \<And> x y. \<lbrakk> m = K x y; x \<in> ty1 i q; y \<in> ty2 i q \<rbrakk> \<Longrightarrow> Q+ \<rbrakk> \<Longrightarrow> Q"+ by(auto simp: KT_def)++lemma in_PKTE [elim!]:+ "\<lbrakk> m \<in> PKT ty i q;+ \<And> x. \<lbrakk> m = PK x; x \<in> ty i q \<rbrakk> \<Longrightarrow> Q+ \<rbrakk> \<Longrightarrow> Q"+ by(auto simp: PKT_def)++lemma in_SKTE [elim!]:+ "\<lbrakk> m \<in> SKT ty i q;+ \<And> x. \<lbrakk> m = SK x; x \<in> ty i q \<rbrakk> \<Longrightarrow> Q+ \<rbrakk> \<Longrightarrow> Q"+ by(auto simp: SKT_def)+++subsection{* Specialization of the Chain Rule *}++text{* We prove the case distinction on messages known to the+ intruder with respect to an typed state, because we need+ a sufficiently precise invariant when reasoning about the+ contents of a variable.+*}+lemma (in typed_state) knows_cases:+ assumes known: "m' \<in> knows t"+ shows "+ (m' \<in> IK0 \<and> + hint ''case_name'' ''ik0''+ ) \<or>+ (\<exists> m. m' = Hash m \<and> Ln m \<prec> Ln (Hash m) \<and>+ hint ''case_name'' ''fake''+ ) \<or>+ (\<exists> m k. m' = Enc m k \<and> + Ln m \<prec> Ln (Enc m k) \<and> Ln k \<prec> Ln (Enc m k) \<and>+ hint ''case_name'' ''fake''+ ) \<or>+ (\<exists> x y. m' = Tup x y \<and> + Ln x \<prec> Ln (Tup x y) \<and> Ln y \<prec> Ln (Tup x y) \<and>+ hint ''case_name'' ''fake''+ ) \<or>+ (\<exists> R \<in> P. \<exists> i. roleMap r i = Some R \<and> + (\<exists> step \<in> set R. + (sendStep step \<or> noteStep step) \<and>+ (\<exists> m. Some m = inst s i (stepPat step) \<and> decrChain [] t {St (i, step)} m m') \<and>+ prefixClose s t R step i \<and>+ (\<forall> v \<in> FV (stepPat step). \<forall> n. v = MVar n \<longrightarrow> + s (MVar n, i) \<in> typing (R, n) i (t,r,s)) \<and>+ hint ''decrChainFrom'' (i, R, step) \<and>+ hint ''case_name'' ''decrypt''+ )++ ) \<or>+ (\<exists> a. m' = SK a \<and> LKR a \<prec> Ln m' \<and> hint ''case_name'' ''asym_lkr'') \<or>+ (\<exists> a b. m' = K a b \<and> LKR a \<prec> Ln m' \<and> hint ''case_name'' ''sym_lkr1'') \<or>+ (\<exists> a b. m' = K a b \<and> LKR b \<prec> Ln m' \<and> hint ''case_name'' ''sym_lkr2'') \<or>+ (\<exists> A. \<exists> a \<in> A. m' = KShr A \<and> LKR (LAg a) \<prec> Ln m' \<and> hint ''case_name'' ''shr_lkr'')+ "+ (is "?ik0 \<or> ?hash \<or> ?encr \<or> ?tup \<or> ?decr \<or> ?keys")+proof -+ from known have+ "(m' \<in> IK0) \<or>+ (\<exists> m. m' = Hash m \<and> Ln m \<prec> Ln (Hash m)) \<or>+ (\<exists> m k. m' = Enc m k \<and> Ln m \<prec> Ln (Enc m k) \<and> Ln k \<prec> Ln (Enc m k)) \<or>+ (\<exists> x y. m' = Tup x y \<and> Ln x \<prec> Ln (Tup x y) \<and> Ln y \<prec> Ln (Tup x y)) \<or>+ (\<exists> i done todo skipped. r i = Some (done, todo, skipped) \<and> + (\<exists> l pt m. + Send l pt \<in> set done \<and> Some m = inst s i pt \<and> + decrChain [] t {St (i, Send l pt)} m m'+ )+ ) \<or>+ (\<exists> i done todo skipped. r i = Some (done, todo, skipped) \<and> + (\<exists> l ty pt m. + Note l ty pt \<in> set done \<and> Note l ty pt \<notin> skipped \<and> + Some m = inst s i pt \<and> + decrChain [] t {St (i, Note l ty pt)} m m'+ )+ ) \<or>+ (\<exists> a. m' = SK a \<and> LKR a \<prec> Ln m') \<or>+ (\<exists> a b. m' = K a b \<and> LKR a \<prec> Ln m') \<or>+ (\<exists> a b. m' = K a b \<and> LKR b \<prec> Ln m') \<or> + (\<exists> A. \<exists> a \<in> A. m' = KShr A \<and> LKR (LAg a) \<prec> Ln m')+ "+ (is "?ik0_raw \<or> ?hash_raw \<or> ?encr_raw \<or> ?tup_raw \<or> ?decr_raw \<or> ?note_raw \<or> ?keys_raw")+ by (rule knows_cases_raw)+ moreover + {+ assume "?ik0_raw" + hence ?thesis by( simp add: remove_hints)+ }+ moreover + {+ assume "?hash_raw" + hence ?thesis by( simp add: remove_hints)+ }+ moreover + {+ assume "?encr_raw" + hence ?thesis by( simp add: remove_hints)+ }+ moreover + {+ assume "?tup_raw" + hence ?thesis by( simp add: remove_hints)+ }+ moreover + {+ assume "?keys_raw" + hence ?thesis by( simp add: remove_hints)+ }+ moreover+ { assume ?decr_raw then+ obtain i "done" todo l msg skipped m+ where thread_exists: "r i = Some (done, todo,skipped)"+ and send_done: "Send l msg \<in> set done"+ and msg: "Some m = inst s i msg"+ and decrChain: "decrChain [] t {St (i, Send l msg)} m m'"+ by fast+ then interpret th1: typed_thread P t r s i "done" todo skipped "typing"+ using approximates by unfold_locales+ from send_done have send_step: "(i, Send l msg) \<in> steps t" + by (rule th1.in_steps_send[THEN iffD1])+ moreover+ have "prefixClose s t (done@todo) (Send l msg) i" using send_step+ by(auto intro!: prefixCloseI th1.roleMap)+ moreover+ have send_in_role: "Send l msg \<in> set (done @ todo)"+ using send_done by simp+ moreover+ note in_approxD[OF th1.approximates send_step th1.roleMap, simplified]+ ultimately+ have ?decr using decrChain msg+ apply -+ apply(rule bexI[OF _ th1.role_in_P])+ apply(rule exI)+ apply(rule conjI[OF th1.roleMap])+ apply(rule bexI[OF _ send_in_role])+ by(auto simp: remove_hints)+ hence ?thesis by blast + }+ moreover+ {+ assume ?note_raw+ then obtain i "done" todo skipped l ty pt m+ where thread_exists: "r i = Some (done, todo,skipped)"+ and inDone: "Note l ty pt \<in> set done"+ and notinSkipped: "Note l ty pt \<notin> skipped"+ and msg: "Some m = inst s i pt"+ and decrChain: "decrChain [] t {St (i, Note l ty pt)} m m'"+ by fast+ then interpret th1: typed_thread P t r s i "done" todo skipped "typing"+ using approximates by unfold_locales+ from inDone and notinSkipped have note_step: "(i, Note l ty pt) \<in> steps t" + by (fastsimp dest!: th1.in_steps_eq_in_done)+ moreover+ have "prefixClose s t (done@todo) (Note l ty pt) i" using note_step+ by(auto intro!: prefixCloseI th1.roleMap)+ moreover+ have note_in_role: "Note l ty pt \<in> set (done @ todo)"+ using inDone by simp+ moreover+ note in_approxD[OF th1.approximates note_step th1.roleMap, simplified]+ ultimately+ have ?decr using decrChain msg+ apply -+ apply(rule bexI[OF _ th1.role_in_P])+ apply(rule exI)++ apply(rule conjI[OF th1.roleMap])+ apply(rule bexI[OF _ note_in_role])+ by(auto simp: remove_hints)+ hence ?thesis by blast + }+ ultimately+ show ?thesis by fastsimp+qed+++lemma (in reachable_state) decrChain_AgentTE:+ assumes decrChain: "decrChain path t from m m'"+ and AgentT: "m \<in> AgentT i (t,r,s)" + and nonempty: "from = {} \<Longrightarrow> Q"+ shows "Q"+ using decrChain AgentT nonempty+ by (auto simp: AgentT_def Agent_def)++(*+lemma (in reachable_state) decrChain_AgentTE:+ assumes decrChain: "decrChain path t from m m'"+ and AgentT: "m \<in> AgentT i (t,r,s)" + and elim: "m = m' \<Longrightarrow> Q"+ shows "Q"+ using decrChain AgentT elim+ by (auto simp: AgentT_def)+*)++lemma (in reachable_state) decrChain_imp_predOrd:+ "\<lbrakk> decrChain path t from m m' \<rbrakk> \<Longrightarrow>+ \<exists> im \<in> pairParts m. (\<forall> f \<in> from. f \<prec> Ln im) \<and> Ln im \<preceq> Ln m'"+proof(induct m arbitrary: path "from")+ case (Tup x y) thus ?case+ apply(simp)+ apply(erule disjE)+ apply(clarsimp)+ apply(rule disjI2)+ apply(fastsimp intro: less_le_trans)+ done+qed fastsimp+++lemma (in reachable_state) decrChain_KnownT:+ assumes decrChain: "decrChain path t from m m'"+ and KnownT: "m \<in> KnownT step i (t,r,s)"+ shows "\<exists> im \<in> pairParts m. + (\<forall> f \<in> from. f \<prec> Ln im) \<and> Ln im \<prec> St (i, step)"+proof -+ obtain im+ where "im \<in> pairParts m" and "\<forall>f \<in> from. f \<prec> Ln im"+ using decrChain by (fast dest!: decrChain_imp_predOrd)+ with KnownT show ?thesis+ by (fastsimp simp: KnownT_def intro: pairParts_before)+qed++lemma (in reachable_state) decrChain_KnownTE:+ assumes decrChain: "decrChain path t from m m'"+ and KnownT: "m \<in> KnownT step i (t,r,s)"+ and elim: "\<And> im. \<lbrakk> im \<in> pairParts m; + \<forall> f \<in> from. f \<prec> Ln im;+ Ln im \<prec> St (i, step)+ \<rbrakk> \<Longrightarrow> Q"+ shows "Q"+ using decrChain KnownT+ by(auto dest!: decrChain_KnownT elim)++lemma (in reachable_state) decrChain_SumT_KnownTE:+ assumes KnownT: "m \<in> SumT (KnownT step) ty i (t,r,s)" + and decrChain: "decrChain path t from m m'"+ and elimK: "\<And> im. \<lbrakk> im \<in> pairParts m; + \<forall> f \<in> from. f \<prec> Ln im;+ Ln im \<prec> St (i, step)+ \<rbrakk> \<Longrightarrow> Q"+ and elimTy: "m \<in> ty i (t,r,s) \<Longrightarrow> Q"+ shows "Q"+ using decrChain KnownT elimK elimTy+ by(auto elim!: in_SumTE decrChain_KnownTE)+++lemma (in reachable_state) AV_in_AgentT [iff]: + "s (AV a aTid) \<in> AgentT i q"+using inst_AVar_cases +by (auto simp: AgentT_def Agent_def)++++subsection{* Weak-Atomicity Type Annotation *}+++definition weakly_atomic :: "typing"+where + "weakly_atomic x = (case x of (role,v) \<Rightarrow> foldr + (\<lambda> step msgTy. + if (recvStep step \<and> v \<in> FMV (stepPat step))+ then SumT (KnownT step) SomeNonceT+ else msgTy+ ) + role EmptyT)"+++lemma monoTyp_weakly_atomic:+ "monoTyp weakly_atomic"+proof -+ { fix m v R tid t r s t' r'+ assume "m \<in> foldr (\<lambda>step. If (recvStep step \<and> v \<in> FMV (stepPat step)) (SumT (KnownT step) SomeNonceT)) R EmptyT tid (t, r, s)"+ hence "m \<in> foldr (\<lambda>step. If (recvStep step \<and> v \<in> FMV (stepPat step)) (SumT (KnownT step) SomeNonceT)) R EmptyT tid (t @ t', r', s)"+ by (induct R) (auto simp: SumT_def KnownT_def SomeNonceT_def)+ }+ thus ?thesis+ by (auto simp: monoTyp_def weakly_atomic_def)+qed++++end++(* TODO: + - Remove agent variables from protocol model by + replacing them with type annotations. ++ [General version will require us to reintroduce create event.+ But composition becomes nicer, as we can now model protocols, which+ use parameters that are secret values and so on.+ ]+++ - Put decryption chain case into recursion of chain+ predicate to make more information available locally.+*)++
@@ -0,0 +1,863 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+(*+Commands for role and protocols definitions in the ESPLogic.++Side effect: registers the two definitional commands "role" and "protocol".+*)++signature ESPL_DEFINITIONS =+sig+ (* Additional Utilities *)+ val unnamed_caseN: string++ datatype steptyp = Recv | Send+ val mk_rolestep: steptyp * term * term -> term+ val dest_rolestep: term -> steptyp * term * term+ val dest_role: term -> (steptyp * term * term) list+ val dest_variable_store_lookup: term -> term * (term * term)+ val dest_non_refl_eq: typ -> term -> term * term++ val get_unfold_thms: Proof.context -> term -> thm list+ val get_rolestep_msg: Proof.context -> string -> term++ (* Role Definitions *)+ val define_rolestep_cmd+ : string -> Args.src list -> steptyp * term * term -> local_theory -> + ((term * thm) * (term * thm)) * local_theory+ + val define_role_cmd+ : binding * ((binding * Args.src list) * string) -> local_theory ->+ ((term * thm) * ((term * thm) * (term * thm)) list) * local_theory++ (* Protocol Definitions *)+ val define_proto_cmd+ : binding * ((binding * Args.src list) * string) -> local_theory -> + (term * thm) * local_theory++ (* Managing the Chain Rule and Its Expansion with Named Cases *)+ structure TypeElimRulesData : GENERIC_DATA+ val lookup_type_elim_rules: Proof.context -> TypeElimRulesData.T++ val insert_case_names: Proof.context -> thm -> thm+ val source_case_names: thm -> string list++ val refine_knows_cases+ : Proof.context -> term option -> thm -> thm+ val prepare_sources_elim: Proof.context -> thm -> term -> thm++ structure KnowsCasesCache : NAMED_THMS+ val precompute_source_elim_rules+ : thm -> Proof.context -> (string * thm list) list * local_theory++ (* Type Invariant Definitions Combined With Chain Rule Expansion *)+ val type_invariant_cmd+ : (binding * string) * ((binding * Args.src list) * string) ->+ local_theory -> local_theory+end;++structure ESPL_Definitions: ESPL_DEFINITIONS =+struct++open ESPL_Utils;++(******************************************************************************+** Additional Utilities+******************************************************************************)+++datatype steptyp = Recv | Send | Note of term;++fun mk_rolestep (Send, lbl, msg) = @{const Send} $ lbl $ msg+ | mk_rolestep (Recv, lbl, msg) = @{const Recv} $ lbl $ msg+ | mk_rolestep (Note nTy, lbl, msg) = @{const Note} $ lbl $ nTy $ msg++fun dest_rolestep (Const (@{const_name Send},_) $ lbl $ msg) = (Send, lbl, msg)+ | dest_rolestep (Const (@{const_name Recv},_) $ lbl $ msg) = (Recv, lbl, msg)+ | dest_rolestep (Const (@{const_name Note},_) $ lbl $ nTy $ msg) = (Note nTy, lbl, msg)+ | dest_rolestep t = raise TERM ("dest_rolestep", [t])++val dest_role = map dest_rolestep o HOLogic.dest_list++(* Destruct a symbolic representation of the contents+ of a protocol variable. +*)+fun dest_variable_store_lookup (t as (s $ lv)) =+ if (Term.fastype_of s = @{typ "store"})+ then (case HOLogic.strip_tuple lv of+ [v,tid] => (s, (v,tid))+ | _ => + raise TERM ("dest_variable_store_lookup: wrong arity",[t]))+ else raise TERM ("dest_variable_store_lookup: wrong type",[t])+ | dest_variable_store_lookup t = + raise TERM ("dest_variable_store_lookup",[t]);+++(* Destruct an non-reflexive equality *)+fun dest_non_refl_eq ty t = + case HOLogic.dest_eq t of+ eq as (lhs,rhs) => + if lhs = rhs+ then raise TERM ("dest_non_refl_eq: reflexive",[t])+ else + if Term.fastype_of lhs = ty+ then eq+ else raise TYPE ("dest_non_refl_eq:",[ty],[t]);+++(* Retrieves the unfold theorems for a constent that were previously stored as+ const_name.unfold. This is not very stable but works for our defintions.++ TODO: Check if there is a more stable machinery for that purpose.+*)+fun get_unfold_thms ctxt (Const (c,_)) = ProofContext.get_thms ctxt (c ^ ".unfold")+ | get_unfold_thms ctxt (Free (c,_)) = ProofContext.get_thms ctxt (c ^ ".unfold")+ | get_unfold_thms _ t = raise TERM ("get_unfold_thms", [t])++(* Lookup the term of the message of a role step *)+fun get_rolestep_msg ctxt step_name = + ProofContext.get_thm ctxt (Thm.def_name (step_name ^ "_pt"))+ |> Thm.prop_of+ |> dest_HOL_def+ |> snd++(* Extract identifiers of message variables in a pattern *)+fun pat_msgvars (Const (@{const_name "PEnc"},_) $ m $ k) = + OrdList.union fast_string_ord (pat_msgvars m) (pat_msgvars k)+ | pat_msgvars (Const (@{const_name "PTup"},_) $ x $ y) = + OrdList.union fast_string_ord (pat_msgvars x) (pat_msgvars y)+ | pat_msgvars (Const (@{const_name "PHash"},_) $ x) = + pat_msgvars x+ | pat_msgvars (Const (@{const_name "PSymK"},_) $ a $ b) = + OrdList.union fast_string_ord (pat_msgvars a) (pat_msgvars b)+ | pat_msgvars (Const (@{const_name "PAsymPK"},_) $ a) =+ pat_msgvars a+ | pat_msgvars (Const (@{const_name "PAsymSK"},_) $ a) =+ pat_msgvars a+ | pat_msgvars (Const (@{const_name "PFresh"},_) $ _) = + []+ | pat_msgvars (Const (@{const_name "PConst"},_) $ _) = + []+ | pat_msgvars (Const (@{const_name "PVar"},_) $ v) = + (case v of+ (Const (@{const_name AVar},_) $ _) => []+ | (Const (@{const_name MVar},_) $ i) => [HOLogic.dest_string i]+ | _ => []+ )+ | pat_msgvars _ = []+++(******************************************************************************+** Role Definitions+******************************************************************************)++(*+ The "role" definition command defines constants for every message and step of+ the role specification and the role specification itself. Furthermore+ wellformedness of the role and several expansion theorems are proven+ automatically. The theorems "role.unfold" can be used if all these+ intermediate definitions need to be simplified away.+*)++(* proves and notes all the theorems associated to a rolestep *)+fun setup_rolestep mk_binding ann_defs lthy =+ let+ val ((msg_const,msg_def),(step_const,step_def)) = ann_defs;++ val ss_step = Simplifier.simpset_of lthy addsimps [step_def];+ val ss_full = ss_step addsimps [msg_def];++ val sendStep_t = @{const sendStep} $ step_const;+ val noteStep_t = @{const noteStep} $ step_const;+ val stepPat_t = @{const stepPat} $ step_const;+ val noteType_t = @{const noteType} $ step_const;++ val inst_t = @{term "inst s i"} $ msg_const;+ val FV_t = @{term "FV"} $ msg_const;+ val FMV_t = @{term "FMV"} $ msg_const;+ val FAV_t = @{term "FAV"} $ msg_const;+ in+ lthy+ (* unfold theorems *)+ |> #2 o Local_Theory.note (mk_binding "unfold", [msg_def,step_def])+ (* step expansions *)+ |> #2 o notes_expansion ss_step+ [ (mk_binding "sendStep_conv", [([sendStep_t],[att_iff_add])]) + , (mk_binding "noteStep_conv", [([noteStep_t],[att_iff_add])]) + , (mk_binding "stepPat_conv", [([stepPat_t],[att_simp_add])]) + , (mk_binding "noteType_conv", [([noteType_t],[att_simp_add])])+ ]+ (* full expansions *)+ |> notes_expansion ss_full+ [ (mk_binding "inst_conv", [([inst_t], [att_simp_add])])+ , (mk_binding "FV_conv", [([FV_t], [att_simp_add])])+ , (mk_binding "FMV_conv", [([FMV_t], [att_simp_add])])+ , (mk_binding "FAV_conv", [([FAV_t], [att_simp_add])])+ ]+ (* restore original annotated definitions *)+ |>> K ann_defs+ end++(* defines the constants needed for a rolestep and setups the associated+ theorems using setup_rolestep+*)+fun define_rolestep_cmd prefix srcs (stepty, lbl, msg) lthy =+ let+ val lbl_str = HOLogic.dest_string lbl;++ val step_name = prefix ^ "_" ^ lbl_str;+ val step_const_bind = Binding.name step_name;+ val step_def_bind = (Binding.suffix_name "_def" step_const_bind, srcs);++ val msg_name = step_name ^ "_pt";+ val msg_const_bind = Binding.name msg_name;+ val msg_def_bind = (Binding.suffix_name "_def" msg_const_bind, srcs);+ val msg_def_eq = Logic.mk_equals (Free (msg_name, @{typ pattern}), msg);+ in+ lthy+ |> Specification.definition + ( SOME (msg_const_bind, SOME @{typ pattern}, NoSyn)+ , (msg_def_bind, msg_def_eq) )+ |-> (fn (msg_const, (_, msg_def)) =>+ Specification.definition+ ( SOME (step_const_bind, SOME @{typ rolestep}, NoSyn)+ , ( step_def_bind+ , Logic.mk_equals (Free (step_name, @{typ rolestep}), + mk_rolestep (stepty, lbl, msg_const))+ ) + )+ #>> (fn (step_const, (_, step_def)) =>+ ((msg_const, msg_def), (step_const, step_def))+ )+ )+ |-> setup_rolestep (fn n => (Binding.qualify true step_name (Binding.name n), srcs))+ end++(* proves and notes all theorems associated to a role *)+fun setup_role mk_binding (defs as ((role_const, role_def), steps)) ctxt =+ let+ val in_set_t = HOLogic.mk_mem (@{term "step :: rolestep"}, + @{term "set :: role => rolestep set"} $ role_const);+ val zip_t = + @{term "zip :: role => 'a list => (rolestep * 'a) list"}+ $ role_const $ @{term "xs :: 'a list"}+ val splits_t =+ @{term "splits :: role => (role * role) list"} $ role_const++ val pat_defs = map (snd o fst) steps;+ val step_defs = map (snd o snd) steps;+ val step_consts = map (fst o snd) steps;++ val ss_role = Simplifier.simpset_of ctxt addsimps [role_def, + @{thm prefixClose_def}, @{thm weakly_atomic_def}];+ val ss_full = ss_role addsimps (pat_defs @ step_defs @+ @{thms wf_role_def distinct_list_def wf_role_axioms_def});++ val simp_tactic = K (FIRSTGOAL (Simplifier.full_simp_tac ss_full));++ val distinct_steps_thms = prove_distinctness ctxt simp_tactic step_consts;++ val wf_goal = HOLogic.mk_Trueprop (@{const wf_role} $ role_const);++ val avars_t = @{const aVars}$ role_const;++ val lastComStep_t = @{const lastComStep} $ role_const;+ val firstComStep_t = @{const firstComStep} $ role_const;++ val ss_prefixClose = ss_role addsimps distinct_steps_thms;++ fun mk_prefixClose_thm step_def =+ let+ val step = step_def |> Thm.prop_of |> dest_HOL_def |> #1;+ val t = @{const prefixClose} $ (Free ("s", @{typ store})) $+ (Free ("t", @{typ explicit_trace})) $+ role_const $ step $ (Free ("i", @{typ tid}));+ in expand_term ss_prefixClose t end++ fun pat_def_msgvars pat_def =+ pat_def |> Thm.prop_of |> dest_HOL_def |> #2 |> pat_msgvars;++ val msgvars = Library.foldl + (fn (vs,def) => OrdList.union fast_string_ord vs (pat_def_msgvars def)) + ([],pat_defs);++ fun mk_weakly_atomic_thm v = expand_term ss_role+ ( @{const weakly_atomic} $ HOLogic.mk_tuple [role_const, HOLogic.mk_string v] );+ in+ ctxt+ (* unfold theorems *)+ |> #2 o Local_Theory.note (mk_binding "unfold", role_def :: step_defs @ pat_defs)+ (* wellformed role *) + |> #2 o notes_proven simp_tactic+ [ (mk_binding "wf_role", [([wf_goal],[att_iff_add])]) ]+ (* distinct steps and prefixClose expansions *)+ |> #2 o Local_Theory.notes+ [ (mk_binding "distinct_steps", [(distinct_steps_thms,[att_iff_add])]) + , (mk_binding "prefixClose_convs", + [(map mk_prefixClose_thm step_defs, [att_iff_add])])+ , (mk_binding "weakly_atomic_convs", + [(map mk_weakly_atomic_thm msgvars, [att_iff_add])])+ ]+ (* expansions *) + |> notes_expansion ss_role+ [ (mk_binding "in_set_conv", [([in_set_t],[att_iff_add])])+ , (mk_binding "zip_conv", [([zip_t],[att_simp_add])])+ , (mk_binding "splits_conv", [([splits_t],[att_simp_add])])+ , (mk_binding "avars_conv", [([avars_t],[att_simp_add])])+ , (mk_binding "lastComStep_conv", [([lastComStep_t],[att_simp_add])])+ , (mk_binding "firstComStep_conv", [([firstComStep_t],[att_simp_add])])+ ]+ (* restore definitions *)+ |>> K defs+ end++(* defines a role and setups all associated theorems using setup_role *)+fun define_role_cmd (raw_bind, raw_spec as ((_,srcs),_)) params_ctxt =+ let+ val (([((_,role_ty),_)],[(role_def_bind, role_eq)]), _) =+ Specification.read_free_spec [(raw_bind, SOME "Protocol.role", NoSyn)] + [raw_spec] params_ctxt;+ val steps = role_eq |> dest_HOL_def |> #2 |> dest_role;++ fun mk_definition ann_step_defs =+ let+ val role_eq = Logic.mk_equals (role_eq |> dest_HOL_def |> #1,+ HOLogic.mk_list @{typ rolestep} (map (fst o snd) ann_step_defs));+ in+ Specification.definition + ( SOME (raw_bind, SOME role_ty, NoSyn)+ , (role_def_bind, role_eq) )+ #>> (fn (role_const,(_,role_def)) => ((role_const,role_def),ann_step_defs))+ end++ val prefix = Binding.name_of raw_bind;+ fun mk_rel_binding name = (Binding.qualify true prefix (Binding.name name), srcs);+ in+ params_ctxt+ |> fold_map (define_rolestep_cmd prefix srcs) steps+ |-> mk_definition+ |-> setup_role mk_rel_binding+ end++(* registering the role definition command as an outer keyword *)+local structure P = OuterParse and K = OuterKeyword in++ val roledef_parser = + P.binding --| P.where_ -- (SpecParse.opt_thm_name ":" -- P.prop);++ val _ =+ OuterSyntax.local_theory "role" "security protocol role definition" + K.thy_decl (roledef_parser >> (fn spec => define_role_cmd spec #> snd));+end;+++(******************************************************************************+** Protocol Definitions+******************************************************************************)++(* proves and notes all theorems associated to a protocol definition *)+fun setup_proto mk_binding (ann_def as (proto_const, proto_def)) ctxt = + let+ val role_consts = proto_def |> Thm.prop_of + |> dest_HOL_def |> #2 |> HOLogic.dest_set;+ val role_unfolds = flat (map (get_unfold_thms ctxt) role_consts);++ val proto_ss = Simplifier.simpset_of ctxt addsimps + (proto_def :: @{thms wf_proto_def});+ val full_ss = proto_ss addsimps role_unfolds;++ fun simp_tactic ss = K (FIRSTGOAL (Simplifier.full_simp_tac ss));++ val wf_proto_thm = prove_prop ctxt (simp_tactic proto_ss)+ (HOLogic.mk_Trueprop (@{const wf_proto} $ proto_const));++ val distinct_roles_thms = + prove_distinctness ctxt (simp_tactic full_ss) role_consts;++ val in_set_t = HOLogic.mk_mem (@{term "R :: role"}, proto_const);++ in + ctxt + (* unfolds, distinct roles, and wf_proto *)+ |> #2 o Local_Theory.notes+ [ (mk_binding "unfold", [(proto_def :: role_unfolds, [])]) + , (mk_binding "distinct_roles", [(distinct_roles_thms,[att_iff_add])]) + , (mk_binding "wf_proto", [([wf_proto_thm], [att_iff_add])])+ ]+ (* expansions *) + |> #2 o notes_expansion proto_ss+ [ (mk_binding "in_set_conv", [([in_set_t],[att_iff_add])])+ ]+ (* restore annotated definition *)+ |> pair ann_def+ end;++fun define_proto_cmd (raw_bind, raw_spec as ((_,srcs),_)) params_ctxt =+ let+ val ((proto_const, (_, proto_def)), spec_ctxt) = params_ctxt + |> Specification.definition_cmd + (SOME (raw_bind, SOME "Protocol.proto", NoSyn), raw_spec);++ val proto_name = Binding.name_of raw_bind;+ fun mk_rel_binding name = + (Binding.qualify true proto_name (Binding.name name), srcs);+ in+ setup_proto mk_rel_binding (proto_const, proto_def) spec_ctxt+ |> apsnd (Local_Theory.theory (fn thy =>+ let+ val locale_b = Binding.name (proto_name ^ "_state");+ val _ = Output.writeln ("\nlocale\n " ^ (Binding.name_of locale_b));+ + (* HACK as I didn't know how to get a hand of the right constant *)+ val proto_t = Syntax.read_term_global thy proto_name;+ val (_,lthy) = + add_simple_locale locale_b "reachable_state" [SOME proto_t] thy;+ in+ lthy |> Local_Theory.exit_global+ end))+ end;++(* registering the protocol definition command *)+local structure P = OuterParse and K = OuterKeyword in+ val protodef_parser = + P.binding --| P.where_ -- (SpecParse.opt_thm_name ":" -- P.prop);+ val _ =+ OuterSyntax.local_theory "protocol" "security protocol definition" + K.thy_decl (protodef_parser >> (fn spec => define_proto_cmd spec #> #2));+end;+++(******************************************************************************+** Sources Case Name Computation+******************************************************************************)+++val unnamed_caseN = "unnamed"++(* Given a list of premises, it extracts the content of the first premise being+ a "case_name" hint.+*)+fun extract_case_name prems = + case Hints.gather_by_name "case_name" prems of+ (name :: _) => HOLogic.dest_string name+ | [] => raise TERM ("extract_case_name", prems);+++(* Given a list of case premises, it extracts the rolestep constant name+ whose specification message was the start for this case.+*)+fun extract_rolestep_name prems = + case Hints.gather_by_name "decrChainFrom" prems of+ (data :: _) => + (case HOLogic.strip_tuple data of+ (_ :: _ :: Const (step_name,_) :: _) => step_name+ | _ => raise TERM ("extract_rolestep_name", prems)+ )+ | _ => raise TERM ("extract_rolestep_name", prems)+++(* Name the variable constructors *)+fun var_name (Const (@{const_name "AVar"},_) $ i) = HOLogic.dest_string i+ | var_name (Const (@{const_name "MVar"},_) $ i) = HOLogic.dest_string i+ | var_name _ = "var"++(* Name the execution literal constructors *)+fun msg_lit_name (Const (@{const_name "ENonce"},_) $ n $ _) = HOLogic.dest_string n+ | msg_lit_name (Const (@{const_name "EConst"},_) $ c) = HOLogic.dest_string c+ | msg_lit_name _ = "lit";+++(* Name the pattern constructors *)+fun msg_name (Const (@{const_name "Enc"},_) $ _ $ _) = "enc"+ | msg_name (Const (@{const_name "Tup"},_) $ _ $ _) = "tup"+ | msg_name (Const (@{const_name "Hash"},_) $ _) = "hash"+ | msg_name (Const (@{const_name "K"},_) $ _ $ _) = "K"+ | msg_name (Const (@{const_name "PK"},_) $ _) = "PK"+ | msg_name (Const (@{const_name "SK"},_) $ _) = "SK"+ | msg_name (Const (@{const_name "Lit"},_) $ l) = msg_lit_name l+ | msg_name _ = "msg"+++(* extract all non-reflexive equalities,+ if there is a lhs with a substitution then use this name+ else use the name of the first rhs+*)+fun extract_msg_name prems =+ let+ val dest_msg_eq = dest_non_refl_eq @{typ execmsg};+ val subst_var = var_name o + #1 o #2 o dest_variable_store_lookup o + #1 o dest_msg_eq;+ val fixed_msg = msg_name o #2 o dest_msg_eq;++ val subst = try hd (ESPL_Utils.gather_props subst_var prems);+ val fixed = try hd (ESPL_Utils.gather_props fixed_msg prems);+ in+ if is_none subst andalso is_none fixed then + NONE+ else+ if subst = fixed then + SOME (the_default "" subst)+ else+ SOME (+ (the_default "" subst) ^+ (if is_some subst andalso is_some fixed then "_" else "") ^+ (the_default "" fixed)+ )+ end ++(* get the case name from a term representing an implication *)+fun get_case_name t =+ let+ val prems = Logic.strip_imp_prems (Term.strip_all_body t);+ in+ case try extract_case_name prems of+ SOME "decrypt" =>+ (let+ val step_name = extract_rolestep_name prems; + val opt_name = extract_msg_name prems;+ in+ (List.last (space_explode "." step_name)) ^+ (case opt_name of+ SOME m => "_" ^ m+ | NONE => "")+ end+ handle _ => "decrypt")+ | SOME name => name+ | NONE => unnamed_caseN+ end;++(* Compute the case names for the given theorem being a case distinction in+ eleminitation form gained from spezializing the knows_cases theorem. +*)+fun source_case_names th =+ th |> Thm.prop_of+ |> Logic.strip_imp_prems+ |> map get_case_name+ |> blank_zero_numbers (op =)+ |> map (append_optional_number "_")+++fun mk_case_name_hint thy name =+ Hints.mk_hint_thm thy "case_name" (HOLogic.mk_string name);++(* Insert the case names into a theorem *)+fun insert_case_names ctxt th =+ let+ val thy = ProofContext.theory_of ctxt;+ val cases = source_case_names th;+ val case_hint = Hints.mk_hint_thm thy "case_name" o HOLogic.mk_string o nth cases;+ fun ins_tac (_,i) = Method.insert_tac [case_hint (i-1)] i;+ in+ HOL_Ext.refine_rule ctxt + (K (ALLGOALS (Hints.remove_all_hints_tac THEN' SUBGOAL ins_tac))) th+ end+++(******************************************************************************+** Chain Rule Expansion+******************************************************************************)++(* FIXME: Not sure if there isn't some additional setup needed.+ For NamedThms it is..+*)++(* Storing the rules used for eliminating the type information *)+structure TypeElimRulesData = Generic_Data+(+ type T = Thm.thm list;+ val empty = [];+ val extend = I;+ fun merge (ths1, ths2) = distinct Thm.eq_thm (ths1 @ ths2)+);++val lookup_type_elim_rules = TypeElimRulesData.get o Context.Proof;+++(* Reorder the bound variables introduced by the expansion of a ticket.++ The argument is premise of the form !! x1..xn. A1 ==> ... An ==> B+ The result is a conversion justifying the permutation of x1...xn+ according to their left-to-right occurrence in the first equality + of the form++ s(MV v tid) = msg+*)+fun reorder_bound_conv ctxt ct = + let+ val t = Thm.term_of ct;+ val dest_subst_eq =+ apfst (dest_variable_store_lookup) o dest_non_refl_eq @{typ execmsg};+ in+ case + t |> Term.strip_all_body + |> Logic.strip_imp_prems+ |> ESPL_Utils.gather_props dest_subst_eq+ |> try hd+ of+ SOME ((_, (_, tidt)), rhst) => + let+ val n = length (Term.strip_all_vars t);+ val p = [] |> fold HOL_Ext.add_bound_list [tidt, rhst] + |> distinct (op =)+ |> map (fn i => n - i - 1);+ in+ HOL_Ext.forall_permute_conv ctxt p ct+ end+ | NONE => Conv.all_conv ct+ end;+++(* reorders the bound variables of the premises according to+ reorder_bound_conv+*)+fun reorder_bound_vars ctxt th =+ HOL_Ext.lift_ground_thm_mod ctxt+ (Conv.fconv_rule o + Conv.prems_conv (Thm.nprems_of th) o reorder_bound_conv)+ th;++(* Eliminates the remaining decryption chains starting from symbolically+ instantiated protocol variables using their type assertions.+*)+fun type_elim_tac ctxt ty_elim_ths = + let+ fun mk_elim_tac ty_elim_th =+ EVERY'+ [ etac ty_elim_th+ , assume_tac+ , TRY o full_simp_tac (simpset_of ctxt)+ , TRY o (REPEAT o etac @{thm conjE})+ , TRY o Orders.order_tac ctxt []+ ]+ in+ (FIRST' (map mk_elim_tac ty_elim_ths)) THEN'+ (TRY o Clasimp.clarsimp_tac (clasimpset_of ctxt))+ end;+++fun expand_knows_cases_tac ctxt ty_elim_ths =+ REPEAT_DETERM1 (+ FIRST [ safe_tac (claset_of ctxt)+ , CHANGED_PROP (TRYALL (full_simp_tac (simpset_of ctxt)))+ , CHANGED_PROP (TRYALL (type_elim_tac ctxt ty_elim_ths))+ ] + );++(* Convert a knows_cases theorem to its elimination form with+ all premises named with the corresponding case name.++ Optionally, changes to the given message term are traced.+*)+fun refine_knows_cases ctxt opt_msg_t case_th =+ let + (* don't track changes to first subgoal "m : knows t" *)+ fun mk_track_tac th (_,i) = Method.insert_tac [th] i;++ val ((track_tac, untrack), ctxt') = + case opt_msg_t of+ SOME msg_t => apfst (apfst mk_track_tac) + (HOL_Ext.track_HOL_term ctxt msg_t)+ | NONE => ((K all_tac, I), ctxt);++ val ty_elim_ths = lookup_type_elim_rules ctxt';++ fun tac lthy = + (ALLGOALS (SUBGOAL track_tac) THEN + expand_knows_cases_tac lthy ty_elim_ths);+ in+ HOL_Ext.refine_rule ctxt' tac case_th+ |> untrack+ |> insert_case_names ctxt+ |> reorder_bound_vars ctxt+ end;+++(* A more convenient interface to refine_knows_cases++ FIXME: Why can't it be merged with refine_knows_cases?+*)+fun prepare_sources_elim ctxt case_th msg_t =+ let+ val lthy = Variable.auto_fixes msg_t ctxt;++ val knows_ct = + HOLogic.mk_mem (msg_t, @{term "knows t"})+ |> HOLogic.mk_Trueprop+ |> Thm.cterm_of (ProofContext.theory_of lthy);++ val knows_th = Thm.assume knows_ct;+ in + (knows_th RS case_th)+ |> HOL_Ext.make_HOL_elim+ |> refine_knows_cases lthy (SOME msg_t)+ |> Thm.implies_intr knows_ct+ |> singleton (ProofContext.export lthy ctxt) + |> Drule.zero_var_indexes+ end;+++(*** Precomputing and storing chain rule expansion in the actual theory ***)++structure KnowsCasesCache = Named_Thms+ (val name ="knows_cases_cache"+ val description = "Cache of protocol and message specific specializations of the knows_cases theorem")++(* shorthand for attributes modifying the knowledge cases *)+val att_knows_cases_cache_add = Attrib.internal (K KnowsCasesCache.add);+val att_knows_cases_cache_del = Attrib.internal (K KnowsCasesCache.del);++(* Precompute and register the standard chain rule expansions +*)+fun precompute_source_elim_rules case_th ctxt =+ let+ val _ = Output.writeln "\n precomputed sources for:"++ fun precompute (msg_t, desc) = + let+ val b = Binding.name ("knows_cases_" ^ desc)+ val _ = Output.writeln (" " ^ Binding.name_of b);+ in+ (b, prepare_sources_elim ctxt case_th msg_t)+ end;++ val prec_ths = Par_List.map precompute+ [ (@{term "LN n i :: execmsg"}, "Nonce")+ , (@{term "Hash m :: execmsg"}, "Hash")+ , (@{term "Enc m k :: execmsg"}, "Enc")+ , (@{term "SK a :: execmsg"}, "SK")+ , (@{term "K a b :: execmsg"}, "K")+ , (@{term "KShr A :: execmsg"}, "KShr")+ ] ++ fun prep_note (b,th) = ((b,[]),[([th],[att_knows_cases_cache_add])]);+ in+ ctxt+(* |> Local_Theory.target (add_sources_rules (map snd prec_ths)) *)+ |> Local_Theory.notes (map prep_note prec_ths)+ end;+++(******************************************************************************+** Type Invariant Definitions+******************************************************************************)++(* Check if a definition reads like: def = weakly_atomic *)+val is_weakly_atomic_typing = + the_default false o try + (curry (op =) @{const weakly_atomic} o + #2 o ESPL_Utils.dest_HOL_def o Thm.prop_of);++(* Destruct a mk_typing constructor *)+fun dest_mk_typing (Const (@{const_name mk_typing},_) $ typ) = + typ |> HOLogic.dest_list |> map HOLogic.dest_prod+ | dest_mk_typing t = raise TERM ("dest_mk_typing", [t]);++(* proves and notes all the theorems associated to a typing *)+fun setup_typing mk_binding ann_def ctxt =+ let+ val (typ_const,typ_def) = ann_def;++ val cs = Classical.claset_of ctxt;+ val ss = Simplifier.simpset_of ctxt + addsimps [typ_def];+ val ss_full = ss addsimps @{thms mk_typing_def};+ + val vars = typ_def |> Thm.prop_of + |> ESPL_Utils.dest_HOL_def |> snd |> dest_mk_typing |> map fst;++ val typ_calls = map (curry (op $) typ_const) vars;++ val mono_typ_th = (@{const monoTyp} $ typ_const)+ |> HOLogic.mk_Trueprop+ |> Thm.cterm_of (ProofContext.theory_of ctxt)+ |> (fn ct => Goal.prove_internal [] ct+ (K (auto_tac (cs, ss)))+ );+ in+ ctxt+ (* expansions for 'calling' the typing with defined variable *)+ |> #2 o ESPL_Utils.notes_expansion ss_full+ [ (mk_binding "defined_vars", [(typ_calls, [att_iff_add])]) ]+ (* monotonicity theorem *)+ |> Local_Theory.note (mk_binding "monoTyp", [mono_typ_th])+ (* restore original annotated definition *)+ |>> K ann_def + end;++(* Defines and setups a typing defined using 'mk_typing'. *)+fun define_typing_cmd ((b,proto_name), ((att,srcs),raw_def)) params_ctxt =+ let+ fun mk_rel_binding name = + (Binding.qualify true (Binding.name_of b) (Binding.name name), srcs);++ val ((typ_const, (_, typ_def)), spec_ctxt) = params_ctxt + |> Specification.definition_cmd + (SOME (b, SOME "WeakTyping.typing", NoSyn)+ , ((att,srcs), raw_def));+ in+ if is_weakly_atomic_typing typ_def then+ ( (typ_const, typ_def)+ , spec_ctxt+ |> Local_Theory.notes + [( mk_rel_binding "unfold_def"+ , [([typ_def], [ESPL_Utils.att_simp_add])]+ )]+ |> #2+ )+ else + setup_typing mk_rel_binding (typ_const, typ_def) spec_ctxt+ end;++(* Add the locale corresponding to the type invariant being defined +*)+fun add_type_invariant_locale (b,(typ_t, proto_t)) =+ add_simple_locale b "typed_state" + [SOME proto_t, NONE, NONE, NONE, SOME typ_t];++(* Defines and setups a typing as well as its corresponding + chain rule expansions.+*)+fun type_invariant_cmd (spec as ((typing_b,proto_name),_)) lthy =+ lthy+ |> #2 o define_typing_cmd spec+ |> Local_Theory.theory (fn thy =>+ let+ val typ_name = Binding.name_of typing_b;+ val typ_t = Syntax.read_term_global thy typ_name;+ val proto_t = Syntax.read_term_global thy proto_name;+ val locale_b = Binding.name (typ_name ^ "_state");+ val _ = Output.writeln ("\nlocale\n " ^ (Binding.name_of locale_b));++ val (_,lthy) = + add_type_invariant_locale (locale_b, (typ_t, proto_t)) thy;+ val case_th = ProofContext.get_thm lthy "knows_cases";+ in+ lthy+ |> #2 o precompute_source_elim_rules case_th+ |> Local_Theory.exit_global + end+ );++(* register the type invariant definition command *)+local structure P = OuterParse and K = OuterKeyword in+ val for_proto = P.$$$ "for" |-- P.term;++ val type_invariant_parser = + P.binding -- for_proto --| P.where_ -- (SpecParse.opt_thm_name ":" -- P.prop);+ val _ =+ OuterSyntax.local_theory "type_invariant" "type invariant definition" + K.thy_decl (type_invariant_parser >> type_invariant_cmd);+end;++end;
@@ -0,0 +1,285 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+(* Attributes and proof methods supporting decryption chain reasoning.+ Side effect: Registers the "prefix_close" and "note_prefix_closed" commands. *)++signature ESPL_METHODS =+sig+ (* "sources" proof method *)+ val sources_tac+ : Proof.context -> bool -> term ->+ thm option -> thm list -> int -> thm -> (cases * thm) Seq.seq+ val sourcesP+ : Context.generic * OuterLex.token list ->+ ((bool * term) * thm option) * (Context.generic * OuterLex.token list)++ (* "prefix_close" proof state transformation *)+ val prefix_close_thms: Proof.context -> thm list -> thm list+ val prefix_close_cmd: Proof.state -> Proof.state+ val note_prefix_closed_cmd: Proof.state -> Proof.state++ (* "completeness_cases_rule" attribute *)+ val completeness_cases_attrib: Context.generic -> thm -> thm+end;++structure ESPL_Methods: ESPL_METHODS =+struct++open ESPL_Utils;++++(******************************************************************************+** "sources" proof method+******************************************************************************)++(* Pretty print resolution failure *)+fun err_no_matching_rule ctxt raw_rules knows_thm =+ error (Pretty.string_of (Pretty.block (Pretty.fbreaks+ [ Pretty.str "none of the rules:"+ , Pretty.indent 2 (Display.pretty_thms ctxt raw_rules)+ , Pretty.str "resolved against:"+ , Pretty.indent 2 (Display.pretty_thm ctxt knows_thm)+ ])))++(* Remove trivial cases,+ insert known facts (except case names), and+ attach case names using Rule_Cases+ to a specialized knows_cases_XXX rule.+*)+fun finalize_knows_cases ctxt minimal facts case_th =+ let+ val is_hint_thm = + can (Hints.dest_hint o HOLogic.dest_Trueprop o Thm.prop_of);++ val facts' = filter (not o is_hint_thm) facts;+ val final_tac = ALLGOALS (+ (if minimal then + TRY o Simplifier.full_simp_tac (simpset_of ctxt)+ else+ TRY o Method.insert_tac facts' THEN'+ TRY o (+ Clasimp.clarsimp_tac (clasimpset_of ctxt) THEN'+ TRY o Orders.order_tac ctxt []+ )+ )+ );+ fun mk_Rule_Cases_cases th =+ Rule_Cases.get (Rule_Cases.name + (ESPL_Definitions.source_case_names th) th)+ in+ case_th+ |> HOL_Ext.refine_rule ctxt (K final_tac)+ |> ` mk_Rule_Cases_cases+ end;++(* The tactic underlying the "sources" proof method *)+fun sources_tac ctxt minimal msg_t opt_raw_rule facts =+ let+ val thy = ProofContext.theory_of ctxt;+ val cert = Thm.cterm_of thy;+ val css as (_, ss) = Clasimp.clasimpset_of ctxt;++ val raw_rules = case opt_raw_rule of+ SOME th => [th]+ | NONE => ESPL_Definitions.KnowsCasesCache.get ctxt;++ val _ =+ if null raw_rules then error "no source elimination rules given" else ();++ (* we assume the first premise of every rule is the knows predicate *)+ val knows_ct = + hd raw_rules+ |> Thm.prop_of+ |> hd o Logic.strip_imp_prems + |> HOLogic.dest_mem o HOLogic.dest_Trueprop+ |> apfst (K msg_t)+ |> HOLogic.mk_Trueprop o HOLogic.mk_mem+ |> cert;++ val predOrd_elim_ths = @{thms in_knows_predOrd1 in_knows_predOrd2}+ val knows_thm = + Goal.prove_internal [] knows_ct + (fn facts' => + ALLGOALS (Method.insert_tac (facts' @ facts)) THEN+ (ALLGOALS (assume_tac ORELSE' eresolve_tac predOrd_elim_ths)+ ORELSE auto_tac (css addIs2 predOrd_elim_ths))+ )+ |> simplify ss++ val (cases, rule) = + case get_first (try (curry (op RS) knows_thm)) raw_rules of+ NONE => err_no_matching_rule ctxt raw_rules knows_thm+ | SOME th => finalize_knows_cases ctxt minimal facts th+ in+ fn i => fn st =>+ CASES (Rule_Cases.make_common false (thy, Thm.prop_of rule) (fst cases)+ )+ (Tactic.rtac rule i) st+ end;++(* Parser for the sources proof method:++ BNF: sources["!"] term ["rule" thm]++ The ! means that a strict mode should be used, where the surrounding facts+ are not passed through automatically.++ The optional theorem can be used to state the rule for the case distinction+ explicitly.+*)+local+ structure P = OuterParse;+ val ruleN = "rule";+ val rule = Scan.lift (Args.$$$ ruleN -- Args.colon) |-- Attrib.thm;+ val opt_bang = Scan.lift (Scan.optional (P.$$$ "!" >> K true) false);+in+ val sourcesP = opt_bang -- Args.term -- Scan.option rule;+end;+++(******************************************************************************+** "prefix_close" proof state transformation+******************************************************************************)+++fun dest_roleMap_eq t = + case HOLogic.dest_eq t of+ (Const (@{const_name roleMap},_) $ r $ i, + Const (@{const_name Some},_) $ R) => (r, (i, R))+ | _ => raise TERM ("dest_roleMap_eq", [t])+ ++fun dest_in_steps t = + case HOLogic.dest_mem t of+ (estep, Const (@{const_name steps}, _) $ t) => + (case HOLogic.strip_tuple estep of+ i :: step :: _ => (i, step, t)+ | _ => raise TERM ("dest_MkStep_in_steps",[t]))+ | _ => raise TERM ("dest_MkStep_in_steps",[t])++fun split_conj_thm th =+ (split_conj_thm (th RS @{thm conjunct1}) @+ (split_conj_thm (th RS @{thm conjunct2}))) + handle THM _ => [th];++fun derive_step_thms th = map_filter (try (fn rule => th RS rule)) + @{thms in_steps_predOrd1 in_steps_predOrd2 steps_in_steps}+++(* NOTE: this works only correctly in the context of a reachable_state locale+ as the theorem ext_prefixClose is dependent on this locale.+*)+fun prefix_close_thms ctxt facts = + let+ val prefixClose_th = ProofContext.get_thm ctxt "ext_prefixClose";+ fun close step roleMap = [step, roleMap] MRS prefixClose_th;+ val expand = Simplifier.simplify (Simplifier.simpset_of ctxt);+ val distinct_prop = distinct (Thm.eq_thm);+ (* fun new_fact th = + forall (not_equal (Thm.prop_of th) o Thm.prop_of) facts; *)+ in+ facts+ |> maps split_conj_thm+ |> maps derive_step_thms+ |> distinct_prop+ |> maps (fn step_th => map_filter (try (close step_th)) facts)+ |> maps (split_conj_thm o expand)+ |> curry (op @) facts+ |> distinct_prop+ (* |> filter new_fact *)+ end;++(* Note all facts derivable from the given theorems using all rules from the+ decryption chain calculus except the chain rule+*)+fun note_prefix_closed_cmd state =+ let val ctxt = Proof.context_of state;+ val facts = Proof.the_facts state;+ val facts' = facts @ prefix_close_thms ctxt facts+ in Proof.put_facts (SOME facts') state end++(* A proof state transformation implementing prefix closing of+ the currently used facts.+*)+fun prefix_close_cmd state = + let+ val using = state + |> Proof.goal+ |> (fn {context = ctxt, facts=using, goal=_} => + prefix_close_thms ctxt using)++ in Proof.using_i [[(using,[])]] state end;++(* registering the prefix_close command *)+val _ =+ OuterSyntax.command "prefix_close" "prefix close facts being used"+ (OuterKeyword.tag_proof OuterKeyword.prf_decl)+ (Scan.succeed (Toplevel.print o (Toplevel.proof prefix_close_cmd)));+++(******************************************************************************+** "completeness_cases" attribute+******************************************************************************)++(* Extract the case name of the premise by checking for the corresponding hint *)+fun extract_completeness_case_name prems = + case Hints.gather_by_name "completenessCase" prems of+ (data :: _) => + (case HOLogic.strip_tuple data of+ (Const (step_name,_) :: v :: _) => + List.last (space_explode "." step_name) ^ "_" ^ HOLogic.dest_string v+ | _ => raise TERM ("extract_completeness_case_name", prems)+ )+ | [] => raise TERM ("extract_completeness_case_name", prems)+++(* Return the case names according to the hints *)+fun completeness_case_names th =+ let+ val extract = + extract_completeness_case_name o + Logic.strip_imp_prems o Term.strip_all_body;+ fun name_of prem = + case try extract prem of+ SOME name => name+ | NONE => ESPL_Definitions.unnamed_caseN+ in+ th + |> Thm.prop_of+ |> Logic.strip_imp_prems+ |> map name_of+ |> blank_zero_numbers (op =)+ |> map (append_optional_number "_")+ end;++(* Convert the conclusion of a completeness induction rule into elimination+ form and name all the different cases according to the hints. +*)+fun completeness_cases_attrib ctxt th =+ let+ val cs = Classical.get_cs ctxt;+ val ss = (Context.cases Simplifier.global_simpset_of Simplifier.simpset_of ctxt)+ addsimps @{thms finite_setdiff_compute};+ fun add_case_info th = th+ |> Rule_Cases.add_consumes 0+ |> Rule_Cases.name (completeness_case_names th)++ in + th+ |> SINGLE (REPEAT (safe_tac cs THEN (TRYALL (full_simp_tac ss)))) + |> the+ |> add_case_info+ end++end
@@ -0,0 +1,200 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+(* Various utility functions for working with Pure, HOL, and ESPL related terms. *)++signature ESPL_UTILS =+sig+ (* ML specific functions *)+ val choose2: 'a list -> ('a * 'a) list+ val unique_numbers: int -> ('a * 'a -> bool) -> 'a list -> ('a * int) list+ val optional_numbers: ('a * 'a -> bool) -> 'a list -> ('a * int option) list+ val blank_zero_numbers: ('a * 'a -> bool) -> 'a list -> ('a * int option) list+ val append_optional_number: string -> string * int option -> string++ (* Pure specific functions *)+ val local_standard': thm -> thm+ val expand_term: simpset -> term -> thm+ val thms_to_simpset: Proof.context -> thm list -> simpset+ val prove_prop + : Proof.context -> ({prems: thm list, context: Proof.context} -> tactic) -> term -> thm+ val notes_expansion+ : simpset -> (Attrib.binding * (term list * Args.src list) list) list ->+ local_theory -> (string * thm list) list * local_theory+ val note_expansion+ : simpset -> Attrib.binding * term list -> + local_theory -> (string * thm list) * local_theory+ val notes_proven+ : ({prems: thm list, context: Proof.context} -> tactic) ->+ (Attrib.binding * (term list * Args.src list) list) list ->+ Proof.context -> (string * thm list) list * local_theory+ val note_proven+ : ({prems: thm list, context: Proof.context} -> tactic) ->+ Attrib.binding * term list ->+ Proof.context -> (string * thm list) * local_theory+ val add_simple_locale+ : binding -> xstring -> term option list -> theory -> string * local_theory+ val add_simple_locale_cmd+ : binding ->+ xstring -> term option list -> Toplevel.transition -> Toplevel.transition++ (* HOL specific functions *)+ val gather_props: (term -> 'a) -> term list -> 'a list+ val dest_HOL_def: term -> term * term+ val symmetric_HOL_def: thm -> thm+ val prove_distinctness: + Proof.context -> ({prems: thm list, context: Proof.context} -> tactic) -> term list -> thm list+ val att_iff_add: Args.src+ val att_simp_add: Args.src+end;++structure ESPL_Utils: ESPL_UTILS =+struct++(******************************************************************************+** ML specific functions+******************************************************************************)++(* all possibilities to choose two elements out of a list *)+fun choose2 [] = []+ | choose2 (x::xs) = map (pair x) xs @ choose2 xs++(* adds numbers to a list of possibly dupliate names such that each of the+ duplicate name gets its own number.+*)+fun unique_numbers start eq (names : 'a list) = + let fun add_number (numbered, name) = + case AList.lookup eq numbered name of+ SOME i => + ((name, i+1) :: numbered)+ | NONE => + ((name, start) :: numbered)+ in rev (Library.foldl add_number ([],names)) end;++(* like unique numbers but doesn't assign a number to non-duplicate names *)+fun optional_numbers eq =+ let+ fun mk_optional [] = []+ | mk_optional ((n,i)::xs) = + (n, if (i > 1) orelse (exists (curry eq n o fst) xs) then SOME i else NONE) + :: mk_optional xs+ in mk_optional o unique_numbers 1 eq end;++(* like unique numbers, but blanks out the first occurrences of an element*)+fun blank_zero_numbers eq =+ let fun blank (n,i) = if (equal i 0) then (n,NONE) else (n,SOME i)+ in map blank o unique_numbers 0 eq end;++(* appends an optional number using the given separator *)+fun append_optional_number _ (n,NONE) = n+ | append_optional_number sep (n,SOME i) = n ^ sep ^ string_of_int i+++(******************************************************************************+** Pure specific functions+******************************************************************************)++(* An adaption of Drule.standard' such that hypotheses are not 'taken down' as+ premises +*)+val local_standard' =+ forall_intr_frees+ #> `Thm.maxidx_of+ #-> (fn maxidx =>+ Thm.forall_elim_vars (maxidx + 1)+ #> Thm.strip_shyps+ #> zero_var_indexes+ #> Thm.varifyT);++(* Generate the theorem proving the expansion of a term wrto to the given+ simpset and convert it into a rule.+*)+fun expand_term ss t = t+ |> Thm.cterm_of (ProofContext.theory_of (MetaSimplifier.the_context ss))+ |> Simplifier.rewrite ss+ |> (fn conv => conv RS @{thm meta_eq_to_obj_eq}) + |> local_standard'++(* Prove the validity of a proposition with a given tactic. *)+fun prove_prop ctxt mk_tactic goal = Goal.prove ctxt [] [] goal mk_tactic;++(* create a simpset consisting only of the given theorems in the given context *)+fun thms_to_simpset ctxt ths = + Simplifier.context ctxt (MetaSimplifier.empty_ss addsimps ths);++(* Expand a list of terms and note the resulting theorems. *)+fun notes_expansion ss to_expand = + Local_Theory.notes (map (apsnd (map (apfst (map (expand_term ss))))) to_expand);++(* Expand a term and note the resulting theorem. *)+fun note_expansion ss (a, ts) = + notes_expansion ss [(a, [(ts, [])])] #>> the_single;++(* Prove a list of propositions and note the resulting theorems *)+fun notes_proven mk_tactic to_prove ctxt = + Local_Theory.notes + (map (apsnd (map (apfst (map (prove_prop ctxt mk_tactic))))) to_prove) + ctxt;++(* Prove a proposition and note the resulting theorem *)+fun note_proven mk_tactic (a, ts) = + notes_proven mk_tactic [(a, [(ts, [])])] #>> the_single;+++(* A simplified version of the Expression.add_locale command for+ emulating the Isar script "locale b = loc_name inst" where+ inst is a positional instantiation.+*)+fun add_simple_locale b loc_name inst thy =+ Expression.add_locale b (Binding.empty)+ ( [ ( Locale.intern thy loc_name+ , ( ("",false)+ , Expression.Positional inst+ )+ )+ ]+ , [] )+ []+ thy;++fun add_simple_locale_cmd b loc_name inst =+ Toplevel.begin_local_theory false (#2 o add_simple_locale b loc_name inst);+++(******************************************************************************+** HOL specific functions+******************************************************************************)++(* Gathers proposition destructible using the given destructor *)+fun gather_props dest = map_filter (try (dest o HOLogic.dest_Trueprop))++(* destruct a HOL definition; i.e. either "lhs == rhs" or "lhs = rhs" *)+fun dest_HOL_def t = + (t |> HOLogic.dest_Trueprop |> HOLogic.dest_eq)+ handle TERM _ => Logic.dest_equals t++(* returns the symmetric variant of a Pure or HOL equality *)+fun symmetric_HOL_def th = + Thm.symmetric th+ handle THM ("symmetric", _, _) => th RS sym |> Drule.zero_var_indexes++(* Proves the distinctness of all non-reflexive pairs of the list of terms+ using the given tactic.+*)+fun prove_distinctness ctxt mk_tactic ts =+ let fun mk_ineqs (t1,t2) = + let val th = prove_prop ctxt mk_tactic + (HOLogic.mk_Trueprop (HOLogic.mk_not( HOLogic.mk_eq (t1,t2))))+ in [th, th RS @{thm not_sym}] end+ in flat (map mk_ineqs (choose2 ts)) end++(* shorthands for common attributes *)+val att_iff_add = Attrib.internal (K Clasimp.iff_add)+val att_simp_add = Attrib.internal (K Simplifier.simp_add)++end;
@@ -0,0 +1,45 @@+(* + NOTE: This file takes quite some time to load due+ to the large number of examples included.+*)+theory Technical_Report+imports+(* Preliminaries *)++ "ESPLogic/DistinctList"+ "ESPLogic/HOL_ext"+ "ESPLogic/Hints"+++(* Standard Security Protocol Model *)++ "ESPLogic/Protocol"++ "ESPLogic/ExecMessage"+ (* "ESPLogic/Subst" *)+ (* "ESPLogic/StandardModel" -- not yet adapted to new explicit model *)++(* Security Proof Construction *)++ "ESPLogic/ExplicitModel"+ "ESPLogic/InferenceRules"+ "ESPLogic/WeakTyping"+ "ESPLogic/Capabilities"++ "ESPLogic/Syntax"+ "ESPLogic/Automation"++ "ESPLogic"+ "Tutorial"+(* Case Studies *)++ "compromising_adversaries/All_Examples" +begin++(* The purpose of this file is to load all stable theories in order+ to generate the technical report detailing the results of the theories.+*)++end++
@@ -0,0 +1,295 @@+theory Tutorial+imports+ ESPLogic+begin++chapter{* A Short Tutorial on the Theories *}++text{*+ Here, we explain the differences to the presentation given in+ the submitted paper. Furthermore, we illustrate the usage of+ the Isabelle theories on the running example of the paper.++ There are two syntaxes for specifying patterns and + messages. For one there is the syntax given by their construction+ as algebraic datatypes. This syntax is used for specifying and+ proving inference rules and all the other infrastructure. Then,+ in the theory Syntax, we define an alternative syntax which+ is used for the definition of actual protocols and their proofs.+ We introduce this additional syntax because otherwise to shorten+ the representation of patterns and messages.+ + The following example pattern represents the first+ message of the client role of the CR protocol in the paper.+*}++definition somePt :: pattern+where "somePt = PEnc (PFresh ''n'') (PAsymPK (PVar (AVar ''s'')))"++text{*+ The atomic sets $\textit{Const}$, $\textit{Fresh}$, and $\textit{Var}$ + from the paper, are represented explicitely using the constructors+ @{const PConst}, @{const PFresh}, @{const PVar}. The injection of +*}+++lemma inst_example: + "inst \<sigma> i somePt = Some (Enc (LN ''n'' i) (PK (\<sigma>(AV ''s'' i))))"+ unfolding somePt_def by simp++text{*+ Roles and protocols are modeled according to the types+ given in the paper. However, the assumptions about+ duplicate-freeness and no sending of message variables+ before receiving them is handled using the following+ two locales.+*}++print_locale wf_role+print_locale wf_proto++text{*+ Roles are defined using the custom ``role'' command.++ \begin{quote}\bf+ If this command doesn't work for you (outer syntax error),+ then you forgot to replace the ``isar-keywords.el'' file.+ Check the README file for instructions.+ \end{quote}++ The benefit of these commands is that they prove a number+ of simple theorems which are later used for automation. Typical+ things include distinctness of role steps in a role and no+ sending of non-received message variables. ++ Here, the running example from the paper. (Due to a name-clash+ with existing constants, we call the $C$ role client and + the $S$ role server.+*}++role client+where "client =+ [ Send ''1'' (PEnc (sLN ''k'') (sPK ''s''))+ , Recv ''2'' (PHash (sLN ''k''))+ ]"++thm client.unfold+thm client_1.sendStep_conv++role server+where "server =+ [ Recv ''1'' (PEnc (sLMV ''v'') (sPK ''s''))+ , Send ''2'' (PHash (sLMV ''v''))+ ]"++protocol CR+where "CR = {client,server}"++text{* + The role command also defines constants representing+ the individual role steps and their patterns. + They are labelled according+ to the label. Hence, labels must be distinct for these+ constants to be definable. For example @{const client_1} is+ the first role step of the @{const client} role. @{const client_1_pt} + is the pattern of this role step.++ The protocol definition command also introduces a locale CR\_state+ that provides a convenient way for proving theorems under+ the assumption that @{term "(t,r,s)"} is a reachable state.+ The construction is based on the+ function @{const reachable} (cf. ExecutionModel.thy).+ Most theorems are derived under the assumption that+ we are reasoning about a reachable state of some + protocol $P$. In Isabelle, we model this using the+ following locale.+*}++print_locale reachable_state++text{* We adapt notation a bit more to the paper.*}++abbreviation (in reachable_state) "th \<equiv> r"+abbreviation (in reachable_state) "tr \<equiv> t"+abbreviation (in reachable_state) "\<sigma> \<equiv> s"+abbreviation (in reachable_state) "role \<equiv> roleMap"++text{*+ Note that the naming convention is a bit different from+ the paper. The default reachable state is $(t,r,s)$ which+ corresponds to the reachable state $(tr,th,\<sigma>)$ in the+ paper.++ The functions @{const knows} and @{const steps} are defined+ as in the paper. The event order relation is modelled by+ the function @{const predOrd}. In the locale + reachable\_state it is abbreviated as $\prec$. The+ inference rules are derived in the theory InferenceRules.+ As an example, we show the chain rule.+*}++lemma (in reachable_state) chain_rule:+ assumes known: "m' \<in> knows t"+ shows+ "(m' \<in> IK0) \<or>+ (\<exists> m. m' = Hash m \<and> Ln m \<prec> Ln (Hash m)) \<or>+ (\<exists> m k. m' = Enc m k \<and> Ln m \<prec> Ln (Enc m k) \<and> Ln k \<prec> Ln (Enc m k)) \<or>+ (\<exists> x y. m' = Tup x y \<and> Ln x \<prec> Ln (Tup x y) \<and> Ln y \<prec> Ln (Tup x y)) \<or>+ (\<exists> i done todo skipped. r i = Some (done, todo, skipped) \<and> + (\<exists> l pt m. + Send l pt \<in> set done \<and> Some m = inst s i pt \<and> + decrChain [] t {St (i, Send l pt)} m m'+ )+ ) \<or>+ (\<exists> i done todo skipped. r i = Some (done, todo, skipped) \<and> + (\<exists> l ty pt m. + Note l ty pt \<in> set done \<and> Note l ty pt \<notin> skipped \<and> + Some m = inst s i pt \<and> + decrChain [] t {St (i, Note l ty pt)} m m'+ )+ ) \<or>+ (\<exists> a. m' = SK a \<and> LKR a \<prec> Ln m') \<or>+ (\<exists> a b. m' = K a b \<and> LKR a \<prec> Ln m') \<or>+ (\<exists> a b. m' = K a b \<and> LKR b \<prec> Ln m') \<or> + (\<exists> A. \<exists> a \<in> A. m' = KShr A \<and> LKR (Lit (EAgent a)) \<prec> Ln m')+ "+ using known by (rule knows_cases_raw)++text{*+ Note that learn events have to be represented explicitely.+ We are using the constructors @{const St} for step events+ and @{const Ln} for learn events. Basic learn events are+ marked with @{const Step} and @{const Learns}. The confusion+ with respect to the paper version comes from the desire+ to have short names.+*}++text{* + Weak atomicity is a special type invariant defined+ in the WeakTyping theory. We prove that every reachable state+ of the @{const CR} is also weakly atomic by specifying + the following type invariant.+*}+++type_invariant atomic_CR for CR+where "atomic_CR = weakly_atomic"++(* declare (in CR_state) event_predOrdI[intro] *)++sublocale CR_state \<subseteq> atomic_CR_state+proof -+ have "(tr, th, \<sigma>) \<in> approx weakly_atomic"+ proof(cases rule: reachable_in_approxI_ext+ [OF monoTyp_weakly_atomic, completeness_cases_rule])+ case (server_1_v tr th \<sigma> tid)+ then interpret state: atomic_CR_state tr th \<sigma>+ by unfold_locales auto+ show ?case using server_1_v+ by (sources "Enc (\<sigma> (MV ''v'' tid)) (PK (\<sigma> (AV ''s'' tid)))") + (auto intro: event_predOrdI)+ qed+ thus "atomic_CR_state tr th \<sigma>" by unfold_locales simp+qed++text{*+ We can now use the "sources" method to prove security+ properties for reachable states of the @{const CR} protocol.+*}++lemma (in CR_state) nonce_after_lkr:+ assumes asms: + "role th i = Some client"+ "LN ''k'' i \<in> knows tr"+ shows "LKR (\<sigma>(AV ''s'' i)) \<prec> Ln (LN ''k'' i)" (is "?lkrbef")+using asms+proof(sources "LN ''k'' i")+ case client_1_k+ thus "?thesis" by(sources "SK (\<sigma> (AV ''s'' i))") auto+thm noteStep_def+qed++lemma (in CR_state) client_k_secrecy:+ assumes asms:+ "role th i = Some client"+ "RLKR (\<sigma>(AV ''s'' i)) \<notin> reveals tr"+ shows "LN ''k'' i \<notin> knows tr"+using asms+by(auto dest!: nonce_after_lkr intro: compr_predOrdI)++lemma (in CR_state) client_k_secrecy_old:+ assumes asms:+ "role th i = Some client"+ "LN ''k'' i \<in> knows tr"+ "RLKR (\<sigma>(AV ''s'' i)) \<notin> reveals tr"+ shows "False"+using asms+proof(sources "LN ''k'' i")+ case client_1_k thus False by (sources "SK (\<sigma> (AV ''s'' i))") (auto intro: compr_predOrdI)+qed++lemma (in CR_state) client_nisynch:+ assumes asms: "(i, client_2) \<in> steps tr"+ "roleMap th i = Some client"+ and reveal_after: "\<sigma>(AV ''s'' i) \<in> lkreveals tr \<Longrightarrow> St (i, client_2) \<prec> LKR (\<sigma>(AV ''s'' i))"+ shows+ "\<exists> j. role th j = Some server \<and>+ \<sigma>(AV ''s'' i) = \<sigma>(AV ''s'' j) \<and>+ LN ''k'' i = s(MV ''v'' j) \<and>+ St(i, client_1) \<prec> St (j, server_1) \<and>+ St(j, server_2) \<prec> St (i, client_2)" (is "?syncWith")+proof -+ note_prefix_closed facts = asms+ thus ?thesis+ proof(sources! "Hash (LN ''k'' i)")+ case fake+ thus "?thesis" using facts and reveal_after + apply -+ apply(frule_tac x = "LN ''k'' i" in in_knows_predOrd1)++ apply(frule nonce_after_lkr)+ apply(assumption)+ apply(frule_tac x = "\<sigma> (AV ''s'' i)" in in_lkreveals_predOrd1)+ apply(simp)+ done+ next+ case (server_2_hash j)+ note facts_s2h = this + thus "?thesis" using facts and reveal_after + proof (sources! "Enc (\<sigma> (MV ''v'' j)) (PK (\<sigma> (AV ''s'' j)))")+ case fake + thus "?thesis" using facts and facts_s2h and reveal_after+ apply -+ apply(frule_tac x = "\<sigma> (MV ''v'' j)" in in_knows_predOrd1)+ apply(frule nonce_after_lkr)+ apply(simp)+ apply(frule in_lkreveals_predOrd1)+ apply(simp)+ done+ next + case client_1_enc thus "?thesis" using facts_s2h and facts and reveal_after by auto+ qed+ qed+qed + ++text{*+ Please note that the easiest way to construct machine-checked+ security proofs is to use the 'scyther-proof' tool, as described+ in the accompanying README file.++ The only exception are security proofs with respect to compromising+ adversaries, as described in Martin Schaub, ``Efficient Interactive+ Construction of Machine-Checked Protocol Security Proofs in the Context of+ Dynamically Compromising Adversaries''. Master Thesis. ETH Zurich, 2011.+ See the corresponding publication in the 'publications' directory and+ the corresponding examples in 'compromising_adversaries'.+*}+++end++++ +
@@ -0,0 +1,27 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)+theory All_Examples+imports+ "CR_paper_acm"+ "NS_Public_acm"+ "PFS_acm"+ "TLS_acm" + "wPFS_acm"+begin++text{* + Runs all examples that verify protocols against dynamically compromising+ adversaries.+*}++end
@@ -0,0 +1,595 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)++theory "CR_paper_acm"+imports+ "../ESPLogic"+begin++section{* CR Paper as testing ground for acm *}++subsection{* Protocol Specificiation *}++role C+where "C =+ [ + Note ''1'' State <| sN ''k'', sAV ''S'' |>+ , Send ''2'' ( PEnc ( sN ''k'' ) ( sPK ''S'' ) )+ , Note ''3'' State <| PHash ( sN ''k'' ), sAV ''S'' |>+ , Recv ''4'' ( PHash ( sN ''k'' ) )+ , Note ''5'' SessKey (sN ''k'')+ ]"++role S+where "S =+ [ Recv ''1'' ( PEnc ( sMV ''k'' ) ( sPK ''S'' ) )+ , Note ''2'' State <| sMV ''k'', sAV ''S'', PEnc ( sMV ''k'' ) ( sPK ''S'' ), PHash ( sMV ''k'' ) |>+ , Send ''3'' ( PHash ( sMV ''k'' ) )+ , Note ''4'' SessKey (sMV ''k'')+ ]"++protocol CR+where "CR = { C, S }"+++++(* TODO remove *)+declare (in CR_state) C_1_def[simp]+declare (in CR_state) C_3_def[simp]+declare (in CR_state) C_5_def[simp]+declare (in CR_state) S_2_def[simp]+declare (in CR_state) S_4_def[simp]++++subsection {* Typing Definition *}+type_invariant auto_msc_typing for CR+where "auto_msc_typing = mk_typing+ [ ((S, ''k''), (SumT (KnownT S_1) (NonceT C ''k'')))+ ]"+++sublocale CR_state < auto_msc_typing_state+proof -+ have "(t,r,s) : approx auto_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF auto_msc_typing.monoTyp, completeness_cases_rule])+ case (S_1_k t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc ( s(MV ''k'' tid0) ) ( PK ( s(AV ''S'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ qed+ thus "auto_msc_typing_state t r s" by unfold_locales auto+qed++subsection{* Partnering Definition *}++definition+ CR_trusted :: "partnering"+where+ "CR_trusted q = + Id \<union>+ mk_partnering C S {(sN ''k'' ,sMV ''k'',S_1),+ (sAV ''S'', sAV ''S'',S_1)} q \<union> + mk_partnering S C {(sMV ''k'', sN ''k'', C_2),+ (sAV ''S'', sAV ''S'', C_2)} q"++lemmas (in CR_state) CR_trusted_conv = + setEqImpTupleIn[OF CR_trusted_def, of _ _ "(t,r,s)", simplified]++lemmas (in CR_state) CR_trustedI[intro!] = CR_trusted_conv[THEN iffD2,simplified mk_partnering_conv,simplified]+++subsection{* Adversary Compromise Model Definitions *}++definition (in CR_state) ADVprod :: "tid \<Rightarrow> state set"+where+ "ADVprod i = acm {LKRprotected i {AVar ''S''}}"++locale CR_state_ADVprod = CR_state ++ fixes test :: tid+ assumes compromiseModel [simp,intro!]: "(t,r,s) \<in> ADVprod test"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVprod_def], simplified]+end++++definition (in CR_state) ADVint :: "tid \<Rightarrow> state set"+where + "ADVint i = acm {LKRothers i}"++locale CR_state_ADVint = CR_state ++ fixes test :: tid+ assumes compromiseModel [simp,intro!]: "(t,r,s) \<in> ADVint test"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVint_def], simplified]+end++++definition (in CR_state) ADVsessKey :: "tid \<Rightarrow> state set"+where+"ADVsessKey i = acm {SkR i CR_trusted}"++locale CR_state_ADVsessKey = CR_state ++ fixes test :: tid+ assumes compromiseModel [simp,intro!]: "(t,r,s) \<in> ADVsessKey test"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVsessKey_def], simplified]+end++++definition (in CR_state) ADVstate :: "tid \<Rightarrow> state set"+where+"ADVstate i = acm {StR i CR_trusted}"++locale CR_state_ADVstate = CR_state ++ fixes test :: tid+ assumes compromiseModel [simp,intro!]: "(t,r,s) \<in> ADVstate test"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVstate_def], simplified]+end+++definition (in CR_state) ADVcaC :: "tid \<Rightarrow> state set"+where+"ADVcaC i = acm {LKRactor i (AVar ''C'')}"++locale CR_state_ADVcaC = CR_state ++ fixes test :: tid+ assumes compromiseModel [simp,intro!]: "(t,r,s) \<in> ADVcaC test"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVcaC_def], simplified]+end++++definition (in CR_state) ADVall :: "tid \<Rightarrow> state set"+where+"ADVall i = acm {+ LKRactor i (AVar ''C''), + SkR i CR_trusted, + StR i CR_trusted, + LKRactor i (AVar ''C'') }"++locale CR_state_ADVall = CR_state ++ fixes test :: tid+ assumes compromiseModel [simp,intro!]: "(t,r,s) \<in> ADVall test"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVall_def], simplified]+end+++section{* Security Proofs *}++subsection{* Origin Proofs *}+lemma (in CR_state) C_k_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some C"+ shows+ "LN ''k'' test \<in> knows t \<longrightarrow>+ RLKR (s(AV ''S'' test)) \<in> reveals t\<or>+ (\<exists> j. (test,j) \<in> CR_trusted (t,r,s) \<and> RCompr SessKey j \<in> reveals t) \<or>+ (\<exists> j. (test,j) \<in> CR_trusted (t,r,s) \<and> RCompr State j \<in> reveals t) "+ (is "?knows \<longrightarrow> ?origins")+proof+ assume "?knows"+ thus "?origins" using facts+ proof (sources "LN ''k'' test")+ case C_1_k+ thus ?thesis+ by(auto intro: compr_predOrdI) + next+ case C_2_k+ thus ?thesis+ by (sources "SK (s (AV ''S'' test))") (auto intro: compr_predOrdI)+ next + case (S_2_k tid1')+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid1')))")+ case C_2_enc+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case (S_4_k tid')+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid')))")+ case C_2_enc+ thus ?thesis + by (fastsimp dest: compr_predOrdI)+ qed+ next+ case C_5_k+ thus ?thesis+ by (fastsimp dest: compr_predOrdI)+ qed+qed+++subsection{* Secrecy Proofs *}++lemma (in CR_state_ADVprod) C_k_secrecy_protected:+ assumes facts:+ "roleMap r test = Some C"+ "LN ''k'' test \<in> knows t"+ shows+ False+using facts+by(fastsimp dest: C_k_origin allowed_reveals)++lemma (in CR_state_ADVint) C_k_secrecy_others:+ assumes facts:+ "roleMap r test = Some C"+ "LN ''k'' test \<in> knows t"+ shows+ False+using facts+apply -+apply(frule C_k_origin, assumption)+by(auto dest: allowed_reveals)+++lemma (in CR_state_ADVsessKey) C_k_secrecy_sessKey:+ assumes facts:+ "roleMap r test = Some C"+ "LN ''k'' test \<in> knows t"+ shows+ False+using facts+apply -+apply(frule C_k_origin, assumption)+by(auto dest: allowed_reveals)+++lemma (in CR_state_ADVstate) C_k_secrecy_state:+ assumes facts:+ "roleMap r test = Some C"+ "LN ''k'' test \<in> knows t"+ shows+ False+using facts+apply -+apply(frule C_k_origin, assumption)+by(auto dest: allowed_reveals)+++lemma (in CR_state_ADVcaC) C_k_secrecy_actor:+ assumes facts:+ "roleMap r test = Some C"+ "LN ''k'' test \<in> knows t"+ shows+ False+using facts+apply -+apply(frule C_k_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in CR_state_ADVall) C_k_secrecy_all:+ assumes facts:+ "roleMap r test = Some C"+ "LN ''k'' test \<in> knows t"+ shows+ False+using facts+apply -+apply(frule C_k_origin, assumption)+by(auto dest: allowed_reveals)+++subsection{* Authentication Proofs *}++lemma (in CR_state_ADVprod) C_ni_synch_protected:+ assumes facts:+ "roleMap r test = Some C"+ "( test, C_4 ) \<in> steps t"+ shows+ "(\<exists> tid2.+ roleMap r tid2 = Some S \<and>+ s(AV ''S'' test) = s(AV ''S'' tid2) \<and>+ LN ''k'' test = s(MV ''k'' tid2) \<and>+ St( test, C_2 ) \<prec> St( tid2, S_1 ) \<and>+ St( tid2, S_1 ) \<prec> St( tid2, S_3 ) \<and>+ St( tid2, S_3 ) \<prec> St( test, C_4 ))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Hash ( LN ''k'' test )")+ case fake+ thus ?thesis + by(fastsimp dest: C_k_secrecy_protected intro: event_predOrdI)+ next+ case (S_3_hash tid2)+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid2)))")+ case C_2_enc+ thus ?thesis by force+ next+ case fake+ thus ?thesis+ by (fastsimp dest: C_k_secrecy_protected intro: event_predOrdI)+ qed+ next+ case C_3_hash+ thus ?thesis+ by(fastsimp dest: compr_predOrdI allowed_reveals)+ next+ case (S_2_hash tid2)+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid2)))")+ case fake+ thus ?thesis+ by (fastsimp dest: C_k_secrecy_protected intro: event_predOrdI)+ next+ case C_2_enc+ thus ?thesis+ by(fastsimp dest: compr_predOrdI allowed_reveals)+ qed+ qed+qed+++lemma (in CR_state_ADVint) C_ni_synch_others:+ assumes facts:+ "roleMap r test = Some C"+ "( test, C_4 ) \<in> steps t"+ shows+ "(\<exists> tid2.+ roleMap r tid2 = Some S \<and>+ s(AV ''S'' test) = s(AV ''S'' tid2) \<and>+ LN ''k'' test = s(MV ''k'' tid2) \<and>+ St( test, C_2 ) \<prec> St( tid2, S_1 ) \<and>+ St( tid2, S_1 ) \<prec> St( tid2, S_3 ) \<and>+ St( tid2, S_3 ) \<prec> St( test, C_4 ))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Hash ( LN ''k'' test )")+ case fake+ thus ?thesis + by(fastsimp dest: C_k_secrecy_others intro: event_predOrdI)+ next+ case (S_3_hash tid2)+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid2)))")+ case C_2_enc+ thus ?thesis by force+ next+ case fake+ thus ?thesis+ by (fastsimp dest: C_k_secrecy_others intro: event_predOrdI)+ qed+ next+ case C_3_hash+ thus ?thesis+ by(fastsimp dest: compr_predOrdI allowed_reveals)+ next+ case (S_2_hash tid2)+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid2)))")+ case fake+ thus ?thesis+ by (fastsimp dest: C_k_secrecy_others intro: event_predOrdI)+ next+ case C_2_enc+ thus ?thesis+ by(fastsimp dest: compr_predOrdI allowed_reveals)+ qed+ qed+qed++lemma (in CR_state_ADVsessKey) C_ni_synch_sessKey:+ assumes facts:+ "roleMap r test = Some C"+ "( test, C_4 ) \<in> steps t"+ shows+ "(\<exists> tid2.+ roleMap r tid2 = Some S \<and>+ s(AV ''S'' test) = s(AV ''S'' tid2) \<and>+ LN ''k'' test = s(MV ''k'' tid2) \<and>+ St( test, C_2 ) \<prec> St( tid2, S_1 ) \<and>+ St( tid2, S_1 ) \<prec> St( tid2, S_3 ) \<and>+ St( tid2, S_3 ) \<prec> St( test, C_4 ))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Hash ( LN ''k'' test )")+ case fake+ thus ?thesis + by(fastsimp dest: C_k_secrecy_sessKey intro: event_predOrdI)+ next+ case (S_3_hash tid2)+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid2)))")+ case C_2_enc+ thus ?thesis by force+ next+ case fake+ thus ?thesis+ by (fastsimp dest: C_k_secrecy_sessKey intro: event_predOrdI)+ qed+ next+ case C_3_hash+ thus ?thesis+ by(fastsimp dest: compr_predOrdI allowed_reveals)+ next+ case (S_2_hash tid2)+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid2)))")+ case fake+ thus ?thesis+ by (fastsimp dest: C_k_secrecy_sessKey intro: event_predOrdI)+ next+ case C_2_enc+ thus ?thesis+ by(fastsimp dest: compr_predOrdI allowed_reveals)+ qed+ qed+qed++lemma (in CR_state_ADVstate) C_ni_synch_state:+ assumes facts:+ "roleMap r test = Some C"+ "( test, C_4 ) \<in> steps t"+ shows+ "(\<exists> tid2.+ roleMap r tid2 = Some S \<and>+ s(AV ''S'' test) = s(AV ''S'' tid2) \<and>+ LN ''k'' test = s(MV ''k'' tid2) \<and>+ St( test, C_2 ) \<prec> St( tid2, S_1 ) \<and>+ St( tid2, S_1 ) \<prec> St( tid2, S_3 ) \<and>+ St( tid2, S_3 ) \<prec> St( test, C_4 ))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Hash ( LN ''k'' test )")+ case fake+ thus ?thesis + by(fastsimp dest: C_k_secrecy_state intro: event_predOrdI)+ next+ case (S_3_hash tid2)+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid2)))")+ case C_2_enc+ thus ?thesis by force+ next+ case fake+ thus ?thesis+ by (fastsimp dest: C_k_secrecy_state intro: event_predOrdI)+ qed+ next+ case C_3_hash+ thus ?thesis+ by(fastsimp dest: compr_predOrdI allowed_reveals)+ next+ case (S_2_hash tid2)+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid2)))")+ case fake+ thus ?thesis+ by (fastsimp dest: C_k_secrecy_state intro: event_predOrdI)+ next+ case C_2_enc+ thus ?thesis+ by(fastsimp dest: compr_predOrdI allowed_reveals)+ qed+ qed+qed++lemma (in CR_state_ADVcaC) C_ni_synch_actor:+ assumes facts:+ "roleMap r test = Some C"+ "( test, C_4 ) \<in> steps t"+ shows+ "(\<exists> tid2.+ roleMap r tid2 = Some S \<and>+ s(AV ''S'' test) = s(AV ''S'' tid2) \<and>+ LN ''k'' test = s(MV ''k'' tid2) \<and>+ St( test, C_2 ) \<prec> St( tid2, S_1 ) \<and>+ St( tid2, S_1 ) \<prec> St( tid2, S_3 ) \<and>+ St( tid2, S_3 ) \<prec> St( test, C_4 ))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Hash ( LN ''k'' test )")+ case fake+ thus ?thesis + by(fastsimp dest: C_k_secrecy_actor intro: event_predOrdI)+ next+ case (S_3_hash tid2)+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid2)))")+ case C_2_enc+ thus ?thesis by force+ next+ case fake+ thus ?thesis+ by (fastsimp dest: C_k_secrecy_actor intro: event_predOrdI)+ qed+ next+ case C_3_hash+ thus ?thesis+ by(fastsimp dest: compr_predOrdI allowed_reveals)+ next+ case (S_2_hash tid2)+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid2)))")+ case fake+ thus ?thesis+ by (fastsimp dest: C_k_secrecy_actor intro: event_predOrdI)+ next+ case C_2_enc+ thus ?thesis+ by(fastsimp dest: compr_predOrdI allowed_reveals)+ qed+ qed+qed++++lemma (in CR_state_ADVall) C_ni_synch_all:+ assumes facts:+ "roleMap r test = Some C"+ "( test, C_4 ) \<in> steps t"+ shows+ "(\<exists> tid2.+ roleMap r tid2 = Some S \<and>+ s(AV ''S'' test) = s(AV ''S'' tid2) \<and>+ LN ''k'' test = s(MV ''k'' tid2) \<and>+ St( test, C_2 ) \<prec> St( tid2, S_1 ) \<and>+ St( tid2, S_1 ) \<prec> St( tid2, S_3 ) \<and>+ St( tid2, S_3 ) \<prec> St( test, C_4 ))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Hash ( LN ''k'' test )")+ case fake+ thus ?thesis + by(fastsimp dest: C_k_secrecy_all intro: event_predOrdI)+ next+ case (S_3_hash tid2)+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid2)))")+ case C_2_enc+ thus ?thesis by force+ next+ case fake+ thus ?thesis+ by (fastsimp dest: C_k_secrecy_all intro: event_predOrdI)+ qed+ next+ case C_3_hash+ thus ?thesis+ by(fastsimp dest: compr_predOrdI allowed_reveals)+ next+ case (S_2_hash tid2)+ thus ?thesis+ proof(sources "Enc (LN ''k'' test) (PK (s (AV ''S'' tid2)))")+ case fake+ thus ?thesis+ by (fastsimp dest: C_k_secrecy_all intro: event_predOrdI)+ next+ case C_2_enc+ thus ?thesis+ by(fastsimp dest: compr_predOrdI allowed_reveals)+ qed+ qed+qed++end
@@ -0,0 +1,462 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)++theory "NS_Public_acm"+imports+ "../ESPLogic"+begin++section{* Security Proofs for a typed version of NSL *}++subsection{* Protocol Specificiation *}++role I+where "I =+ [ + Send ''1'' ( PEnc <| sC ''1'', sN ''ni'', sAV ''I'' |>+ ( sPK ''R'' ))++ , Recv ''2'' ( PEnc <| sC ''2'', sN ''ni'', sMV ''nr'', sAV ''R''+ |>+ ( sPK ''I'' ))+ , Send ''3'' ( PEnc <| sC ''3'', sMV ''nr'' |> ( sPK ''R'' ) )+ , Note ''4'' SessKey (PHash (<| sN ''ni'', sMV ''nr'' |>))+ ]"++role R+where "R =+ [+ Recv ''1'' ( PEnc <| sC ''1'', sMV ''ni'', sAV ''I'' |>+ ( sPK ''R'' ) )+ , Send ''2'' ( PEnc <| sC ''2'', sMV ''ni'', sN ''nr'', sAV ''R''+ |>+ ( sPK ''I'' ) )+ , Recv ''3'' ( PEnc <| sC ''3'', sN ''nr'' |> ( sPK ''R'' ))+ , Note ''4'' SessKey (PHash (<| sMV ''ni'', sN ''nr'' |>))+ ]"++protocol ns_public+where "ns_public = { I, R }"++(* TODO remove *)+declare (in ns_public_state) I_4_def[simp]+declare (in ns_public_state) R_4_def[simp]+++subsection {* Typing Definition *}+type_invariant auto_msc_typing for ns_public+where "auto_msc_typing = mk_typing+ [ ((R, ''ni''), (SumT (KnownT R_1) (NonceT I ''ni'')))+ , ((I, ''nr''), (SumT (KnownT I_2) (NonceT R ''nr'')))+ ]"++sublocale ns_public_state < auto_msc_typing_state+proof -+ have "(t,r,s) : approx auto_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF auto_msc_typing.monoTyp, completeness_cases_rule])+ case (I_2_nr t r s tid0) + note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''2'', LN ''ni'' tid0, s(MV ''nr'' tid0),+ s(AV ''R'' tid0)+ |}+ ( PK ( s(AV ''I'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (R_1_ni t r s tid0)+ note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''1'', s(MV ''ni'' tid0), s(AV ''I'' tid0) |}+ ( PK ( s(AV ''R'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ qed+ thus "auto_msc_typing_state t r s" by unfold_locales auto+qed++subsection{* Partnering Definition *}++definition+ ns_public_trusted :: "partnering"+where+ "ns_public_trusted q = + Id \<union>+ mk_partnering I R + {(sN ''ni'', sMV ''ni'', R_1),+ (sMV ''nr'', sN ''nr'', R_2),+ (sAV ''I'', sAV ''I'', R_1),+ (sAV ''R'', sAV ''R'', R_1)} q \<union> + mk_partnering R I + {(sMV ''ni'', sN ''ni'', I_1),+ (sN ''nr'', sMV ''nr'', I_2),+ (sAV ''I'', sAV ''I'', I_1),+ (sAV ''R'', sAV ''R'', I_1)} q"+++lemmas (in ns_public_state) ns_public_trusted_conv = + setEqImpTupleIn[OF ns_public_trusted_def, of _ _ "(t,r,s)", simplified]++lemmas (in ns_public_state) ns_public_trustedI[intro!] = ns_public_trusted_conv[THEN iffD2,simplified mk_partnering_conv,simplified]++subsection{* Adversary Compromise Model Definitions *}++definition (in ns_public_state) ADVall :: "tid \<Rightarrow> state set"+where+"ADVall i = acm {LKRothers i, StR i ns_public_trusted, SkR i ns_public_trusted, RNR}"++locale ns_public_state_ADVall = ns_public_state ++ fixes test :: tid+ assumes compromiseModel [simp,intro!]: "(t,r,s) \<in> ADVall test"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVall_def], simplified]+end++section{* Security Proofs *}++subsection{* Origin Proofs *}+lemma (in ns_public_state) I_ni_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some I"+ shows+ "LN ''ni'' test \<in> knows t \<longrightarrow>+ RLKR (s(AV ''I'' test)) \<in> reveals t \<or> + RLKR (s(AV ''R'' test)) \<in> reveals t"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume "?knows"+ note_prefix_closed facts = facts this+ thus ?origins+ proof(sources " LN ''ni'' test ")+ case I_1_ni thus ?thesis + by(sources "SK (s (AV ''R'' test))") (auto intro: compr_predOrdI)+ next+ case (R_2_ni tid1) + thus ?thesis+ proof(sources "Enc {| LC ''1'', LN ''ni'' test, s(AV ''I'' tid1) |} ( PK ( s(AV ''R'' tid1) ) ) ")+ case I_1_enc+ thus ?thesis+ by(sources "SK (s (AV ''I'' test))") (auto intro: compr_predOrdI)+ qed+ qed+qed++lemma (in ns_public_state) R_nr_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some R"+ shows+ "LN ''nr'' test \<in> knows t \<longrightarrow> + RLKR (s(AV ''I'' test)) \<in> reveals t \<or> + RLKR (s(AV ''R'' test)) \<in> reveals t"+ (is "?knows \<longrightarrow> ?origins")+proof + assume "?knows"+ thus "?origins" using facts+ proof(sources " LN ''nr'' test ")+ case (I_3_nr tid1)+ thus ?thesis+ proof(sources "Enc {| LC ''2'', LN ''ni'' tid1, LN ''nr'' test, s(AV ''R'' tid1) |}( PK ( s(AV ''I'' tid1) ) ) ")+ case R_2_enc+ thus ?thesis+ by(sources "SK (s (AV ''R'' tid1))") (auto intro: compr_predOrdI)+ qed+ next+ case R_2_nr+ thus ?thesis+ by(sources "SK (s (AV ''I'' test))") (auto intro: compr_predOrdI)+ qed+qed++lemma (in ns_public_state) I_nr_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some I"+ "( test, I_2) \<in> steps t"+ shows+ "s(MV ''nr'' test) \<in> knows t \<longrightarrow>+ RLKR (s(AV ''I'' test)) \<in> reveals t \<or> + RLKR (s(AV ''R'' test)) \<in> reveals t"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume "?knows"+ note_prefix_closed facts = facts this+ thus ?origins+ proof(sources + "Enc {| LC ''2'', LN ''ni'' test, s(MV ''nr'' test), s(AV ''R'' test)|} ( PK ( s(AV ''I'' test) ) ) ")+ case fake+ thus ?thesis+ by(fastsimp dest: I_ni_origin intro: event_predOrdI)+ next+ case (R_2_enc tid1')+ thus ?thesis+ by(auto dest: R_nr_origin intro: event_predOrdI) + qed+qed++lemma (in ns_public_state) R_ni_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some R"+ "( test, R_3 ) \<in> steps t"+ shows + "s(MV ''ni'' test) \<in> knows t \<longrightarrow> + RLKR (s(AV ''I'' test)) \<in> reveals t \<or>+ RLKR (s(AV ''R'' test)) \<in> reveals t"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume "?knows"+ note_prefix_closed facts = facts this+ thus "?origins" + proof(sources "Enc {| LC ''3'', LN ''nr'' test |} ( PK ( s(AV ''R'' test) ) ) ")+ case fake+ thus ?thesis + by (fastsimp dest: R_nr_origin intro: event_predOrdI)+ next+ case (I_3_enc tid1) + thus ?thesis+ proof(sources "Enc {| LC ''2'', LN ''ni'' tid1, LN ''nr'' test, s(AV ''R'' test)|}( PK ( s(AV ''I'' tid1) ) ) ")+ case fake + thus ?thesis+ by(fastsimp dest: R_nr_origin intro: event_predOrdI) + next+ case R_2_enc+ thus ?thesis + by (fastsimp dest: I_ni_origin intro: event_predOrdI) + qed+ qed+qed++lemma (in ns_public_state) I_sessKey_origin [rule_format]:+assumes facts:+ "roleMap r test = Some I"+ "( test, I_2 ) \<in> steps t"+ shows + "Hash \<lbrace> LN ''ni'' test, s(MV ''nr'' test) \<rbrace> \<in> knows t \<longrightarrow> + RLKR (s(AV ''I'' test)) \<in> reveals t \<or>+ RLKR (s(AV ''R'' test)) \<in> reveals t \<or> + (\<exists> tid1. (test,tid1) \<in> ns_public_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t)"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume "?knows"+ note_prefix_closed facts = facts this+ thus "?origins"+ proof(sources "Hash \<lbrace>LN ''ni'' test, s (MV ''nr'' test)\<rbrace>")+ case fake+ thus ?thesis+ by(fastsimp dest: I_ni_origin intro: event_predOrdI)+ next+ case I_4_hash+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case (R_4_hash tid1)+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''2'', LN ''ni'' test, LN ''nr'' tid1, s (AV ''R'' test)\<rbrace>+ (PK (s (AV ''I'' test)))")+ case fake+ thus ?thesis+ by(fastsimp dest: I_ni_origin intro: event_predOrdI)+ next+ case R_2_enc+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ qed+qed++lemma (in ns_public_state) R_sessKey_origin [rule_format]:+assumes facts:+ "roleMap r test = Some R"+ "( test, R_3 ) \<in> steps t"+ shows + "Hash \<lbrace> s(MV ''ni'' test), LN ''nr'' test \<rbrace> \<in> knows t \<longrightarrow> + RLKR (s(AV ''I'' test)) \<in> reveals t \<or>+ RLKR (s(AV ''R'' test)) \<in> reveals t \<or> + (\<exists> tid1. (test,tid1) \<in> ns_public_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t)"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume "?knows"+ note_prefix_closed facts = facts this+ thus "?origins"+ proof(sources "Hash \<lbrace>s (MV ''ni'' test), LN ''nr'' test\<rbrace>")+ case fake+ thus ?thesis+ by(fastsimp dest: R_nr_origin intro: event_predOrdI)+ next+ case R_4_hash+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case (I_4_hash tid1)+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''2'', LN ''ni'' tid1, LN ''nr'' test, s (AV ''R'' tid1)\<rbrace>+ (PK (s (AV ''I'' tid1)))")+ case fake+ thus ?thesis+ by(fastsimp dest: R_nr_origin intro: event_predOrdI)+ next+ case R_2_enc+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ qed+qed+++subsection{* Secrecy Proofs *}++lemma (in ns_public_state_ADVall) I_ni_secrecy:+ assumes facts:+ "roleMap r test = Some I"+ "LN ''ni'' test \<in> knows t"+ shows "False"+using facts+by(insert I_ni_origin, fastsimp dest!: allowed_reveals)++lemma (in ns_public_state_ADVall) R_nr_secrecy:+ assumes facts:+ "roleMap r test = Some R"+ "LN ''nr'' test \<in> knows t"+ shows "False"+using facts+by(insert R_nr_origin, fastsimp dest!: allowed_reveals)++lemma (in ns_public_state_ADVall) I_nr_secrecy:+ assumes facts:+ "roleMap r test = Some I"+ "( test, I_2 ) \<in> steps t"+ "s(MV ''nr'' test) \<in> knows t"+ shows "False"+using facts+by(insert I_nr_origin, fastsimp dest!: allowed_reveals)+++lemma (in ns_public_state_ADVall) R_ni_secrecy:+ assumes facts:+ "roleMap r test = Some R"+ "( test, R_3 ) \<in> steps t"+ "s(MV ''ni'' test) \<in> knows t"+ shows "False"+using facts+by(insert R_ni_origin, fastsimp dest!: allowed_reveals)++lemma (in ns_public_state_ADVall) I_sessKey_secrecy:+ assumes facts:+ "roleMap r test = Some I"+ "( test, I_2 ) \<in> steps t"+ "Hash \<lbrace> LN ''ni'' test, s(MV ''nr'' test) \<rbrace> \<in> knows t"+ shows "False"+using facts+apply - +apply(frule I_sessKey_origin, safe)+apply(drule allowed_reveals, clarsimp)++done++lemma (in ns_public_state_ADVall) R_sessKey_secrecy:+ assumes facts:+ "roleMap r test = Some R"+ "( test, R_3 ) \<in> steps t"+ "Hash \<lbrace> s(MV ''ni'' test), LN ''nr'' test \<rbrace> \<in> knows t"+ shows "False"+using facts+apply - +apply(frule R_sessKey_origin, safe)+apply(drule allowed_reveals, clarsimp)++done+++subsection{* Authentication Proofs *}++lemma (in ns_public_state_ADVall) I_ni_synch:+ assumes facts:+ "roleMap r test = Some I"+ "( test, I_3 ) \<in> steps t"+ shows+ "(? tid2.+ roleMap r tid2 = Some R &+ s(AV ''I'' test) = s(AV ''I'' tid2) &+ s(AV ''R'' test) = s(AV ''R'' tid2) &+ LN ''ni'' test = s(MV ''ni'' tid2) &+ s(MV ''nr'' test) = LN ''nr'' tid2 &+ St( test, I_1 ) \<prec> St( tid2, R_1 ) &+ St( tid2, R_1 ) \<prec> St( tid2, R_2 ) &+ St( tid2, R_2 ) \<prec> St( test, I_2 ) &+ St( test, I_2 ) \<prec> St( test, I_3 ))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Enc {| LC ''2'', LN ''ni'' test, s(MV ''nr'' test),s(AV ''R'' test)|}( PK ( s(AV ''I'' test) ) ) ")+ case fake+ thus ?thesis by (auto dest: I_ni_secrecy intro: event_predOrdI)+ next+ case (R_2_enc tid2) + thus ?thesis+ proof(sources "Enc {| LC ''1'', LN ''ni'' test, s(AV ''I'' test) |}( PK ( s(AV ''R'' test) ) ) ")+ case fake + thus ?thesis by (auto dest: I_ni_secrecy intro: event_predOrdI)+ next+ case I_1_enc+ thus ?thesis+ by(fastsimp)+ qed+ qed+qed++lemma (in ns_public_state_ADVall) R_ni_synch:+ assumes facts:+ "roleMap r test = Some R"+ "( test, R_3 ) \<in> steps t"+ shows+ "(? tid2.+ roleMap r tid2 = Some I &+ s(AV ''I'' test) = s(AV ''I'' tid2) &+ s(AV ''R'' test) = s(AV ''R'' tid2) &+ s(MV ''ni'' test) = LN ''ni'' tid2 &+ LN ''nr'' test = s(MV ''nr'' tid2) &+ St( tid2, I_1 ) \<prec> St( test, R_1) &+ St( test, R_1 ) \<prec> St( test, R_2) &+ St( test, R_2 ) \<prec> St( tid2, I_2 ) &+ St( tid2, I_2 ) \<prec> St( tid2, I_3 ) &+ St( tid2, I_3 ) \<prec> St( test, R_3 ))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Enc {| LC ''1'', s(MV ''ni'' test), s(AV ''I'' test) |}( PK ( s(AV ''R'' test) ) ) ")+ case (I_1_enc tid2) + thus ?thesis+ proof(sources "Enc {| LC ''3'', LN ''nr'' test |} ( PK ( s(AV ''R'' test) ) ) ")+ case fake+ thus ?thesis by (auto dest: R_nr_secrecy intro: event_predOrdI) + next+ case (I_3_enc tid3) + thus ?thesis + proof(sources "Enc {| LC ''2'', LN ''ni'' tid3, LN ''nr'' test, s(AV ''R'' test)|}( PK ( s(AV ''I'' tid3) ) ) ")+ case fake+ thus ?thesis by (auto dest: R_nr_secrecy intro: event_predOrdI)+ next+ case R_2_enc+ thus ?thesis by (auto intro: event_predOrdI)+ qed+ qed+ next+ case fake+ thus ?thesis+ by (auto dest: R_ni_secrecy intro: event_predOrdI)+ qed+qed+++end
@@ -0,0 +1,472 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)++theory "PFS_acm"+imports+ "../ESPLogic"+begin++section{* Security Proofs for a protocol guaranteeing PFS *}++subsection{* Protocol Specificiation *}++role A+where "A =+ [ + Send ''1'' ( PEnc \<langle> sC ''1'', sAV ''B'', PAsymPK ( sN ''na'' ) \<rangle>+ ( sSK ''A'' )+ )+ , Recv ''2'' ( PEnc ( PEnc \<langle> sC ''2'', sAV ''A'', sMV ''k'' \<rangle>+ ( sSK ''B'' )+ )+ ( PAsymPK ( sN ''na'' ) )+ )+ , Send ''3'' (PEnc \<langle> sC ''3'', sAV ''B'', PHash ( sMV ''k'') \<rangle> ( sSK ''A'' ))+ , Note ''4'' SessKey (sMV ''k'')+ ]"++role B+where "B =+ [ Recv ''1'' ( PEnc \<langle> sC ''1'', sAV ''B'', sMV ''pkNa'' \<rangle>+ ( sSK ''A'' )+ )+ , Send ''2'' ( PEnc ( PEnc \<langle> sC ''2'', sAV ''A'', sN ''k'' \<rangle>+ ( sSK ''B'' )+ )+ ( sMV ''pkNa'' )+ )+ , Recv ''3'' (PEnc \<langle> sC ''3'', sAV ''B'', PHash ( sN ''k'') \<rangle> ( sSK ''A'' ))+ , Note ''4'' SessKey (sN ''k'')+ ]"++protocol PFS+where "PFS = { A, B }"++(* TODO remove *)+declare (in PFS_state) A_4_def[simp]+declare (in PFS_state) B_4_def[simp]++subsection {* Typing Definition *}++type_invariant auto_msc_typing for PFS+where "auto_msc_typing = mk_typing+ [ ((A, ''k''), (SumT (KnownT A_2) (NonceT B ''k'')))+ , ((B, ''pkNa''), (SumT (KnownT B_1) (PKT (NonceT A ''na''))))+ ]"++sublocale PFS_state \<subseteq> auto_msc_typing_state+proof -+ have "(t,r,s) \<in> approx auto_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF auto_msc_typing.monoTyp, completeness_cases_rule])+ case (A_2_k t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc ( Enc \<lbrace> LC ''2'', s(AV ''A'' tid0), s(MV ''k'' tid0) \<rbrace>+ ( SK ( s(AV ''B'' tid0) ) )+ )+ ( PK ( LN ''na'' tid0 ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc \<lbrace> LC ''2'', s(AV ''A'' tid0), s(MV ''k'' tid0) \<rbrace>+ ( SK ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (B_1_pkNa t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc \<lbrace> LC ''1'', s(AV ''B'' tid0), s(MV ''pkNa'' tid0) \<rbrace>+ ( SK ( s(AV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ qed+ thus "auto_msc_typing_state t r s" by unfold_locales auto+qed++subsection{* Partnering Definition *}++definition+ PFS_trusted :: "partnering"+where+ "PFS_trusted q = + Id \<union>+ mk_partnering A B + {(sAV ''A'', sAV ''A'', B_1),+ (sAV ''B'', sAV ''B'', B_1),+ (sMV ''k'', sN ''k'', B_2),+ ( PAsymPK ( sN ''na'' ), sMV ''pkNa'', B_1)} q \<union> + mk_partnering B A + {(sAV ''A'', sAV ''A'', A_1),+ (sAV ''B'', sAV ''B'', A_1),+ (sN ''k'', sMV ''k'', A_2),+ (sMV ''pkNa'', PAsymPK ( sN ''na'' ), A_1)} q"+++lemmas (in PFS_state) PFS_trusted_conv = + setEqImpTupleIn[OF PFS_trusted_def, of _ _ "(t,r,s)", simplified]++lemmas (in PFS_state) PFS_trustedI[intro!] = PFS_trusted_conv[THEN iffD2,simplified mk_partnering_conv,simplified]++subsection{* Adversary Compromise Model Definitions *}++definition (in PFS_state) ADVall :: "tid \<Rightarrow> state set"+where+"ADVall i = acm {LKRothers i, LKRafter i, SkR i PFS_trusted}"++locale PFS_state_ADVall = PFS_state ++ fixes test :: tid+ assumes compromiseModel [simp,intro!]: "(t,r,s) \<in> ADVall test"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVall_def], simplified]+end++section {* Security Properties *}++subsection{* Origin Proofs *}++lemma (in PFS_state) B_k_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some B"+ shows+ "LN ''k'' test \<in> knows t \<longrightarrow>+ LKR (s(AV ''A'' test)) \<prec> St (test, B_2) \<or> + (\<exists> tid1. (test,tid1) \<in> PFS_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t)"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume "?knows"+ thus "?origins" using facts + proof(sources " LN ''k'' test ")+ case B_2_k+ thus ?thesis+ proof(sources "Enc \<lbrace> LC ''1'', s(AV ''B'' test), s(MV ''pkNa'' test) \<rbrace>+ ( SK ( s(AV ''A'' test) ) ) ")+ case fake+ thus ?thesis + by (sources "SK (s (AV ''A'' test))") (fastsimp intro: predOrd_distinct'_trans)+ next+ case (A_1_enc tid1)+ thus ?thesis + proof(sources " SK ( LN ''na'' tid1 ) ")+ qed+ qed+ next+ case (A_4_k tid1)+ thus ?thesis+ proof(sources "Enc (Enc \<lbrace>LC ''2'', s (AV ''A'' tid1), LN ''k'' test\<rbrace> (SK (s (AV ''B'' tid1))))+ (PK (LN ''na'' tid1))")+ case fake+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''2'', s (AV ''A'' tid1), LN ''k'' test\<rbrace> (SK (s (AV ''B'' tid1)))")+ case B_2_enc_1+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''1'', s (AV ''B'' tid1), s (MV ''pkNa'' test)\<rbrace>+ (SK (s (AV ''A'' tid1)))")+ case fake+ thus ?thesis+ by (sources "SK (s (AV ''A'' test))") (fastsimp intro: predOrd_distinct'_trans)+ next+ case (A_1_enc tid1')+ thus ?thesis+ by (sources "SK (LN ''na'' tid1')")+ qed+ qed+ next+ case B_2_enc+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case B_4_k+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+qed++lemma (in PFS_state) A_k_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some A"+ "( test, A_3 ) \<in> steps t"+ shows+ "s(MV ''k'' test) \<in> knows t \<longrightarrow>+ LKR (s(AV ''A'' test)) \<prec> St (test, A_2) \<or> + LKR (s(AV ''B'' test)) \<prec> St (test, A_2) \<or> + (\<exists> tid1. (test,tid1) \<in> PFS_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t)"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume "?knows"+ note_prefix_closed facts = facts this+ thus "?origins"+ proof(sources "Enc ( Enc \<lbrace> LC ''2'', s(AV ''A'' test), s(MV ''k'' test) \<rbrace> ( SK ( s(AV ''B'' test) ) )+ )( PK ( LN ''na'' test ) ) ")+ case fake+ thus ?thesis+ proof(sources "Enc \<lbrace> LC ''2'', s(AV ''A'' test), s(MV ''k'' test) \<rbrace>+ ( SK ( s(AV ''B'' test) ) ) ")+ case fake+ thus ?thesis+ by (sources "SK (s (AV ''B'' test))") (fastsimp intro: predOrd_distinct'_trans)+ next+ case (B_2_enc_1 tid1)+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''1'', s (AV ''B'' test), s (MV ''pkNa'' tid1)\<rbrace>+ (SK (s (AV ''A'' test)))")+ case fake+ thus ?thesis+ by (sources "SK (s (AV ''A'' tid1))")(fastsimp intro: predOrd_distinct'_trans) next+ case (A_1_enc tid1')+ thus ?thesis+ by (sources "SK (LN ''na'' tid1')")+ qed+ qed+ next+ case (B_2_enc tid1)+ thus ?thesis + proof(sources "LN ''k'' tid1")+ case (A_4_k test')+ note facts = facts this+ thus ?thesis + proof(sources "Enc (Enc \<lbrace>LC ''2'', s (AV ''A'' test'), LN ''k'' tid1\<rbrace> (SK (s (AV ''B'' test'))))+ (PK (LN ''na'' test'))")+ case fake+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''2'', s (AV ''A'' test'), LN ''k'' tid1\<rbrace> (SK (s (AV ''B'' test')))")+ case B_2_enc_1+ thus ?thesis+ by (sources "SK (LN ''na'' test)")+ qed+ next+ case B_2_enc+ note_unified facts = facts this+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case B_2_k+ thus ?thesis + by (sources "SK (LN ''na'' test)")+ next+ case B_4_k+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ qed+qed+++subsection{* Secrecy Proofs *}+lemma (in PFS_state_ADVall) B_sec_k:+ assumes facts:+ "roleMap r test = Some B"+ "LN ''k'' test \<in> knows t"+ "(test,B_3) \<in> steps t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ moreover {+ assume "LKR (s (AV ''A'' test)) \<prec> St (test, B_2)"+ hence "?thesis" using facts+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (auto dest: allowed_reveals)+ }+ moreover {+ assume "(\<exists>tid1. (test, tid1) \<in> PFS_trusted (t, r, s) \<and> RCompr SessKey tid1 \<in> reveals t) \<or> + (\<exists>tid1. (test, tid1) \<in> PFS_trusted (t, r, s) \<and> RCompr State tid1 \<in> reveals t)"+ hence "?thesis" using facts by(auto dest: allowed_reveals)+ }+ ultimately show ?thesis by (auto dest: B_k_origin)+qed++lemma (in PFS_state_ADVall) A_sec_k:+ assumes facts:+ "roleMap r test = Some A"+ "( test, A_3 ) \<in> steps t"+ "s(MV ''k'' test) \<in> knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ moreover {+ assume "LKR (s (AV ''A'' test)) \<prec> St (test, A_2)"+ hence "?thesis" using facts+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (auto dest: allowed_reveals)+ }+ moreover {+ assume "LKR (s (AV ''B'' test)) \<prec> St (test, A_2)"+ hence "?thesis" using facts+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (auto dest: allowed_reveals)+ } + moreover {+ assume "(\<exists>tid1. (test, tid1) \<in> PFS_trusted (t, r, s) \<and> RCompr SessKey tid1 \<in> reveals t) \<or> + (\<exists>tid1. (test, tid1) \<in> PFS_trusted (t, r, s) \<and> RCompr State tid1 \<in> reveals t)"+ hence "?thesis" using facts by(auto dest: allowed_reveals)+ }+ ultimately show ?thesis by (auto dest: A_k_origin)+qed+++subsection{* Authentication Proofs *}+lemma (in PFS_state_ADVall) A_ni_auth:+ assumes facts:+ "roleMap r test = Some A"+ "(test, A_3) \<in> steps t"+ shows+ "\<exists> tid1. + roleMap r tid1 = Some B \<and>+ s(AV ''A'' test) = s(AV ''A'' tid1) \<and>+ s(AV ''B'' test) = s(AV ''B'' tid1) \<and>+ s(MV ''k'' test) = LN ''k'' tid1 \<and>+ PK (LN ''na'' test) = s (MV ''pkNa'' tid1) \<and>+ St (test, A_1) \<prec> St (tid1, B_1) \<and>+ St (tid1, B_2) \<prec> St (test, A_2)"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Enc (Enc \<lbrace>LC ''2'', s (AV ''A'' test), s (MV ''k'' test)\<rbrace> (SK (s (AV ''B'' test)))) (PK (LN ''na'' test))")+ case fake+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''2'', s (AV ''A'' test), s (MV ''k'' test)\<rbrace> (SK (s (AV ''B'' test)))")+ case fake+ thus ?thesis+ by (fastsimp dest: A_sec_k event_predOrdI)+ next+ case (B_2_enc_1 tid1)+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''1'', s (AV ''B'' test), s (MV ''pkNa'' tid1)\<rbrace> (SK (s (AV ''A'' test)))")+ case fake+ thus ?thesis+ proof(sources "SK (s (AV ''A'' tid1))")+ case asym_lkr+ thus ?thesis+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (fastsimp dest: allowed_reveals)+ qed+ next+ case (A_1_enc test)+ thus ?thesis+ by (sources "SK (LN ''na'' test)") + qed+ qed+ next+ case (B_2_enc tid1)+ thus ?thesis + proof(sources "Enc \<lbrace>LC ''1'', s (AV ''B'' test), PK (LN ''na'' test)\<rbrace> (SK (s (AV ''A'' test)))")+ case fake+ thus ?thesis+ proof(sources "SK (s (AV ''A'' tid1))")+ case asym_lkr+ thus ?thesis+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (fastsimp dest: allowed_reveals)+ qed+ next+ case A_1_enc+ thus ?thesis by force+ qed + qed+qed++lemma (in PFS_state_ADVall) B_ni_auth:+ assumes facts:+ "roleMap r test = Some B"+ "(test, B_3) \<in> steps t"+ shows+ "\<exists> tid1. + roleMap r tid1 = Some A \<and>+ s(AV ''A'' tid1) = s(AV ''A'' test) \<and>+ s(AV ''B'' tid1) = s(AV ''B'' test) \<and>+ s(MV ''k'' tid1) = LN ''k'' test \<and>+ PK (LN ''na'' tid1) = s (MV ''pkNa'' test) \<and>+ St (tid1, A_1) \<prec> St (test, B_1) \<and>+ St (test, B_2) \<prec> St (tid1, A_2) \<and>+ St (tid1, A_3) \<prec> St (test, B_3)"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''3'', s (AV ''B'' test), Hash (LN ''k'' test)\<rbrace> (SK (s (AV ''A'' test)))")+ case fake+ thus ?thesis+ proof(sources "SK (s (AV ''A'' test))")+ case asym_lkr+ thus ?thesis+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (auto dest: allowed_reveals)+ qed+ next+ case (A_3_enc tid3)+ thus ?thesis+ proof(sources "Enc (Enc \<lbrace>LC ''2'', s (AV ''A'' test), LN ''k'' test\<rbrace> (SK (s (AV ''B'' tid3)))) (PK (LN ''na'' tid3))")+ case fake+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''2'', s (AV ''A'' tid3), LN ''k'' test\<rbrace> (SK (s (AV ''B'' tid3)))")+ case fake+ thus ?thesis + proof(sources "SK (s (AV ''B'' tid3))")+ case asym_lkr+ thus ?thesis+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (fastsimp dest: allowed_reveals) + qed+ next+ case B_2_enc_1+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''1'', s (AV ''B'' tid3), s (MV ''pkNa'' test)\<rbrace> (SK (s (AV ''A'' tid3)))")+ case fake+ thus ?thesis + proof(sources "SK (s (AV ''A'' tid3))")+ case asym_lkr+ thus ?thesis+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (fastsimp dest: allowed_reveals)+ qed+ next+ case (A_1_enc tid2)+ thus ?thesis+ by (sources "SK (LN ''na'' tid2)")+ qed+ qed+ next+ case B_2_enc+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''1'', s (AV ''B'' tid3), PK (LN ''na'' tid3)\<rbrace> (SK (s (AV ''A'' tid3)))")+ case fake+ thus ?thesis+ proof(sources "SK (s (AV ''A'' tid3))")+ case asym_lkr+ thus ?thesis+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (fastsimp dest: allowed_reveals)+ qed+ next+ case A_1_enc+ thus ?thesis+ by force+ qed+ qed+ qed+qed++end
@@ -0,0 +1,1528 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)++theory "TLS_acm"+imports+ "../ESPLogic"+begin++section{* Security Proofs for the TLS protocol *}++subsection{* Protocol Specificiation *}++role C+where "C =+ [ + Note ''0'' RandGen <| sN ''nc'', sN ''sid'', sN ''pc'' |>+ , Note ''1'' State <| sN ''nc'', sN ''sid'', sN ''pc'' |>+ , Send ''2'' <| sAV ''C'', sN ''nc'', sN ''sid'', sN ''pc'' |> + , Note ''3'' State <| sN ''nc'', sN ''sid'', sN ''pc'' |>+ , Recv ''4'' <| sMV ''ns'', sN ''sid'', sMV ''ps'' |>+ , Note ''5'' State <| sN ''nc'', sN ''sid'', sN ''pc'', sN ''pms'', sMV ''ns'', sMV ''ps'' |>+ , Send ''6'' <| PEnc <| sC ''TT0'', sN ''pms'' |> ( sPK ''S'' ),+ PEnc <| sC ''TT1'',+ PHash <| sC ''TT2'', sMV ''ns'', sAV ''S'', sN ''pms'' |>+ |>+ ( sSK ''C'' ),+ PEnc <| sC ''TT3'', sN ''sid'',+ PHash <| sC ''TT4'', sC ''PRF'', sN ''pms'', sN ''nc'', sMV ''ns''+ |>,+ sN ''nc'', sN ''pc'', sAV ''C'', sMV ''ns'', sMV ''ps'', sAV ''S''+ |>+ ( PHash <| sC ''clientKey'', sN ''nc'', sMV ''ns'',+ PHash <| sC ''TT4'', sC ''PRF'', sN ''pms'', sN ''nc'', sMV ''ns''+ |>+ |>+ )+ |>+ , Note ''7'' State <| sN ''nc'', sN ''sid'', sN ''pc'', sN ''pms'', sMV ''ns'', sMV ''ps'' |>+ , Recv ''8'' ( PEnc <| sC ''TT3'', sN ''sid'',+ PHash <| sC ''TT4'', sC ''PRF'', sN ''pms'', sN ''nc'', sMV ''ns''+ |>,+ sN ''nc'', sN ''pc'', sAV ''C'', sMV ''ns'', sMV ''ps'', sAV ''S''+ |>+ ( PHash <| sC ''serverKey'', sN ''nc'', sMV ''ns'',+ PHash <| sC ''TT4'', sC ''PRF'', sN ''pms'', sN ''nc'', sMV ''ns''+ |>+ |>+ )+ )+ , Note ''9'' SessKey <| PHash <| sC ''serverKey'', sN ''nc'', sMV ''ns'',+ PHash <| sC ''TT4'', sC ''PRF'', sN ''pms'', sN ''nc'', sMV ''ns''+ |>+ |>,+ + PHash <| sC ''clientKey'', sN ''nc'', sMV ''ns'',+ PHash <| sC ''TT4'', sC ''PRF'', sN ''pms'', sN ''nc'', sMV ''ns''+ |>+ |>+ |>+ ]"++role S+where "S =+ [+ Recv ''1'' <| sAV ''C'', sMV ''nc'', sMV ''sid'', sMV ''pc'' |>+ , Note ''0'' RandGen <| sN ''ns'', sN ''ps'' |>+ , Note ''2'' State <| sN ''ns'', sMV ''sid'', sN ''ps'', sMV ''nc'', sMV ''sid'', sMV ''pc'' |>+ , Send ''3'' <| sN ''ns'', sMV ''sid'', sN ''ps'' |>+ , Note ''4'' State <| sN ''ns'', sMV ''sid'', sN ''ps'', sMV ''nc'', sMV ''sid'', sMV ''pc'' |>+ , Recv ''5'' <| PEnc <| sC ''TT0'', sMV ''pms'' |> ( sPK ''S'' ),+ PEnc <| sC ''TT1'',+ PHash <| sC ''TT2'', sN ''ns'', sAV ''S'', sMV ''pms'' |>+ |>+ ( sSK ''C'' ),+ PEnc <| sC ''TT3'', sMV ''sid'',+ PHash <| sC ''TT4'', sC ''PRF'', sMV ''pms'', sMV ''nc'', sN ''ns''+ |>,+ sMV ''nc'', sMV ''pc'', sAV ''C'', sN ''ns'', sN ''ps'', sAV ''S''+ |>+ ( PHash <| sC ''clientKey'', sMV ''nc'', sN ''ns'',+ PHash <| sC ''TT4'', sC ''PRF'', sMV ''pms'', sMV ''nc'',+ sN ''ns''+ |>+ |>+ )+ |>+ , Note ''6'' State <| sMV ''pms'', sN ''ns'', sMV ''sid'', sN ''ps'', sMV ''nc'', sMV ''sid'', sMV ''pc'' |>+ , Send ''7'' ( PEnc <| sC ''TT3'', sMV ''sid'',+ PHash <| sC ''TT4'', sC ''PRF'', sMV ''pms'', sMV ''nc'', sN ''ns''+ |>,+ sMV ''nc'', sMV ''pc'', sAV ''C'', sN ''ns'', sN ''ps'', sAV ''S''+ |>+ ( PHash <| sC ''serverKey'', sMV ''nc'', sN ''ns'',+ PHash <| sC ''TT4'', sC ''PRF'', sMV ''pms'', sMV ''nc'', sN ''ns''+ |>+ |>+ )+ )+ , Note ''8'' SessKey <| PHash <| sC ''serverKey'', sMV ''nc'', sN ''ns'',+ PHash <| sC ''TT4'', sC ''PRF'', sMV ''pms'', sMV ''nc'', sN ''ns''+ |>+ |>,+ PHash <| sC ''clientKey'', sMV ''nc'', sN ''ns'',+ PHash <| sC ''TT4'', sC ''PRF'', sMV ''pms'', sMV ''nc'',+ sN ''ns''+ |>+ |>+ |>+ + ]"++protocol TLS+where "TLS = { C, S }"++subsection {* Typing Definition *}+type_invariant auto_msc_typing for TLS+where "auto_msc_typing = mk_typing+ [ ((S, ''nc''), (KnownT S_1))+ , ((C, ''ns''), (KnownT C_4))+ , ((S, ''pc''), (KnownT S_1))+ , ((S, ''pms''), (SumT (KnownT S_5) (NonceT C ''pms'')))+ , ((C, ''ps''), (KnownT C_4))+ , ((S, ''sid''), (KnownT S_1))+ ]"++sublocale TLS_state < auto_msc_typing_state+proof -+ have "(t,r,s) : approx auto_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF auto_msc_typing.monoTyp, completeness_cases_rule])+ case (C_4_ns t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (C_4_ps t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (S_1_nc t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (S_1_pc t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (S_1_sid t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ by (fastsimp intro: event_predOrdI split: if_splits)+ next+ case (S_5_pms t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc {| LC ''TT0'', s(MV ''pms'' tid0) |}+ ( PK ( s(AV ''S'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ qed+ thus "auto_msc_typing_state t r s" by unfold_locales auto+qed+++(* TODO remove *)+declare (in TLS_state) C_1_def[simp]+declare (in TLS_state) C_3_def[simp]+declare (in TLS_state) C_5_def[simp]+declare (in TLS_state) C_7_def[simp]+declare (in TLS_state) C_9_def[simp]+declare (in TLS_state) S_2_def[simp]+declare (in TLS_state) S_4_def[simp]+declare (in TLS_state) S_6_def[simp]+declare (in TLS_state) S_8_def[simp]+declare (in TLS_state) C_0_def[simp]+declare (in TLS_state) S_0_def[simp]++subsection{* Partnering Definition *}++text{* +Strongest possible partnering definition:+- Direction C to S is trivial, since all possible variables of either C or S are used.+- For direction S to C it is only a subset of variables:+ Assume a thread tid1 sends C,nc,sid,pc and the adversary already knows nc'\<noteq>nc, ps'\<noteq>ps, pc'\<noteq>pc and sid'\<noteq>sid. Then the test thread receives C,nc'sid',pc' and sends ns,sid',ps. Now the partnering in both directions is broken. However the adversary can bring thread tid1 to receive ns,sid,pc', state compromise him to receive pms and then use the signed message send in the next client step to trick the test thread of accepting pms. All other messages from C_6 can be faked if pms is known!.+*}++definition+ TLS_trusted :: "partnering"+where+ "TLS_trusted q = + Id \<union> + mk_partnering C S + {(sN ''pc'', sMV ''pc'', S_1),+ (sN ''nc'', sMV ''nc'', S_1),+ (sN ''sid'', sMV ''sid'',S_1),+ (sAV ''C'', sAV ''C'', S_1),+ (sAV ''S'', sAV ''S'', S_1),+ (sMV ''ns'', sN ''ns'', S_3),+ (sMV ''ps'', sN ''ps'', S_3),+ (sN ''pms'', sMV ''pms'',S_5)} q \<union>+ mk_partnering S C + {(sAV ''C'', sAV ''C'', C_2),+ (sAV ''S'', sAV ''S'', C_2),+ (sN ''ns'', sMV ''ns'', C_4),+ (sMV ''pms'', sN ''pms'',C_6)} q"+++lemmas (in TLS_state) TLS_trusted_conv = + setEqImpTupleIn[OF TLS_trusted_def, of _ _ "(t,r,s)",simplified]++lemmas (in TLS_state) TLS_trustedI[intro!] = TLS_trusted_conv[THEN iffD2,simplified mk_partnering_conv,simplified]+++subsection{* Adversary Compromise Model Definitions *}+text {*+Random number generator compromises are not possible. On one hand pms cannot be revealed any way, otherwise all values could be faked. On the other hand, the strong authentication properties don't hold any more. The reason is that the adversary might just get nc and ns before they are sent.+*}++definition (in TLS_state) ADVnotRNR :: "tid \<Rightarrow> state set"+where+"ADVnotRNR i = acm {LKRothers i, StR i TLS_trusted, SkR i TLS_trusted}"++locale TLS_state_ADVnotRNR = TLS_state ++ fixes test :: tid+ assumes compromiseModel [intro!]: "(t,r,s) \<in> ADVnotRNR test"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVnotRNR_def], simplified]+end+++definition (in TLS_state) ADVall :: "tid \<Rightarrow> state set"+where+"ADVall i = acm {LKRothers i, StR i TLS_trusted, SkR i TLS_trusted, RNR}"++locale TLS_state_ADVall = TLS_state ++ fixes test :: tid+ assumes compromiseModel [intro!]: "(t,r,s) \<in> ADVall test"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVall_def], simplified]+end++definition (in TLS_state) ADVallActor :: "tid \<Rightarrow> varid \<Rightarrow> state set"+where+"ADVallActor i me = acm {LKRothers i, StR i TLS_trusted, SkR i TLS_trusted, RNR, LKRactor i me}"++locale TLS_state_ADVallActorC = TLS_state ++ fixes test :: tid+ assumes compromiseModel [intro!]: "(t,r,s) \<in> ADVallActor test (AVar ''C'')"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVallActor_def], simplified]+end++locale TLS_state_ADVallActorS = TLS_state ++ fixes test :: tid+ assumes compromiseModel [intro!]: "(t,r,s) \<in> ADVallActor test (AVar ''S'')"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVallActor_def], simplified]+end++section{* Security Proofs *}+++subsection{* Origin Proofs *}+lemma (in TLS_state) C_pms_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some C"+ shows+ "LN ''pms'' test \<in> knows t \<longrightarrow>+ RLKR (s(AV ''S'' test)) \<in> reveals t \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr State tid1 \<in> reveals t) \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t)" + (is "?knows \<longrightarrow> ?origins")+proof + assume ?knows+ thus ?origins using facts+ proof(sources " LN ''pms'' test ")+ case C_6_pms + thus ?thesis + by (sources "SK (s (AV ''S'' test))") (auto intro: compr_predOrdI)+ next+ case C_5_pms+ thus ?thesis+ by(auto intro: compr_predOrdI)+ next+ case C_7_pms+ thus ?thesis+ by(auto intro: compr_predOrdI)+ next+ case (S_6_pms tid1)+ thus ?thesis+ (* Proof Idea: If the adversary has learned pms from S_6_pms, then how could he send the messages in S_5 *)+ proof(sources "Enc \<lbrace>LC ''TT1'', Hash \<lbrace>LC ''TT2'', LN ''ns'' tid1, s (AV ''S'' tid1), LN ''pms'' test\<rbrace>\<rbrace>+ (SK (s (AV ''C'' tid1)))")+ case fake+ thus ?thesis+ proof(sources "Hash \<lbrace>LC ''TT2'', LN ''ns'' tid1, s (AV ''S'' tid1), LN ''pms'' test\<rbrace>")+ case C_6_hash+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT3'', s (MV ''sid'' tid1),+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1), LN ''ns'' tid1\<rbrace>,+ s (MV ''nc'' tid1), s (MV ''pc'' tid1), s (AV ''C'' tid1), LN ''ns'' tid1,+ LN ''ps'' tid1, s (AV ''S'' tid1)\<rbrace>+ (Hash \<lbrace>LC ''clientKey'', s (MV ''nc'' tid1), LN ''ns'' tid1,+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1),+ LN ''ns'' tid1\<rbrace>\<rbrace>)")+ case fake+ thus ?thesis+ proof(sources "Hash \<lbrace>LC ''clientKey'', s (MV ''nc'' tid1), LN ''ns'' tid1,+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1),+ LN ''ns'' tid1\<rbrace>\<rbrace>")+ case fake+ thus ?thesis + by(sources "Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1),+ LN ''ns'' tid1\<rbrace>")+ next+ case C_9_hash_1+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ qed+ qed+ next+ case C_6_enc_1+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT3'', s (MV ''sid'' tid1),+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1), LN ''ns'' tid1\<rbrace>, s (MV ''nc'' tid1),+ s (MV ''pc'' tid1), s (AV ''C'' tid1), LN ''ns'' tid1, LN ''ps'' tid1, s (AV ''S'' tid1)\<rbrace>+ (Hash \<lbrace>LC ''clientKey'', s (MV ''nc'' tid1), LN ''ns'' tid1,+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1), LN ''ns'' tid1\<rbrace>\<rbrace>)")+ case fake+ thus ?thesis+ proof(sources "Hash \<lbrace>LC ''clientKey'', s (MV ''nc'' tid1), LN ''ns'' tid1,+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1), LN ''ns'' tid1\<rbrace>\<rbrace>")+ case fake+ thus ?thesis+ by(sources "Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1), LN ''ns'' tid1\<rbrace>") next+ case C_9_hash_1+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case C_6_enc_2+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ qed+ qed+qed++++lemma (in TLS_state) C_PRF_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some C"+ shows+ "Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test, s(MV ''ns'' test)|} \<in> knows t \<longrightarrow>+ RLKR (s(AV ''S'' test)) \<in> reveals t \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr State tid1 \<in> reveals t) \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t)" + (is "?knows \<longrightarrow> ?origins")+proof+ assume ?knows+ thus ?origins using facts + proof(sources "Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test, s(MV ''ns'' test)|} ")+ case fake+ thus ?thesis+ by (auto dest: C_pms_origin intro: event_predOrdI)+ next+ case C_6_hash_1+ thus ?thesis+ proof(sources "Hash {| LC ''clientKey'', LN ''nc'' test, s(MV ''ns'' test),+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,s(MV ''ns'' test)|}|} ")+ case C_9_hash_1+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case (S_8_hash_1 tid1)+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT3'', s (MV ''sid'' tid1),+ Hash+ \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ LN ''ns'' tid1\<rbrace>,+ LN ''nc'' test, s (MV ''pc'' tid1), s (AV ''C'' tid1),+ LN ''ns'' tid1, LN ''ps'' tid1, s (AV ''S'' tid1)\<rbrace>+ (Hash+ \<lbrace>LC ''clientKey'', LN ''nc'' test, LN ''ns'' tid1,+ Hash+ \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ LN ''ns'' tid1\<rbrace>\<rbrace>)")+ case C_6_enc_2+ thus ?thesis + by (auto intro: compr_predOrdI)+ qed+ qed + next+ case (S_7_hash tid1)+ thus ?thesis+ proof(sources "Hash {| LC ''serverKey'', LN ''nc'' test, LN ''ns'' tid1,+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,LN ''ns'' tid1|}|} ")+ case C_9_hash+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case S_8_hash+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT3'', s (MV ''sid'' tid1),+ Hash+ \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ LN ''ns'' tid1\<rbrace>,+ LN ''nc'' test, s (MV ''pc'' tid1), s (AV ''C'' tid1),+ LN ''ns'' tid1, LN ''ps'' tid1, s (AV ''S'' tid1)\<rbrace>+ (Hash+ \<lbrace>LC ''clientKey'', LN ''nc'' test, LN ''ns'' tid1,+ Hash+ \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ LN ''ns'' tid1\<rbrace>\<rbrace>)")+ case C_6_enc_2+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ qed+ qed+qed+++lemma (in TLS_state) C_clientKey_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some C"+ shows+ "Hash {| LC ''clientKey'', LN ''nc'' test, s(MV ''ns'' test),+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test, s(MV ''ns'' test) |}|} \<in> knows t+ \<longrightarrow> RLKR (s(AV ''S'' test)) \<in> reveals t \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr State tid1 \<in> reveals t) \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t)"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume ?knows+ thus ?origins using facts+ proof(sources "Hash {| LC ''clientKey'', LN ''nc'' test, s(MV ''ns'' test),+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,s(MV ''ns'' test)|}|} ")+ case fake+ thus ?thesis+ by (auto dest: C_PRF_origin intro: event_predOrdI)+ next+ case C_9_hash_1+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case (S_8_hash_1 tid1)+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT3'', s (MV ''sid'' tid1),+ Hash+ \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ LN ''ns'' tid1\<rbrace>,+ LN ''nc'' test, s (MV ''pc'' tid1), s (AV ''C'' tid1),+ LN ''ns'' tid1, LN ''ps'' tid1, s (AV ''S'' tid1)\<rbrace>+ (Hash+ \<lbrace>LC ''clientKey'', LN ''nc'' test, LN ''ns'' tid1,+ Hash+ \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ LN ''ns'' tid1\<rbrace>\<rbrace>)")+ case C_6_enc_2+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ qed+qed+++lemma (in TLS_state) C_serverKey_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some C"+ shows+ "Hash {| LC ''serverKey'', LN ''nc'' test, s(MV ''ns'' test),+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test, s(MV ''ns'' test)|}|} \<in> knows t+ \<longrightarrow> RLKR (s(AV ''S'' test)) \<in> reveals t \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr State tid1 \<in> reveals t) \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t)"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume ?knows+ thus ?origins using facts+ proof(sources "Hash {| LC ''serverKey'', LN ''nc'' test, s(MV ''ns'' test),+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test, s(MV ''ns'' test)|}|} ")+ case fake+ thus ?thesis+ by (auto dest: C_PRF_origin intro: event_predOrdI)+ next+ case C_9_hash+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case (S_8_hash tid1)+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT3'', s (MV ''sid'' tid1),+ Hash+ \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ LN ''ns'' tid1\<rbrace>,+ LN ''nc'' test, s (MV ''pc'' tid1), s (AV ''C'' tid1),+ LN ''ns'' tid1, LN ''ps'' tid1, s (AV ''S'' tid1)\<rbrace>+ (Hash+ \<lbrace>LC ''clientKey'', LN ''nc'' test, LN ''ns'' tid1,+ Hash+ \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ LN ''ns'' tid1\<rbrace>\<rbrace>)")+ case fake+ thus ?thesis+ by(auto intro: event_predOrdI dest!: C_clientKey_origin)+ next+ case C_6_enc_2+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ qed+qed+++++lemma (in TLS_state) S_pms_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_5 ) \<in> steps t"+ shows+ "s(MV ''pms'' test) \<in> knows t \<longrightarrow>+ RLKR (s(AV ''S'' test)) \<in> reveals t \<or> + RLKR (s(AV ''C'' test)) \<in> reveals t \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr State tid1 \<in> reveals t) \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t)"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume ?knows+ note_prefix_closed facts = facts this+ thus ?origins+ proof(sources "Enc {| LC ''TT1'',Hash {| LC ''TT2'', LN ''ns'' test, s(AV ''S'' test), s(MV ''pms'' test)|}|}+ ( SK ( s(AV ''C'' test) ) ) ")+ case fake+ thus ?thesis+ by(sources "SK (s (AV ''C'' test))") (auto intro: compr_predOrdI)+ next+ case (C_6_enc_1 tid1)+ thus ?thesis+ proof(sources "LN ''pms'' tid1")+ case C_6_pms+ thus ?thesis+ by(sources "SK (s (AV ''S'' test))") (auto intro: compr_predOrdI)+ next+ case C_5_pms+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case C_7_pms+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case (S_6_pms tid2)+ note_unified facts = this+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT1'', Hash \<lbrace>LC ''TT2'', LN ''ns'' tid2, s (AV ''S'' tid2), LN ''pms'' tid1\<rbrace>\<rbrace>+ (SK (s (AV ''C'' tid2)))")+ case fake+ thus ?thesis+ by (sources "Hash \<lbrace>LC ''TT2'', LN ''ns'' tid2, s (AV ''S'' tid2), LN ''pms'' tid1\<rbrace>")+ next+ case C_6_enc_1+ note_unified facts = facts this+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ qed+ qed+qed+++lemma (in TLS_state) S_PRF_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_5 ) \<in> steps t"+ shows + "Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test), s(MV ''nc'' test), LN ''ns'' test|} \<in> knows t \<longrightarrow>+ RLKR (s(AV ''S'' test)) \<in> reveals t \<or> + RLKR (s(AV ''C'' test)) \<in> reveals t \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr State tid1 \<in> reveals t) \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t)"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume ?knows+ note_prefix_closed facts = facts this+ thus ?origins+ proof(sources "Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),s(MV ''nc'' test), LN ''ns'' test|} ")+ case (C_6_hash_1 tid1)+ thus ?thesis+ proof(sources "Hash {| LC ''clientKey'', LN ''nc'' tid1, LN ''ns'' test,+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' tid1, LN ''nc'' tid1, LN ''ns'' test|} |} ")+ case C_9_hash_1+ thus ?thesis + proof(sources "Enc \<lbrace>LC ''TT1'',+ Hash+ \<lbrace>LC ''TT2'', LN ''ns'' test, s (AV ''S'' test),+ LN ''pms'' tid1\<rbrace>\<rbrace>+ (SK (s (AV ''C'' test)))")+ case fake+ thus ?thesis+ by(sources "SK (s (AV ''C'' test))") (auto intro: compr_predOrdI)+ next+ case C_6_enc_1+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case S_8_hash_1+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case S_7_hash+ thus ?thesis+ proof(sources "Hash {| LC ''serverKey'', s(MV ''nc'' test), LN ''ns'' test,+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test), s(MV ''nc'' test), LN ''ns'' test |}|} ")+ case (C_9_hash tid1)+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT1'', Hash \<lbrace>LC ''TT2'', LN ''ns'' test, s (AV ''S'' test), LN ''pms'' tid1\<rbrace>\<rbrace>+ (SK (s (AV ''C'' test)))")+ case fake+ thus ?thesis+ by(sources "SK (s (AV ''C'' test))") (auto intro: compr_predOrdI)+ next+ case C_6_enc_1+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case S_8_hash+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case fake+ thus ?thesis+ by (auto dest: S_pms_origin intro: event_predOrdI)+ qed+qed+++lemma (in TLS_state) S_clientKey_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_5 ) \<in> steps t"+ shows+ "Hash {| LC ''clientKey'', s(MV ''nc'' test), LN ''ns'' test,+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),s(MV ''nc'' test), LN ''ns'' test |}|} \<in> knows t+ \<longrightarrow>+ RLKR (s(AV ''S'' test)) \<in> reveals t \<or> + RLKR (s(AV ''C'' test)) \<in> reveals t \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr State tid1 \<in> reveals t) \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t)"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume ?knows+ note_prefix_closed facts = facts this+ thus ?origins+ proof(sources "Hash {| LC ''clientKey'', s(MV ''nc'' test), LN ''ns'' test,+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),s(MV ''nc'' test), LN ''ns'' test|}|} ")+ case fake+ thus ?thesis+ by (auto dest: S_PRF_origin intro: event_predOrdI)+ next+ case (C_9_hash_1 tid1)+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT1'', Hash \<lbrace>LC ''TT2'', LN ''ns'' test, s (AV ''S'' test), LN ''pms'' tid1\<rbrace>\<rbrace>+ (SK (s (AV ''C'' test)))")+ case fake+ thus ?thesis+ by(sources "SK (s (AV ''C'' test))") (auto intro: compr_predOrdI)+ next+ case C_6_enc_1+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case S_8_hash_1+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+qed+++lemma (in TLS_state) S_serverKey_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_5 ) \<in> steps t"+ shows + "Hash {| LC ''serverKey'', s(MV ''nc'' test), LN ''ns'' test,+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),s(MV ''nc'' test), LN ''ns'' test |}|} \<in> knows t+ \<longrightarrow>+ RLKR (s(AV ''S'' test)) \<in> reveals t \<or> + RLKR (s(AV ''C'' test)) \<in> reveals t \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr State tid1 \<in> reveals t) \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t)"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume ?knows+ note_prefix_closed facts = facts this+ thus ?origins+ proof(sources "Hash {| LC ''serverKey'', s(MV ''nc'' test), LN ''ns'' test,+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),s(MV ''nc'' test), LN ''ns'' test|} |} ")+ case fake+ thus ?thesis+ by (auto dest: S_PRF_origin intro: event_predOrdI)+ next+ case (C_9_hash tid1)+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT1'', Hash \<lbrace>LC ''TT2'', LN ''ns'' test, s (AV ''S'' test), LN ''pms'' tid1\<rbrace>\<rbrace>+ (SK (s (AV ''C'' test)))")+ case fake+ thus ?thesis+ by(sources "SK (s (AV ''C'' test))") (auto intro: compr_predOrdI)+ next+ case C_6_enc_1+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case S_8_hash+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+qed++subsection{* Secrecy Proofs *}++lemma (in TLS_state_ADVall) C_pms_sec:+ assumes facts:+ "roleMap r test = Some C"+ "LN ''pms'' test \<in> knows t"+ shows "False"+using facts+apply -+apply(frule C_pms_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVall) C_PRF_sec:+ assumes facts:+ "roleMap r test = Some C"+ "Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test, s(MV ''ns'' test) |} \<in> knows t"+ shows "False"+using facts+apply -+apply(frule C_PRF_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVall) C_clientKey_sec:+ assumes facts:+ "roleMap r test = Some C"+ "Hash {| LC ''clientKey'', LN ''nc'' test, s(MV ''ns'' test),+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test, s(MV ''ns'' test)|}|} \<in> knows t"+ shows "False"+using facts+apply -+apply(frule C_clientKey_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVall) C_serverKey_sec:+ assumes facts:+ "roleMap r test = Some C"+ "Hash {| LC ''serverKey'', LN ''nc'' test, s(MV ''ns'' test),+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ s(MV ''ns'' test)+ |}+ |} : knows t"+ shows "False"+using facts +apply -+apply(frule C_serverKey_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVall) S_pms_sec:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_5 ) \<in> steps t"+ "s(MV ''pms'' test) \<in> knows t"+ shows "False"+using facts+apply -+apply(frule S_pms_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVall) S_PRF_sec:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_5 ) \<in> steps t"+ "Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),+ s(MV ''nc'' test), LN ''ns'' test+ |} \<in> knows t"+ shows "False"+using facts+apply -+apply(frule S_PRF_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVall) S_clientKey_sec:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_5 ) \<in> steps t"+ "Hash {| LC ''clientKey'', s(MV ''nc'' test), LN ''ns'' test,+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),+ s(MV ''nc'' test), LN ''ns'' test+ |}+ |} \<in> knows t"+ shows "False"+using facts+apply -+apply(frule S_clientKey_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVnotRNR) C_pms_sec:+ assumes facts:+ "roleMap r test = Some C"+ "LN ''pms'' test \<in> knows t"+ shows "False"+using facts+apply -+apply(frule C_pms_origin, assumption)+by(auto dest: allowed_reveals C_pms_origin) ++lemma (in TLS_state_ADVnotRNR) C_PRF_sec:+ assumes facts:+ "roleMap r test = Some C"+ "Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test, s(MV ''ns'' test) |} \<in> knows t"+ shows "False"+using facts+apply -+apply(frule C_PRF_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVnotRNR) C_clientKey_sec:+ assumes facts:+ "roleMap r test = Some C"+ "Hash {| LC ''clientKey'', LN ''nc'' test, s(MV ''ns'' test),+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test, s(MV ''ns'' test)|}|} \<in> knows t"+ shows "False"+using facts+apply -+apply(frule C_clientKey_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVnotRNR) C_serverKey_sec:+ assumes facts:+ "roleMap r test = Some C"+ "Hash {| LC ''serverKey'', LN ''nc'' test, s(MV ''ns'' test),+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ s(MV ''ns'' test)+ |}+ |} : knows t"+ shows "False"+using facts +apply -+apply(frule C_serverKey_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVnotRNR) S_pms_sec:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_5 ) \<in> steps t"+ "s(MV ''pms'' test) \<in> knows t"+ shows "False"+using facts+apply -+apply(frule S_pms_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVnotRNR) S_PRF_sec:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_5 ) \<in> steps t"+ "Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),+ s(MV ''nc'' test), LN ''ns'' test+ |} \<in> knows t"+ shows "False"+using facts+apply -+apply(frule S_PRF_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVnotRNR) S_clientKey_sec:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_5 ) \<in> steps t"+ "Hash {| LC ''clientKey'', s(MV ''nc'' test), LN ''ns'' test,+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),+ s(MV ''nc'' test), LN ''ns'' test+ |}+ |} \<in> knows t"+ shows "False"+using facts+apply -+apply(frule S_clientKey_origin, assumption)+by(auto dest: allowed_reveals)++lemma (in TLS_state_ADVnotRNR) S_serverKey_sec:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_5 ) \<in> steps t"+ "Hash {| LC ''serverKey'', s(MV ''nc'' test), LN ''ns'' test,+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),+ s(MV ''nc'' test), LN ''ns'' test+ |}+ |} \<in> knows t"+ shows "False"+using facts+apply -+apply(frule S_serverKey_origin, assumption)+by(auto dest: allowed_reveals)++subsection{* Authentication Proofs *}+++lemma (in TLS_state_ADVallActorC) C_ni_synch:+ assumes facts:+ "roleMap r test = Some C"+ "( test, C_8 ) \<in> steps t"+ shows+ "(? tid2.+ roleMap r tid2 = Some S &+ s(AV ''C'' test) = s(AV ''C'' tid2) &+ s(AV ''S'' test) = s(AV ''S'' tid2) &+ LN ''nc'' test = s(MV ''nc'' tid2) &+ s(MV ''ns'' test) = LN ''ns'' tid2 &+ LN ''pc'' test = s(MV ''pc'' tid2) &+ s(MV ''ps'' test) = LN ''ps'' tid2 &+ LN ''sid'' test = s(MV ''sid'' tid2) &+ LN ''pms'' test = s(MV ''pms'' tid2) &+ (St( tid2, S_1 )) \<prec> (St( tid2, S_3 )) &+ (St( test, C_4 )) \<prec> (St( test, C_6 )) &+ (St( test, C_6 )) \<prec> (St( tid2, S_5 )) &+ (St( tid2, S_5 )) \<prec> (St( tid2, S_7 )) &+ (St( tid2, S_7 )) \<prec> (St( test, C_8 )))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources "+ Enc {| LC ''TT3'', LN ''sid'' test,+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ s(MV ''ns'' test)+ |},+ LN ''nc'' test, LN ''pc'' test, s(AV ''C'' test),+ s(MV ''ns'' test), s(MV ''ps'' test), s(AV ''S'' test)+ |}+ ( Hash {| LC ''serverKey'', LN ''nc'' test, s(MV ''ns'' test),+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ s(MV ''ns'' test)+ |}+ |}+ ) ")+ case fake+ note_unified facts = facts this+ moreover {+ assume "RLKR (s (AV ''S'' test)) \<in> reveals t"+ hence "False" using facts+ by(auto dest!: allowed_reveals)+ }+ moreover {+ assume "\<exists>tid1. (test, tid1) \<in> TLS_trusted (t, r, s) \<and> RCompr State tid1 \<in> reveals t"+ hence "False" by (auto dest: allowed_reveals)+ }+ moreover {+ assume "(\<exists>tid1. (test, tid1) \<in> TLS_trusted (t, r, s) \<and> RCompr SessKey tid1 \<in> reveals t)"+ hence "False" by (auto dest: allowed_reveals)+ }+ ultimately show ?thesis+ apply -+ apply (drule event_predOrdI, drule C_serverKey_origin, assumption)+ by (auto)+ next+ case (S_7_enc tid2)+ thus ?thesis+ proof(sources "Enc {| LC ''TT0'', LN ''pms'' test |}( PK ( s(AV ''S'' test) ) ) ")+ case fake+ note_unified facts = facts this+ moreover {+ assume "RLKR (s (AV ''S'' test)) \<in> reveals t"+ hence "False" using facts+ by(auto dest!: allowed_reveals)+ }+ moreover {+ assume "\<exists>tid1. (test, tid1) \<in> TLS_trusted (t, r, s) \<and> RCompr State tid1 \<in> reveals t"+ hence "False" by (auto dest: allowed_reveals)+ }+ moreover {+ assume "(\<exists>tid1. (test, tid1) \<in> TLS_trusted (t, r, s) \<and> RCompr SessKey tid1 \<in> reveals t)"+ hence "False" by (auto dest: allowed_reveals)+ }+ ultimately show ?thesis+ apply -+ apply (drule event_predOrdI, drule C_pms_origin, assumption)+ by (auto)+ next+ case C_6_enc+ thus ?thesis by auto+ qed+ qed+qed++text {*+The variable agreement cannot be stronger. The reason is that only those listed below are +protected by the signature of C. Hence the adversary could fake the rest if he decrypts the TT1 message+with the pms in it.+*}+lemma (in TLS_state_ADVallActorS) S_ni_synch:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_7 ) \<in> steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some C &+ s(AV ''C'' tid1) = s(AV ''C'' test) &+ s(AV ''S'' tid1) = s(AV ''S'' test) &+ s(MV ''ns'' tid1) = LN ''ns'' test &+ LN ''pms'' tid1 = s(MV ''pms'' test) &+ (St( test, S_1 )) \<prec> (St( test, S_3 )) &+ (St( tid1, C_4 )) \<prec> (St( tid1, C_6 )) &+ (St( tid1, C_6 )) \<prec> (St( test, S_5 )) &+ (St( test, S_5 )) \<prec> (St( test, S_7 )))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT1'',+ Hash+ \<lbrace>LC ''TT2'', LN ''ns'' test, s (AV ''S'' test),+ s (MV ''pms'' test)\<rbrace>\<rbrace>+ (SK (s (AV ''C'' test)))")+ case fake+ thus ?thesis+ proof(sources "SK (s (AV ''C'' test))")+ qed (force dest: compr_predOrdI allowed_reveals)+ next+ case (C_6_enc_1 tid1)+ thus ?thesis+ proof(sources "Enc {| LC ''TT3'', s(MV ''sid'' test),+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),+ s(MV ''nc'' test), LN ''ns'' test+ |},+ s(MV ''nc'' test), s(MV ''pc'' test), s(AV ''C'' test),+ LN ''ns'' test, LN ''ps'' test, s(AV ''S'' test)+ |}+ ( Hash {| LC ''clientKey'', s(MV ''nc'' test), LN ''ns'' test,+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),+ s(MV ''nc'' test), LN ''ns'' test+ |}+ |}+ ) ")+ case fake+ thus ?thesis+ by auto+ next+ case C_6_enc_2+ thus ?thesis+ by auto+ qed+ qed+qed++lemma (in TLS_state_ADVnotRNR) C_ni_synch:+ assumes facts:+ "roleMap r test = Some C"+ "( test, C_8 ) \<in> steps t"+ shows+ "(? tid2.+ roleMap r tid2 = Some S &+ s(AV ''C'' test) = s(AV ''C'' tid2) &+ s(AV ''S'' test) = s(AV ''S'' tid2) &+ LN ''nc'' test = s(MV ''nc'' tid2) &+ s(MV ''ns'' test) = LN ''ns'' tid2 &+ LN ''pc'' test = s(MV ''pc'' tid2) &+ s(MV ''ps'' test) = LN ''ps'' tid2 &+ LN ''sid'' test = s(MV ''sid'' tid2) &+ LN ''pms'' test = s(MV ''pms'' tid2) &+ (St( test, C_2 )) \<prec> (St( tid2, S_1 )) &+ (St( tid2, S_1 )) \<prec> (St( tid2, S_3 )) &+ (St( tid2, S_3 )) \<prec> (St( test, C_4 )) &+ (St( test, C_4 )) \<prec> (St( test, C_6 )) &+ (St( test, C_6 )) \<prec> (St( tid2, S_5 )) &+ (St( tid2, S_5 )) \<prec> (St( tid2, S_7 )) &+ (St( tid2, S_7 )) \<prec> (St( test, C_8 )))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources "+ Enc {| LC ''TT3'', LN ''sid'' test,+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ s(MV ''ns'' test)+ |},+ LN ''nc'' test, LN ''pc'' test, s(AV ''C'' test),+ s(MV ''ns'' test), s(MV ''ps'' test), s(AV ''S'' test)+ |}+ ( Hash {| LC ''serverKey'', LN ''nc'' test, s(MV ''ns'' test),+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ s(MV ''ns'' test)+ |}+ |}+ ) ")+ case fake+ thus ?thesis + by (auto dest: C_PRF_sec intro: event_predOrdI)+ next+ case (S_7_enc tid2)+ thus ?thesis+ proof(sources "Enc {| LC ''TT0'', LN ''pms'' test |}( PK ( s(AV ''S'' test) ) ) ")+ case fake+ thus ?thesis + by (auto dest: C_pms_sec intro: event_predOrdI)+ next+ case C_6_enc+ thus ?thesis+ proof(sources "LN ''nc'' test")+ case C_2_nc+ thus ?thesis+ proof(sources "LN ''ns'' tid2")+ case S_3_ns+ thus ?thesis by force+ qed (force dest: allowed_reveals compr_predOrdI)++ next+ case C_6_nc+ thus ?thesis+ by(sources "Hash \<lbrace>LC ''clientKey'', LN ''nc'' test, LN ''ns'' tid2,+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test, LN ''ns'' tid2\<rbrace>\<rbrace>")+ qed (force dest: allowed_reveals compr_predOrdI)++ qed+ qed+qed++lemma (in TLS_state_ADVnotRNR) S_ni_synch:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_7 ) \<in> steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some C &+ s(AV ''C'' tid1) = s(AV ''C'' test) &+ s(AV ''S'' tid1) = s(AV ''S'' test) &+ LN ''nc'' tid1 = s(MV ''nc'' test) &+ s(MV ''ns'' tid1) = LN ''ns'' test &+ LN ''pc'' tid1 = s(MV ''pc'' test) &+ s(MV ''ps'' tid1) = LN ''ps'' test &+ LN ''sid'' tid1 = s(MV ''sid'' test) &+ LN ''pms'' tid1 = s(MV ''pms'' test) &+ (St( tid1, C_2 )) \<prec> (St( test, S_1 )) &+ (St( test, S_1 )) \<prec> (St( test, S_3 )) &+ (St( test, S_3 )) \<prec> (St( tid1, C_4 )) &+ (St( tid1, C_4 )) \<prec> (St( tid1, C_6 )) &+ (St( tid1, C_6 )) \<prec> (St( test, S_5 )) &+ (St( test, S_5 )) \<prec> (St( test, S_7 )))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources "+ Enc {| LC ''TT3'', s(MV ''sid'' test),+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),+ s(MV ''nc'' test), LN ''ns'' test+ |},+ s(MV ''nc'' test), s(MV ''pc'' test), s(AV ''C'' test),+ LN ''ns'' test, LN ''ps'' test, s(AV ''S'' test)+ |}+ ( Hash {| LC ''clientKey'', s(MV ''nc'' test), LN ''ns'' test,+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),+ s(MV ''nc'' test), LN ''ns'' test+ |}+ |}+ ) ")+ case fake + thus ?thesis + by (auto dest: S_PRF_sec intro: event_predOrdI) + next+ case (C_6_enc_2 tid3)+ thus ?thesis+ proof(sources "LN ''ns'' test")+ case S_3_ns+ thus ?thesis+ proof(sources "LN ''nc'' tid3")+ case C_2_nc+ thus ?thesis+ by force+ qed (force dest: allowed_reveals compr_predOrdI)++ qed (force dest: allowed_reveals compr_predOrdI)++ qed+qed+++lemma (in TLS_state_ADVall) C_ni_synch:+ assumes facts:+ "roleMap r test = Some C"+ "( test, C_8 ) \<in> steps t"+ shows+ "(? tid2.+ roleMap r tid2 = Some S &+ s(AV ''C'' test) = s(AV ''C'' tid2) &+ s(AV ''S'' test) = s(AV ''S'' tid2) &+ LN ''nc'' test = s(MV ''nc'' tid2) &+ s(MV ''ns'' test) = LN ''ns'' tid2 &+ LN ''pc'' test = s(MV ''pc'' tid2) &+ s(MV ''ps'' test) = LN ''ps'' tid2 &+ LN ''sid'' test = s(MV ''sid'' tid2) &+ LN ''pms'' test = s(MV ''pms'' tid2) &+ (St( tid2, S_1 )) \<prec> (St( tid2, S_3 )) &+ (St( test, C_4 )) \<prec> (St( test, C_6 )) &+ (St( test, C_6 )) \<prec> (St( tid2, S_5 )) &+ (St( tid2, S_5 )) \<prec> (St( tid2, S_7 )) &+ (St( tid2, S_7 )) \<prec> (St( test, C_8 )))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources "+ Enc {| LC ''TT3'', LN ''sid'' test,+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ s(MV ''ns'' test)+ |},+ LN ''nc'' test, LN ''pc'' test, s(AV ''C'' test),+ s(MV ''ns'' test), s(MV ''ps'' test), s(AV ''S'' test)+ |}+ ( Hash {| LC ''serverKey'', LN ''nc'' test, s(MV ''ns'' test),+ Hash {| LC ''TT4'', LC ''PRF'', LN ''pms'' test, LN ''nc'' test,+ s(MV ''ns'' test)+ |}+ |}+ ) ")+ case fake+ thus ?thesis + by (auto dest: C_PRF_sec intro: event_predOrdI)+ next+ case (S_7_enc tid2)+ thus ?thesis+ proof(sources "Enc {| LC ''TT0'', LN ''pms'' test |}( PK ( s(AV ''S'' test) ) ) ")+ case fake+ thus ?thesis + by (auto dest: C_pms_sec intro: event_predOrdI)+ next+ case C_6_enc+ thus ?thesis by auto+ qed+ qed+qed++lemma (in TLS_state_ADVall) S_ni_synch:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_7 ) \<in> steps t"+ shows+ "(? tid1.+ roleMap r tid1 = Some C &+ s(AV ''C'' tid1) = s(AV ''C'' test) &+ s(AV ''S'' tid1) = s(AV ''S'' test) &+ LN ''nc'' tid1 = s(MV ''nc'' test) &+ s(MV ''ns'' tid1) = LN ''ns'' test &+ LN ''pc'' tid1 = s(MV ''pc'' test) &+ s(MV ''ps'' tid1) = LN ''ps'' test &+ LN ''sid'' tid1 = s(MV ''sid'' test) &+ LN ''pms'' tid1 = s(MV ''pms'' test) &+ (St( test, S_1 )) \<prec> (St( test, S_3 )) &+ (St( tid1, C_4 )) \<prec> (St( tid1, C_6 )) &+ (St( tid1, C_6 )) \<prec> (St( test, S_5 )) &+ (St( test, S_5 )) \<prec> (St( test, S_7 )))"+proof -+ note_prefix_closed facts = facts+ thus ?thesis proof(sources "+ Enc {| LC ''TT3'', s(MV ''sid'' test),+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),+ s(MV ''nc'' test), LN ''ns'' test+ |},+ s(MV ''nc'' test), s(MV ''pc'' test), s(AV ''C'' test),+ LN ''ns'' test, LN ''ps'' test, s(AV ''S'' test)+ |}+ ( Hash {| LC ''clientKey'', s(MV ''nc'' test), LN ''ns'' test,+ Hash {| LC ''TT4'', LC ''PRF'', s(MV ''pms'' test),+ s(MV ''nc'' test), LN ''ns'' test+ |}+ |}+ ) ")+ case fake + thus ?thesis + by (auto dest: S_PRF_sec intro: event_predOrdI) + next+ case (C_6_enc_2 tid3)+ thus ?thesis by auto+ qed+qed++++section{* Use lemmas from a different Role *}++definition+ TLS_partners :: "partnering"+where+ "TLS_partners q = + mk_partnering C S + {(sAV ''C'', sAV ''C'', S_1),+ (sAV ''S'', sAV ''S'', S_1),+ (sMV ''ns'', sN ''ns'', S_3),+ (sN ''pms'', sMV ''pms'',S_5)} q \<union>+ mk_partnering S C + {(sAV ''C'', sAV ''C'', C_2),+ (sAV ''S'', sAV ''S'', C_2),+ (sN ''ns'', sMV ''ns'', C_4),+ (sMV ''pms'', sN ''pms'',C_6)} q"+++lemmas (in TLS_state) TLS_partners_conv = + setEqImpTupleIn[OF TLS_partners_def, of _ _ "(t,r,s)",simplified]++lemmas (in TLS_state) TLS_partnersI[intro!] = TLS_partners_conv[THEN iffD2,simplified mk_partnering_conv,simplified]++++declare (in TLS_state) S_6_def[simp del]+lemma (in TLS_state) TLS_partners_revealsExist:+ assumes facts:+ "roleMap r i = Some C"+ "roleMap r test = Some S"+ "(test,S_3) \<in> steps t"+ "(i,test) \<in> TLS_partners (t,r,s)"+ "(i,tid1) \<in> TLS_partners (t,r,s) \<and> (tid1, S_6) \<in> steps t"+ shows+ "test = tid1"+proof -+ from facts+ have "roleMap r tid1 = Some S"+ by (fastsimp dest: mk_partneringRole simp add: TLS_partners_conv)+ note_prefix_closed facts = facts this+ thus ?thesis+ proof -+ from facts+ have "(i, tid1) \<in> mk_partnering TLS_acm.C S+ {(sLAV ''C'', sLAV ''C'', S_1), (sLAV ''S'', sLAV ''S'', S_1),+ (sLMV ''ns'', sLN ''ns'', S_3), (sLN ''pms'', sLMV ''pms'', S_5)}+ (t, r, s)"+ by (fastsimp simp add: TLS_partners_conv dest: mk_partneringRole)+ moreover+ from facts + have "(i, test) \<in> mk_partnering TLS_acm.C S+ {(sLAV ''C'', sLAV ''C'', S_1), (sLAV ''S'', sLAV ''S'', S_1),+ (sLMV ''ns'', sLN ''ns'', S_3), (sLN ''pms'', sLMV ''pms'', S_5)}+ (t, r, s)"+ by (fastsimp simp add: TLS_partners_conv dest: mk_partneringRole)+ ultimately+ show ?thesis+ using facts+ apply -+ apply(drule_tac ?st = "S_3" in uniquePartner)+ by(blast intro: event_predOrdI)++ qed +qed+declare (in TLS_state) S_6_def[simp]++lemma (in TLS_state) C_pms_origin_reuse [rule_format]:+ assumes facts:+ "roleMap r test = Some C"+ shows+ "LN ''pms'' test \<in> knows t \<longrightarrow>+ RLKR (s(AV ''S'' test)) \<in> reveals t \<or> + (test, Note ''5'' State C_5_pt) \<in> steps t \<or>+ (test, Note ''7'' State C_7_pt) \<in> steps t \<or>+ (test, Note ''9'' SessKey C_9_pt) \<in> steps t \<or>+ (\<exists> tid1. (test,tid1) \<in> TLS_partners (t,r,s) \<and> (tid1, Note ''6'' State S_6_pt) \<in> steps t)"+ (is "?knows \<longrightarrow> ?origins")+proof + assume ?knows+ thus ?origins using facts+ proof(sources " LN ''pms'' test ")+ case C_6_pms + thus ?thesis + by (sources "SK (s (AV ''S'' test))") (auto intro: compr_predOrdI)+ next+ case C_5_pms+ thus ?thesis+ by(auto intro: event_predOrdI)+ next+ case C_7_pms+ thus ?thesis+ by(auto intro: event_predOrdI)+ next+ case (S_6_pms tid1)+ thus ?thesis+ (* Proof Idea: If the adversary has learned pms from S_6_pms, then how could he send the messages in S_5 *)+ proof(sources "Enc \<lbrace>LC ''TT1'', Hash \<lbrace>LC ''TT2'', LN ''ns'' tid1, s (AV ''S'' tid1), LN ''pms'' test\<rbrace>\<rbrace>+ (SK (s (AV ''C'' tid1)))")+ case fake+ thus ?thesis+ proof(sources "Hash \<lbrace>LC ''TT2'', LN ''ns'' tid1, s (AV ''S'' tid1), LN ''pms'' test\<rbrace>")+ case C_6_hash+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT3'', s (MV ''sid'' tid1),+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1), LN ''ns'' tid1\<rbrace>,+ s (MV ''nc'' tid1), s (MV ''pc'' tid1), s (AV ''C'' tid1), LN ''ns'' tid1,+ LN ''ps'' tid1, s (AV ''S'' tid1)\<rbrace>+ (Hash \<lbrace>LC ''clientKey'', s (MV ''nc'' tid1), LN ''ns'' tid1,+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1),+ LN ''ns'' tid1\<rbrace>\<rbrace>)")+ case fake+ thus ?thesis+ proof(sources "Hash \<lbrace>LC ''clientKey'', s (MV ''nc'' tid1), LN ''ns'' tid1,+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1),+ LN ''ns'' tid1\<rbrace>\<rbrace>")+ case fake+ thus ?thesis + by(sources "Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1),+ LN ''ns'' tid1\<rbrace>")+ next+ case C_9_hash_1+ thus ?thesis+ by (auto intro: event_predOrdI)+ qed+ qed+ qed+ next+ case C_6_enc_1+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''TT3'', s (MV ''sid'' tid1),+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1), LN ''ns'' tid1\<rbrace>, s (MV ''nc'' tid1),+ s (MV ''pc'' tid1), s (AV ''C'' tid1), LN ''ns'' tid1, LN ''ps'' tid1, s (AV ''S'' tid1)\<rbrace>+ (Hash \<lbrace>LC ''clientKey'', s (MV ''nc'' tid1), LN ''ns'' tid1,+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1), LN ''ns'' tid1\<rbrace>\<rbrace>)")+ case fake+ thus ?thesis+ proof(sources "Hash \<lbrace>LC ''clientKey'', s (MV ''nc'' tid1), LN ''ns'' tid1,+ Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1), LN ''ns'' tid1\<rbrace>\<rbrace>")+ case fake+ thus ?thesis+ by(sources "Hash \<lbrace>LC ''TT4'', LC ''PRF'', LN ''pms'' test, s (MV ''nc'' tid1), LN ''ns'' tid1\<rbrace>") next+ case C_9_hash_1+ thus ?thesis+ by (auto intro: event_predOrdI)+ qed+ next+ case C_6_enc_2+ thus ?thesis+ by (auto intro: event_predOrdI)+ qed+ qed+ qed+qed+++lemma (in TLS_state) S_pms_origin_reuse [rule_format]:+ assumes facts:+ "roleMap r test = Some S"+ "( test, S_5 ) \<in> steps t"+ shows+ "s(MV ''pms'' test) \<in> knows t \<longrightarrow>+ RLKR (s(AV ''S'' test)) \<in> reveals t \<or> + RLKR (s(AV ''C'' test)) \<in> reveals t \<or> + (\<exists> tid1. (test,tid1) \<in> TLS_partners (t,r,s) \<and> + (+ (tid1, Note ''5'' State C_5_pt) \<in> steps t \<or>+ (tid1, Note ''7'' State C_7_pt) \<in> steps t \<or>+ (tid1, Note ''9'' SessKey C_9_pt) \<in> steps t + )) \<or>+ (test, Note ''6'' State S_6_pt) \<in> steps t"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume ?knows+ note_prefix_closed facts = facts this+ thus ?origins+ proof(sources "Enc {| LC ''TT1'',Hash {| LC ''TT2'', LN ''ns'' test, s(AV ''S'' test), s(MV ''pms'' test)|}|}+ ( SK ( s(AV ''C'' test) ) ) ")+ case fake+ thus ?thesis+ by(sources "SK (s (AV ''C'' test))") (auto intro: compr_predOrdI)+ next+ case (C_6_enc_1 tid1)+ note_unified facts = facts this++ hence "(test,tid1) \<in> TLS_partners (t,r,s)"+ by fastsimp+ note_unified facts = facts this+ moreover + {+ assume "RLKR (s (AV ''S'' tid1)) \<in> reveals t"+ hence "?thesis" using facts by fastsimp+ }+ moreover{+ assume "(tid1, Note ''5'' State C_5_pt) \<in> steps t"+ hence "?thesis" using facts by blast+ }+ moreover {+ assume "(tid1, Note ''7'' State C_7_pt) \<in> steps t"+ hence "?thesis" using facts by blast+ }+ moreover {+ assume "(tid1, Note ''9'' SessKey C_9_pt) \<in> steps t"+ hence "?thesis" using facts by blast+ }+ moreover {+ assume "\<exists>tid1a. (tid1, tid1a) \<in> TLS_partners (t, r, s) \<and> (tid1a, Note ''6'' State S_6_pt) \<in> steps t"+ note_unified facts = facts this+ obtain tid1a where+ partCompr: "(tid1, tid1a) \<in> TLS_partners (t, r, s) \<and> (tid1a, Note ''6'' State S_6_pt) \<in> steps t"+ using facts by fastsimp+ hence "test = tid1a" using facts+ apply -+ apply(rule TLS_partners_revealsExist,assumption,assumption,rule event_predOrdI, assumption) + by fastsimp++ hence "?thesis"+ using facts partCompr+ by fastsimp+ }+ ultimately+ show ?thesis using facts+ apply -+ apply(frule event_predOrdI, frule C_pms_origin_reuse, assumption)+ by fastsimp+ qed+qed+end
@@ -0,0 +1,492 @@+(*****************************************************************************+ * ESPL --- an embedded security protocol logic+ * http://people.inf.ethz.ch/meiersi/espl/+ *+ * Copyright (c) 2009-2011, Simon Meier, ETH Zurich, Switzerland+ *+ * Extension to compromising adversaries:+ *+ * Copyright (c) 2010-2011, Martin Schaub, ETH Zurich, Switzerland+ *+ * All rights reserved. See file LICENCE for more information.+ ******************************************************************************)++theory "wPFS_acm"+imports+ "../ESPLogic"+begin++section{* Security Proofs for a protocol guaranteeing wPFS *}++subsection{* Protocol Specificiation *}++role A+where "A =+ [ + Note ''N0'' State \<langle> sN ''sid'', sAV ''B'', sAV ''A'', PAsymPK ( sN ''na'' ), sN ''na'', PAsymSK ( sN ''na'' ) \<rangle> + , Send ''1'' ( PEnc \<langle> sC ''1'', sN ''sid'', sAV ''B'', PAsymPK ( sN ''na'' ) \<rangle>+ ( sSK ''A'' )+ )+ , Note ''N1'' State \<langle> PAsymPK ( sN ''na'' ), sN ''na'', sN ''sid'', sAV ''B'', sAV ''A'', PAsymSK ( sN ''na'' ) \<rangle> + , Recv ''2'' ( PEnc ( PEnc \<langle> sC ''2'', sN ''sid'', sAV ''A'', sMV ''k'' \<rangle>+ ( sSK ''B'' )+ )+ ( PAsymPK ( sN ''na'' ) )+ )+ , Note ''N2'' State \<langle> sMV ''k'', sN ''sid'', sAV ''B'', sAV ''A'' \<rangle>+ , Note ''3'' SessKey (sMV ''k'')+ ]"++role B+where "B =+ [ Recv ''1'' ( PEnc \<langle> sC ''1'', sMV ''sid'', sAV ''B'', sMV ''pkNa'' \<rangle>+ ( sSK ''A'' )+ )+ , Note ''N1'' State \<langle> sN ''k'', sMV ''pkNa'', sN ''sid'', sAV ''B'', sAV ''A''\<rangle>+ , Send ''2'' ( PEnc ( PEnc \<langle> sC ''2'', sMV ''sid'', sAV ''A'', sN ''k'' \<rangle>+ ( sSK ''B'' )+ )+ ( sMV ''pkNa'' )+ )+ , Note ''N2'' State \<langle> sN ''k'', sMV ''sid'', sAV ''B'', sAV ''A'' \<rangle> + , Note ''3'' SessKey (sN ''k'')+ ]"++protocol wPFS+where "wPFS = { A, B }"++(* TODO remove *)+declare (in wPFS_state) A_3_def[simp]+declare (in wPFS_state) B_3_def[simp]+declare (in wPFS_state) A_N0_def[simp]+declare (in wPFS_state) A_N1_def[simp]+declare (in wPFS_state) B_N1_def[simp]+declare (in wPFS_state) A_N2_def[simp]+declare (in wPFS_state) B_N2_def[simp]++subsection {* Typing Definition *}+type_invariant auto_msc_typing for wPFS+where "auto_msc_typing = mk_typing+ [ ((A, ''k''), (SumT (KnownT A_2) (NonceT B ''k'')))+ , ((B, ''pkNa''), (SumT (KnownT B_1) (PKT (NonceT A ''na''))))+ , ((B, ''sid''), (SumT (KnownT B_1) (NonceT A ''sid'')))+ ]"++sublocale wPFS_state \<subseteq> auto_msc_typing_state+proof -+ have "(t,r,s) \<in> approx auto_msc_typing"+ proof(cases rule: reachable_in_approxI_ext+ [OF auto_msc_typing.monoTyp, completeness_cases_rule])+ case (A_2_k t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc ( Enc \<lbrace> LC ''2'', LN ''sid'' tid0, s(AV ''A'' tid0),+ s(MV ''k'' tid0)+ \<rbrace>+ ( SK ( s(AV ''B'' tid0) ) )+ )+ ( PK ( LN ''na'' tid0 ) ) ")+ case fake note_unified facts = this facts+ thus ?thesis proof(sources! "+ Enc \<lbrace> LC ''2'', LN ''sid'' tid0, s(AV ''A'' tid0), s(MV ''k'' tid0)+ \<rbrace>+ ( SK ( s(AV ''B'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (B_1_pkNa t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc \<lbrace> LC ''1'', s(MV ''sid'' tid0), s(AV ''B'' tid0),+ s(MV ''pkNa'' tid0)+ \<rbrace>+ ( SK ( s(AV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ next+ case (B_1_sid t r s tid0) note facts = this+ then interpret state: auto_msc_typing_state t r s+ by unfold_locales auto+ show ?case using facts+ proof(sources! "+ Enc \<lbrace> LC ''1'', s(MV ''sid'' tid0), s(AV ''B'' tid0),+ s(MV ''pkNa'' tid0)+ \<rbrace>+ ( SK ( s(AV ''A'' tid0) ) ) ")+ qed (insert facts, ((fastsimp intro: event_predOrdI split: if_splits) | (fastsimp intro: event_predOrdI split: if_splits))+)?+ qed+ thus "auto_msc_typing_state t r s" by unfold_locales auto+qed++subsection{* Partnering Definition *}++definition+ wPFS_trusted :: "partnering"+where+ "wPFS_trusted q = + Id \<union>+ mk_partnering A B + {(sAV ''A'', sAV ''A'', B_1),+ (sAV ''B'', sAV ''B'', B_1),+ (sMV ''k'', sN ''k'', B_2),+ (sN ''sid'', sMV ''sid'', B_1)} q \<union> + mk_partnering B A + {(sAV ''A'', sAV ''A'', A_1),+ (sAV ''B'', sAV ''B'', A_1),+ (sMV ''sid'', sN ''sid'', A_1)} q"+++lemmas (in wPFS_state) wPFS_trusted_conv = + setEqImpTupleIn[OF wPFS_trusted_def, of _ _ "(t,r,s)", simplified]++lemmas (in wPFS_state) wPFS_trustedI[intro!] = wPFS_trusted_conv[THEN iffD2,simplified mk_partnering_conv,simplified]++subsection{* Adversary Compromise Model Definitions *}++definition (in wPFS_state) ADVall :: "tid \<Rightarrow> state set"+where+(* "ADVall i = acm {LKRothers i, LKRafterCorrect i wPFS_trusted, SkR i wPFS_trusted, StR i wPFS_trusted}" *)+"ADVall i = acm {LKRothers i, LKRafter i, SkR i wPFS_trusted, StR i wPFS_trusted}"++locale wPFS_state_ADVall = wPFS_state ++ fixes test :: tid+ assumes compromiseModel [simp,intro!]: "(t,r,s) \<in> ADVall test"+begin+ lemmas allowed_reveals = acm_to_caps[OF compromiseModel[simplified ADVall_def], simplified]+end++section {* Security Properties *}++subsection{* Origin Proofs *}++lemma (in wPFS_state) B_k_origin[rule_format]:+ assumes facts:+ "roleMap r test = Some B"+ shows+ "LN ''k'' test \<in> knows t \<longrightarrow>+ LKR (s(AV ''A'' test)) \<prec> St (test, B_1) \<or> + (\<exists> tid1. (test,tid1) \<in> wPFS_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t) \<or>+ (\<exists> tid1. (test,tid1) \<in> wPFS_trusted (t,r,s) \<and> RCompr State tid1 \<in> reveals t)"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume "?knows"+ thus "?origins" using facts + proof(sources " LN ''k'' test ")+ case B_2_k+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''1'', s (MV ''sid'' test), s (AV ''B'' test), s (MV ''pkNa'' test)\<rbrace>+ (SK (s (AV ''A'' test)))")+ case fake+ thus ?thesis+ by (sources "SK (s (AV ''A'' test))") (fastsimp intro: predOrd_distinct'_trans)+ next+ case (A_1_enc tid1)+ thus ?thesis + proof(sources " SK ( LN ''na'' tid1 ) ")+ case A_N1_SK+ thus ?thesis + by (fastsimp intro: compr_predOrdI)+ next+ case A_N0_SK+ thus ?thesis+ by (fastsimp intro: compr_predOrdI)+ qed+ qed+ next+ case B_3_k+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case B_N1_k+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case B_N2_k+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case (A_N2_k tid1)+ thus ?thesis+ proof(sources "Enc (Enc \<lbrace>LC ''2'', LN ''sid'' tid1, s (AV ''A'' tid1), LN ''k'' test\<rbrace> (SK (s (AV ''B'' tid1))))+ (PK (LN ''na'' tid1))")+ case fake+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''2'', LN ''sid'' tid1, s (AV ''A'' tid1), LN ''k'' test\<rbrace> (SK (s (AV ''B'' tid1)))")+ case B_2_enc_1+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case B_2_enc+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case (A_3_k tid1)+ thus ?thesis+ proof(sources "Enc (Enc \<lbrace>LC ''2'', LN ''sid'' tid1, s (AV ''A'' tid1), LN ''k'' test\<rbrace> (SK (s (AV ''B'' tid1))))+ (PK (LN ''na'' tid1))")+ case fake+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''2'', LN ''sid'' tid1, s (AV ''A'' tid1), LN ''k'' test\<rbrace> (SK (s (AV ''B'' tid1)))")+ case B_2_enc_1+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case B_2_enc+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ qed+qed++++lemma (in wPFS_state) A_k_origin [rule_format]:+ assumes facts:+ "roleMap r test = Some A"+ "( test, A_2 ) \<in> steps t"+ shows+ "s(MV ''k'' test) \<in> knows t \<longrightarrow>+ LKR (s(AV ''A'' test)) \<prec> St (test, A_2) \<or> + LKR (s(AV ''B'' test)) \<prec> St (test, A_2) \<or> + (\<exists> tid1. (test,tid1) \<in> wPFS_trusted (t,r,s) \<and> RCompr SessKey tid1 \<in> reveals t) \<or>+ (\<exists> tid1. (test,tid1) \<in> wPFS_trusted (t,r,s) \<and> RCompr State tid1 \<in> reveals t)"+ (is "?knows \<longrightarrow> ?origins")+proof+ assume "?knows"+ note_prefix_closed facts = facts this+ thus "?origins"+ proof(sources "Enc (Enc \<lbrace>LC ''2'', LN ''sid'' test, s (AV ''A'' test), s (MV ''k'' test)\<rbrace> (SK (s (AV ''B'' test))))+ (PK (LN ''na'' test))")+ case fake+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''2'', LN ''sid'' test, s (AV ''A'' test), s (MV ''k'' test)\<rbrace> (SK (s (AV ''B'' test)))")+ case fake+ thus ?thesis+ by (sources "SK (s (AV ''B'' test))") (fastsimp intro: predOrd_distinct'_trans)+ next+ case (B_2_enc_1 tid1)+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''1'', LN ''sid'' test, s (AV ''B'' test), s (MV ''pkNa'' tid1)\<rbrace> (SK (s (AV ''A'' test)))")+ case fake+ thus ?thesis+ by (sources "SK (s (AV ''A'' test))") (fastsimp intro: predOrd_distinct'_trans)+ qed+ qed+ next+ case (B_2_enc tid1)+ thus ?thesis+ proof(sources "LN ''k'' tid1")+ case B_N1_k+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case B_N2_k+ thus ?thesis+ by (auto intro: compr_predOrdI) + next+ case B_3_k+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case B_2_k+ thus ?thesis+ proof(sources "SK (LN ''na'' test)")+ case A_N1_SK+ thus ?thesis+ by (auto intro: compr_predOrdI)+ next+ case A_N0_SK+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case (A_N2_k test')+ note_unified facts = facts this+ thus ?thesis+ proof(sources "Enc (Enc \<lbrace>LC ''2'', LN ''sid'' test', s (AV ''A'' test'), LN ''k'' tid1\<rbrace> (SK (s (AV ''B'' test'))))+ (PK (LN ''na'' test'))")+ case fake+ thus ?thesis+ by (sources "Enc \<lbrace>LC ''2'', LN ''sid'' test', s (AV ''A'' test'), LN ''k'' tid1\<rbrace>+ (SK (s (AV ''B'' test')))")+ next+ case B_2_enc+ note_unified facts = facts this+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ next+ case (A_3_k test')+ note_unified facts = facts this+ thus ?thesis+ proof(sources "Enc (Enc \<lbrace>LC ''2'', LN ''sid'' test', s (AV ''A'' test'), LN ''k'' tid1\<rbrace> (SK (s (AV ''B'' test'))))+ (PK (LN ''na'' test'))")+ case fake+ thus ?thesis+ by (sources "Enc \<lbrace>LC ''2'', LN ''sid'' test', s (AV ''A'' test'), LN ''k'' tid1\<rbrace>+ (SK (s (AV ''B'' test')))")+ next+ case B_2_enc+ note_unified facts = facts this+ thus ?thesis+ by (auto intro: compr_predOrdI)+ qed+ qed+ qed+qed++subsection{* Secrecy Proofs *}+lemma (in wPFS_state_ADVall) B_sec_k:+ assumes facts:+ "roleMap r test = Some B"+ "LN ''k'' test \<in> knows t"+ "(test,B_2) \<in> steps t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ moreover {+ assume "LKR (s (AV ''A'' test)) \<prec> St (test, B_1)"+ hence "?thesis" using facts+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (auto dest: allowed_reveals)+ }+ moreover {+ assume "(\<exists>tid1. (test, tid1) \<in> wPFS_trusted (t, r, s) \<and> RCompr SessKey tid1 \<in> reveals t) \<or> + (\<exists>tid1. (test, tid1) \<in> wPFS_trusted (t, r, s) \<and> RCompr State tid1 \<in> reveals t)"+ hence "?thesis" using facts by(auto dest: allowed_reveals)+ }+ ultimately show ?thesis by (auto dest: B_k_origin)+qed++lemma (in wPFS_state_ADVall) A_sec_k:+ assumes facts:+ "roleMap r test = Some A"+ "( test, A_2 ) \<in> steps t"+ "s(MV ''k'' test) \<in> knows t"+ shows "False"+proof -+ note_prefix_closed facts = facts+ moreover {+ assume "LKR (s (AV ''A'' test)) \<prec> St (test, A_2)"+ hence "?thesis" using facts+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (auto dest: allowed_reveals)+ }+ moreover {+ assume "LKR (s (AV ''B'' test)) \<prec> St (test, A_2)"+ hence "?thesis" using facts+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (auto dest: allowed_reveals)+ } + moreover {+ assume "(\<exists>tid1. (test, tid1) \<in> wPFS_trusted (t, r, s) \<and> RCompr SessKey tid1 \<in> reveals t) \<or> + (\<exists>tid1. (test, tid1) \<in> wPFS_trusted (t, r, s) \<and> RCompr State tid1 \<in> reveals t)"+ hence "?thesis" using facts by(auto dest: allowed_reveals)+ }+ ultimately show ?thesis by (auto dest: A_k_origin)+qed+++subsection{* Authentication Proofs *}+lemma (in wPFS_state_ADVall) A_ni_auth:+ assumes facts:+ "roleMap r test = Some A"+ "(test, A_2) \<in> steps t"+ shows+ "\<exists> tid1. + roleMap r tid1 = Some B \<and>+ s(AV ''A'' test) = s(AV ''A'' tid1) \<and>+ s(AV ''B'' test) = s(AV ''B'' tid1) \<and>+ s(MV ''k'' test) = LN ''k'' tid1 \<and>+ LN ''sid'' test = s(MV ''sid'' tid1) \<and>+ PK (LN ''na'' test) = s (MV ''pkNa'' tid1) \<and>+ St (test, A_1) \<prec> St (tid1, B_1) \<and>+ St (tid1, B_2) \<prec> St (test, A_2)"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Enc (Enc \<lbrace>LC ''2'', LN ''sid'' test, s (AV ''A'' test), s (MV ''k'' test)\<rbrace> (SK (s (AV ''B'' test)))) (PK (LN ''na'' test))")+ case fake+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''2'', LN ''sid'' test, s (AV ''A'' test), s (MV ''k'' test)\<rbrace> (SK (s (AV ''B'' test)))")+ case fake+ thus ?thesis+ by (fastsimp dest: A_sec_k event_predOrdI)+ next+ case (B_2_enc_1 tid1)+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''1'', LN ''sid'' test, s (AV ''B'' test), s (MV ''pkNa'' tid1)\<rbrace> (SK (s (AV ''A'' test)))")+ case fake+ thus ?thesis+ proof(sources "SK (s (AV ''A'' tid1))")+ case asym_lkr+ thus ?thesis+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (fastsimp dest: allowed_reveals)+ qed+ qed+ qed+ next+ case (B_2_enc tid1)+ thus ?thesis + proof(sources "Enc \<lbrace>LC ''1'', LN ''sid'' test, s (AV ''B'' test), PK (LN ''na'' test)\<rbrace> (SK (s (AV ''A'' test)))")+ case fake+ thus ?thesis+ proof(sources "SK (s (AV ''A'' tid1))")+ case asym_lkr+ thus ?thesis+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (fastsimp dest: allowed_reveals)+ qed+ next+ case A_1_enc+ thus ?thesis by force+ qed + qed+qed++lemma (in wPFS_state_ADVall) B_ni_auth:+ assumes facts:+ "roleMap r test = Some B"+ "(test, B_2) \<in> steps t"+ shows+ "\<exists> tid1. + roleMap r tid1 = Some A \<and>+ s(AV ''A'' tid1) = s(AV ''A'' test) \<and>+ s(AV ''B'' tid1) = s(AV ''B'' test) \<and>+ PK (LN ''na'' tid1) = s (MV ''pkNa'' test) \<and>+ LN ''sid'' tid1 = s (MV ''sid'' test) \<and>+ St (tid1, A_1) \<prec> St (test, B_1)"+proof -+ note_prefix_closed facts = facts+ thus ?thesis+ proof(sources "Enc \<lbrace>LC ''1'', s (MV ''sid'' test), s (AV ''B'' test), s (MV ''pkNa'' test)\<rbrace>+ (SK (s (AV ''A'' test)))")+ case fake+ thus ?thesis+ proof(sources "SK (s (AV ''A'' test))")+ case asym_lkr+ thus ?thesis+ apply -+ apply(frule lkr_in_reveals_predOrd1)+ by (fastsimp dest: allowed_reveals)+ qed+ next+ case (A_1_enc tid1)+ thus ?thesis+ by auto+ qed+qed++end
@@ -0,0 +1,645 @@+;;+;; Keyword classification tables for Isabelle/Isar.+;; Generated from Pure + Pure-ProofGeneral + HOL + HOLCF + IOA + HOL-Boogie + HOL-Nominal + HOL-SMT + HOL-Statespace.+;; *** DO NOT EDIT *** DO NOT EDIT *** DO NOT EDIT ***+;;++(defconst isar-keywords-major+ '("\\."+ "\\.\\."+ "Isabelle\\.command"+ "Isar\\.begin_document"+ "Isar\\.define_command"+ "Isar\\.edit_document"+ "Isar\\.end_document"+ "ML"+ "ML_command"+ "ML_prf"+ "ML_val"+ "ProofGeneral\\.inform_file_processed"+ "ProofGeneral\\.inform_file_retracted"+ "ProofGeneral\\.kill_proof"+ "ProofGeneral\\.pr"+ "ProofGeneral\\.process_pgip"+ "ProofGeneral\\.restart"+ "ProofGeneral\\.undo"+ "abbreviation"+ "also"+ "apply"+ "apply_end"+ "arities"+ "assume"+ "atom_decl"+ "atp_info"+ "atp_kill"+ "atp_messages"+ "atp_minimize"+ "attribute_setup"+ "automaton"+ "ax_specification"+ "axclass"+ "axiomatization"+ "axioms"+ "back"+ "boogie_end"+ "boogie_open"+ "boogie_status"+ "boogie_vc"+ "by"+ "cannot_undo"+ "case"+ "cd"+ "chapter"+ "class"+ "class_deps"+ "classes"+ "classrel"+ "code_abort"+ "code_class"+ "code_const"+ "code_datatype"+ "code_deps"+ "code_include"+ "code_instance"+ "code_library"+ "code_module"+ "code_modulename"+ "code_monad"+ "code_pred"+ "code_reserved"+ "code_thms"+ "code_type"+ "coinductive"+ "coinductive_set"+ "commit"+ "constdefs"+ "consts"+ "consts_code"+ "context"+ "corollary"+ "cpodef"+ "datatype"+ "declaration"+ "declare"+ "def"+ "defaultsort"+ "defer"+ "defer_recdef"+ "definition"+ "defs"+ "disable_pr"+ "display_drafts"+ "domain"+ "domain_isomorphism"+ "done"+ "enable_pr"+ "end"+ "equivariance"+ "exit"+ "export_code"+ "extract"+ "extract_type"+ "finalconsts"+ "finally"+ "find_consts"+ "find_theorems"+ "fix"+ "fixpat"+ "fixrec"+ "from"+ "full_prf"+ "fun"+ "function"+ "global"+ "guess"+ "have"+ "header"+ "help"+ "hence"+ "hide"+ "inductive"+ "inductive_cases"+ "inductive_set"+ "init_toplevel"+ "instance"+ "instantiation"+ "interpret"+ "interpretation"+ "judgment"+ "kill"+ "kill_thy"+ "lemma"+ "lemmas"+ "let"+ "linear_undo"+ "local"+ "local_setup"+ "locale"+ "method_setup"+ "moreover"+ "new_domain"+ "next"+ "nitpick"+ "nitpick_params"+ "no_notation"+ "no_syntax"+ "no_translations"+ "nominal_datatype"+ "nominal_inductive"+ "nominal_inductive2"+ "nominal_primrec"+ "nonterminals"+ "normal_form"+ "notation"+ "note"+ "note_prefix_closed"+ "note_unified"+ "note_cyclic"+ "obtain"+ "oops"+ "oracle"+ "overloading"+ "parse_ast_translation"+ "parse_translation"+ "pcpodef"+ "pr"+ "prefer"+ "presume"+ "pretty_setmargin"+ "prf"+ "primrec"+ "print_abbrevs"+ "print_antiquotations"+ "print_ast_translation"+ "print_atps"+ "print_attributes"+ "print_binds"+ "print_cases"+ "print_claset"+ "print_classes"+ "print_codeproc"+ "print_codesetup"+ "print_commands"+ "print_configs"+ "print_context"+ "print_drafts"+ "print_facts"+ "print_induct_rules"+ "print_interps"+ "print_locale"+ "print_locales"+ "print_methods"+ "print_orders"+ "print_rules"+ "print_simpset"+ "print_statement"+ "print_syntax"+ "print_theorems"+ "print_theory"+ "print_trans_rules"+ "print_translation"+ "proof"+ "prop"+ "protocol"+ "pwd"+ "qed"+ "quickcheck"+ "quickcheck_params"+ "quit"+ "realizability"+ "realizers"+ "recdef"+ "recdef_tc"+ "record"+ "refute"+ "refute_params"+ "remove_thy"+ "rep_datatype"+ "role"+ "repdef"+ "sect"+ "section"+ "setup"+ "show"+ "simproc_setup"+ "sledgehammer"+ "smt_status"+ "sorry"+ "specification"+ "statespace"+ "subclass"+ "sublocale"+ "subsect"+ "subsection"+ "subsubsect"+ "subsubsection"+ "syntax"+ "term"+ "termination"+ "text"+ "text_raw"+ "then"+ "theorem"+ "theorems"+ "theory"+ "thm"+ "thm_deps"+ "thus"+ "thy_deps"+ "touch_thy"+ "translations"+ "txt"+ "txt_raw"+ "typ"+ "typed_print_translation"+ "typedecl"+ "typedef"+ "types"+ "types_code"+ "type_invariant"+ "ultimately"+ "undo"+ "undos_proof"+ "unfolding"+ "unused_thms"+ "use"+ "use_thy"+ "using"+ "prefix_close"+ "value"+ "values"+ "welcome"+ "with"+ "{"+ "}"))++(defconst isar-keywords-minor+ '("actions"+ "advanced"+ "and"+ "assumes"+ "attach"+ "avoids"+ "begin"+ "binder"+ "compose"+ "congs"+ "constrains"+ "contains"+ "defines"+ "file"+ "fixes"+ "for"+ "hide_action"+ "hints"+ "identifier"+ "if"+ "imports"+ "in"+ "infix"+ "infixl"+ "infixr"+ "initially"+ "inputs"+ "internals"+ "is"+ "lazy"+ "module_name"+ "monos"+ "morphisms"+ "notes"+ "obtains"+ "open"+ "output"+ "outputs"+ "overloaded"+ "permissive"+ "pervasive"+ "post"+ "pre"+ "rename"+ "restrict"+ "shows"+ "signature"+ "states"+ "structure"+ "to"+ "transitions"+ "transrel"+ "unchecked"+ "uses"+ "where"))++(defconst isar-keywords-control+ '("Isabelle\\.command"+ "Isar\\.begin_document"+ "Isar\\.define_command"+ "Isar\\.edit_document"+ "Isar\\.end_document"+ "ProofGeneral\\.inform_file_processed"+ "ProofGeneral\\.inform_file_retracted"+ "ProofGeneral\\.kill_proof"+ "ProofGeneral\\.process_pgip"+ "ProofGeneral\\.restart"+ "ProofGeneral\\.undo"+ "cannot_undo"+ "exit"+ "init_toplevel"+ "kill"+ "linear_undo"+ "quit"+ "undo"+ "undos_proof"))++(defconst isar-keywords-diag+ '("ML_command"+ "ML_val"+ "ProofGeneral\\.pr"+ "atp_info"+ "atp_kill"+ "atp_messages"+ "atp_minimize"+ "boogie_status"+ "cd"+ "class_deps"+ "code_deps"+ "code_thms"+ "commit"+ "disable_pr"+ "display_drafts"+ "enable_pr"+ "export_code"+ "find_consts"+ "find_theorems"+ "full_prf"+ "header"+ "help"+ "kill_thy"+ "nitpick"+ "normal_form"+ "pr"+ "pretty_setmargin"+ "prf"+ "print_abbrevs"+ "print_antiquotations"+ "print_atps"+ "print_attributes"+ "print_binds"+ "print_cases"+ "print_claset"+ "print_classes"+ "print_codeproc"+ "print_codesetup"+ "print_commands"+ "print_configs"+ "print_context"+ "print_drafts"+ "print_facts"+ "print_induct_rules"+ "print_interps"+ "print_locale"+ "print_locales"+ "print_methods"+ "print_orders"+ "print_rules"+ "print_simpset"+ "print_statement"+ "print_syntax"+ "print_theorems"+ "print_theory"+ "print_trans_rules"+ "prop"+ "pwd"+ "quickcheck"+ "refute"+ "remove_thy"+ "sledgehammer"+ "smt_status"+ "term"+ "thm"+ "thm_deps"+ "thy_deps"+ "touch_thy"+ "typ"+ "unused_thms"+ "use_thy"+ "value"+ "values"+ "welcome"))++(defconst isar-keywords-theory-begin+ '("theory"))++(defconst isar-keywords-theory-switch+ '())++(defconst isar-keywords-theory-end+ '("end"))++(defconst isar-keywords-theory-heading+ '("chapter"+ "section"+ "subsection"+ "subsubsection"))++(defconst isar-keywords-theory-decl+ '("ML"+ "abbreviation"+ "arities"+ "atom_decl"+ "attribute_setup"+ "automaton"+ "axclass"+ "axiomatization"+ "axioms"+ "boogie_end"+ "boogie_open"+ "class"+ "classes"+ "classrel"+ "code_abort"+ "code_class"+ "code_const"+ "code_datatype"+ "code_include"+ "code_instance"+ "code_library"+ "code_module"+ "code_modulename"+ "code_monad"+ "code_reserved"+ "code_type"+ "coinductive"+ "coinductive_set"+ "constdefs"+ "consts"+ "consts_code"+ "context"+ "datatype"+ "declaration"+ "declare"+ "defaultsort"+ "defer_recdef"+ "definition"+ "defs"+ "domain"+ "domain_isomorphism"+ "equivariance"+ "extract"+ "extract_type"+ "finalconsts"+ "fixpat"+ "fixrec"+ "fun"+ "global"+ "hide"+ "inductive"+ "inductive_set"+ "instantiation"+ "judgment"+ "lemmas"+ "local"+ "local_setup"+ "locale"+ "method_setup"+ "new_domain"+ "nitpick_params"+ "no_notation"+ "no_syntax"+ "no_translations"+ "nominal_datatype"+ "nonterminals"+ "notation"+ "oracle"+ "overloading"+ "parse_ast_translation"+ "parse_translation"+ "primrec"+ "print_ast_translation"+ "print_translation"+ "protocol"+ "quickcheck_params"+ "realizability"+ "realizers"+ "recdef"+ "record"+ "refute_params"+ "repdef"+ "role"+ "setup"+ "simproc_setup"+ "statespace"+ "syntax"+ "text"+ "text_raw"+ "theorems"+ "translations"+ "typed_print_translation"+ "typedecl"+ "types"+ "types_code"+ "type_invariant"+ "use"))++(defconst isar-keywords-theory-script+ '("inductive_cases"))++(defconst isar-keywords-theory-goal+ '("ax_specification"+ "boogie_vc"+ "code_pred"+ "corollary"+ "cpodef"+ "function"+ "instance"+ "interpretation"+ "lemma"+ "nominal_inductive"+ "nominal_inductive2"+ "nominal_primrec"+ "pcpodef"+ "recdef_tc"+ "rep_datatype"+ "specification"+ "subclass"+ "sublocale"+ "termination"+ "theorem"+ "typedef"))++(defconst isar-keywords-qed+ '("\\."+ "\\.\\."+ "by"+ "done"+ "sorry"))++(defconst isar-keywords-qed-block+ '("qed"))++(defconst isar-keywords-qed-global+ '("oops"))++(defconst isar-keywords-proof-heading+ '("sect"+ "subsect"+ "subsubsect"))++(defconst isar-keywords-proof-goal+ '("have"+ "hence"+ "interpret"))++(defconst isar-keywords-proof-block+ '("next"+ "proof"))++(defconst isar-keywords-proof-open+ '("{"))++(defconst isar-keywords-proof-close+ '("}"))++(defconst isar-keywords-proof-chain+ '("finally"+ "from"+ "then"+ "ultimately"+ "with"))++(defconst isar-keywords-proof-decl+ '("ML_prf"+ "also"+ "let"+ "moreover"+ "note"+ "note_prefix_closed"+ "note_unified"+ "note_cyclic"+ "txt"+ "txt_raw"+ "unfolding"+ "using"+ "prefix_close"))++(defconst isar-keywords-proof-asm+ '("assume"+ "case"+ "def"+ "fix"+ "presume"))++(defconst isar-keywords-proof-asm-goal+ '("guess"+ "obtain"+ "show"+ "thus"))++(defconst isar-keywords-proof-script+ '("apply"+ "apply_end"+ "back"+ "defer"+ "prefer"))++(provide 'isar-keywords)
@@ -0,0 +1,6240 @@+/*!+ * jQuery JavaScript Library v1.4.2+ * http://jquery.com/+ *+ * Copyright 2010, John Resig+ * Dual licensed under the MIT or GPL Version 2 licenses.+ * http://jquery.org/license+ *+ * Includes Sizzle.js+ * http://sizzlejs.com/+ * Copyright 2010, The Dojo Foundation+ * Released under the MIT, BSD, and GPL Licenses.+ *+ * Date: Sat Feb 13 22:33:48 2010 -0500+ */+(function( window, undefined ) {++// Define a local copy of jQuery+var jQuery = function( selector, context ) {+ // The jQuery object is actually just the init constructor 'enhanced'+ return new jQuery.fn.init( selector, context );+ },++ // Map over jQuery in case of overwrite+ _jQuery = window.jQuery,++ // Map over the $ in case of overwrite+ _$ = window.$,++ // Use the correct document accordingly with window argument (sandbox)+ document = window.document,++ // A central reference to the root jQuery(document)+ rootjQuery,++ // A simple way to check for HTML strings or ID strings+ // (both of which we optimize for)+ quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/,++ // Is it a simple selector+ isSimple = /^.[^:#\[\.,]*$/,++ // Check if a string has a non-whitespace character in it+ rnotwhite = /\S/,++ // Used for trimming whitespace+ rtrim = /^(\s|\u00A0)+|(\s|\u00A0)+$/g,++ // Match a standalone tag+ rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>)?$/,++ // Keep a UserAgent string for use with jQuery.browser+ userAgent = navigator.userAgent,++ // For matching the engine and version of the browser+ browserMatch,+ + // Has the ready events already been bound?+ readyBound = false,+ + // The functions to execute on DOM ready+ readyList = [],++ // The ready event handler+ DOMContentLoaded,++ // Save a reference to some core methods+ toString = Object.prototype.toString,+ hasOwnProperty = Object.prototype.hasOwnProperty,+ push = Array.prototype.push,+ slice = Array.prototype.slice,+ indexOf = Array.prototype.indexOf;++jQuery.fn = jQuery.prototype = {+ init: function( selector, context ) {+ var match, elem, ret, doc;++ // Handle $(""), $(null), or $(undefined)+ if ( !selector ) {+ return this;+ }++ // Handle $(DOMElement)+ if ( selector.nodeType ) {+ this.context = this[0] = selector;+ this.length = 1;+ return this;+ }+ + // The body element only exists once, optimize finding it+ if ( selector === "body" && !context ) {+ this.context = document;+ this[0] = document.body;+ this.selector = "body";+ this.length = 1;+ return this;+ }++ // Handle HTML strings+ if ( typeof selector === "string" ) {+ // Are we dealing with HTML string or an ID?+ match = quickExpr.exec( selector );++ // Verify a match, and that no context was specified for #id+ if ( match && (match[1] || !context) ) {++ // HANDLE: $(html) -> $(array)+ if ( match[1] ) {+ doc = (context ? context.ownerDocument || context : document);++ // If a single string is passed in and it's a single tag+ // just do a createElement and skip the rest+ ret = rsingleTag.exec( selector );++ if ( ret ) {+ if ( jQuery.isPlainObject( context ) ) {+ selector = [ document.createElement( ret[1] ) ];+ jQuery.fn.attr.call( selector, context, true );++ } else {+ selector = [ doc.createElement( ret[1] ) ];+ }++ } else {+ ret = buildFragment( [ match[1] ], [ doc ] );+ selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;+ }+ + return jQuery.merge( this, selector );+ + // HANDLE: $("#id")+ } else {+ elem = document.getElementById( match[2] );++ if ( elem ) {+ // Handle the case where IE and Opera return items+ // by name instead of ID+ if ( elem.id !== match[2] ) {+ return rootjQuery.find( selector );+ }++ // Otherwise, we inject the element directly into the jQuery object+ this.length = 1;+ this[0] = elem;+ }++ this.context = document;+ this.selector = selector;+ return this;+ }++ // HANDLE: $("TAG")+ } else if ( !context && /^\w+$/.test( selector ) ) {+ this.selector = selector;+ this.context = document;+ selector = document.getElementsByTagName( selector );+ return jQuery.merge( this, selector );++ // HANDLE: $(expr, $(...))+ } else if ( !context || context.jquery ) {+ return (context || rootjQuery).find( selector );++ // HANDLE: $(expr, context)+ // (which is just equivalent to: $(context).find(expr)+ } else {+ return jQuery( context ).find( selector );+ }++ // HANDLE: $(function)+ // Shortcut for document ready+ } else if ( jQuery.isFunction( selector ) ) {+ return rootjQuery.ready( selector );+ }++ if (selector.selector !== undefined) {+ this.selector = selector.selector;+ this.context = selector.context;+ }++ return jQuery.makeArray( selector, this );+ },++ // Start with an empty selector+ selector: "",++ // The current version of jQuery being used+ jquery: "1.4.2",++ // The default length of a jQuery object is 0+ length: 0,++ // The number of elements contained in the matched element set+ size: function() {+ return this.length;+ },++ toArray: function() {+ return slice.call( this, 0 );+ },++ // Get the Nth element in the matched element set OR+ // Get the whole matched element set as a clean array+ get: function( num ) {+ return num == null ?++ // Return a 'clean' array+ this.toArray() :++ // Return just the object+ ( num < 0 ? this.slice(num)[ 0 ] : this[ num ] );+ },++ // Take an array of elements and push it onto the stack+ // (returning the new matched element set)+ pushStack: function( elems, name, selector ) {+ // Build a new jQuery matched element set+ var ret = jQuery();++ if ( jQuery.isArray( elems ) ) {+ push.apply( ret, elems );+ + } else {+ jQuery.merge( ret, elems );+ }++ // Add the old object onto the stack (as a reference)+ ret.prevObject = this;++ ret.context = this.context;++ if ( name === "find" ) {+ ret.selector = this.selector + (this.selector ? " " : "") + selector;+ } else if ( name ) {+ ret.selector = this.selector + "." + name + "(" + selector + ")";+ }++ // Return the newly-formed element set+ return ret;+ },++ // Execute a callback for every element in the matched set.+ // (You can seed the arguments with an array of args, but this is+ // only used internally.)+ each: function( callback, args ) {+ return jQuery.each( this, callback, args );+ },+ + ready: function( fn ) {+ // Attach the listeners+ jQuery.bindReady();++ // If the DOM is already ready+ if ( jQuery.isReady ) {+ // Execute the function immediately+ fn.call( document, jQuery );++ // Otherwise, remember the function for later+ } else if ( readyList ) {+ // Add the function to the wait list+ readyList.push( fn );+ }++ return this;+ },+ + eq: function( i ) {+ return i === -1 ?+ this.slice( i ) :+ this.slice( i, +i + 1 );+ },++ first: function() {+ return this.eq( 0 );+ },++ last: function() {+ return this.eq( -1 );+ },++ slice: function() {+ return this.pushStack( slice.apply( this, arguments ),+ "slice", slice.call(arguments).join(",") );+ },++ map: function( callback ) {+ return this.pushStack( jQuery.map(this, function( elem, i ) {+ return callback.call( elem, i, elem );+ }));+ },+ + end: function() {+ return this.prevObject || jQuery(null);+ },++ // For internal use only.+ // Behaves like an Array's method, not like a jQuery method.+ push: push,+ sort: [].sort,+ splice: [].splice+};++// Give the init function the jQuery prototype for later instantiation+jQuery.fn.init.prototype = jQuery.fn;++jQuery.extend = jQuery.fn.extend = function() {+ // copy reference to target object+ var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options, name, src, copy;++ // Handle a deep copy situation+ if ( typeof target === "boolean" ) {+ deep = target;+ target = arguments[1] || {};+ // skip the boolean and the target+ i = 2;+ }++ // Handle case when target is a string or something (possible in deep copy)+ if ( typeof target !== "object" && !jQuery.isFunction(target) ) {+ target = {};+ }++ // extend jQuery itself if only one argument is passed+ if ( length === i ) {+ target = this;+ --i;+ }++ for ( ; i < length; i++ ) {+ // Only deal with non-null/undefined values+ if ( (options = arguments[ i ]) != null ) {+ // Extend the base object+ for ( name in options ) {+ src = target[ name ];+ copy = options[ name ];++ // Prevent never-ending loop+ if ( target === copy ) {+ continue;+ }++ // Recurse if we're merging object literal values or arrays+ if ( deep && copy && ( jQuery.isPlainObject(copy) || jQuery.isArray(copy) ) ) {+ var clone = src && ( jQuery.isPlainObject(src) || jQuery.isArray(src) ) ? src+ : jQuery.isArray(copy) ? [] : {};++ // Never move original objects, clone them+ target[ name ] = jQuery.extend( deep, clone, copy );++ // Don't bring in undefined values+ } else if ( copy !== undefined ) {+ target[ name ] = copy;+ }+ }+ }+ }++ // Return the modified object+ return target;+};++jQuery.extend({+ noConflict: function( deep ) {+ window.$ = _$;++ if ( deep ) {+ window.jQuery = _jQuery;+ }++ return jQuery;+ },+ + // Is the DOM ready to be used? Set to true once it occurs.+ isReady: false,+ + // Handle when the DOM is ready+ ready: function() {+ // Make sure that the DOM is not already loaded+ if ( !jQuery.isReady ) {+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).+ if ( !document.body ) {+ return setTimeout( jQuery.ready, 13 );+ }++ // Remember that the DOM is ready+ jQuery.isReady = true;++ // If there are functions bound, to execute+ if ( readyList ) {+ // Execute all of them+ var fn, i = 0;+ while ( (fn = readyList[ i++ ]) ) {+ fn.call( document, jQuery );+ }++ // Reset the list of functions+ readyList = null;+ }++ // Trigger any bound ready events+ if ( jQuery.fn.triggerHandler ) {+ jQuery( document ).triggerHandler( "ready" );+ }+ }+ },+ + bindReady: function() {+ if ( readyBound ) {+ return;+ }++ readyBound = true;++ // Catch cases where $(document).ready() is called after the+ // browser event has already occurred.+ if ( document.readyState === "complete" ) {+ return jQuery.ready();+ }++ // Mozilla, Opera and webkit nightlies currently support this event+ if ( document.addEventListener ) {+ // Use the handy event callback+ document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false );+ + // A fallback to window.onload, that will always work+ window.addEventListener( "load", jQuery.ready, false );++ // If IE event model is used+ } else if ( document.attachEvent ) {+ // ensure firing before onload,+ // maybe late but safe also for iframes+ document.attachEvent("onreadystatechange", DOMContentLoaded);+ + // A fallback to window.onload, that will always work+ window.attachEvent( "onload", jQuery.ready );++ // If IE and not a frame+ // continually check to see if the document is ready+ var toplevel = false;++ try {+ toplevel = window.frameElement == null;+ } catch(e) {}++ if ( document.documentElement.doScroll && toplevel ) {+ doScrollCheck();+ }+ }+ },++ // See test/unit/core.js for details concerning isFunction.+ // Since version 1.3, DOM methods and functions like alert+ // aren't supported. They return false on IE (#2968).+ isFunction: function( obj ) {+ return toString.call(obj) === "[object Function]";+ },++ isArray: function( obj ) {+ return toString.call(obj) === "[object Array]";+ },++ isPlainObject: function( obj ) {+ // Must be an Object.+ // Because of IE, we also have to check the presence of the constructor property.+ // Make sure that DOM nodes and window objects don't pass through, as well+ if ( !obj || toString.call(obj) !== "[object Object]" || obj.nodeType || obj.setInterval ) {+ return false;+ }+ + // Not own constructor property must be Object+ if ( obj.constructor+ && !hasOwnProperty.call(obj, "constructor")+ && !hasOwnProperty.call(obj.constructor.prototype, "isPrototypeOf") ) {+ return false;+ }+ + // Own properties are enumerated firstly, so to speed up,+ // if last one is own, then all properties are own.+ + var key;+ for ( key in obj ) {}+ + return key === undefined || hasOwnProperty.call( obj, key );+ },++ isEmptyObject: function( obj ) {+ for ( var name in obj ) {+ return false;+ }+ return true;+ },+ + error: function( msg ) {+ throw msg;+ },+ + parseJSON: function( data ) {+ if ( typeof data !== "string" || !data ) {+ return null;+ }++ // Make sure leading/trailing whitespace is removed (IE can't handle it)+ data = jQuery.trim( data );+ + // Make sure the incoming data is actual JSON+ // Logic borrowed from http://json.org/json2.js+ if ( /^[\],:{}\s]*$/.test(data.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, "@")+ .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, "]")+ .replace(/(?:^|:|,)(?:\s*\[)+/g, "")) ) {++ // Try to use the native JSON parser first+ return window.JSON && window.JSON.parse ?+ window.JSON.parse( data ) :+ (new Function("return " + data))();++ } else {+ jQuery.error( "Invalid JSON: " + data );+ }+ },++ noop: function() {},++ // Evalulates a script in a global context+ globalEval: function( data ) {+ if ( data && rnotwhite.test(data) ) {+ // Inspired by code by Andrea Giammarchi+ // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html+ var head = document.getElementsByTagName("head")[0] || document.documentElement,+ script = document.createElement("script");++ script.type = "text/javascript";++ if ( jQuery.support.scriptEval ) {+ script.appendChild( document.createTextNode( data ) );+ } else {+ script.text = data;+ }++ // Use insertBefore instead of appendChild to circumvent an IE6 bug.+ // This arises when a base node is used (#2709).+ head.insertBefore( script, head.firstChild );+ head.removeChild( script );+ }+ },++ nodeName: function( elem, name ) {+ return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();+ },++ // args is for internal usage only+ each: function( object, callback, args ) {+ var name, i = 0,+ length = object.length,+ isObj = length === undefined || jQuery.isFunction(object);++ if ( args ) {+ if ( isObj ) {+ for ( name in object ) {+ if ( callback.apply( object[ name ], args ) === false ) {+ break;+ }+ }+ } else {+ for ( ; i < length; ) {+ if ( callback.apply( object[ i++ ], args ) === false ) {+ break;+ }+ }+ }++ // A special, fast, case for the most common use of each+ } else {+ if ( isObj ) {+ for ( name in object ) {+ if ( callback.call( object[ name ], name, object[ name ] ) === false ) {+ break;+ }+ }+ } else {+ for ( var value = object[0];+ i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {}+ }+ }++ return object;+ },++ trim: function( text ) {+ return (text || "").replace( rtrim, "" );+ },++ // results is for internal usage only+ makeArray: function( array, results ) {+ var ret = results || [];++ if ( array != null ) {+ // The window, strings (and functions) also have 'length'+ // The extra typeof function check is to prevent crashes+ // in Safari 2 (See: #3039)+ if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {+ push.call( ret, array );+ } else {+ jQuery.merge( ret, array );+ }+ }++ return ret;+ },++ inArray: function( elem, array ) {+ if ( array.indexOf ) {+ return array.indexOf( elem );+ }++ for ( var i = 0, length = array.length; i < length; i++ ) {+ if ( array[ i ] === elem ) {+ return i;+ }+ }++ return -1;+ },++ merge: function( first, second ) {+ var i = first.length, j = 0;++ if ( typeof second.length === "number" ) {+ for ( var l = second.length; j < l; j++ ) {+ first[ i++ ] = second[ j ];+ }+ + } else {+ while ( second[j] !== undefined ) {+ first[ i++ ] = second[ j++ ];+ }+ }++ first.length = i;++ return first;+ },++ grep: function( elems, callback, inv ) {+ var ret = [];++ // Go through the array, only saving the items+ // that pass the validator function+ for ( var i = 0, length = elems.length; i < length; i++ ) {+ if ( !inv !== !callback( elems[ i ], i ) ) {+ ret.push( elems[ i ] );+ }+ }++ return ret;+ },++ // arg is for internal usage only+ map: function( elems, callback, arg ) {+ var ret = [], value;++ // Go through the array, translating each of the items to their+ // new value (or values).+ for ( var i = 0, length = elems.length; i < length; i++ ) {+ value = callback( elems[ i ], i, arg );++ if ( value != null ) {+ ret[ ret.length ] = value;+ }+ }++ return ret.concat.apply( [], ret );+ },++ // A global GUID counter for objects+ guid: 1,++ proxy: function( fn, proxy, thisObject ) {+ if ( arguments.length === 2 ) {+ if ( typeof proxy === "string" ) {+ thisObject = fn;+ fn = thisObject[ proxy ];+ proxy = undefined;++ } else if ( proxy && !jQuery.isFunction( proxy ) ) {+ thisObject = proxy;+ proxy = undefined;+ }+ }++ if ( !proxy && fn ) {+ proxy = function() {+ return fn.apply( thisObject || this, arguments );+ };+ }++ // Set the guid of unique handler to the same of original handler, so it can be removed+ if ( fn ) {+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;+ }++ // So proxy can be declared as an argument+ return proxy;+ },++ // Use of jQuery.browser is frowned upon.+ // More details: http://docs.jquery.com/Utilities/jQuery.browser+ uaMatch: function( ua ) {+ ua = ua.toLowerCase();++ var match = /(webkit)[ \/]([\w.]+)/.exec( ua ) ||+ /(opera)(?:.*version)?[ \/]([\w.]+)/.exec( ua ) ||+ /(msie) ([\w.]+)/.exec( ua ) ||+ !/compatible/.test( ua ) && /(mozilla)(?:.*? rv:([\w.]+))?/.exec( ua ) ||+ [];++ return { browser: match[1] || "", version: match[2] || "0" };+ },++ browser: {}+});++browserMatch = jQuery.uaMatch( userAgent );+if ( browserMatch.browser ) {+ jQuery.browser[ browserMatch.browser ] = true;+ jQuery.browser.version = browserMatch.version;+}++// Deprecated, use jQuery.browser.webkit instead+if ( jQuery.browser.webkit ) {+ jQuery.browser.safari = true;+}++if ( indexOf ) {+ jQuery.inArray = function( elem, array ) {+ return indexOf.call( array, elem );+ };+}++// All jQuery objects should point back to these+rootjQuery = jQuery(document);++// Cleanup functions for the document ready method+if ( document.addEventListener ) {+ DOMContentLoaded = function() {+ document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false );+ jQuery.ready();+ };++} else if ( document.attachEvent ) {+ DOMContentLoaded = function() {+ // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).+ if ( document.readyState === "complete" ) {+ document.detachEvent( "onreadystatechange", DOMContentLoaded );+ jQuery.ready();+ }+ };+}++// The DOM ready check for Internet Explorer+function doScrollCheck() {+ if ( jQuery.isReady ) {+ return;+ }++ try {+ // If IE is used, use the trick by Diego Perini+ // http://javascript.nwbox.com/IEContentLoaded/+ document.documentElement.doScroll("left");+ } catch( error ) {+ setTimeout( doScrollCheck, 1 );+ return;+ }++ // and execute any waiting functions+ jQuery.ready();+}++function evalScript( i, elem ) {+ if ( elem.src ) {+ jQuery.ajax({+ url: elem.src,+ async: false,+ dataType: "script"+ });+ } else {+ jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );+ }++ if ( elem.parentNode ) {+ elem.parentNode.removeChild( elem );+ }+}++// Mutifunctional method to get and set values to a collection+// The value/s can be optionally by executed if its a function+function access( elems, key, value, exec, fn, pass ) {+ var length = elems.length;+ + // Setting many attributes+ if ( typeof key === "object" ) {+ for ( var k in key ) {+ access( elems, k, key[k], exec, fn, value );+ }+ return elems;+ }+ + // Setting one attribute+ if ( value !== undefined ) {+ // Optionally, function values get executed if exec is true+ exec = !pass && exec && jQuery.isFunction(value);+ + for ( var i = 0; i < length; i++ ) {+ fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );+ }+ + return elems;+ }+ + // Getting an attribute+ return length ? fn( elems[0], key ) : undefined;+}++function now() {+ return (new Date).getTime();+}+(function() {++ jQuery.support = {};++ var root = document.documentElement,+ script = document.createElement("script"),+ div = document.createElement("div"),+ id = "script" + now();++ div.style.display = "none";+ div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";++ var all = div.getElementsByTagName("*"),+ a = div.getElementsByTagName("a")[0];++ // Can't get basic test support+ if ( !all || !all.length || !a ) {+ return;+ }++ jQuery.support = {+ // IE strips leading whitespace when .innerHTML is used+ leadingWhitespace: div.firstChild.nodeType === 3,++ // Make sure that tbody elements aren't automatically inserted+ // IE will insert them into empty tables+ tbody: !div.getElementsByTagName("tbody").length,++ // Make sure that link elements get serialized correctly by innerHTML+ // This requires a wrapper element in IE+ htmlSerialize: !!div.getElementsByTagName("link").length,++ // Get the style information from getAttribute+ // (IE uses .cssText insted)+ style: /red/.test( a.getAttribute("style") ),++ // Make sure that URLs aren't manipulated+ // (IE normalizes it by default)+ hrefNormalized: a.getAttribute("href") === "/a",++ // Make sure that element opacity exists+ // (IE uses filter instead)+ // Use a regex to work around a WebKit issue. See #5145+ opacity: /^0.55$/.test( a.style.opacity ),++ // Verify style float existence+ // (IE uses styleFloat instead of cssFloat)+ cssFloat: !!a.style.cssFloat,++ // Make sure that if no value is specified for a checkbox+ // that it defaults to "on".+ // (WebKit defaults to "" instead)+ checkOn: div.getElementsByTagName("input")[0].value === "on",++ // Make sure that a selected-by-default option has a working selected property.+ // (WebKit defaults to false instead of true, IE too, if it's in an optgroup)+ optSelected: document.createElement("select").appendChild( document.createElement("option") ).selected,++ parentNode: div.removeChild( div.appendChild( document.createElement("div") ) ).parentNode === null,++ // Will be defined later+ deleteExpando: true,+ checkClone: false,+ scriptEval: false,+ noCloneEvent: true,+ boxModel: null+ };++ script.type = "text/javascript";+ try {+ script.appendChild( document.createTextNode( "window." + id + "=1;" ) );+ } catch(e) {}++ root.insertBefore( script, root.firstChild );++ // Make sure that the execution of code works by injecting a script+ // tag with appendChild/createTextNode+ // (IE doesn't support this, fails, and uses .text instead)+ if ( window[ id ] ) {+ jQuery.support.scriptEval = true;+ delete window[ id ];+ }++ // Test to see if it's possible to delete an expando from an element+ // Fails in Internet Explorer+ try {+ delete script.test;+ + } catch(e) {+ jQuery.support.deleteExpando = false;+ }++ root.removeChild( script );++ if ( div.attachEvent && div.fireEvent ) {+ div.attachEvent("onclick", function click() {+ // Cloning a node shouldn't copy over any+ // bound event handlers (IE does this)+ jQuery.support.noCloneEvent = false;+ div.detachEvent("onclick", click);+ });+ div.cloneNode(true).fireEvent("onclick");+ }++ div = document.createElement("div");+ div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";++ var fragment = document.createDocumentFragment();+ fragment.appendChild( div.firstChild );++ // WebKit doesn't clone checked state correctly in fragments+ jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;++ // Figure out if the W3C box model works as expected+ // document.body must exist before we can do this+ jQuery(function() {+ var div = document.createElement("div");+ div.style.width = div.style.paddingLeft = "1px";++ document.body.appendChild( div );+ jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;+ document.body.removeChild( div ).style.display = 'none';++ div = null;+ });++ // Technique from Juriy Zaytsev+ // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/+ var eventSupported = function( eventName ) { + var el = document.createElement("div"); + eventName = "on" + eventName; ++ var isSupported = (eventName in el); + if ( !isSupported ) { + el.setAttribute(eventName, "return;"); + isSupported = typeof el[eventName] === "function"; + } + el = null; ++ return isSupported; + };+ + jQuery.support.submitBubbles = eventSupported("submit");+ jQuery.support.changeBubbles = eventSupported("change");++ // release memory in IE+ root = script = div = all = a = null;+})();++jQuery.props = {+ "for": "htmlFor",+ "class": "className",+ readonly: "readOnly",+ maxlength: "maxLength",+ cellspacing: "cellSpacing",+ rowspan: "rowSpan",+ colspan: "colSpan",+ tabindex: "tabIndex",+ usemap: "useMap",+ frameborder: "frameBorder"+};+var expando = "jQuery" + now(), uuid = 0, windowData = {};++jQuery.extend({+ cache: {},+ + expando:expando,++ // The following elements throw uncatchable exceptions if you+ // attempt to add expando properties to them.+ noData: {+ "embed": true,+ "object": true,+ "applet": true+ },++ data: function( elem, name, data ) {+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {+ return;+ }++ elem = elem == window ?+ windowData :+ elem;++ var id = elem[ expando ], cache = jQuery.cache, thisCache;++ if ( !id && typeof name === "string" && data === undefined ) {+ return null;+ }++ // Compute a unique ID for the element+ if ( !id ) { + id = ++uuid;+ }++ // Avoid generating a new cache unless none exists and we+ // want to manipulate it.+ if ( typeof name === "object" ) {+ elem[ expando ] = id;+ thisCache = cache[ id ] = jQuery.extend(true, {}, name);++ } else if ( !cache[ id ] ) {+ elem[ expando ] = id;+ cache[ id ] = {};+ }++ thisCache = cache[ id ];++ // Prevent overriding the named cache with undefined values+ if ( data !== undefined ) {+ thisCache[ name ] = data;+ }++ return typeof name === "string" ? thisCache[ name ] : thisCache;+ },++ removeData: function( elem, name ) {+ if ( elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()] ) {+ return;+ }++ elem = elem == window ?+ windowData :+ elem;++ var id = elem[ expando ], cache = jQuery.cache, thisCache = cache[ id ];++ // If we want to remove a specific section of the element's data+ if ( name ) {+ if ( thisCache ) {+ // Remove the section of cache data+ delete thisCache[ name ];++ // If we've removed all the data, remove the element's cache+ if ( jQuery.isEmptyObject(thisCache) ) {+ jQuery.removeData( elem );+ }+ }++ // Otherwise, we want to remove all of the element's data+ } else {+ if ( jQuery.support.deleteExpando ) {+ delete elem[ jQuery.expando ];++ } else if ( elem.removeAttribute ) {+ elem.removeAttribute( jQuery.expando );+ }++ // Completely remove the data cache+ delete cache[ id ];+ }+ }+});++jQuery.fn.extend({+ data: function( key, value ) {+ if ( typeof key === "undefined" && this.length ) {+ return jQuery.data( this[0] );++ } else if ( typeof key === "object" ) {+ return this.each(function() {+ jQuery.data( this, key );+ });+ }++ var parts = key.split(".");+ parts[1] = parts[1] ? "." + parts[1] : "";++ if ( value === undefined ) {+ var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);++ if ( data === undefined && this.length ) {+ data = jQuery.data( this[0], key );+ }+ return data === undefined && parts[1] ?+ this.data( parts[0] ) :+ data;+ } else {+ return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function() {+ jQuery.data( this, key, value );+ });+ }+ },++ removeData: function( key ) {+ return this.each(function() {+ jQuery.removeData( this, key );+ });+ }+});+jQuery.extend({+ queue: function( elem, type, data ) {+ if ( !elem ) {+ return;+ }++ type = (type || "fx") + "queue";+ var q = jQuery.data( elem, type );++ // Speed up dequeue by getting out quickly if this is just a lookup+ if ( !data ) {+ return q || [];+ }++ if ( !q || jQuery.isArray(data) ) {+ q = jQuery.data( elem, type, jQuery.makeArray(data) );++ } else {+ q.push( data );+ }++ return q;+ },++ dequeue: function( elem, type ) {+ type = type || "fx";++ var queue = jQuery.queue( elem, type ), fn = queue.shift();++ // If the fx queue is dequeued, always remove the progress sentinel+ if ( fn === "inprogress" ) {+ fn = queue.shift();+ }++ if ( fn ) {+ // Add a progress sentinel to prevent the fx queue from being+ // automatically dequeued+ if ( type === "fx" ) {+ queue.unshift("inprogress");+ }++ fn.call(elem, function() {+ jQuery.dequeue(elem, type);+ });+ }+ }+});++jQuery.fn.extend({+ queue: function( type, data ) {+ if ( typeof type !== "string" ) {+ data = type;+ type = "fx";+ }++ if ( data === undefined ) {+ return jQuery.queue( this[0], type );+ }+ return this.each(function( i, elem ) {+ var queue = jQuery.queue( this, type, data );++ if ( type === "fx" && queue[0] !== "inprogress" ) {+ jQuery.dequeue( this, type );+ }+ });+ },+ dequeue: function( type ) {+ return this.each(function() {+ jQuery.dequeue( this, type );+ });+ },++ // Based off of the plugin by Clint Helfers, with permission.+ // http://blindsignals.com/index.php/2009/07/jquery-delay/+ delay: function( time, type ) {+ time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;+ type = type || "fx";++ return this.queue( type, function() {+ var elem = this;+ setTimeout(function() {+ jQuery.dequeue( elem, type );+ }, time );+ });+ },++ clearQueue: function( type ) {+ return this.queue( type || "fx", [] );+ }+});+var rclass = /[\n\t]/g,+ rspace = /\s+/,+ rreturn = /\r/g,+ rspecialurl = /href|src|style/,+ rtype = /(button|input)/i,+ rfocusable = /(button|input|object|select|textarea)/i,+ rclickable = /^(a|area)$/i,+ rradiocheck = /radio|checkbox/;++jQuery.fn.extend({+ attr: function( name, value ) {+ return access( this, name, value, true, jQuery.attr );+ },++ removeAttr: function( name, fn ) {+ return this.each(function(){+ jQuery.attr( this, name, "" );+ if ( this.nodeType === 1 ) {+ this.removeAttribute( name );+ }+ });+ },++ addClass: function( value ) {+ if ( jQuery.isFunction(value) ) {+ return this.each(function(i) {+ var self = jQuery(this);+ self.addClass( value.call(this, i, self.attr("class")) );+ });+ }++ if ( value && typeof value === "string" ) {+ var classNames = (value || "").split( rspace );++ for ( var i = 0, l = this.length; i < l; i++ ) {+ var elem = this[i];++ if ( elem.nodeType === 1 ) {+ if ( !elem.className ) {+ elem.className = value;++ } else {+ var className = " " + elem.className + " ", setClass = elem.className;+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {+ if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) {+ setClass += " " + classNames[c];+ }+ }+ elem.className = jQuery.trim( setClass );+ }+ }+ }+ }++ return this;+ },++ removeClass: function( value ) {+ if ( jQuery.isFunction(value) ) {+ return this.each(function(i) {+ var self = jQuery(this);+ self.removeClass( value.call(this, i, self.attr("class")) );+ });+ }++ if ( (value && typeof value === "string") || value === undefined ) {+ var classNames = (value || "").split(rspace);++ for ( var i = 0, l = this.length; i < l; i++ ) {+ var elem = this[i];++ if ( elem.nodeType === 1 && elem.className ) {+ if ( value ) {+ var className = (" " + elem.className + " ").replace(rclass, " ");+ for ( var c = 0, cl = classNames.length; c < cl; c++ ) {+ className = className.replace(" " + classNames[c] + " ", " ");+ }+ elem.className = jQuery.trim( className );++ } else {+ elem.className = "";+ }+ }+ }+ }++ return this;+ },++ toggleClass: function( value, stateVal ) {+ var type = typeof value, isBool = typeof stateVal === "boolean";++ if ( jQuery.isFunction( value ) ) {+ return this.each(function(i) {+ var self = jQuery(this);+ self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal );+ });+ }++ return this.each(function() {+ if ( type === "string" ) {+ // toggle individual class names+ var className, i = 0, self = jQuery(this),+ state = stateVal,+ classNames = value.split( rspace );++ while ( (className = classNames[ i++ ]) ) {+ // check each className given, space seperated list+ state = isBool ? state : !self.hasClass( className );+ self[ state ? "addClass" : "removeClass" ]( className );+ }++ } else if ( type === "undefined" || type === "boolean" ) {+ if ( this.className ) {+ // store className if set+ jQuery.data( this, "__className__", this.className );+ }++ // toggle whole className+ this.className = this.className || value === false ? "" : jQuery.data( this, "__className__" ) || "";+ }+ });+ },++ hasClass: function( selector ) {+ var className = " " + selector + " ";+ for ( var i = 0, l = this.length; i < l; i++ ) {+ if ( (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {+ return true;+ }+ }++ return false;+ },++ val: function( value ) {+ if ( value === undefined ) {+ var elem = this[0];++ if ( elem ) {+ if ( jQuery.nodeName( elem, "option" ) ) {+ return (elem.attributes.value || {}).specified ? elem.value : elem.text;+ }++ // We need to handle select boxes special+ if ( jQuery.nodeName( elem, "select" ) ) {+ var index = elem.selectedIndex,+ values = [],+ options = elem.options,+ one = elem.type === "select-one";++ // Nothing was selected+ if ( index < 0 ) {+ return null;+ }++ // Loop through all the selected options+ for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {+ var option = options[ i ];++ if ( option.selected ) {+ // Get the specifc value for the option+ value = jQuery(option).val();++ // We don't need an array for one selects+ if ( one ) {+ return value;+ }++ // Multi-Selects return an array+ values.push( value );+ }+ }++ return values;+ }++ // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified+ if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {+ return elem.getAttribute("value") === null ? "on" : elem.value;+ }+ ++ // Everything else, we just grab the value+ return (elem.value || "").replace(rreturn, "");++ }++ return undefined;+ }++ var isFunction = jQuery.isFunction(value);++ return this.each(function(i) {+ var self = jQuery(this), val = value;++ if ( this.nodeType !== 1 ) {+ return;+ }++ if ( isFunction ) {+ val = value.call(this, i, self.val());+ }++ // Typecast each time if the value is a Function and the appended+ // value is therefore different each time.+ if ( typeof val === "number" ) {+ val += "";+ }++ if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {+ this.checked = jQuery.inArray( self.val(), val ) >= 0;++ } else if ( jQuery.nodeName( this, "select" ) ) {+ var values = jQuery.makeArray(val);++ jQuery( "option", this ).each(function() {+ this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;+ });++ if ( !values.length ) {+ this.selectedIndex = -1;+ }++ } else {+ this.value = val;+ }+ });+ }+});++jQuery.extend({+ attrFn: {+ val: true,+ css: true,+ html: true,+ text: true,+ data: true,+ width: true,+ height: true,+ offset: true+ },+ + attr: function( elem, name, value, pass ) {+ // don't set attributes on text and comment nodes+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {+ return undefined;+ }++ if ( pass && name in jQuery.attrFn ) {+ return jQuery(elem)[name](value);+ }++ var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),+ // Whether we are setting (or getting)+ set = value !== undefined;++ // Try to normalize/fix the name+ name = notxml && jQuery.props[ name ] || name;++ // Only do all the following if this is a node (faster for style)+ if ( elem.nodeType === 1 ) {+ // These attributes require special treatment+ var special = rspecialurl.test( name );++ // Safari mis-reports the default selected property of an option+ // Accessing the parent's selectedIndex property fixes it+ if ( name === "selected" && !jQuery.support.optSelected ) {+ var parent = elem.parentNode;+ if ( parent ) {+ parent.selectedIndex;+ + // Make sure that it also works with optgroups, see #5701+ if ( parent.parentNode ) {+ parent.parentNode.selectedIndex;+ }+ }+ }++ // If applicable, access the attribute via the DOM 0 way+ if ( name in elem && notxml && !special ) {+ if ( set ) {+ // We can't allow the type property to be changed (since it causes problems in IE)+ if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {+ jQuery.error( "type property can't be changed" );+ }++ elem[ name ] = value;+ }++ // browsers index elements by id/name on forms, give priority to attributes.+ if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {+ return elem.getAttributeNode( name ).nodeValue;+ }++ // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set+ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/+ if ( name === "tabIndex" ) {+ var attributeNode = elem.getAttributeNode( "tabIndex" );++ return attributeNode && attributeNode.specified ?+ attributeNode.value :+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?+ 0 :+ undefined;+ }++ return elem[ name ];+ }++ if ( !jQuery.support.style && notxml && name === "style" ) {+ if ( set ) {+ elem.style.cssText = "" + value;+ }++ return elem.style.cssText;+ }++ if ( set ) {+ // convert the value to a string (all browsers do this but IE) see #1070+ elem.setAttribute( name, "" + value );+ }++ var attr = !jQuery.support.hrefNormalized && notxml && special ?+ // Some attributes require a special call on IE+ elem.getAttribute( name, 2 ) :+ elem.getAttribute( name );++ // Non-existent attributes return null, we normalize to undefined+ return attr === null ? undefined : attr;+ }++ // elem is actually elem.style ... set the style+ // Using attr for specific style information is now deprecated. Use style instead.+ return jQuery.style( elem, name, value );+ }+});+var rnamespaces = /\.(.*)$/,+ fcleanup = function( nm ) {+ return nm.replace(/[^\w\s\.\|`]/g, function( ch ) {+ return "\\" + ch;+ });+ };++/*+ * A number of helper functions used for managing events.+ * Many of the ideas behind this code originated from+ * Dean Edwards' addEvent library.+ */+jQuery.event = {++ // Bind an event to an element+ // Original by Dean Edwards+ add: function( elem, types, handler, data ) {+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {+ return;+ }++ // For whatever reason, IE has trouble passing the window object+ // around, causing it to be cloned in the process+ if ( elem.setInterval && ( elem !== window && !elem.frameElement ) ) {+ elem = window;+ }++ var handleObjIn, handleObj;++ if ( handler.handler ) {+ handleObjIn = handler;+ handler = handleObjIn.handler;+ }++ // Make sure that the function being executed has a unique ID+ if ( !handler.guid ) {+ handler.guid = jQuery.guid++;+ }++ // Init the element's event structure+ var elemData = jQuery.data( elem );++ // If no elemData is found then we must be trying to bind to one of the+ // banned noData elements+ if ( !elemData ) {+ return;+ }++ var events = elemData.events = elemData.events || {},+ eventHandle = elemData.handle, eventHandle;++ if ( !eventHandle ) {+ elemData.handle = eventHandle = function() {+ // Handle the second event of a trigger and when+ // an event is called after a page has unloaded+ return typeof jQuery !== "undefined" && !jQuery.event.triggered ?+ jQuery.event.handle.apply( eventHandle.elem, arguments ) :+ undefined;+ };+ }++ // Add elem as a property of the handle function+ // This is to prevent a memory leak with non-native events in IE.+ eventHandle.elem = elem;++ // Handle multiple events separated by a space+ // jQuery(...).bind("mouseover mouseout", fn);+ types = types.split(" ");++ var type, i = 0, namespaces;++ while ( (type = types[ i++ ]) ) {+ handleObj = handleObjIn ?+ jQuery.extend({}, handleObjIn) :+ { handler: handler, data: data };++ // Namespaced event handlers+ if ( type.indexOf(".") > -1 ) {+ namespaces = type.split(".");+ type = namespaces.shift();+ handleObj.namespace = namespaces.slice(0).sort().join(".");++ } else {+ namespaces = [];+ handleObj.namespace = "";+ }++ handleObj.type = type;+ handleObj.guid = handler.guid;++ // Get the current list of functions bound to this event+ var handlers = events[ type ],+ special = jQuery.event.special[ type ] || {};++ // Init the event handler queue+ if ( !handlers ) {+ handlers = events[ type ] = [];++ // Check for a special event handler+ // Only use addEventListener/attachEvent if the special+ // events handler returns false+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {+ // Bind the global event handler to the element+ if ( elem.addEventListener ) {+ elem.addEventListener( type, eventHandle, false );++ } else if ( elem.attachEvent ) {+ elem.attachEvent( "on" + type, eventHandle );+ }+ }+ }+ + if ( special.add ) { + special.add.call( elem, handleObj ); ++ if ( !handleObj.handler.guid ) {+ handleObj.handler.guid = handler.guid;+ }+ }++ // Add the function to the element's handler list+ handlers.push( handleObj );++ // Keep track of which events have been used, for global triggering+ jQuery.event.global[ type ] = true;+ }++ // Nullify elem to prevent memory leaks in IE+ elem = null;+ },++ global: {},++ // Detach an event or set of events from an element+ remove: function( elem, types, handler, pos ) {+ // don't do events on text and comment nodes+ if ( elem.nodeType === 3 || elem.nodeType === 8 ) {+ return;+ }++ var ret, type, fn, i = 0, all, namespaces, namespace, special, eventType, handleObj, origType,+ elemData = jQuery.data( elem ),+ events = elemData && elemData.events;++ if ( !elemData || !events ) {+ return;+ }++ // types is actually an event object here+ if ( types && types.type ) {+ handler = types.handler;+ types = types.type;+ }++ // Unbind all events for the element+ if ( !types || typeof types === "string" && types.charAt(0) === "." ) {+ types = types || "";++ for ( type in events ) {+ jQuery.event.remove( elem, type + types );+ }++ return;+ }++ // Handle multiple events separated by a space+ // jQuery(...).unbind("mouseover mouseout", fn);+ types = types.split(" ");++ while ( (type = types[ i++ ]) ) {+ origType = type;+ handleObj = null;+ all = type.indexOf(".") < 0;+ namespaces = [];++ if ( !all ) {+ // Namespaced event handlers+ namespaces = type.split(".");+ type = namespaces.shift();++ namespace = new RegExp("(^|\\.)" + + jQuery.map( namespaces.slice(0).sort(), fcleanup ).join("\\.(?:.*\\.)?") + "(\\.|$)")+ }++ eventType = events[ type ];++ if ( !eventType ) {+ continue;+ }++ if ( !handler ) {+ for ( var j = 0; j < eventType.length; j++ ) {+ handleObj = eventType[ j ];++ if ( all || namespace.test( handleObj.namespace ) ) {+ jQuery.event.remove( elem, origType, handleObj.handler, j );+ eventType.splice( j--, 1 );+ }+ }++ continue;+ }++ special = jQuery.event.special[ type ] || {};++ for ( var j = pos || 0; j < eventType.length; j++ ) {+ handleObj = eventType[ j ];++ if ( handler.guid === handleObj.guid ) {+ // remove the given handler for the given type+ if ( all || namespace.test( handleObj.namespace ) ) {+ if ( pos == null ) {+ eventType.splice( j--, 1 );+ }++ if ( special.remove ) {+ special.remove.call( elem, handleObj );+ }+ }++ if ( pos != null ) {+ break;+ }+ }+ }++ // remove generic event handler if no more handlers exist+ if ( eventType.length === 0 || pos != null && eventType.length === 1 ) {+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {+ removeEvent( elem, type, elemData.handle );+ }++ ret = null;+ delete events[ type ];+ }+ }++ // Remove the expando if it's no longer used+ if ( jQuery.isEmptyObject( events ) ) {+ var handle = elemData.handle;+ if ( handle ) {+ handle.elem = null;+ }++ delete elemData.events;+ delete elemData.handle;++ if ( jQuery.isEmptyObject( elemData ) ) {+ jQuery.removeData( elem );+ }+ }+ },++ // bubbling is internal+ trigger: function( event, data, elem /*, bubbling */ ) {+ // Event object or event type+ var type = event.type || event,+ bubbling = arguments[3];++ if ( !bubbling ) {+ event = typeof event === "object" ?+ // jQuery.Event object+ event[expando] ? event :+ // Object literal+ jQuery.extend( jQuery.Event(type), event ) :+ // Just the event type (string)+ jQuery.Event(type);++ if ( type.indexOf("!") >= 0 ) {+ event.type = type = type.slice(0, -1);+ event.exclusive = true;+ }++ // Handle a global trigger+ if ( !elem ) {+ // Don't bubble custom events when global (to avoid too much overhead)+ event.stopPropagation();++ // Only trigger if we've ever bound an event for it+ if ( jQuery.event.global[ type ] ) {+ jQuery.each( jQuery.cache, function() {+ if ( this.events && this.events[type] ) {+ jQuery.event.trigger( event, data, this.handle.elem );+ }+ });+ }+ }++ // Handle triggering a single element++ // don't do events on text and comment nodes+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {+ return undefined;+ }++ // Clean up in case it is reused+ event.result = undefined;+ event.target = elem;++ // Clone the incoming data, if any+ data = jQuery.makeArray( data );+ data.unshift( event );+ }++ event.currentTarget = elem;++ // Trigger the event, it is assumed that "handle" is a function+ var handle = jQuery.data( elem, "handle" );+ if ( handle ) {+ handle.apply( elem, data );+ }++ var parent = elem.parentNode || elem.ownerDocument;++ // Trigger an inline bound script+ try {+ if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {+ if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {+ event.result = false;+ }+ }++ // prevent IE from throwing an error for some elements with some event types, see #3533+ } catch (e) {}++ if ( !event.isPropagationStopped() && parent ) {+ jQuery.event.trigger( event, data, parent, true );++ } else if ( !event.isDefaultPrevented() ) {+ var target = event.target, old,+ isClick = jQuery.nodeName(target, "a") && type === "click",+ special = jQuery.event.special[ type ] || {};++ if ( (!special._default || special._default.call( elem, event ) === false) && + !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {++ try {+ if ( target[ type ] ) {+ // Make sure that we don't accidentally re-trigger the onFOO events+ old = target[ "on" + type ];++ if ( old ) {+ target[ "on" + type ] = null;+ }++ jQuery.event.triggered = true;+ target[ type ]();+ }++ // prevent IE from throwing an error for some elements with some event types, see #3533+ } catch (e) {}++ if ( old ) {+ target[ "on" + type ] = old;+ }++ jQuery.event.triggered = false;+ }+ }+ },++ handle: function( event ) {+ var all, handlers, namespaces, namespace, events;++ event = arguments[0] = jQuery.event.fix( event || window.event );+ event.currentTarget = this;++ // Namespaced event handlers+ all = event.type.indexOf(".") < 0 && !event.exclusive;++ if ( !all ) {+ namespaces = event.type.split(".");+ event.type = namespaces.shift();+ namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");+ }++ var events = jQuery.data(this, "events"), handlers = events[ event.type ];++ if ( events && handlers ) {+ // Clone the handlers to prevent manipulation+ handlers = handlers.slice(0);++ for ( var j = 0, l = handlers.length; j < l; j++ ) {+ var handleObj = handlers[ j ];++ // Filter the functions by class+ if ( all || namespace.test( handleObj.namespace ) ) {+ // Pass in a reference to the handler function itself+ // So that we can later remove it+ event.handler = handleObj.handler;+ event.data = handleObj.data;+ event.handleObj = handleObj;+ + var ret = handleObj.handler.apply( this, arguments );++ if ( ret !== undefined ) {+ event.result = ret;+ if ( ret === false ) {+ event.preventDefault();+ event.stopPropagation();+ }+ }++ if ( event.isImmediatePropagationStopped() ) {+ break;+ }+ }+ }+ }++ return event.result;+ },++ props: "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),++ fix: function( event ) {+ if ( event[ expando ] ) {+ return event;+ }++ // store a copy of the original event object+ // and "clone" to set read-only properties+ var originalEvent = event;+ event = jQuery.Event( originalEvent );++ for ( var i = this.props.length, prop; i; ) {+ prop = this.props[ --i ];+ event[ prop ] = originalEvent[ prop ];+ }++ // Fix target property, if necessary+ if ( !event.target ) {+ event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either+ }++ // check if target is a textnode (safari)+ if ( event.target.nodeType === 3 ) {+ event.target = event.target.parentNode;+ }++ // Add relatedTarget, if necessary+ if ( !event.relatedTarget && event.fromElement ) {+ event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement;+ }++ // Calculate pageX/Y if missing and clientX/Y available+ if ( event.pageX == null && event.clientX != null ) {+ var doc = document.documentElement, body = document.body;+ event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);+ event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);+ }++ // Add which for key events+ if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) ) {+ event.which = event.charCode || event.keyCode;+ }++ // Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)+ if ( !event.metaKey && event.ctrlKey ) {+ event.metaKey = event.ctrlKey;+ }++ // Add which for click: 1 === left; 2 === middle; 3 === right+ // Note: button is not normalized, so don't use it+ if ( !event.which && event.button !== undefined ) {+ event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));+ }++ return event;+ },++ // Deprecated, use jQuery.guid instead+ guid: 1E8,++ // Deprecated, use jQuery.proxy instead+ proxy: jQuery.proxy,++ special: {+ ready: {+ // Make sure the ready event is setup+ setup: jQuery.bindReady,+ teardown: jQuery.noop+ },++ live: {+ add: function( handleObj ) {+ jQuery.event.add( this, handleObj.origType, jQuery.extend({}, handleObj, {handler: liveHandler}) ); + },++ remove: function( handleObj ) {+ var remove = true,+ type = handleObj.origType.replace(rnamespaces, "");+ + jQuery.each( jQuery.data(this, "events").live || [], function() {+ if ( type === this.origType.replace(rnamespaces, "") ) {+ remove = false;+ return false;+ }+ });++ if ( remove ) {+ jQuery.event.remove( this, handleObj.origType, liveHandler );+ }+ }++ },++ beforeunload: {+ setup: function( data, namespaces, eventHandle ) {+ // We only want to do this special case on windows+ if ( this.setInterval ) {+ this.onbeforeunload = eventHandle;+ }++ return false;+ },+ teardown: function( namespaces, eventHandle ) {+ if ( this.onbeforeunload === eventHandle ) {+ this.onbeforeunload = null;+ }+ }+ }+ }+};++var removeEvent = document.removeEventListener ?+ function( elem, type, handle ) {+ elem.removeEventListener( type, handle, false );+ } : + function( elem, type, handle ) {+ elem.detachEvent( "on" + type, handle );+ };++jQuery.Event = function( src ) {+ // Allow instantiation without the 'new' keyword+ if ( !this.preventDefault ) {+ return new jQuery.Event( src );+ }++ // Event object+ if ( src && src.type ) {+ this.originalEvent = src;+ this.type = src.type;+ // Event type+ } else {+ this.type = src;+ }++ // timeStamp is buggy for some events on Firefox(#3843)+ // So we won't rely on the native value+ this.timeStamp = now();++ // Mark it as fixed+ this[ expando ] = true;+};++function returnFalse() {+ return false;+}+function returnTrue() {+ return true;+}++// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding+// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html+jQuery.Event.prototype = {+ preventDefault: function() {+ this.isDefaultPrevented = returnTrue;++ var e = this.originalEvent;+ if ( !e ) {+ return;+ }+ + // if preventDefault exists run it on the original event+ if ( e.preventDefault ) {+ e.preventDefault();+ }+ // otherwise set the returnValue property of the original event to false (IE)+ e.returnValue = false;+ },+ stopPropagation: function() {+ this.isPropagationStopped = returnTrue;++ var e = this.originalEvent;+ if ( !e ) {+ return;+ }+ // if stopPropagation exists run it on the original event+ if ( e.stopPropagation ) {+ e.stopPropagation();+ }+ // otherwise set the cancelBubble property of the original event to true (IE)+ e.cancelBubble = true;+ },+ stopImmediatePropagation: function() {+ this.isImmediatePropagationStopped = returnTrue;+ this.stopPropagation();+ },+ isDefaultPrevented: returnFalse,+ isPropagationStopped: returnFalse,+ isImmediatePropagationStopped: returnFalse+};++// Checks if an event happened on an element within another element+// Used in jQuery.event.special.mouseenter and mouseleave handlers+var withinElement = function( event ) {+ // Check if mouse(over|out) are still within the same parent element+ var parent = event.relatedTarget;++ // Firefox sometimes assigns relatedTarget a XUL element+ // which we cannot access the parentNode property of+ try {+ // Traverse up the tree+ while ( parent && parent !== this ) {+ parent = parent.parentNode;+ }++ if ( parent !== this ) {+ // set the correct event type+ event.type = event.data;++ // handle event if we actually just moused on to a non sub-element+ jQuery.event.handle.apply( this, arguments );+ }++ // assuming we've left the element since we most likely mousedover a xul element+ } catch(e) { }+},++// In case of event delegation, we only need to rename the event.type,+// liveHandler will take care of the rest.+delegate = function( event ) {+ event.type = event.data;+ jQuery.event.handle.apply( this, arguments );+};++// Create mouseenter and mouseleave events+jQuery.each({+ mouseenter: "mouseover",+ mouseleave: "mouseout"+}, function( orig, fix ) {+ jQuery.event.special[ orig ] = {+ setup: function( data ) {+ jQuery.event.add( this, fix, data && data.selector ? delegate : withinElement, orig );+ },+ teardown: function( data ) {+ jQuery.event.remove( this, fix, data && data.selector ? delegate : withinElement );+ }+ };+});++// submit delegation+if ( !jQuery.support.submitBubbles ) {++ jQuery.event.special.submit = {+ setup: function( data, namespaces ) {+ if ( this.nodeName.toLowerCase() !== "form" ) {+ jQuery.event.add(this, "click.specialSubmit", function( e ) {+ var elem = e.target, type = elem.type;++ if ( (type === "submit" || type === "image") && jQuery( elem ).closest("form").length ) {+ return trigger( "submit", this, arguments );+ }+ });+ + jQuery.event.add(this, "keypress.specialSubmit", function( e ) {+ var elem = e.target, type = elem.type;++ if ( (type === "text" || type === "password") && jQuery( elem ).closest("form").length && e.keyCode === 13 ) {+ return trigger( "submit", this, arguments );+ }+ });++ } else {+ return false;+ }+ },++ teardown: function( namespaces ) {+ jQuery.event.remove( this, ".specialSubmit" );+ }+ };++}++// change delegation, happens here so we have bind.+if ( !jQuery.support.changeBubbles ) {++ var formElems = /textarea|input|select/i,++ changeFilters,++ getVal = function( elem ) {+ var type = elem.type, val = elem.value;++ if ( type === "radio" || type === "checkbox" ) {+ val = elem.checked;++ } else if ( type === "select-multiple" ) {+ val = elem.selectedIndex > -1 ?+ jQuery.map( elem.options, function( elem ) {+ return elem.selected;+ }).join("-") :+ "";++ } else if ( elem.nodeName.toLowerCase() === "select" ) {+ val = elem.selectedIndex;+ }++ return val;+ },++ testChange = function testChange( e ) {+ var elem = e.target, data, val;++ if ( !formElems.test( elem.nodeName ) || elem.readOnly ) {+ return;+ }++ data = jQuery.data( elem, "_change_data" );+ val = getVal(elem);++ // the current data will be also retrieved by beforeactivate+ if ( e.type !== "focusout" || elem.type !== "radio" ) {+ jQuery.data( elem, "_change_data", val );+ }+ + if ( data === undefined || val === data ) {+ return;+ }++ if ( data != null || val ) {+ e.type = "change";+ return jQuery.event.trigger( e, arguments[1], elem );+ }+ };++ jQuery.event.special.change = {+ filters: {+ focusout: testChange, ++ click: function( e ) {+ var elem = e.target, type = elem.type;++ if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) {+ return testChange.call( this, e );+ }+ },++ // Change has to be called before submit+ // Keydown will be called before keypress, which is used in submit-event delegation+ keydown: function( e ) {+ var elem = e.target, type = elem.type;++ if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") ||+ (e.keyCode === 32 && (type === "checkbox" || type === "radio")) ||+ type === "select-multiple" ) {+ return testChange.call( this, e );+ }+ },++ // Beforeactivate happens also before the previous element is blurred+ // with this event you can't trigger a change event, but you can store+ // information/focus[in] is not needed anymore+ beforeactivate: function( e ) {+ var elem = e.target;+ jQuery.data( elem, "_change_data", getVal(elem) );+ }+ },++ setup: function( data, namespaces ) {+ if ( this.type === "file" ) {+ return false;+ }++ for ( var type in changeFilters ) {+ jQuery.event.add( this, type + ".specialChange", changeFilters[type] );+ }++ return formElems.test( this.nodeName );+ },++ teardown: function( namespaces ) {+ jQuery.event.remove( this, ".specialChange" );++ return formElems.test( this.nodeName );+ }+ };++ changeFilters = jQuery.event.special.change.filters;+}++function trigger( type, elem, args ) {+ args[0].type = type;+ return jQuery.event.handle.apply( elem, args );+}++// Create "bubbling" focus and blur events+if ( document.addEventListener ) {+ jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {+ jQuery.event.special[ fix ] = {+ setup: function() {+ this.addEventListener( orig, handler, true );+ }, + teardown: function() { + this.removeEventListener( orig, handler, true );+ }+ };++ function handler( e ) { + e = jQuery.event.fix( e );+ e.type = fix;+ return jQuery.event.handle.call( this, e );+ }+ });+}++jQuery.each(["bind", "one"], function( i, name ) {+ jQuery.fn[ name ] = function( type, data, fn ) {+ // Handle object literals+ if ( typeof type === "object" ) {+ for ( var key in type ) {+ this[ name ](key, data, type[key], fn);+ }+ return this;+ }+ + if ( jQuery.isFunction( data ) ) {+ fn = data;+ data = undefined;+ }++ var handler = name === "one" ? jQuery.proxy( fn, function( event ) {+ jQuery( this ).unbind( event, handler );+ return fn.apply( this, arguments );+ }) : fn;++ if ( type === "unload" && name !== "one" ) {+ this.one( type, data, fn );++ } else {+ for ( var i = 0, l = this.length; i < l; i++ ) {+ jQuery.event.add( this[i], type, handler, data );+ }+ }++ return this;+ };+});++jQuery.fn.extend({+ unbind: function( type, fn ) {+ // Handle object literals+ if ( typeof type === "object" && !type.preventDefault ) {+ for ( var key in type ) {+ this.unbind(key, type[key]);+ }++ } else {+ for ( var i = 0, l = this.length; i < l; i++ ) {+ jQuery.event.remove( this[i], type, fn );+ }+ }++ return this;+ },+ + delegate: function( selector, types, data, fn ) {+ return this.live( types, data, fn, selector );+ },+ + undelegate: function( selector, types, fn ) {+ if ( arguments.length === 0 ) {+ return this.unbind( "live" );+ + } else {+ return this.die( types, null, fn, selector );+ }+ },+ + trigger: function( type, data ) {+ return this.each(function() {+ jQuery.event.trigger( type, data, this );+ });+ },++ triggerHandler: function( type, data ) {+ if ( this[0] ) {+ var event = jQuery.Event( type );+ event.preventDefault();+ event.stopPropagation();+ jQuery.event.trigger( event, data, this[0] );+ return event.result;+ }+ },++ toggle: function( fn ) {+ // Save reference to arguments for access in closure+ var args = arguments, i = 1;++ // link all the functions, so any of them can unbind this click handler+ while ( i < args.length ) {+ jQuery.proxy( fn, args[ i++ ] );+ }++ return this.click( jQuery.proxy( fn, function( event ) {+ // Figure out which function to execute+ var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;+ jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );++ // Make sure that clicks stop+ event.preventDefault();++ // and execute the function+ return args[ lastToggle ].apply( this, arguments ) || false;+ }));+ },++ hover: function( fnOver, fnOut ) {+ return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );+ }+});++var liveMap = {+ focus: "focusin",+ blur: "focusout",+ mouseenter: "mouseover",+ mouseleave: "mouseout"+};++jQuery.each(["live", "die"], function( i, name ) {+ jQuery.fn[ name ] = function( types, data, fn, origSelector /* Internal Use Only */ ) {+ var type, i = 0, match, namespaces, preType,+ selector = origSelector || this.selector,+ context = origSelector ? this : jQuery( this.context );++ if ( jQuery.isFunction( data ) ) {+ fn = data;+ data = undefined;+ }++ types = (types || "").split(" ");++ while ( (type = types[ i++ ]) != null ) {+ match = rnamespaces.exec( type );+ namespaces = "";++ if ( match ) {+ namespaces = match[0];+ type = type.replace( rnamespaces, "" );+ }++ if ( type === "hover" ) {+ types.push( "mouseenter" + namespaces, "mouseleave" + namespaces );+ continue;+ }++ preType = type;++ if ( type === "focus" || type === "blur" ) {+ types.push( liveMap[ type ] + namespaces );+ type = type + namespaces;++ } else {+ type = (liveMap[ type ] || type) + namespaces;+ }++ if ( name === "live" ) {+ // bind live handler+ context.each(function(){+ jQuery.event.add( this, liveConvert( type, selector ),+ { data: data, selector: selector, handler: fn, origType: type, origHandler: fn, preType: preType } );+ });++ } else {+ // unbind live handler+ context.unbind( liveConvert( type, selector ), fn );+ }+ }+ + return this;+ }+});++function liveHandler( event ) {+ var stop, elems = [], selectors = [], args = arguments,+ related, match, handleObj, elem, j, i, l, data,+ events = jQuery.data( this, "events" );++ // Make sure we avoid non-left-click bubbling in Firefox (#3861)+ if ( event.liveFired === this || !events || !events.live || event.button && event.type === "click" ) {+ return;+ }++ event.liveFired = this;++ var live = events.live.slice(0);++ for ( j = 0; j < live.length; j++ ) {+ handleObj = live[j];++ if ( handleObj.origType.replace( rnamespaces, "" ) === event.type ) {+ selectors.push( handleObj.selector );++ } else {+ live.splice( j--, 1 );+ }+ }++ match = jQuery( event.target ).closest( selectors, event.currentTarget );++ for ( i = 0, l = match.length; i < l; i++ ) {+ for ( j = 0; j < live.length; j++ ) {+ handleObj = live[j];++ if ( match[i].selector === handleObj.selector ) {+ elem = match[i].elem;+ related = null;++ // Those two events require additional checking+ if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) {+ related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0];+ }++ if ( !related || related !== elem ) {+ elems.push({ elem: elem, handleObj: handleObj });+ }+ }+ }+ }++ for ( i = 0, l = elems.length; i < l; i++ ) {+ match = elems[i];+ event.currentTarget = match.elem;+ event.data = match.handleObj.data;+ event.handleObj = match.handleObj;++ if ( match.handleObj.origHandler.apply( match.elem, args ) === false ) {+ stop = false;+ break;+ }+ }++ return stop;+}++function liveConvert( type, selector ) {+ return "live." + (type && type !== "*" ? type + "." : "") + selector.replace(/\./g, "`").replace(/ /g, "&");+}++jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " ++ "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " ++ "change select submit keydown keypress keyup error").split(" "), function( i, name ) {++ // Handle event binding+ jQuery.fn[ name ] = function( fn ) {+ return fn ? this.bind( name, fn ) : this.trigger( name );+ };++ if ( jQuery.attrFn ) {+ jQuery.attrFn[ name ] = true;+ }+});++// Prevent memory leaks in IE+// Window isn't included so as not to unbind existing unload events+// More info:+// - http://isaacschlueter.com/2006/10/msie-memory-leaks/+if ( window.attachEvent && !window.addEventListener ) {+ window.attachEvent("onunload", function() {+ for ( var id in jQuery.cache ) {+ if ( jQuery.cache[ id ].handle ) {+ // Try/Catch is to handle iframes being unloaded, see #4280+ try {+ jQuery.event.remove( jQuery.cache[ id ].handle.elem );+ } catch(e) {}+ }+ }+ });+}+/*!+ * Sizzle CSS Selector Engine - v1.0+ * Copyright 2009, The Dojo Foundation+ * Released under the MIT, BSD, and GPL Licenses.+ * More information: http://sizzlejs.com/+ */+(function(){++var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,+ done = 0,+ toString = Object.prototype.toString,+ hasDuplicate = false,+ baseHasDuplicate = true;++// Here we check if the JavaScript engine is using some sort of+// optimization where it does not always call our comparision+// function. If that is the case, discard the hasDuplicate value.+// Thus far that includes Google Chrome.+[0, 0].sort(function(){+ baseHasDuplicate = false;+ return 0;+});++var Sizzle = function(selector, context, results, seed) {+ results = results || [];+ var origContext = context = context || document;++ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {+ return [];+ }+ + if ( !selector || typeof selector !== "string" ) {+ return results;+ }++ var parts = [], m, set, checkSet, extra, prune = true, contextXML = isXML(context),+ soFar = selector;+ + // Reset the position of the chunker regexp (start from head)+ while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {+ soFar = m[3];+ + parts.push( m[1] );+ + if ( m[2] ) {+ extra = m[3];+ break;+ }+ }++ if ( parts.length > 1 && origPOS.exec( selector ) ) {+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {+ set = posProcess( parts[0] + parts[1], context );+ } else {+ set = Expr.relative[ parts[0] ] ?+ [ context ] :+ Sizzle( parts.shift(), context );++ while ( parts.length ) {+ selector = parts.shift();++ if ( Expr.relative[ selector ] ) {+ selector += parts.shift();+ }+ + set = posProcess( selector, set );+ }+ }+ } else {+ // Take a shortcut and set the context if the root selector is an ID+ // (but not if it'll be faster if the inner selector is an ID)+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {+ var ret = Sizzle.find( parts.shift(), context, contextXML );+ context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];+ }++ if ( context ) {+ var ret = seed ?+ { expr: parts.pop(), set: makeArray(seed) } :+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );+ set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;++ if ( parts.length > 0 ) {+ checkSet = makeArray(set);+ } else {+ prune = false;+ }++ while ( parts.length ) {+ var cur = parts.pop(), pop = cur;++ if ( !Expr.relative[ cur ] ) {+ cur = "";+ } else {+ pop = parts.pop();+ }++ if ( pop == null ) {+ pop = context;+ }++ Expr.relative[ cur ]( checkSet, pop, contextXML );+ }+ } else {+ checkSet = parts = [];+ }+ }++ if ( !checkSet ) {+ checkSet = set;+ }++ if ( !checkSet ) {+ Sizzle.error( cur || selector );+ }++ if ( toString.call(checkSet) === "[object Array]" ) {+ if ( !prune ) {+ results.push.apply( results, checkSet );+ } else if ( context && context.nodeType === 1 ) {+ for ( var i = 0; checkSet[i] != null; i++ ) {+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {+ results.push( set[i] );+ }+ }+ } else {+ for ( var i = 0; checkSet[i] != null; i++ ) {+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {+ results.push( set[i] );+ }+ }+ }+ } else {+ makeArray( checkSet, results );+ }++ if ( extra ) {+ Sizzle( extra, origContext, results, seed );+ Sizzle.uniqueSort( results );+ }++ return results;+};++Sizzle.uniqueSort = function(results){+ if ( sortOrder ) {+ hasDuplicate = baseHasDuplicate;+ results.sort(sortOrder);++ if ( hasDuplicate ) {+ for ( var i = 1; i < results.length; i++ ) {+ if ( results[i] === results[i-1] ) {+ results.splice(i--, 1);+ }+ }+ }+ }++ return results;+};++Sizzle.matches = function(expr, set){+ return Sizzle(expr, null, null, set);+};++Sizzle.find = function(expr, context, isXML){+ var set, match;++ if ( !expr ) {+ return [];+ }++ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {+ var type = Expr.order[i], match;+ + if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {+ var left = match[1];+ match.splice(1,1);++ if ( left.substr( left.length - 1 ) !== "\\" ) {+ match[1] = (match[1] || "").replace(/\\/g, "");+ set = Expr.find[ type ]( match, context, isXML );+ if ( set != null ) {+ expr = expr.replace( Expr.match[ type ], "" );+ break;+ }+ }+ }+ }++ if ( !set ) {+ set = context.getElementsByTagName("*");+ }++ return {set: set, expr: expr};+};++Sizzle.filter = function(expr, set, inplace, not){+ var old = expr, result = [], curLoop = set, match, anyFound,+ isXMLFilter = set && set[0] && isXML(set[0]);++ while ( expr && set.length ) {+ for ( var type in Expr.filter ) {+ if ( (match = Expr.leftMatch[ type ].exec( expr )) != null && match[2] ) {+ var filter = Expr.filter[ type ], found, item, left = match[1];+ anyFound = false;++ match.splice(1,1);++ if ( left.substr( left.length - 1 ) === "\\" ) {+ continue;+ }++ if ( curLoop === result ) {+ result = [];+ }++ if ( Expr.preFilter[ type ] ) {+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );++ if ( !match ) {+ anyFound = found = true;+ } else if ( match === true ) {+ continue;+ }+ }++ if ( match ) {+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {+ if ( item ) {+ found = filter( item, match, i, curLoop );+ var pass = not ^ !!found;++ if ( inplace && found != null ) {+ if ( pass ) {+ anyFound = true;+ } else {+ curLoop[i] = false;+ }+ } else if ( pass ) {+ result.push( item );+ anyFound = true;+ }+ }+ }+ }++ if ( found !== undefined ) {+ if ( !inplace ) {+ curLoop = result;+ }++ expr = expr.replace( Expr.match[ type ], "" );++ if ( !anyFound ) {+ return [];+ }++ break;+ }+ }+ }++ // Improper expression+ if ( expr === old ) {+ if ( anyFound == null ) {+ Sizzle.error( expr );+ } else {+ break;+ }+ }++ old = expr;+ }++ return curLoop;+};++Sizzle.error = function( msg ) {+ throw "Syntax error, unrecognized expression: " + msg;+};++var Expr = Sizzle.selectors = {+ order: [ "ID", "NAME", "TAG" ],+ match: {+ ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,+ CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,+ TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,+ PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/+ },+ leftMatch: {},+ attrMap: {+ "class": "className",+ "for": "htmlFor"+ },+ attrHandle: {+ href: function(elem){+ return elem.getAttribute("href");+ }+ },+ relative: {+ "+": function(checkSet, part){+ var isPartStr = typeof part === "string",+ isTag = isPartStr && !/\W/.test(part),+ isPartStrNotTag = isPartStr && !isTag;++ if ( isTag ) {+ part = part.toLowerCase();+ }++ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {+ if ( (elem = checkSet[i]) ) {+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}++ checkSet[i] = isPartStrNotTag || elem && elem.nodeName.toLowerCase() === part ?+ elem || false :+ elem === part;+ }+ }++ if ( isPartStrNotTag ) {+ Sizzle.filter( part, checkSet, true );+ }+ },+ ">": function(checkSet, part){+ var isPartStr = typeof part === "string";++ if ( isPartStr && !/\W/.test(part) ) {+ part = part.toLowerCase();++ for ( var i = 0, l = checkSet.length; i < l; i++ ) {+ var elem = checkSet[i];+ if ( elem ) {+ var parent = elem.parentNode;+ checkSet[i] = parent.nodeName.toLowerCase() === part ? parent : false;+ }+ }+ } else {+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {+ var elem = checkSet[i];+ if ( elem ) {+ checkSet[i] = isPartStr ?+ elem.parentNode :+ elem.parentNode === part;+ }+ }++ if ( isPartStr ) {+ Sizzle.filter( part, checkSet, true );+ }+ }+ },+ "": function(checkSet, part, isXML){+ var doneName = done++, checkFn = dirCheck;++ if ( typeof part === "string" && !/\W/.test(part) ) {+ var nodeCheck = part = part.toLowerCase();+ checkFn = dirNodeCheck;+ }++ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);+ },+ "~": function(checkSet, part, isXML){+ var doneName = done++, checkFn = dirCheck;++ if ( typeof part === "string" && !/\W/.test(part) ) {+ var nodeCheck = part = part.toLowerCase();+ checkFn = dirNodeCheck;+ }++ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);+ }+ },+ find: {+ ID: function(match, context, isXML){+ if ( typeof context.getElementById !== "undefined" && !isXML ) {+ var m = context.getElementById(match[1]);+ return m ? [m] : [];+ }+ },+ NAME: function(match, context){+ if ( typeof context.getElementsByName !== "undefined" ) {+ var ret = [], results = context.getElementsByName(match[1]);++ for ( var i = 0, l = results.length; i < l; i++ ) {+ if ( results[i].getAttribute("name") === match[1] ) {+ ret.push( results[i] );+ }+ }++ return ret.length === 0 ? null : ret;+ }+ },+ TAG: function(match, context){+ return context.getElementsByTagName(match[1]);+ }+ },+ preFilter: {+ CLASS: function(match, curLoop, inplace, result, not, isXML){+ match = " " + match[1].replace(/\\/g, "") + " ";++ if ( isXML ) {+ return match;+ }++ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {+ if ( elem ) {+ if ( not ^ (elem.className && (" " + elem.className + " ").replace(/[\t\n]/g, " ").indexOf(match) >= 0) ) {+ if ( !inplace ) {+ result.push( elem );+ }+ } else if ( inplace ) {+ curLoop[i] = false;+ }+ }+ }++ return false;+ },+ ID: function(match){+ return match[1].replace(/\\/g, "");+ },+ TAG: function(match, curLoop){+ return match[1].toLowerCase();+ },+ CHILD: function(match){+ if ( match[1] === "nth" ) {+ // parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(+ match[2] === "even" && "2n" || match[2] === "odd" && "2n+1" ||+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);++ // calculate the numbers (first)n+(last) including if they are negative+ match[2] = (test[1] + (test[2] || 1)) - 0;+ match[3] = test[3] - 0;+ }++ // TODO: Move to normal caching system+ match[0] = done++;++ return match;+ },+ ATTR: function(match, curLoop, inplace, result, not, isXML){+ var name = match[1].replace(/\\/g, "");+ + if ( !isXML && Expr.attrMap[name] ) {+ match[1] = Expr.attrMap[name];+ }++ if ( match[2] === "~=" ) {+ match[4] = " " + match[4] + " ";+ }++ return match;+ },+ PSEUDO: function(match, curLoop, inplace, result, not){+ if ( match[1] === "not" ) {+ // If we're dealing with a complex expression, or a simple one+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {+ match[3] = Sizzle(match[3], null, null, curLoop);+ } else {+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);+ if ( !inplace ) {+ result.push.apply( result, ret );+ }+ return false;+ }+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {+ return true;+ }+ + return match;+ },+ POS: function(match){+ match.unshift( true );+ return match;+ }+ },+ filters: {+ enabled: function(elem){+ return elem.disabled === false && elem.type !== "hidden";+ },+ disabled: function(elem){+ return elem.disabled === true;+ },+ checked: function(elem){+ return elem.checked === true;+ },+ selected: function(elem){+ // Accessing this property makes selected-by-default+ // options in Safari work properly+ elem.parentNode.selectedIndex;+ return elem.selected === true;+ },+ parent: function(elem){+ return !!elem.firstChild;+ },+ empty: function(elem){+ return !elem.firstChild;+ },+ has: function(elem, i, match){+ return !!Sizzle( match[3], elem ).length;+ },+ header: function(elem){+ return /h\d/i.test( elem.nodeName );+ },+ text: function(elem){+ return "text" === elem.type;+ },+ radio: function(elem){+ return "radio" === elem.type;+ },+ checkbox: function(elem){+ return "checkbox" === elem.type;+ },+ file: function(elem){+ return "file" === elem.type;+ },+ password: function(elem){+ return "password" === elem.type;+ },+ submit: function(elem){+ return "submit" === elem.type;+ },+ image: function(elem){+ return "image" === elem.type;+ },+ reset: function(elem){+ return "reset" === elem.type;+ },+ button: function(elem){+ return "button" === elem.type || elem.nodeName.toLowerCase() === "button";+ },+ input: function(elem){+ return /input|select|textarea|button/i.test(elem.nodeName);+ }+ },+ setFilters: {+ first: function(elem, i){+ return i === 0;+ },+ last: function(elem, i, match, array){+ return i === array.length - 1;+ },+ even: function(elem, i){+ return i % 2 === 0;+ },+ odd: function(elem, i){+ return i % 2 === 1;+ },+ lt: function(elem, i, match){+ return i < match[3] - 0;+ },+ gt: function(elem, i, match){+ return i > match[3] - 0;+ },+ nth: function(elem, i, match){+ return match[3] - 0 === i;+ },+ eq: function(elem, i, match){+ return match[3] - 0 === i;+ }+ },+ filter: {+ PSEUDO: function(elem, match, i, array){+ var name = match[1], filter = Expr.filters[ name ];++ if ( filter ) {+ return filter( elem, i, match, array );+ } else if ( name === "contains" ) {+ return (elem.textContent || elem.innerText || getText([ elem ]) || "").indexOf(match[3]) >= 0;+ } else if ( name === "not" ) {+ var not = match[3];++ for ( var i = 0, l = not.length; i < l; i++ ) {+ if ( not[i] === elem ) {+ return false;+ }+ }++ return true;+ } else {+ Sizzle.error( "Syntax error, unrecognized expression: " + name );+ }+ },+ CHILD: function(elem, match){+ var type = match[1], node = elem;+ switch (type) {+ case 'only':+ case 'first':+ while ( (node = node.previousSibling) ) {+ if ( node.nodeType === 1 ) { + return false; + }+ }+ if ( type === "first" ) { + return true; + }+ node = elem;+ case 'last':+ while ( (node = node.nextSibling) ) {+ if ( node.nodeType === 1 ) { + return false; + }+ }+ return true;+ case 'nth':+ var first = match[2], last = match[3];++ if ( first === 1 && last === 0 ) {+ return true;+ }+ + var doneName = match[0],+ parent = elem.parentNode;+ + if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {+ var count = 0;+ for ( node = parent.firstChild; node; node = node.nextSibling ) {+ if ( node.nodeType === 1 ) {+ node.nodeIndex = ++count;+ }+ } + parent.sizcache = doneName;+ }+ + var diff = elem.nodeIndex - last;+ if ( first === 0 ) {+ return diff === 0;+ } else {+ return ( diff % first === 0 && diff / first >= 0 );+ }+ }+ },+ ID: function(elem, match){+ return elem.nodeType === 1 && elem.getAttribute("id") === match;+ },+ TAG: function(elem, match){+ return (match === "*" && elem.nodeType === 1) || elem.nodeName.toLowerCase() === match;+ },+ CLASS: function(elem, match){+ return (" " + (elem.className || elem.getAttribute("class")) + " ")+ .indexOf( match ) > -1;+ },+ ATTR: function(elem, match){+ var name = match[1],+ result = Expr.attrHandle[ name ] ?+ Expr.attrHandle[ name ]( elem ) :+ elem[ name ] != null ?+ elem[ name ] :+ elem.getAttribute( name ),+ value = result + "",+ type = match[2],+ check = match[4];++ return result == null ?+ type === "!=" :+ type === "=" ?+ value === check :+ type === "*=" ?+ value.indexOf(check) >= 0 :+ type === "~=" ?+ (" " + value + " ").indexOf(check) >= 0 :+ !check ?+ value && result !== false :+ type === "!=" ?+ value !== check :+ type === "^=" ?+ value.indexOf(check) === 0 :+ type === "$=" ?+ value.substr(value.length - check.length) === check :+ type === "|=" ?+ value === check || value.substr(0, check.length + 1) === check + "-" :+ false;+ },+ POS: function(elem, match, i, array){+ var name = match[2], filter = Expr.setFilters[ name ];++ if ( filter ) {+ return filter( elem, i, match, array );+ }+ }+ }+};++var origPOS = Expr.match.POS;++for ( var type in Expr.match ) {+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source.replace(/\\(\d+)/g, function(all, num){+ return "\\" + (num - 0 + 1);+ }));+}++var makeArray = function(array, results) {+ array = Array.prototype.slice.call( array, 0 );++ if ( results ) {+ results.push.apply( results, array );+ return results;+ }+ + return array;+};++// Perform a simple check to determine if the browser is capable of+// converting a NodeList to an array using builtin methods.+// Also verifies that the returned array holds DOM nodes+// (which is not the case in the Blackberry browser)+try {+ Array.prototype.slice.call( document.documentElement.childNodes, 0 )[0].nodeType;++// Provide a fallback method if it does not work+} catch(e){+ makeArray = function(array, results) {+ var ret = results || [];++ if ( toString.call(array) === "[object Array]" ) {+ Array.prototype.push.apply( ret, array );+ } else {+ if ( typeof array.length === "number" ) {+ for ( var i = 0, l = array.length; i < l; i++ ) {+ ret.push( array[i] );+ }+ } else {+ for ( var i = 0; array[i]; i++ ) {+ ret.push( array[i] );+ }+ }+ }++ return ret;+ };+}++var sortOrder;++if ( document.documentElement.compareDocumentPosition ) {+ sortOrder = function( a, b ) {+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {+ if ( a == b ) {+ hasDuplicate = true;+ }+ return a.compareDocumentPosition ? -1 : 1;+ }++ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;+ if ( ret === 0 ) {+ hasDuplicate = true;+ }+ return ret;+ };+} else if ( "sourceIndex" in document.documentElement ) {+ sortOrder = function( a, b ) {+ if ( !a.sourceIndex || !b.sourceIndex ) {+ if ( a == b ) {+ hasDuplicate = true;+ }+ return a.sourceIndex ? -1 : 1;+ }++ var ret = a.sourceIndex - b.sourceIndex;+ if ( ret === 0 ) {+ hasDuplicate = true;+ }+ return ret;+ };+} else if ( document.createRange ) {+ sortOrder = function( a, b ) {+ if ( !a.ownerDocument || !b.ownerDocument ) {+ if ( a == b ) {+ hasDuplicate = true;+ }+ return a.ownerDocument ? -1 : 1;+ }++ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();+ aRange.setStart(a, 0);+ aRange.setEnd(a, 0);+ bRange.setStart(b, 0);+ bRange.setEnd(b, 0);+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);+ if ( ret === 0 ) {+ hasDuplicate = true;+ }+ return ret;+ };+}++// Utility function for retreiving the text value of an array of DOM nodes+function getText( elems ) {+ var ret = "", elem;++ for ( var i = 0; elems[i]; i++ ) {+ elem = elems[i];++ // Get the text from text nodes and CDATA nodes+ if ( elem.nodeType === 3 || elem.nodeType === 4 ) {+ ret += elem.nodeValue;++ // Traverse everything else, except comment nodes+ } else if ( elem.nodeType !== 8 ) {+ ret += getText( elem.childNodes );+ }+ }++ return ret;+}++// Check to see if the browser returns elements by name when+// querying by getElementById (and provide a workaround)+(function(){+ // We're going to inject a fake input element with a specified name+ var form = document.createElement("div"),+ id = "script" + (new Date).getTime();+ form.innerHTML = "<a name='" + id + "'/>";++ // Inject it into the root element, check its status, and remove it quickly+ var root = document.documentElement;+ root.insertBefore( form, root.firstChild );++ // The workaround has to do additional checks after a getElementById+ // Which slows things down for other browsers (hence the branching)+ if ( document.getElementById( id ) ) {+ Expr.find.ID = function(match, context, isXML){+ if ( typeof context.getElementById !== "undefined" && !isXML ) {+ var m = context.getElementById(match[1]);+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];+ }+ };++ Expr.filter.ID = function(elem, match){+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");+ return elem.nodeType === 1 && node && node.nodeValue === match;+ };+ }++ root.removeChild( form );+ root = form = null; // release memory in IE+})();++(function(){+ // Check to see if the browser returns only elements+ // when doing getElementsByTagName("*")++ // Create a fake element+ var div = document.createElement("div");+ div.appendChild( document.createComment("") );++ // Make sure no comments are found+ if ( div.getElementsByTagName("*").length > 0 ) {+ Expr.find.TAG = function(match, context){+ var results = context.getElementsByTagName(match[1]);++ // Filter out possible comments+ if ( match[1] === "*" ) {+ var tmp = [];++ for ( var i = 0; results[i]; i++ ) {+ if ( results[i].nodeType === 1 ) {+ tmp.push( results[i] );+ }+ }++ results = tmp;+ }++ return results;+ };+ }++ // Check to see if an attribute returns normalized href attributes+ div.innerHTML = "<a href='#'></a>";+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&+ div.firstChild.getAttribute("href") !== "#" ) {+ Expr.attrHandle.href = function(elem){+ return elem.getAttribute("href", 2);+ };+ }++ div = null; // release memory in IE+})();++if ( document.querySelectorAll ) {+ (function(){+ var oldSizzle = Sizzle, div = document.createElement("div");+ div.innerHTML = "<p class='TEST'></p>";++ // Safari can't handle uppercase or unicode characters when+ // in quirks mode.+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {+ return;+ }+ + Sizzle = function(query, context, extra, seed){+ context = context || document;++ // Only use querySelectorAll on non-XML documents+ // (ID selectors don't work in non-HTML documents)+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {+ try {+ return makeArray( context.querySelectorAll(query), extra );+ } catch(e){}+ }+ + return oldSizzle(query, context, extra, seed);+ };++ for ( var prop in oldSizzle ) {+ Sizzle[ prop ] = oldSizzle[ prop ];+ }++ div = null; // release memory in IE+ })();+}++(function(){+ var div = document.createElement("div");++ div.innerHTML = "<div class='test e'></div><div class='test'></div>";++ // Opera can't find a second classname (in 9.6)+ // Also, make sure that getElementsByClassName actually exists+ if ( !div.getElementsByClassName || div.getElementsByClassName("e").length === 0 ) {+ return;+ }++ // Safari caches class attributes, doesn't catch changes (in 3.2)+ div.lastChild.className = "e";++ if ( div.getElementsByClassName("e").length === 1 ) {+ return;+ }+ + Expr.order.splice(1, 0, "CLASS");+ Expr.find.CLASS = function(match, context, isXML) {+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {+ return context.getElementsByClassName(match[1]);+ }+ };++ div = null; // release memory in IE+})();++function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {+ var elem = checkSet[i];+ if ( elem ) {+ elem = elem[dir];+ var match = false;++ while ( elem ) {+ if ( elem.sizcache === doneName ) {+ match = checkSet[elem.sizset];+ break;+ }++ if ( elem.nodeType === 1 && !isXML ){+ elem.sizcache = doneName;+ elem.sizset = i;+ }++ if ( elem.nodeName.toLowerCase() === cur ) {+ match = elem;+ break;+ }++ elem = elem[dir];+ }++ checkSet[i] = match;+ }+ }+}++function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {+ var elem = checkSet[i];+ if ( elem ) {+ elem = elem[dir];+ var match = false;++ while ( elem ) {+ if ( elem.sizcache === doneName ) {+ match = checkSet[elem.sizset];+ break;+ }++ if ( elem.nodeType === 1 ) {+ if ( !isXML ) {+ elem.sizcache = doneName;+ elem.sizset = i;+ }+ if ( typeof cur !== "string" ) {+ if ( elem === cur ) {+ match = true;+ break;+ }++ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {+ match = elem;+ break;+ }+ }++ elem = elem[dir];+ }++ checkSet[i] = match;+ }+ }+}++var contains = document.compareDocumentPosition ? function(a, b){+ return !!(a.compareDocumentPosition(b) & 16);+} : function(a, b){+ return a !== b && (a.contains ? a.contains(b) : true);+};++var isXML = function(elem){+ // documentElement is verified for cases where it doesn't yet exist+ // (such as loading iframes in IE - #4833) + var documentElement = (elem ? elem.ownerDocument || elem : 0).documentElement;+ return documentElement ? documentElement.nodeName !== "HTML" : false;+};++var posProcess = function(selector, context){+ var tmpSet = [], later = "", match,+ root = context.nodeType ? [context] : context;++ // Position selectors must be done after the filter+ // And so must :not(positional) so we move all PSEUDOs to the end+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {+ later += match[0];+ selector = selector.replace( Expr.match.PSEUDO, "" );+ }++ selector = Expr.relative[selector] ? selector + "*" : selector;++ for ( var i = 0, l = root.length; i < l; i++ ) {+ Sizzle( selector, root[i], tmpSet );+ }++ return Sizzle.filter( later, tmpSet );+};++// EXPOSE+jQuery.find = Sizzle;+jQuery.expr = Sizzle.selectors;+jQuery.expr[":"] = jQuery.expr.filters;+jQuery.unique = Sizzle.uniqueSort;+jQuery.text = getText;+jQuery.isXMLDoc = isXML;+jQuery.contains = contains;++return;++window.Sizzle = Sizzle;++})();+var runtil = /Until$/,+ rparentsprev = /^(?:parents|prevUntil|prevAll)/,+ // Note: This RegExp should be improved, or likely pulled from Sizzle+ rmultiselector = /,/,+ slice = Array.prototype.slice;++// Implement the identical functionality for filter and not+var winnow = function( elements, qualifier, keep ) {+ if ( jQuery.isFunction( qualifier ) ) {+ return jQuery.grep(elements, function( elem, i ) {+ return !!qualifier.call( elem, i, elem ) === keep;+ });++ } else if ( qualifier.nodeType ) {+ return jQuery.grep(elements, function( elem, i ) {+ return (elem === qualifier) === keep;+ });++ } else if ( typeof qualifier === "string" ) {+ var filtered = jQuery.grep(elements, function( elem ) {+ return elem.nodeType === 1;+ });++ if ( isSimple.test( qualifier ) ) {+ return jQuery.filter(qualifier, filtered, !keep);+ } else {+ qualifier = jQuery.filter( qualifier, filtered );+ }+ }++ return jQuery.grep(elements, function( elem, i ) {+ return (jQuery.inArray( elem, qualifier ) >= 0) === keep;+ });+};++jQuery.fn.extend({+ find: function( selector ) {+ var ret = this.pushStack( "", "find", selector ), length = 0;++ for ( var i = 0, l = this.length; i < l; i++ ) {+ length = ret.length;+ jQuery.find( selector, this[i], ret );++ if ( i > 0 ) {+ // Make sure that the results are unique+ for ( var n = length; n < ret.length; n++ ) {+ for ( var r = 0; r < length; r++ ) {+ if ( ret[r] === ret[n] ) {+ ret.splice(n--, 1);+ break;+ }+ }+ }+ }+ }++ return ret;+ },++ has: function( target ) {+ var targets = jQuery( target );+ return this.filter(function() {+ for ( var i = 0, l = targets.length; i < l; i++ ) {+ if ( jQuery.contains( this, targets[i] ) ) {+ return true;+ }+ }+ });+ },++ not: function( selector ) {+ return this.pushStack( winnow(this, selector, false), "not", selector);+ },++ filter: function( selector ) {+ return this.pushStack( winnow(this, selector, true), "filter", selector );+ },+ + is: function( selector ) {+ return !!selector && jQuery.filter( selector, this ).length > 0;+ },++ closest: function( selectors, context ) {+ if ( jQuery.isArray( selectors ) ) {+ var ret = [], cur = this[0], match, matches = {}, selector;++ if ( cur && selectors.length ) {+ for ( var i = 0, l = selectors.length; i < l; i++ ) {+ selector = selectors[i];++ if ( !matches[selector] ) {+ matches[selector] = jQuery.expr.match.POS.test( selector ) ? + jQuery( selector, context || this.context ) :+ selector;+ }+ }++ while ( cur && cur.ownerDocument && cur !== context ) {+ for ( selector in matches ) {+ match = matches[selector];++ if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) {+ ret.push({ selector: selector, elem: cur });+ delete matches[selector];+ }+ }+ cur = cur.parentNode;+ }+ }++ return ret;+ }++ var pos = jQuery.expr.match.POS.test( selectors ) ? + jQuery( selectors, context || this.context ) : null;++ return this.map(function( i, cur ) {+ while ( cur && cur.ownerDocument && cur !== context ) {+ if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selectors) ) {+ return cur;+ }+ cur = cur.parentNode;+ }+ return null;+ });+ },+ + // Determine the position of an element within+ // the matched set of elements+ index: function( elem ) {+ if ( !elem || typeof elem === "string" ) {+ return jQuery.inArray( this[0],+ // If it receives a string, the selector is used+ // If it receives nothing, the siblings are used+ elem ? jQuery( elem ) : this.parent().children() );+ }+ // Locate the position of the desired element+ return jQuery.inArray(+ // If it receives a jQuery object, the first element is used+ elem.jquery ? elem[0] : elem, this );+ },++ add: function( selector, context ) {+ var set = typeof selector === "string" ?+ jQuery( selector, context || this.context ) :+ jQuery.makeArray( selector ),+ all = jQuery.merge( this.get(), set );++ return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ?+ all :+ jQuery.unique( all ) );+ },++ andSelf: function() {+ return this.add( this.prevObject );+ }+});++// A painfully simple check to see if an element is disconnected+// from a document (should be improved, where feasible).+function isDisconnected( node ) {+ return !node || !node.parentNode || node.parentNode.nodeType === 11;+}++jQuery.each({+ parent: function( elem ) {+ var parent = elem.parentNode;+ return parent && parent.nodeType !== 11 ? parent : null;+ },+ parents: function( elem ) {+ return jQuery.dir( elem, "parentNode" );+ },+ parentsUntil: function( elem, i, until ) {+ return jQuery.dir( elem, "parentNode", until );+ },+ next: function( elem ) {+ return jQuery.nth( elem, 2, "nextSibling" );+ },+ prev: function( elem ) {+ return jQuery.nth( elem, 2, "previousSibling" );+ },+ nextAll: function( elem ) {+ return jQuery.dir( elem, "nextSibling" );+ },+ prevAll: function( elem ) {+ return jQuery.dir( elem, "previousSibling" );+ },+ nextUntil: function( elem, i, until ) {+ return jQuery.dir( elem, "nextSibling", until );+ },+ prevUntil: function( elem, i, until ) {+ return jQuery.dir( elem, "previousSibling", until );+ },+ siblings: function( elem ) {+ return jQuery.sibling( elem.parentNode.firstChild, elem );+ },+ children: function( elem ) {+ return jQuery.sibling( elem.firstChild );+ },+ contents: function( elem ) {+ return jQuery.nodeName( elem, "iframe" ) ?+ elem.contentDocument || elem.contentWindow.document :+ jQuery.makeArray( elem.childNodes );+ }+}, function( name, fn ) {+ jQuery.fn[ name ] = function( until, selector ) {+ var ret = jQuery.map( this, fn, until );+ + if ( !runtil.test( name ) ) {+ selector = until;+ }++ if ( selector && typeof selector === "string" ) {+ ret = jQuery.filter( selector, ret );+ }++ ret = this.length > 1 ? jQuery.unique( ret ) : ret;++ if ( (this.length > 1 || rmultiselector.test( selector )) && rparentsprev.test( name ) ) {+ ret = ret.reverse();+ }++ return this.pushStack( ret, name, slice.call(arguments).join(",") );+ };+});++jQuery.extend({+ filter: function( expr, elems, not ) {+ if ( not ) {+ expr = ":not(" + expr + ")";+ }++ return jQuery.find.matches(expr, elems);+ },+ + dir: function( elem, dir, until ) {+ var matched = [], cur = elem[dir];+ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {+ if ( cur.nodeType === 1 ) {+ matched.push( cur );+ }+ cur = cur[dir];+ }+ return matched;+ },++ nth: function( cur, result, dir, elem ) {+ result = result || 1;+ var num = 0;++ for ( ; cur; cur = cur[dir] ) {+ if ( cur.nodeType === 1 && ++num === result ) {+ break;+ }+ }++ return cur;+ },++ sibling: function( n, elem ) {+ var r = [];++ for ( ; n; n = n.nextSibling ) {+ if ( n.nodeType === 1 && n !== elem ) {+ r.push( n );+ }+ }++ return r;+ }+});+var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g,+ rleadingWhitespace = /^\s+/,+ rxhtmlTag = /(<([\w:]+)[^>]*?)\/>/g,+ rselfClosing = /^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,+ rtagName = /<([\w:]+)/,+ rtbody = /<tbody/i,+ rhtml = /<|&#?\w+;/,+ rnocache = /<script|<object|<embed|<option|<style/i,+ rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, // checked="checked" or checked (html5)+ fcloseTag = function( all, front, tag ) {+ return rselfClosing.test( tag ) ?+ all :+ front + "></" + tag + ">";+ },+ wrapMap = {+ option: [ 1, "<select multiple='multiple'>", "</select>" ],+ legend: [ 1, "<fieldset>", "</fieldset>" ],+ thead: [ 1, "<table>", "</table>" ],+ tr: [ 2, "<table><tbody>", "</tbody></table>" ],+ td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],+ col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],+ area: [ 1, "<map>", "</map>" ],+ _default: [ 0, "", "" ]+ };++wrapMap.optgroup = wrapMap.option;+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;+wrapMap.th = wrapMap.td;++// IE can't serialize <link> and <script> tags normally+if ( !jQuery.support.htmlSerialize ) {+ wrapMap._default = [ 1, "div<div>", "</div>" ];+}++jQuery.fn.extend({+ text: function( text ) {+ if ( jQuery.isFunction(text) ) {+ return this.each(function(i) {+ var self = jQuery(this);+ self.text( text.call(this, i, self.text()) );+ });+ }++ if ( typeof text !== "object" && text !== undefined ) {+ return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );+ }++ return jQuery.text( this );+ },++ wrapAll: function( html ) {+ if ( jQuery.isFunction( html ) ) {+ return this.each(function(i) {+ jQuery(this).wrapAll( html.call(this, i) );+ });+ }++ if ( this[0] ) {+ // The elements to wrap the target around+ var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);++ if ( this[0].parentNode ) {+ wrap.insertBefore( this[0] );+ }++ wrap.map(function() {+ var elem = this;++ while ( elem.firstChild && elem.firstChild.nodeType === 1 ) {+ elem = elem.firstChild;+ }++ return elem;+ }).append(this);+ }++ return this;+ },++ wrapInner: function( html ) {+ if ( jQuery.isFunction( html ) ) {+ return this.each(function(i) {+ jQuery(this).wrapInner( html.call(this, i) );+ });+ }++ return this.each(function() {+ var self = jQuery( this ), contents = self.contents();++ if ( contents.length ) {+ contents.wrapAll( html );++ } else {+ self.append( html );+ }+ });+ },++ wrap: function( html ) {+ return this.each(function() {+ jQuery( this ).wrapAll( html );+ });+ },++ unwrap: function() {+ return this.parent().each(function() {+ if ( !jQuery.nodeName( this, "body" ) ) {+ jQuery( this ).replaceWith( this.childNodes );+ }+ }).end();+ },++ append: function() {+ return this.domManip(arguments, true, function( elem ) {+ if ( this.nodeType === 1 ) {+ this.appendChild( elem );+ }+ });+ },++ prepend: function() {+ return this.domManip(arguments, true, function( elem ) {+ if ( this.nodeType === 1 ) {+ this.insertBefore( elem, this.firstChild );+ }+ });+ },++ before: function() {+ if ( this[0] && this[0].parentNode ) {+ return this.domManip(arguments, false, function( elem ) {+ this.parentNode.insertBefore( elem, this );+ });+ } else if ( arguments.length ) {+ var set = jQuery(arguments[0]);+ set.push.apply( set, this.toArray() );+ return this.pushStack( set, "before", arguments );+ }+ },++ after: function() {+ if ( this[0] && this[0].parentNode ) {+ return this.domManip(arguments, false, function( elem ) {+ this.parentNode.insertBefore( elem, this.nextSibling );+ });+ } else if ( arguments.length ) {+ var set = this.pushStack( this, "after", arguments );+ set.push.apply( set, jQuery(arguments[0]).toArray() );+ return set;+ }+ },+ + // keepData is for internal use only--do not document+ remove: function( selector, keepData ) {+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {+ if ( !selector || jQuery.filter( selector, [ elem ] ).length ) {+ if ( !keepData && elem.nodeType === 1 ) {+ jQuery.cleanData( elem.getElementsByTagName("*") );+ jQuery.cleanData( [ elem ] );+ }++ if ( elem.parentNode ) {+ elem.parentNode.removeChild( elem );+ }+ }+ }+ + return this;+ },++ empty: function() {+ for ( var i = 0, elem; (elem = this[i]) != null; i++ ) {+ // Remove element nodes and prevent memory leaks+ if ( elem.nodeType === 1 ) {+ jQuery.cleanData( elem.getElementsByTagName("*") );+ }++ // Remove any remaining nodes+ while ( elem.firstChild ) {+ elem.removeChild( elem.firstChild );+ }+ }+ + return this;+ },++ clone: function( events ) {+ // Do the clone+ var ret = this.map(function() {+ if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) {+ // IE copies events bound via attachEvent when+ // using cloneNode. Calling detachEvent on the+ // clone will also remove the events from the orignal+ // In order to get around this, we use innerHTML.+ // Unfortunately, this means some modifications to+ // attributes in IE that are actually only stored+ // as properties will not be copied (such as the+ // the name attribute on an input).+ var html = this.outerHTML, ownerDocument = this.ownerDocument;+ if ( !html ) {+ var div = ownerDocument.createElement("div");+ div.appendChild( this.cloneNode(true) );+ html = div.innerHTML;+ }++ return jQuery.clean([html.replace(rinlinejQuery, "")+ // Handle the case in IE 8 where action=/test/> self-closes a tag+ .replace(/=([^="'>\s]+\/)>/g, '="$1">')+ .replace(rleadingWhitespace, "")], ownerDocument)[0];+ } else {+ return this.cloneNode(true);+ }+ });++ // Copy the events from the original to the clone+ if ( events === true ) {+ cloneCopyEvent( this, ret );+ cloneCopyEvent( this.find("*"), ret.find("*") );+ }++ // Return the cloned set+ return ret;+ },++ html: function( value ) {+ if ( value === undefined ) {+ return this[0] && this[0].nodeType === 1 ?+ this[0].innerHTML.replace(rinlinejQuery, "") :+ null;++ // See if we can take a shortcut and just use innerHTML+ } else if ( typeof value === "string" && !rnocache.test( value ) &&+ (jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value )) &&+ !wrapMap[ (rtagName.exec( value ) || ["", ""])[1].toLowerCase() ] ) {++ value = value.replace(rxhtmlTag, fcloseTag);++ try {+ for ( var i = 0, l = this.length; i < l; i++ ) {+ // Remove element nodes and prevent memory leaks+ if ( this[i].nodeType === 1 ) {+ jQuery.cleanData( this[i].getElementsByTagName("*") );+ this[i].innerHTML = value;+ }+ }++ // If using innerHTML throws an exception, use the fallback method+ } catch(e) {+ this.empty().append( value );+ }++ } else if ( jQuery.isFunction( value ) ) {+ this.each(function(i){+ var self = jQuery(this), old = self.html();+ self.empty().append(function(){+ return value.call( this, i, old );+ });+ });++ } else {+ this.empty().append( value );+ }++ return this;+ },++ replaceWith: function( value ) {+ if ( this[0] && this[0].parentNode ) {+ // Make sure that the elements are removed from the DOM before they are inserted+ // this can help fix replacing a parent with child elements+ if ( jQuery.isFunction( value ) ) {+ return this.each(function(i) {+ var self = jQuery(this), old = self.html();+ self.replaceWith( value.call( this, i, old ) );+ });+ }++ if ( typeof value !== "string" ) {+ value = jQuery(value).detach();+ }++ return this.each(function() {+ var next = this.nextSibling, parent = this.parentNode;++ jQuery(this).remove();++ if ( next ) {+ jQuery(next).before( value );+ } else {+ jQuery(parent).append( value );+ }+ });+ } else {+ return this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value );+ }+ },++ detach: function( selector ) {+ return this.remove( selector, true );+ },++ domManip: function( args, table, callback ) {+ var results, first, value = args[0], scripts = [], fragment, parent;++ // We can't cloneNode fragments that contain checked, in WebKit+ if ( !jQuery.support.checkClone && arguments.length === 3 && typeof value === "string" && rchecked.test( value ) ) {+ return this.each(function() {+ jQuery(this).domManip( args, table, callback, true );+ });+ }++ if ( jQuery.isFunction(value) ) {+ return this.each(function(i) {+ var self = jQuery(this);+ args[0] = value.call(this, i, table ? self.html() : undefined);+ self.domManip( args, table, callback );+ });+ }++ if ( this[0] ) {+ parent = value && value.parentNode;++ // If we're in a fragment, just use that instead of building a new one+ if ( jQuery.support.parentNode && parent && parent.nodeType === 11 && parent.childNodes.length === this.length ) {+ results = { fragment: parent };++ } else {+ results = buildFragment( args, this, scripts );+ }+ + fragment = results.fragment;+ + if ( fragment.childNodes.length === 1 ) {+ first = fragment = fragment.firstChild;+ } else {+ first = fragment.firstChild;+ }++ if ( first ) {+ table = table && jQuery.nodeName( first, "tr" );++ for ( var i = 0, l = this.length; i < l; i++ ) {+ callback.call(+ table ?+ root(this[i], first) :+ this[i],+ i > 0 || results.cacheable || this.length > 1 ?+ fragment.cloneNode(true) :+ fragment+ );+ }+ }++ if ( scripts.length ) {+ jQuery.each( scripts, evalScript );+ }+ }++ return this;++ function root( elem, cur ) {+ return jQuery.nodeName(elem, "table") ?+ (elem.getElementsByTagName("tbody")[0] ||+ elem.appendChild(elem.ownerDocument.createElement("tbody"))) :+ elem;+ }+ }+});++function cloneCopyEvent(orig, ret) {+ var i = 0;++ ret.each(function() {+ if ( this.nodeName !== (orig[i] && orig[i].nodeName) ) {+ return;+ }++ var oldData = jQuery.data( orig[i++] ), curData = jQuery.data( this, oldData ), events = oldData && oldData.events;++ if ( events ) {+ delete curData.handle;+ curData.events = {};++ for ( var type in events ) {+ for ( var handler in events[ type ] ) {+ jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data );+ }+ }+ }+ });+}++function buildFragment( args, nodes, scripts ) {+ var fragment, cacheable, cacheresults,+ doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document);++ // Only cache "small" (1/2 KB) strings that are associated with the main document+ // Cloning options loses the selected state, so don't cache them+ // IE 6 doesn't like it when you put <object> or <embed> elements in a fragment+ // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache+ if ( args.length === 1 && typeof args[0] === "string" && args[0].length < 512 && doc === document &&+ !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) {++ cacheable = true;+ cacheresults = jQuery.fragments[ args[0] ];+ if ( cacheresults ) {+ if ( cacheresults !== 1 ) {+ fragment = cacheresults;+ }+ }+ }++ if ( !fragment ) {+ fragment = doc.createDocumentFragment();+ jQuery.clean( args, doc, fragment, scripts );+ }++ if ( cacheable ) {+ jQuery.fragments[ args[0] ] = cacheresults ? fragment : 1;+ }++ return { fragment: fragment, cacheable: cacheable };+}++jQuery.fragments = {};++jQuery.each({+ appendTo: "append",+ prependTo: "prepend",+ insertBefore: "before",+ insertAfter: "after",+ replaceAll: "replaceWith"+}, function( name, original ) {+ jQuery.fn[ name ] = function( selector ) {+ var ret = [], insert = jQuery( selector ),+ parent = this.length === 1 && this[0].parentNode;+ + if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {+ insert[ original ]( this[0] );+ return this;+ + } else {+ for ( var i = 0, l = insert.length; i < l; i++ ) {+ var elems = (i > 0 ? this.clone(true) : this).get();+ jQuery.fn[ original ].apply( jQuery(insert[i]), elems );+ ret = ret.concat( elems );+ }+ + return this.pushStack( ret, name, insert.selector );+ }+ };+});++jQuery.extend({+ clean: function( elems, context, fragment, scripts ) {+ context = context || document;++ // !context.createElement fails in IE with an error but returns typeof 'object'+ if ( typeof context.createElement === "undefined" ) {+ context = context.ownerDocument || context[0] && context[0].ownerDocument || document;+ }++ var ret = [];++ for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {+ if ( typeof elem === "number" ) {+ elem += "";+ }++ if ( !elem ) {+ continue;+ }++ // Convert html string into DOM nodes+ if ( typeof elem === "string" && !rhtml.test( elem ) ) {+ elem = context.createTextNode( elem );++ } else if ( typeof elem === "string" ) {+ // Fix "XHTML"-style tags in all browsers+ elem = elem.replace(rxhtmlTag, fcloseTag);++ // Trim whitespace, otherwise indexOf won't work as expected+ var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(),+ wrap = wrapMap[ tag ] || wrapMap._default,+ depth = wrap[0],+ div = context.createElement("div");++ // Go to html and back, then peel off extra wrappers+ div.innerHTML = wrap[1] + elem + wrap[2];++ // Move to the right depth+ while ( depth-- ) {+ div = div.lastChild;+ }++ // Remove IE's autoinserted <tbody> from table fragments+ if ( !jQuery.support.tbody ) {++ // String was a <table>, *may* have spurious <tbody>+ var hasBody = rtbody.test(elem),+ tbody = tag === "table" && !hasBody ?+ div.firstChild && div.firstChild.childNodes :++ // String was a bare <thead> or <tfoot>+ wrap[1] === "<table>" && !hasBody ?+ div.childNodes :+ [];++ for ( var j = tbody.length - 1; j >= 0 ; --j ) {+ if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) {+ tbody[ j ].parentNode.removeChild( tbody[ j ] );+ }+ }++ }++ // IE completely kills leading whitespace when innerHTML is used+ if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {+ div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild );+ }++ elem = div.childNodes;+ }++ if ( elem.nodeType ) {+ ret.push( elem );+ } else {+ ret = jQuery.merge( ret, elem );+ }+ }++ if ( fragment ) {+ for ( var i = 0; ret[i]; i++ ) {+ if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) {+ scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] );+ + } else {+ if ( ret[i].nodeType === 1 ) {+ ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) );+ }+ fragment.appendChild( ret[i] );+ }+ }+ }++ return ret;+ },+ + cleanData: function( elems ) {+ var data, id, cache = jQuery.cache,+ special = jQuery.event.special,+ deleteExpando = jQuery.support.deleteExpando;+ + for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {+ id = elem[ jQuery.expando ];+ + if ( id ) {+ data = cache[ id ];+ + if ( data.events ) {+ for ( var type in data.events ) {+ if ( special[ type ] ) {+ jQuery.event.remove( elem, type );++ } else {+ removeEvent( elem, type, data.handle );+ }+ }+ }+ + if ( deleteExpando ) {+ delete elem[ jQuery.expando ];++ } else if ( elem.removeAttribute ) {+ elem.removeAttribute( jQuery.expando );+ }+ + delete cache[ id ];+ }+ }+ }+});+// exclude the following css properties to add px+var rexclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,+ ralpha = /alpha\([^)]*\)/,+ ropacity = /opacity=([^)]*)/,+ rfloat = /float/i,+ rdashAlpha = /-([a-z])/ig,+ rupper = /([A-Z])/g,+ rnumpx = /^-?\d+(?:px)?$/i,+ rnum = /^-?\d/,++ cssShow = { position: "absolute", visibility: "hidden", display:"block" },+ cssWidth = [ "Left", "Right" ],+ cssHeight = [ "Top", "Bottom" ],++ // cache check for defaultView.getComputedStyle+ getComputedStyle = document.defaultView && document.defaultView.getComputedStyle,+ // normalize float css property+ styleFloat = jQuery.support.cssFloat ? "cssFloat" : "styleFloat",+ fcamelCase = function( all, letter ) {+ return letter.toUpperCase();+ };++jQuery.fn.css = function( name, value ) {+ return access( this, name, value, true, function( elem, name, value ) {+ if ( value === undefined ) {+ return jQuery.curCSS( elem, name );+ }+ + if ( typeof value === "number" && !rexclude.test(name) ) {+ value += "px";+ }++ jQuery.style( elem, name, value );+ });+};++jQuery.extend({+ style: function( elem, name, value ) {+ // don't set styles on text and comment nodes+ if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {+ return undefined;+ }++ // ignore negative width and height values #1599+ if ( (name === "width" || name === "height") && parseFloat(value) < 0 ) {+ value = undefined;+ }++ var style = elem.style || elem, set = value !== undefined;++ // IE uses filters for opacity+ if ( !jQuery.support.opacity && name === "opacity" ) {+ if ( set ) {+ // IE has trouble with opacity if it does not have layout+ // Force it by setting the zoom level+ style.zoom = 1;++ // Set the alpha filter to set the opacity+ var opacity = parseInt( value, 10 ) + "" === "NaN" ? "" : "alpha(opacity=" + value * 100 + ")";+ var filter = style.filter || jQuery.curCSS( elem, "filter" ) || "";+ style.filter = ralpha.test(filter) ? filter.replace(ralpha, opacity) : opacity;+ }++ return style.filter && style.filter.indexOf("opacity=") >= 0 ?+ (parseFloat( ropacity.exec(style.filter)[1] ) / 100) + "":+ "";+ }++ // Make sure we're using the right name for getting the float value+ if ( rfloat.test( name ) ) {+ name = styleFloat;+ }++ name = name.replace(rdashAlpha, fcamelCase);++ if ( set ) {+ style[ name ] = value;+ }++ return style[ name ];+ },++ css: function( elem, name, force, extra ) {+ if ( name === "width" || name === "height" ) {+ var val, props = cssShow, which = name === "width" ? cssWidth : cssHeight;++ function getWH() {+ val = name === "width" ? elem.offsetWidth : elem.offsetHeight;++ if ( extra === "border" ) {+ return;+ }++ jQuery.each( which, function() {+ if ( !extra ) {+ val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;+ }++ if ( extra === "margin" ) {+ val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0;+ } else {+ val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;+ }+ });+ }++ if ( elem.offsetWidth !== 0 ) {+ getWH();+ } else {+ jQuery.swap( elem, props, getWH );+ }++ return Math.max(0, Math.round(val));+ }++ return jQuery.curCSS( elem, name, force );+ },++ curCSS: function( elem, name, force ) {+ var ret, style = elem.style, filter;++ // IE uses filters for opacity+ if ( !jQuery.support.opacity && name === "opacity" && elem.currentStyle ) {+ ret = ropacity.test(elem.currentStyle.filter || "") ?+ (parseFloat(RegExp.$1) / 100) + "" :+ "";++ return ret === "" ?+ "1" :+ ret;+ }++ // Make sure we're using the right name for getting the float value+ if ( rfloat.test( name ) ) {+ name = styleFloat;+ }++ if ( !force && style && style[ name ] ) {+ ret = style[ name ];++ } else if ( getComputedStyle ) {++ // Only "float" is needed here+ if ( rfloat.test( name ) ) {+ name = "float";+ }++ name = name.replace( rupper, "-$1" ).toLowerCase();++ var defaultView = elem.ownerDocument.defaultView;++ if ( !defaultView ) {+ return null;+ }++ var computedStyle = defaultView.getComputedStyle( elem, null );++ if ( computedStyle ) {+ ret = computedStyle.getPropertyValue( name );+ }++ // We should always get a number back from opacity+ if ( name === "opacity" && ret === "" ) {+ ret = "1";+ }++ } else if ( elem.currentStyle ) {+ var camelCase = name.replace(rdashAlpha, fcamelCase);++ ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];++ // From the awesome hack by Dean Edwards+ // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291++ // If we're not dealing with a regular pixel number+ // but a number that has a weird ending, we need to convert it to pixels+ if ( !rnumpx.test( ret ) && rnum.test( ret ) ) {+ // Remember the original values+ var left = style.left, rsLeft = elem.runtimeStyle.left;++ // Put in the new values to get a computed value out+ elem.runtimeStyle.left = elem.currentStyle.left;+ style.left = camelCase === "fontSize" ? "1em" : (ret || 0);+ ret = style.pixelLeft + "px";++ // Revert the changed values+ style.left = left;+ elem.runtimeStyle.left = rsLeft;+ }+ }++ return ret;+ },++ // A method for quickly swapping in/out CSS properties to get correct calculations+ swap: function( elem, options, callback ) {+ var old = {};++ // Remember the old values, and insert the new ones+ for ( var name in options ) {+ old[ name ] = elem.style[ name ];+ elem.style[ name ] = options[ name ];+ }++ callback.call( elem );++ // Revert the old values+ for ( var name in options ) {+ elem.style[ name ] = old[ name ];+ }+ }+});++if ( jQuery.expr && jQuery.expr.filters ) {+ jQuery.expr.filters.hidden = function( elem ) {+ var width = elem.offsetWidth, height = elem.offsetHeight,+ skip = elem.nodeName.toLowerCase() === "tr";++ return width === 0 && height === 0 && !skip ?+ true :+ width > 0 && height > 0 && !skip ?+ false :+ jQuery.curCSS(elem, "display") === "none";+ };++ jQuery.expr.filters.visible = function( elem ) {+ return !jQuery.expr.filters.hidden( elem );+ };+}+var jsc = now(),+ rscript = /<script(.|\s)*?\/script>/gi,+ rselectTextarea = /select|textarea/i,+ rinput = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,+ jsre = /=\?(&|$)/,+ rquery = /\?/,+ rts = /(\?|&)_=.*?(&|$)/,+ rurl = /^(\w+:)?\/\/([^\/?#]+)/,+ r20 = /%20/g,++ // Keep a copy of the old load method+ _load = jQuery.fn.load;++jQuery.fn.extend({+ load: function( url, params, callback ) {+ if ( typeof url !== "string" ) {+ return _load.call( this, url );++ // Don't do a request if no elements are being requested+ } else if ( !this.length ) {+ return this;+ }++ var off = url.indexOf(" ");+ if ( off >= 0 ) {+ var selector = url.slice(off, url.length);+ url = url.slice(0, off);+ }++ // Default to a GET request+ var type = "GET";++ // If the second parameter was provided+ if ( params ) {+ // If it's a function+ if ( jQuery.isFunction( params ) ) {+ // We assume that it's the callback+ callback = params;+ params = null;++ // Otherwise, build a param string+ } else if ( typeof params === "object" ) {+ params = jQuery.param( params, jQuery.ajaxSettings.traditional );+ type = "POST";+ }+ }++ var self = this;++ // Request the remote document+ jQuery.ajax({+ url: url,+ type: type,+ dataType: "html",+ data: params,+ complete: function( res, status ) {+ // If successful, inject the HTML into all the matched elements+ if ( status === "success" || status === "notmodified" ) {+ // See if a selector was specified+ self.html( selector ?+ // Create a dummy div to hold the results+ jQuery("<div />")+ // inject the contents of the document in, removing the scripts+ // to avoid any 'Permission Denied' errors in IE+ .append(res.responseText.replace(rscript, ""))++ // Locate the specified elements+ .find(selector) :++ // If not, just inject the full result+ res.responseText );+ }++ if ( callback ) {+ self.each( callback, [res.responseText, status, res] );+ }+ }+ });++ return this;+ },++ serialize: function() {+ return jQuery.param(this.serializeArray());+ },+ serializeArray: function() {+ return this.map(function() {+ return this.elements ? jQuery.makeArray(this.elements) : this;+ })+ .filter(function() {+ return this.name && !this.disabled &&+ (this.checked || rselectTextarea.test(this.nodeName) ||+ rinput.test(this.type));+ })+ .map(function( i, elem ) {+ var val = jQuery(this).val();++ return val == null ?+ null :+ jQuery.isArray(val) ?+ jQuery.map( val, function( val, i ) {+ return { name: elem.name, value: val };+ }) :+ { name: elem.name, value: val };+ }).get();+ }+});++// Attach a bunch of functions for handling common AJAX events+jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), function( i, o ) {+ jQuery.fn[o] = function( f ) {+ return this.bind(o, f);+ };+});++jQuery.extend({++ get: function( url, data, callback, type ) {+ // shift arguments if data argument was omited+ if ( jQuery.isFunction( data ) ) {+ type = type || callback;+ callback = data;+ data = null;+ }++ return jQuery.ajax({+ type: "GET",+ url: url,+ data: data,+ success: callback,+ dataType: type+ });+ },++ getScript: function( url, callback ) {+ return jQuery.get(url, null, callback, "script");+ },++ getJSON: function( url, data, callback ) {+ return jQuery.get(url, data, callback, "json");+ },++ post: function( url, data, callback, type ) {+ // shift arguments if data argument was omited+ if ( jQuery.isFunction( data ) ) {+ type = type || callback;+ callback = data;+ data = {};+ }++ return jQuery.ajax({+ type: "POST",+ url: url,+ data: data,+ success: callback,+ dataType: type+ });+ },++ ajaxSetup: function( settings ) {+ jQuery.extend( jQuery.ajaxSettings, settings );+ },++ ajaxSettings: {+ url: location.href,+ global: true,+ type: "GET",+ contentType: "application/x-www-form-urlencoded",+ processData: true,+ async: true,+ /*+ timeout: 0,+ data: null,+ username: null,+ password: null,+ traditional: false,+ */+ // Create the request object; Microsoft failed to properly+ // implement the XMLHttpRequest in IE7 (can't request local files),+ // so we use the ActiveXObject when it is available+ // This function can be overriden by calling jQuery.ajaxSetup+ xhr: window.XMLHttpRequest && (window.location.protocol !== "file:" || !window.ActiveXObject) ?+ function() {+ return new window.XMLHttpRequest();+ } :+ function() {+ try {+ return new window.ActiveXObject("Microsoft.XMLHTTP");+ } catch(e) {}+ },+ accepts: {+ xml: "application/xml, text/xml",+ html: "text/html",+ script: "text/javascript, application/javascript",+ json: "application/json, text/javascript",+ text: "text/plain",+ _default: "*/*"+ }+ },++ // Last-Modified header cache for next request+ lastModified: {},+ etag: {},++ ajax: function( origSettings ) {+ var s = jQuery.extend(true, {}, jQuery.ajaxSettings, origSettings);+ + var jsonp, status, data,+ callbackContext = origSettings && origSettings.context || s,+ type = s.type.toUpperCase();++ // convert data if not already a string+ if ( s.data && s.processData && typeof s.data !== "string" ) {+ s.data = jQuery.param( s.data, s.traditional );+ }++ // Handle JSONP Parameter Callbacks+ if ( s.dataType === "jsonp" ) {+ if ( type === "GET" ) {+ if ( !jsre.test( s.url ) ) {+ s.url += (rquery.test( s.url ) ? "&" : "?") + (s.jsonp || "callback") + "=?";+ }+ } else if ( !s.data || !jsre.test(s.data) ) {+ s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";+ }+ s.dataType = "json";+ }++ // Build temporary JSONP function+ if ( s.dataType === "json" && (s.data && jsre.test(s.data) || jsre.test(s.url)) ) {+ jsonp = s.jsonpCallback || ("jsonp" + jsc++);++ // Replace the =? sequence both in the query string and the data+ if ( s.data ) {+ s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");+ }++ s.url = s.url.replace(jsre, "=" + jsonp + "$1");++ // We need to make sure+ // that a JSONP style response is executed properly+ s.dataType = "script";++ // Handle JSONP-style loading+ window[ jsonp ] = window[ jsonp ] || function( tmp ) {+ data = tmp;+ success();+ complete();+ // Garbage collect+ window[ jsonp ] = undefined;++ try {+ delete window[ jsonp ];+ } catch(e) {}++ if ( head ) {+ head.removeChild( script );+ }+ };+ }++ if ( s.dataType === "script" && s.cache === null ) {+ s.cache = false;+ }++ if ( s.cache === false && type === "GET" ) {+ var ts = now();++ // try replacing _= if it is there+ var ret = s.url.replace(rts, "$1_=" + ts + "$2");++ // if nothing was replaced, add timestamp to the end+ s.url = ret + ((ret === s.url) ? (rquery.test(s.url) ? "&" : "?") + "_=" + ts : "");+ }++ // If data is available, append data to url for get requests+ if ( s.data && type === "GET" ) {+ s.url += (rquery.test(s.url) ? "&" : "?") + s.data;+ }++ // Watch for a new set of requests+ if ( s.global && ! jQuery.active++ ) {+ jQuery.event.trigger( "ajaxStart" );+ }++ // Matches an absolute URL, and saves the domain+ var parts = rurl.exec( s.url ),+ remote = parts && (parts[1] && parts[1] !== location.protocol || parts[2] !== location.host);++ // If we're requesting a remote document+ // and trying to load JSON or Script with a GET+ if ( s.dataType === "script" && type === "GET" && remote ) {+ var head = document.getElementsByTagName("head")[0] || document.documentElement;+ var script = document.createElement("script");+ script.src = s.url;+ if ( s.scriptCharset ) {+ script.charset = s.scriptCharset;+ }++ // Handle Script loading+ if ( !jsonp ) {+ var done = false;++ // Attach handlers for all browsers+ script.onload = script.onreadystatechange = function() {+ if ( !done && (!this.readyState ||+ this.readyState === "loaded" || this.readyState === "complete") ) {+ done = true;+ success();+ complete();++ // Handle memory leak in IE+ script.onload = script.onreadystatechange = null;+ if ( head && script.parentNode ) {+ head.removeChild( script );+ }+ }+ };+ }++ // Use insertBefore instead of appendChild to circumvent an IE6 bug.+ // This arises when a base node is used (#2709 and #4378).+ head.insertBefore( script, head.firstChild );++ // We handle everything using the script element injection+ return undefined;+ }++ var requestDone = false;++ // Create the request object+ var xhr = s.xhr();++ if ( !xhr ) {+ return;+ }++ // Open the socket+ // Passing null username, generates a login popup on Opera (#2865)+ if ( s.username ) {+ xhr.open(type, s.url, s.async, s.username, s.password);+ } else {+ xhr.open(type, s.url, s.async);+ }++ // Need an extra try/catch for cross domain requests in Firefox 3+ try {+ // Set the correct header, if data is being sent+ if ( s.data || origSettings && origSettings.contentType ) {+ xhr.setRequestHeader("Content-Type", s.contentType);+ }++ // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.+ if ( s.ifModified ) {+ if ( jQuery.lastModified[s.url] ) {+ xhr.setRequestHeader("If-Modified-Since", jQuery.lastModified[s.url]);+ }++ if ( jQuery.etag[s.url] ) {+ xhr.setRequestHeader("If-None-Match", jQuery.etag[s.url]);+ }+ }++ // Set header so the called script knows that it's an XMLHttpRequest+ // Only send the header if it's not a remote XHR+ if ( !remote ) {+ xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");+ }++ // Set the Accepts header for the server, depending on the dataType+ xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?+ s.accepts[ s.dataType ] + ", */*" :+ s.accepts._default );+ } catch(e) {}++ // Allow custom headers/mimetypes and early abort+ if ( s.beforeSend && s.beforeSend.call(callbackContext, xhr, s) === false ) {+ // Handle the global AJAX counter+ if ( s.global && ! --jQuery.active ) {+ jQuery.event.trigger( "ajaxStop" );+ }++ // close opended socket+ xhr.abort();+ return false;+ }++ if ( s.global ) {+ trigger("ajaxSend", [xhr, s]);+ }++ // Wait for a response to come back+ var onreadystatechange = xhr.onreadystatechange = function( isTimeout ) {+ // The request was aborted+ if ( !xhr || xhr.readyState === 0 || isTimeout === "abort" ) {+ // Opera doesn't call onreadystatechange before this point+ // so we simulate the call+ if ( !requestDone ) {+ complete();+ }++ requestDone = true;+ if ( xhr ) {+ xhr.onreadystatechange = jQuery.noop;+ }++ // The transfer is complete and the data is available, or the request timed out+ } else if ( !requestDone && xhr && (xhr.readyState === 4 || isTimeout === "timeout") ) {+ requestDone = true;+ xhr.onreadystatechange = jQuery.noop;++ status = isTimeout === "timeout" ?+ "timeout" :+ !jQuery.httpSuccess( xhr ) ?+ "error" :+ s.ifModified && jQuery.httpNotModified( xhr, s.url ) ?+ "notmodified" :+ "success";++ var errMsg;++ if ( status === "success" ) {+ // Watch for, and catch, XML document parse errors+ try {+ // process the data (runs the xml through httpData regardless of callback)+ data = jQuery.httpData( xhr, s.dataType, s );+ } catch(err) {+ status = "parsererror";+ errMsg = err;+ }+ }++ // Make sure that the request was successful or notmodified+ if ( status === "success" || status === "notmodified" ) {+ // JSONP handles its own success callback+ if ( !jsonp ) {+ success();+ }+ } else {+ jQuery.handleError(s, xhr, status, errMsg);+ }++ // Fire the complete handlers+ complete();++ if ( isTimeout === "timeout" ) {+ xhr.abort();+ }++ // Stop memory leaks+ if ( s.async ) {+ xhr = null;+ }+ }+ };++ // Override the abort handler, if we can (IE doesn't allow it, but that's OK)+ // Opera doesn't fire onreadystatechange at all on abort+ try {+ var oldAbort = xhr.abort;+ xhr.abort = function() {+ if ( xhr ) {+ oldAbort.call( xhr );+ }++ onreadystatechange( "abort" );+ };+ } catch(e) { }++ // Timeout checker+ if ( s.async && s.timeout > 0 ) {+ setTimeout(function() {+ // Check to see if the request is still happening+ if ( xhr && !requestDone ) {+ onreadystatechange( "timeout" );+ }+ }, s.timeout);+ }++ // Send the data+ try {+ xhr.send( type === "POST" || type === "PUT" || type === "DELETE" ? s.data : null );+ } catch(e) {+ jQuery.handleError(s, xhr, null, e);+ // Fire the complete handlers+ complete();+ }++ // firefox 1.5 doesn't fire statechange for sync requests+ if ( !s.async ) {+ onreadystatechange();+ }++ function success() {+ // If a local callback was specified, fire it and pass it the data+ if ( s.success ) {+ s.success.call( callbackContext, data, status, xhr );+ }++ // Fire the global callback+ if ( s.global ) {+ trigger( "ajaxSuccess", [xhr, s] );+ }+ }++ function complete() {+ // Process result+ if ( s.complete ) {+ s.complete.call( callbackContext, xhr, status);+ }++ // The request was completed+ if ( s.global ) {+ trigger( "ajaxComplete", [xhr, s] );+ }++ // Handle the global AJAX counter+ if ( s.global && ! --jQuery.active ) {+ jQuery.event.trigger( "ajaxStop" );+ }+ }+ + function trigger(type, args) {+ (s.context ? jQuery(s.context) : jQuery.event).trigger(type, args);+ }++ // return XMLHttpRequest to allow aborting the request etc.+ return xhr;+ },++ handleError: function( s, xhr, status, e ) {+ // If a local callback was specified, fire it+ if ( s.error ) {+ s.error.call( s.context || s, xhr, status, e );+ }++ // Fire the global callback+ if ( s.global ) {+ (s.context ? jQuery(s.context) : jQuery.event).trigger( "ajaxError", [xhr, s, e] );+ }+ },++ // Counter for holding the number of active queries+ active: 0,++ // Determines if an XMLHttpRequest was successful or not+ httpSuccess: function( xhr ) {+ try {+ // IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450+ return !xhr.status && location.protocol === "file:" ||+ // Opera returns 0 when status is 304+ ( xhr.status >= 200 && xhr.status < 300 ) ||+ xhr.status === 304 || xhr.status === 1223 || xhr.status === 0;+ } catch(e) {}++ return false;+ },++ // Determines if an XMLHttpRequest returns NotModified+ httpNotModified: function( xhr, url ) {+ var lastModified = xhr.getResponseHeader("Last-Modified"),+ etag = xhr.getResponseHeader("Etag");++ if ( lastModified ) {+ jQuery.lastModified[url] = lastModified;+ }++ if ( etag ) {+ jQuery.etag[url] = etag;+ }++ // Opera returns 0 when status is 304+ return xhr.status === 304 || xhr.status === 0;+ },++ httpData: function( xhr, type, s ) {+ var ct = xhr.getResponseHeader("content-type") || "",+ xml = type === "xml" || !type && ct.indexOf("xml") >= 0,+ data = xml ? xhr.responseXML : xhr.responseText;++ if ( xml && data.documentElement.nodeName === "parsererror" ) {+ jQuery.error( "parsererror" );+ }++ // Allow a pre-filtering function to sanitize the response+ // s is checked to keep backwards compatibility+ if ( s && s.dataFilter ) {+ data = s.dataFilter( data, type );+ }++ // The filter can actually parse the response+ if ( typeof data === "string" ) {+ // Get the JavaScript object, if JSON is used.+ if ( type === "json" || !type && ct.indexOf("json") >= 0 ) {+ data = jQuery.parseJSON( data );++ // If the type is "script", eval it in global context+ } else if ( type === "script" || !type && ct.indexOf("javascript") >= 0 ) {+ jQuery.globalEval( data );+ }+ }++ return data;+ },++ // Serialize an array of form elements or a set of+ // key/values into a query string+ param: function( a, traditional ) {+ var s = [];+ + // Set traditional to true for jQuery <= 1.3.2 behavior.+ if ( traditional === undefined ) {+ traditional = jQuery.ajaxSettings.traditional;+ }+ + // If an array was passed in, assume that it is an array of form elements.+ if ( jQuery.isArray(a) || a.jquery ) {+ // Serialize the form elements+ jQuery.each( a, function() {+ add( this.name, this.value );+ });+ + } else {+ // If traditional, encode the "old" way (the way 1.3.2 or older+ // did it), otherwise encode params recursively.+ for ( var prefix in a ) {+ buildParams( prefix, a[prefix] );+ }+ }++ // Return the resulting serialization+ return s.join("&").replace(r20, "+");++ function buildParams( prefix, obj ) {+ if ( jQuery.isArray(obj) ) {+ // Serialize array item.+ jQuery.each( obj, function( i, v ) {+ if ( traditional || /\[\]$/.test( prefix ) ) {+ // Treat each array item as a scalar.+ add( prefix, v );+ } else {+ // If array item is non-scalar (array or object), encode its+ // numeric index to resolve deserialization ambiguity issues.+ // Note that rack (as of 1.0.0) can't currently deserialize+ // nested arrays properly, and attempting to do so may cause+ // a server error. Possible fixes are to modify rack's+ // deserialization algorithm or to provide an option or flag+ // to force array serialization to be shallow.+ buildParams( prefix + "[" + ( typeof v === "object" || jQuery.isArray(v) ? i : "" ) + "]", v );+ }+ });+ + } else if ( !traditional && obj != null && typeof obj === "object" ) {+ // Serialize object item.+ jQuery.each( obj, function( k, v ) {+ buildParams( prefix + "[" + k + "]", v );+ });+ + } else {+ // Serialize scalar item.+ add( prefix, obj );+ }+ }++ function add( key, value ) {+ // If value is a function, invoke it and return its value+ value = jQuery.isFunction(value) ? value() : value;+ s[ s.length ] = encodeURIComponent(key) + "=" + encodeURIComponent(value);+ }+ }+});+var elemdisplay = {},+ rfxtypes = /toggle|show|hide/,+ rfxnum = /^([+-]=)?([\d+-.]+)(.*)$/,+ timerId,+ fxAttrs = [+ // height animations+ [ "height", "marginTop", "marginBottom", "paddingTop", "paddingBottom" ],+ // width animations+ [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],+ // opacity animations+ [ "opacity" ]+ ];++jQuery.fn.extend({+ show: function( speed, callback ) {+ if ( speed || speed === 0) {+ return this.animate( genFx("show", 3), speed, callback);++ } else {+ for ( var i = 0, l = this.length; i < l; i++ ) {+ var old = jQuery.data(this[i], "olddisplay");++ this[i].style.display = old || "";++ if ( jQuery.css(this[i], "display") === "none" ) {+ var nodeName = this[i].nodeName, display;++ if ( elemdisplay[ nodeName ] ) {+ display = elemdisplay[ nodeName ];++ } else {+ var elem = jQuery("<" + nodeName + " />").appendTo("body");++ display = elem.css("display");++ if ( display === "none" ) {+ display = "block";+ }++ elem.remove();++ elemdisplay[ nodeName ] = display;+ }++ jQuery.data(this[i], "olddisplay", display);+ }+ }++ // Set the display of the elements in a second loop+ // to avoid the constant reflow+ for ( var j = 0, k = this.length; j < k; j++ ) {+ this[j].style.display = jQuery.data(this[j], "olddisplay") || "";+ }++ return this;+ }+ },++ hide: function( speed, callback ) {+ if ( speed || speed === 0 ) {+ return this.animate( genFx("hide", 3), speed, callback);++ } else {+ for ( var i = 0, l = this.length; i < l; i++ ) {+ var old = jQuery.data(this[i], "olddisplay");+ if ( !old && old !== "none" ) {+ jQuery.data(this[i], "olddisplay", jQuery.css(this[i], "display"));+ }+ }++ // Set the display of the elements in a second loop+ // to avoid the constant reflow+ for ( var j = 0, k = this.length; j < k; j++ ) {+ this[j].style.display = "none";+ }++ return this;+ }+ },++ // Save the old toggle function+ _toggle: jQuery.fn.toggle,++ toggle: function( fn, fn2 ) {+ var bool = typeof fn === "boolean";++ if ( jQuery.isFunction(fn) && jQuery.isFunction(fn2) ) {+ this._toggle.apply( this, arguments );++ } else if ( fn == null || bool ) {+ this.each(function() {+ var state = bool ? fn : jQuery(this).is(":hidden");+ jQuery(this)[ state ? "show" : "hide" ]();+ });++ } else {+ this.animate(genFx("toggle", 3), fn, fn2);+ }++ return this;+ },++ fadeTo: function( speed, to, callback ) {+ return this.filter(":hidden").css("opacity", 0).show().end()+ .animate({opacity: to}, speed, callback);+ },++ animate: function( prop, speed, easing, callback ) {+ var optall = jQuery.speed(speed, easing, callback);++ if ( jQuery.isEmptyObject( prop ) ) {+ return this.each( optall.complete );+ }++ return this[ optall.queue === false ? "each" : "queue" ](function() {+ var opt = jQuery.extend({}, optall), p,+ hidden = this.nodeType === 1 && jQuery(this).is(":hidden"),+ self = this;++ for ( p in prop ) {+ var name = p.replace(rdashAlpha, fcamelCase);++ if ( p !== name ) {+ prop[ name ] = prop[ p ];+ delete prop[ p ];+ p = name;+ }++ if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) {+ return opt.complete.call(this);+ }++ if ( ( p === "height" || p === "width" ) && this.style ) {+ // Store display property+ opt.display = jQuery.css(this, "display");++ // Make sure that nothing sneaks out+ opt.overflow = this.style.overflow;+ }++ if ( jQuery.isArray( prop[p] ) ) {+ // Create (if needed) and add to specialEasing+ (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1];+ prop[p] = prop[p][0];+ }+ }++ if ( opt.overflow != null ) {+ this.style.overflow = "hidden";+ }++ opt.curAnim = jQuery.extend({}, prop);++ jQuery.each( prop, function( name, val ) {+ var e = new jQuery.fx( self, opt, name );++ if ( rfxtypes.test(val) ) {+ e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop );++ } else {+ var parts = rfxnum.exec(val),+ start = e.cur(true) || 0;++ if ( parts ) {+ var end = parseFloat( parts[2] ),+ unit = parts[3] || "px";++ // We need to compute starting value+ if ( unit !== "px" ) {+ self.style[ name ] = (end || 1) + unit;+ start = ((end || 1) / e.cur(true)) * start;+ self.style[ name ] = start + unit;+ }++ // If a +=/-= token was provided, we're doing a relative animation+ if ( parts[1] ) {+ end = ((parts[1] === "-=" ? -1 : 1) * end) + start;+ }++ e.custom( start, end, unit );++ } else {+ e.custom( start, val, "" );+ }+ }+ });++ // For JS strict compliance+ return true;+ });+ },++ stop: function( clearQueue, gotoEnd ) {+ var timers = jQuery.timers;++ if ( clearQueue ) {+ this.queue([]);+ }++ this.each(function() {+ // go in reverse order so anything added to the queue during the loop is ignored+ for ( var i = timers.length - 1; i >= 0; i-- ) {+ if ( timers[i].elem === this ) {+ if (gotoEnd) {+ // force the next step to be the last+ timers[i](true);+ }++ timers.splice(i, 1);+ }+ }+ });++ // start the next in the queue if the last step wasn't forced+ if ( !gotoEnd ) {+ this.dequeue();+ }++ return this;+ }++});++// Generate shortcuts for custom animations+jQuery.each({+ slideDown: genFx("show", 1),+ slideUp: genFx("hide", 1),+ slideToggle: genFx("toggle", 1),+ fadeIn: { opacity: "show" },+ fadeOut: { opacity: "hide" }+}, function( name, props ) {+ jQuery.fn[ name ] = function( speed, callback ) {+ return this.animate( props, speed, callback );+ };+});++jQuery.extend({+ speed: function( speed, easing, fn ) {+ var opt = speed && typeof speed === "object" ? speed : {+ complete: fn || !fn && easing ||+ jQuery.isFunction( speed ) && speed,+ duration: speed,+ easing: fn && easing || easing && !jQuery.isFunction(easing) && easing+ };++ opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration :+ jQuery.fx.speeds[opt.duration] || jQuery.fx.speeds._default;++ // Queueing+ opt.old = opt.complete;+ opt.complete = function() {+ if ( opt.queue !== false ) {+ jQuery(this).dequeue();+ }+ if ( jQuery.isFunction( opt.old ) ) {+ opt.old.call( this );+ }+ };++ return opt;+ },++ easing: {+ linear: function( p, n, firstNum, diff ) {+ return firstNum + diff * p;+ },+ swing: function( p, n, firstNum, diff ) {+ return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;+ }+ },++ timers: [],++ fx: function( elem, options, prop ) {+ this.options = options;+ this.elem = elem;+ this.prop = prop;++ if ( !options.orig ) {+ options.orig = {};+ }+ }++});++jQuery.fx.prototype = {+ // Simple function for setting a style value+ update: function() {+ if ( this.options.step ) {+ this.options.step.call( this.elem, this.now, this );+ }++ (jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );++ // Set display property to block for height/width animations+ if ( ( this.prop === "height" || this.prop === "width" ) && this.elem.style ) {+ this.elem.style.display = "block";+ }+ },++ // Get the current size+ cur: function( force ) {+ if ( this.elem[this.prop] != null && (!this.elem.style || this.elem.style[this.prop] == null) ) {+ return this.elem[ this.prop ];+ }++ var r = parseFloat(jQuery.css(this.elem, this.prop, force));+ return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;+ },++ // Start an animation from one number to another+ custom: function( from, to, unit ) {+ this.startTime = now();+ this.start = from;+ this.end = to;+ this.unit = unit || this.unit || "px";+ this.now = this.start;+ this.pos = this.state = 0;++ var self = this;+ function t( gotoEnd ) {+ return self.step(gotoEnd);+ }++ t.elem = this.elem;++ if ( t() && jQuery.timers.push(t) && !timerId ) {+ timerId = setInterval(jQuery.fx.tick, 13);+ }+ },++ // Simple 'show' function+ show: function() {+ // Remember where we started, so that we can go back to it later+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );+ this.options.show = true;++ // Begin the animation+ // Make sure that we start at a small width/height to avoid any+ // flash of content+ this.custom(this.prop === "width" || this.prop === "height" ? 1 : 0, this.cur());++ // Start by showing the element+ jQuery( this.elem ).show();+ },++ // Simple 'hide' function+ hide: function() {+ // Remember where we started, so that we can go back to it later+ this.options.orig[this.prop] = jQuery.style( this.elem, this.prop );+ this.options.hide = true;++ // Begin the animation+ this.custom(this.cur(), 0);+ },++ // Each step of an animation+ step: function( gotoEnd ) {+ var t = now(), done = true;++ if ( gotoEnd || t >= this.options.duration + this.startTime ) {+ this.now = this.end;+ this.pos = this.state = 1;+ this.update();++ this.options.curAnim[ this.prop ] = true;++ for ( var i in this.options.curAnim ) {+ if ( this.options.curAnim[i] !== true ) {+ done = false;+ }+ }++ if ( done ) {+ if ( this.options.display != null ) {+ // Reset the overflow+ this.elem.style.overflow = this.options.overflow;++ // Reset the display+ var old = jQuery.data(this.elem, "olddisplay");+ this.elem.style.display = old ? old : this.options.display;++ if ( jQuery.css(this.elem, "display") === "none" ) {+ this.elem.style.display = "block";+ }+ }++ // Hide the element if the "hide" operation was done+ if ( this.options.hide ) {+ jQuery(this.elem).hide();+ }++ // Reset the properties, if the item has been hidden or shown+ if ( this.options.hide || this.options.show ) {+ for ( var p in this.options.curAnim ) {+ jQuery.style(this.elem, p, this.options.orig[p]);+ }+ }++ // Execute the complete function+ this.options.complete.call( this.elem );+ }++ return false;++ } else {+ var n = t - this.startTime;+ this.state = n / this.options.duration;++ // Perform the easing function, defaults to swing+ var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop];+ var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear");+ this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration);+ this.now = this.start + ((this.end - this.start) * this.pos);++ // Perform the next step of the animation+ this.update();+ }++ return true;+ }+};++jQuery.extend( jQuery.fx, {+ tick: function() {+ var timers = jQuery.timers;++ for ( var i = 0; i < timers.length; i++ ) {+ if ( !timers[i]() ) {+ timers.splice(i--, 1);+ }+ }++ if ( !timers.length ) {+ jQuery.fx.stop();+ }+ },+ + stop: function() {+ clearInterval( timerId );+ timerId = null;+ },+ + speeds: {+ slow: 600,+ fast: 200,+ // Default speed+ _default: 400+ },++ step: {+ opacity: function( fx ) {+ jQuery.style(fx.elem, "opacity", fx.now);+ },++ _default: function( fx ) {+ if ( fx.elem.style && fx.elem.style[ fx.prop ] != null ) {+ fx.elem.style[ fx.prop ] = (fx.prop === "width" || fx.prop === "height" ? Math.max(0, fx.now) : fx.now) + fx.unit;+ } else {+ fx.elem[ fx.prop ] = fx.now;+ }+ }+ }+});++if ( jQuery.expr && jQuery.expr.filters ) {+ jQuery.expr.filters.animated = function( elem ) {+ return jQuery.grep(jQuery.timers, function( fn ) {+ return elem === fn.elem;+ }).length;+ };+}++function genFx( type, num ) {+ var obj = {};++ jQuery.each( fxAttrs.concat.apply([], fxAttrs.slice(0,num)), function() {+ obj[ this ] = type;+ });++ return obj;+}+if ( "getBoundingClientRect" in document.documentElement ) {+ jQuery.fn.offset = function( options ) {+ var elem = this[0];++ if ( options ) { + return this.each(function( i ) {+ jQuery.offset.setOffset( this, options, i );+ });+ }++ if ( !elem || !elem.ownerDocument ) {+ return null;+ }++ if ( elem === elem.ownerDocument.body ) {+ return jQuery.offset.bodyOffset( elem );+ }++ var box = elem.getBoundingClientRect(), doc = elem.ownerDocument, body = doc.body, docElem = doc.documentElement,+ clientTop = docElem.clientTop || body.clientTop || 0, clientLeft = docElem.clientLeft || body.clientLeft || 0,+ top = box.top + (self.pageYOffset || jQuery.support.boxModel && docElem.scrollTop || body.scrollTop ) - clientTop,+ left = box.left + (self.pageXOffset || jQuery.support.boxModel && docElem.scrollLeft || body.scrollLeft) - clientLeft;++ return { top: top, left: left };+ };++} else {+ jQuery.fn.offset = function( options ) {+ var elem = this[0];++ if ( options ) { + return this.each(function( i ) {+ jQuery.offset.setOffset( this, options, i );+ });+ }++ if ( !elem || !elem.ownerDocument ) {+ return null;+ }++ if ( elem === elem.ownerDocument.body ) {+ return jQuery.offset.bodyOffset( elem );+ }++ jQuery.offset.initialize();++ var offsetParent = elem.offsetParent, prevOffsetParent = elem,+ doc = elem.ownerDocument, computedStyle, docElem = doc.documentElement,+ body = doc.body, defaultView = doc.defaultView,+ prevComputedStyle = defaultView ? defaultView.getComputedStyle( elem, null ) : elem.currentStyle,+ top = elem.offsetTop, left = elem.offsetLeft;++ while ( (elem = elem.parentNode) && elem !== body && elem !== docElem ) {+ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {+ break;+ }++ computedStyle = defaultView ? defaultView.getComputedStyle(elem, null) : elem.currentStyle;+ top -= elem.scrollTop;+ left -= elem.scrollLeft;++ if ( elem === offsetParent ) {+ top += elem.offsetTop;+ left += elem.offsetLeft;++ if ( jQuery.offset.doesNotAddBorder && !(jQuery.offset.doesAddBorderForTableAndCells && /^t(able|d|h)$/i.test(elem.nodeName)) ) {+ top += parseFloat( computedStyle.borderTopWidth ) || 0;+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;+ }++ prevOffsetParent = offsetParent, offsetParent = elem.offsetParent;+ }++ if ( jQuery.offset.subtractsBorderForOverflowNotVisible && computedStyle.overflow !== "visible" ) {+ top += parseFloat( computedStyle.borderTopWidth ) || 0;+ left += parseFloat( computedStyle.borderLeftWidth ) || 0;+ }++ prevComputedStyle = computedStyle;+ }++ if ( prevComputedStyle.position === "relative" || prevComputedStyle.position === "static" ) {+ top += body.offsetTop;+ left += body.offsetLeft;+ }++ if ( jQuery.offset.supportsFixedPosition && prevComputedStyle.position === "fixed" ) {+ top += Math.max( docElem.scrollTop, body.scrollTop );+ left += Math.max( docElem.scrollLeft, body.scrollLeft );+ }++ return { top: top, left: left };+ };+}++jQuery.offset = {+ initialize: function() {+ var body = document.body, container = document.createElement("div"), innerDiv, checkDiv, table, td, bodyMarginTop = parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0,+ html = "<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";++ jQuery.extend( container.style, { position: "absolute", top: 0, left: 0, margin: 0, border: 0, width: "1px", height: "1px", visibility: "hidden" } );++ container.innerHTML = html;+ body.insertBefore( container, body.firstChild );+ innerDiv = container.firstChild;+ checkDiv = innerDiv.firstChild;+ td = innerDiv.nextSibling.firstChild.firstChild;++ this.doesNotAddBorder = (checkDiv.offsetTop !== 5);+ this.doesAddBorderForTableAndCells = (td.offsetTop === 5);++ checkDiv.style.position = "fixed", checkDiv.style.top = "20px";+ // safari subtracts parent border width here which is 5px+ this.supportsFixedPosition = (checkDiv.offsetTop === 20 || checkDiv.offsetTop === 15);+ checkDiv.style.position = checkDiv.style.top = "";++ innerDiv.style.overflow = "hidden", innerDiv.style.position = "relative";+ this.subtractsBorderForOverflowNotVisible = (checkDiv.offsetTop === -5);++ this.doesNotIncludeMarginInBodyOffset = (body.offsetTop !== bodyMarginTop);++ body.removeChild( container );+ body = container = innerDiv = checkDiv = table = td = null;+ jQuery.offset.initialize = jQuery.noop;+ },++ bodyOffset: function( body ) {+ var top = body.offsetTop, left = body.offsetLeft;++ jQuery.offset.initialize();++ if ( jQuery.offset.doesNotIncludeMarginInBodyOffset ) {+ top += parseFloat( jQuery.curCSS(body, "marginTop", true) ) || 0;+ left += parseFloat( jQuery.curCSS(body, "marginLeft", true) ) || 0;+ }++ return { top: top, left: left };+ },+ + setOffset: function( elem, options, i ) {+ // set position first, in-case top/left are set even on static elem+ if ( /static/.test( jQuery.curCSS( elem, "position" ) ) ) {+ elem.style.position = "relative";+ }+ var curElem = jQuery( elem ),+ curOffset = curElem.offset(),+ curTop = parseInt( jQuery.curCSS( elem, "top", true ), 10 ) || 0,+ curLeft = parseInt( jQuery.curCSS( elem, "left", true ), 10 ) || 0;++ if ( jQuery.isFunction( options ) ) {+ options = options.call( elem, i, curOffset );+ }++ var props = {+ top: (options.top - curOffset.top) + curTop,+ left: (options.left - curOffset.left) + curLeft+ };+ + if ( "using" in options ) {+ options.using.call( elem, props );+ } else {+ curElem.css( props );+ }+ }+};+++jQuery.fn.extend({+ position: function() {+ if ( !this[0] ) {+ return null;+ }++ var elem = this[0],++ // Get *real* offsetParent+ offsetParent = this.offsetParent(),++ // Get correct offsets+ offset = this.offset(),+ parentOffset = /^body|html$/i.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset();++ // Subtract element margins+ // note: when an element has margin: auto the offsetLeft and marginLeft+ // are the same in Safari causing offset.left to incorrectly be 0+ offset.top -= parseFloat( jQuery.curCSS(elem, "marginTop", true) ) || 0;+ offset.left -= parseFloat( jQuery.curCSS(elem, "marginLeft", true) ) || 0;++ // Add offsetParent borders+ parentOffset.top += parseFloat( jQuery.curCSS(offsetParent[0], "borderTopWidth", true) ) || 0;+ parentOffset.left += parseFloat( jQuery.curCSS(offsetParent[0], "borderLeftWidth", true) ) || 0;++ // Subtract the two offsets+ return {+ top: offset.top - parentOffset.top,+ left: offset.left - parentOffset.left+ };+ },++ offsetParent: function() {+ return this.map(function() {+ var offsetParent = this.offsetParent || document.body;+ while ( offsetParent && (!/^body|html$/i.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) {+ offsetParent = offsetParent.offsetParent;+ }+ return offsetParent;+ });+ }+});+++// Create scrollLeft and scrollTop methods+jQuery.each( ["Left", "Top"], function( i, name ) {+ var method = "scroll" + name;++ jQuery.fn[ method ] = function(val) {+ var elem = this[0], win;+ + if ( !elem ) {+ return null;+ }++ if ( val !== undefined ) {+ // Set the scroll offset+ return this.each(function() {+ win = getWindow( this );++ if ( win ) {+ win.scrollTo(+ !i ? val : jQuery(win).scrollLeft(),+ i ? val : jQuery(win).scrollTop()+ );++ } else {+ this[ method ] = val;+ }+ });+ } else {+ win = getWindow( elem );++ // Return the scroll offset+ return win ? ("pageXOffset" in win) ? win[ i ? "pageYOffset" : "pageXOffset" ] :+ jQuery.support.boxModel && win.document.documentElement[ method ] ||+ win.document.body[ method ] :+ elem[ method ];+ }+ };+});++function getWindow( elem ) {+ return ("scrollTo" in elem && elem.document) ?+ elem :+ elem.nodeType === 9 ?+ elem.defaultView || elem.parentWindow :+ false;+}+// Create innerHeight, innerWidth, outerHeight and outerWidth methods+jQuery.each([ "Height", "Width" ], function( i, name ) {++ var type = name.toLowerCase();++ // innerHeight and innerWidth+ jQuery.fn["inner" + name] = function() {+ return this[0] ?+ jQuery.css( this[0], type, false, "padding" ) :+ null;+ };++ // outerHeight and outerWidth+ jQuery.fn["outer" + name] = function( margin ) {+ return this[0] ?+ jQuery.css( this[0], type, false, margin ? "margin" : "border" ) :+ null;+ };++ jQuery.fn[ type ] = function( size ) {+ // Get window width or height+ var elem = this[0];+ if ( !elem ) {+ return size == null ? null : this;+ }+ + if ( jQuery.isFunction( size ) ) {+ return this.each(function( i ) {+ var self = jQuery( this );+ self[ type ]( size.call( this, i, self[ type ]() ) );+ });+ }++ return ("scrollTo" in elem && elem.document) ? // does it walk and quack like a window?+ // Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode+ elem.document.compatMode === "CSS1Compat" && elem.document.documentElement[ "client" + name ] ||+ elem.document.body[ "client" + name ] :++ // Get document width or height+ (elem.nodeType === 9) ? // is it a document+ // Either scroll[Width/Height] or offset[Width/Height], whichever is greater+ Math.max(+ elem.documentElement["client" + name],+ elem.body["scroll" + name], elem.documentElement["scroll" + name],+ elem.body["offset" + name], elem.documentElement["offset" + name]+ ) :++ // Get or set width or height on the element+ size === undefined ?+ // Get width or height on the element+ jQuery.css( elem, type ) :++ // Set the width or height on the element (default to pixels if value is unitless)+ this.css( type, typeof size === "string" ? size : size + "px" );+ };++});+// Expose jQuery to the global object+window.jQuery = window.$ = jQuery;++})(window);
@@ -0,0 +1,3884 @@+/* + * jquery.layout 1.3.0 - Release Candidate 29.1 + * + * Copyright (c) 2010 + * Fabrizio Balliano (http://www.fabrizioballiano.net) + * Kevin Dalman (http://allpro.net) + * + * Dual licensed under the GPL (http://www.gnu.org/licenses/gpl.html) + * and MIT (http://www.opensource.org/licenses/mit-license.php) licenses. + * + * Docs: http://layout.jquery-dev.net/documentation.html + * Tips: http://layout.jquery-dev.net/tips.html + * Help: http://groups.google.com/group/jquery-ui-layout + * + * $Date: 2010-06-19 08:00:00 (Sat, 12 June 2010) $ + * $Rev: 30291 $ + * + * NOTE: For best code readability, view this with a fixed-width font and tabs equal to 4-chars + */ +;(function ($) { + +$.fn.layout = function (opts) { + +/* + * ########################### + * WIDGET CONFIG & OPTIONS + * ########################### + */ + + // LANGUAGE CUSTOMIZATION - will be *externally customizable* in next version + var lang = { + Pane: "Pane" + , Open: "Open" // eg: "Open Pane" + , Close: "Close" + , Resize: "Resize" + , Slide: "Slide Open" + , Pin: "Pin" + , Unpin: "Un-Pin" + , selector: "selector" + , msgNoRoom: "Not enough room to show this pane." + , errContainerMissing: "UI Layout Initialization Error\n\nThe specified layout-container does not exist." + , errCenterPaneMissing: "UI Layout Initialization Error\n\nThe center-pane element does not exist.\n\nThe center-pane is a required element." + , errContainerHeight: "UI Layout Initialization Warning\n\nThe layout-container \"CONTAINER\" has no height.\n\nTherefore the layout is 0-height and hence 'invisible'!" + , errButton: "Error Adding Button \n\nInvalid " + }; + + // DEFAULT OPTIONS - CHANGE IF DESIRED + var options = { + name: "" // Not required, but useful for buttons and used for the state-cookie + , scrollToBookmarkOnLoad: true // after creating a layout, scroll to bookmark in URL (.../page.htm#myBookmark) + , resizeWithWindow: true // bind thisLayout.resizeAll() to the window.resize event + , resizeWithWindowDelay: 200 // delay calling resizeAll because makes window resizing very jerky + , resizeWithWindowMaxDelay: 0 // 0 = none - force resize every XX ms while window is being resized + , onresizeall_start: null // CALLBACK when resizeAll() STARTS - NOT pane-specific + , onresizeall_end: null // CALLBACK when resizeAll() ENDS - NOT pane-specific + , onload: null // CALLBACK when Layout inits - after options initialized, but before elements + , onunload: null // CALLBACK when Layout is destroyed OR onWindowUnload + , autoBindCustomButtons: false // search for buttons with ui-layout-button class and auto-bind them + , zIndex: null // the PANE zIndex - resizers and masks will be +1 + // PANE SETTINGS + , defaults: { // default options for 'all panes' - will be overridden by 'per-pane settings' + applyDemoStyles: false // NOTE: renamed from applyDefaultStyles for clarity + , closable: true // pane can open & close + , resizable: true // when open, pane can be resized + , slidable: true // when closed, pane can 'slide open' over other panes - closes on mouse-out + , initClosed: false // true = init pane as 'closed' + , initHidden: false // true = init pane as 'hidden' - no resizer-bar/spacing + // SELECTORS + //, paneSelector: "" // MUST be pane-specific - jQuery selector for pane + , contentSelector: ".ui-layout-content" // INNER div/element to auto-size so only it scrolls, not the entire pane! + , contentIgnoreSelector: ".ui-layout-ignore" // element(s) to 'ignore' when measuring 'content' + , findNestedContent: false // true = $P.find(contentSelector), false = $P.children(contentSelector) + // GENERIC ROOT-CLASSES - for auto-generated classNames + , paneClass: "ui-layout-pane" // border-Pane - default: 'ui-layout-pane' + , resizerClass: "ui-layout-resizer" // Resizer Bar - default: 'ui-layout-resizer' + , togglerClass: "ui-layout-toggler" // Toggler Button - default: 'ui-layout-toggler' + , buttonClass: "ui-layout-button" // CUSTOM Buttons - default: 'ui-layout-button-toggle/-open/-close/-pin' + // ELEMENT SIZE & SPACING + //, size: 100 // MUST be pane-specific -initial size of pane + , minSize: 0 // when manually resizing a pane + , maxSize: 0 // ditto, 0 = no limit + , spacing_open: 6 // space between pane and adjacent panes - when pane is 'open' + , spacing_closed: 6 // ditto - when pane is 'closed' + , togglerLength_open: 50 // Length = WIDTH of toggler button on north/south sides - HEIGHT on east/west sides + , togglerLength_closed: 50 // 100% OR -1 means 'full height/width of resizer bar' - 0 means 'hidden' + , togglerAlign_open: "center" // top/left, bottom/right, center, OR... + , togglerAlign_closed: "center" // 1 => nn = offset from top/left, -1 => -nn == offset from bottom/right + , togglerTip_open: lang.Close // Toggler tool-tip (title) + , togglerTip_closed: lang.Open // ditto + , togglerContent_open: "" // text or HTML to put INSIDE the toggler + , togglerContent_closed: "" // ditto + // RESIZING OPTIONS + , resizerDblClickToggle: true // + , autoResize: true // IF size is 'auto' or a percentage, then recalc 'pixel size' whenever the layout resizes + , autoReopen: true // IF a pane was auto-closed due to noRoom, reopen it when there is room? False = leave it closed + , resizerDragOpacity: 1 // option for ui.draggable + //, resizerCursor: "" // MUST be pane-specific - cursor when over resizer-bar + , maskIframesOnResize: true // true = all iframes OR = iframe-selector(s) - adds masking-div during resizing/dragging + , resizeNestedLayout: true // true = trigger nested.resizeAll() when a 'pane' of this layout is the 'container' for another + , resizeWhileDragging: false // true = LIVE Resizing as resizer is dragged + , resizeContentWhileDragging: false // true = re-measure header/footer heights as resizer is dragged + // TIPS & MESSAGES - also see lang object + , noRoomToOpenTip: lang.msgNoRoom + , resizerTip: lang.Resize // Resizer tool-tip (title) + , sliderTip: lang.Slide // resizer-bar triggers 'sliding' when pane is closed + , sliderCursor: "pointer" // cursor when resizer-bar will trigger 'sliding' + , slideTrigger_open: "click" // click, dblclick, mouseenter + , slideTrigger_close: "mouseleave"// click, mouseleave + , hideTogglerOnSlide: false // when pane is slid-open, should the toggler show? + , preventQuickSlideClose: !!($.browser.webkit || $.browser.safari) // Chrome triggers slideClosed as is opening + // HOT-KEYS & MISC + , showOverflowOnHover: false // will bind allowOverflow() utility to pane.onMouseOver + , enableCursorHotkey: true // enabled 'cursor' hotkeys + //, customHotkey: "" // MUST be pane-specific - EITHER a charCode OR a character + , customHotkeyModifier: "SHIFT" // either 'SHIFT', 'CTRL' or 'CTRL+SHIFT' - NOT 'ALT' + // PANE ANIMATION + // NOTE: fxSss_open & fxSss_close options (eg: fxName_open) are auto-generated if not passed + , fxName: "slide" // ('none' or blank), slide, drop, scale + , fxSpeed: null // slow, normal, fast, 200, nnn - if passed, will OVERRIDE fxSettings.duration + , fxSettings: {} // can be passed, eg: { easing: "easeOutBounce", duration: 1500 } + , fxOpacityFix: true // tries to fix opacity in IE to restore anti-aliasing after animation + // CALLBACKS + , triggerEventsOnLoad: false // true = trigger onopen OR onclose callbacks when layout initializes + , triggerEventsWhileDragging: true // true = trigger onresize callback REPEATEDLY if resizeWhileDragging==true + , onshow_start: null // CALLBACK when pane STARTS to Show - BEFORE onopen/onhide_start + , onshow_end: null // CALLBACK when pane ENDS being Shown - AFTER onopen/onhide_end + , onhide_start: null // CALLBACK when pane STARTS to Close - BEFORE onclose_start + , onhide_end: null // CALLBACK when pane ENDS being Closed - AFTER onclose_end + , onopen_start: null // CALLBACK when pane STARTS to Open + , onopen_end: null // CALLBACK when pane ENDS being Opened + , onclose_start: null // CALLBACK when pane STARTS to Close + , onclose_end: null // CALLBACK when pane ENDS being Closed + , onresize_start: null // CALLBACK when pane STARTS being Resized ***FOR ANY REASON*** + , onresize_end: null // CALLBACK when pane ENDS being Resized ***FOR ANY REASON*** + , onsizecontent_start: null // CALLBACK when sizing of content-element STARTS + , onsizecontent_end: null // CALLBACK when sizing of content-element ENDS + , onswap_start: null // CALLBACK when pane STARTS to Swap + , onswap_end: null // CALLBACK when pane ENDS being Swapped + , ondrag_start: null // CALLBACK when pane STARTS being ***MANUALLY*** Resized + , ondrag_end: null // CALLBACK when pane ENDS being ***MANUALLY*** Resized + } + , north: { + paneSelector: ".ui-layout-north" + , size: "auto" // eg: "auto", "30%", 200 + , resizerCursor: "n-resize" // custom = url(myCursor.cur) + , customHotkey: "" // EITHER a charCode OR a character + } + , south: { + paneSelector: ".ui-layout-south" + , size: "auto" + , resizerCursor: "s-resize" + , customHotkey: "" + } + , east: { + paneSelector: ".ui-layout-east" + , size: 200 + , resizerCursor: "e-resize" + , customHotkey: "" + } + , west: { + paneSelector: ".ui-layout-west" + , size: 200 + , resizerCursor: "w-resize" + , customHotkey: "" + } + , center: { + paneSelector: ".ui-layout-center" + , minWidth: 0 + , minHeight: 0 + } + + // STATE MANAGMENT + , useStateCookie: false // Enable cookie-based state-management - can fine-tune with cookie.autoLoad/autoSave + , cookie: { + name: "" // If not specified, will use Layout.name, else just "Layout" + , autoSave: true // Save a state cookie when page exits? + , autoLoad: true // Load the state cookie when Layout inits? + // Cookie Options + , domain: "" + , path: "" + , expires: "" // 'days' to keep cookie - leave blank for 'session cookie' + , secure: false + // List of options to save in the cookie - must be pane-specific + , keys: "north.size,south.size,east.size,west.size,"+ + "north.isClosed,south.isClosed,east.isClosed,west.isClosed,"+ + "north.isHidden,south.isHidden,east.isHidden,west.isHidden" + } + }; + + + // PREDEFINED EFFECTS / DEFAULTS + var effects = { // LIST *PREDEFINED EFFECTS* HERE, even if effect has no settings + slide: { + all: { duration: "fast" } // eg: duration: 1000, easing: "easeOutBounce" + , north: { direction: "up" } + , south: { direction: "down" } + , east: { direction: "right"} + , west: { direction: "left" } + } + , drop: { + all: { duration: "slow" } // eg: duration: 1000, easing: "easeOutQuint" + , north: { direction: "up" } + , south: { direction: "down" } + , east: { direction: "right"} + , west: { direction: "left" } + } + , scale: { + all: { duration: "fast" } + } + }; + + + // DYNAMIC DATA - IS READ-ONLY EXTERNALLY! + var state = { + // generate unique ID to use for event.namespace so can unbind only events added by 'this layout' + id: "layout"+ new Date().getTime() // code uses alias: sID + , initialized: false + , container: {} // init all keys + , north: {} + , south: {} + , east: {} + , west: {} + , center: {} + , cookie: {} // State Managment data storage + }; + + + // INTERNAL CONFIG DATA - DO NOT CHANGE THIS! + var _c = { + allPanes: "north,south,west,east,center" + , borderPanes: "north,south,west,east" + , altSide: { + north: "south" + , south: "north" + , east: "west" + , west: "east" + } + // CSS used in multiple places + , hidden: { visibility: "hidden" } + , visible: { visibility: "visible" } + // layout element settings + , zIndex: { // set z-index values here + pane_normal: 1 // normal z-index for panes + , resizer_normal: 2 // normal z-index for resizer-bars + , iframe_mask: 2 // overlay div used to mask pane(s) during resizing + , pane_sliding: 100 // applied to *BOTH* the pane and its resizer when a pane is 'slid open' + , pane_animate: 1000 // applied to the pane when being animated - not applied to the resizer + , resizer_drag: 10000 // applied to the CLONED resizer-bar when being 'dragged' + } + , resizers: { + cssReq: { + position: "absolute" + , padding: 0 + , margin: 0 + , fontSize: "1px" + , textAlign: "left" // to counter-act "center" alignment! + , overflow: "hidden" // prevent toggler-button from overflowing + // SEE c.zIndex.resizer_normal + } + , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true + background: "#DDD" + , border: "none" + } + } + , togglers: { + cssReq: { + position: "absolute" + , display: "block" + , padding: 0 + , margin: 0 + , overflow: "hidden" + , textAlign: "center" + , fontSize: "1px" + , cursor: "pointer" + , zIndex: 1 + } + , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true + background: "#AAA" + } + } + , content: { + cssReq: { + position: "relative" /* contain floated or positioned elements */ + } + , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true + overflow: "auto" + , padding: "10px" + } + , cssDemoPane: { // DEMO CSS - REMOVE scrolling from 'pane' when it has a content-div + overflow: "hidden" + , padding: 0 + } + } + , panes: { // defaults for ALL panes - overridden by 'per-pane settings' below + cssReq: { + position: "absolute" + , margin: 0 + // SEE c.zIndex.pane_normal + } + , cssDemo: { // DEMO CSS - applied if: options.PANE.applyDemoStyles=true + padding: "10px" + , background: "#FFF" + , border: "1px solid #BBB" + , overflow: "auto" + } + } + , north: { + side: "Top" + , sizeType: "Height" + , dir: "horz" + , cssReq: { + top: 0 + , bottom: "auto" + , left: 0 + , right: 0 + , width: "auto" + // height: DYNAMIC + } + , pins: [] // array of 'pin buttons' to be auto-updated on open/close (classNames) + } + , south: { + side: "Bottom" + , sizeType: "Height" + , dir: "horz" + , cssReq: { + top: "auto" + , bottom: 0 + , left: 0 + , right: 0 + , width: "auto" + // height: DYNAMIC + } + , pins: [] + } + , east: { + side: "Right" + , sizeType: "Width" + , dir: "vert" + , cssReq: { + left: "auto" + , right: 0 + , top: "auto" // DYNAMIC + , bottom: "auto" // DYNAMIC + , height: "auto" + // width: DYNAMIC + } + , pins: [] + } + , west: { + side: "Left" + , sizeType: "Width" + , dir: "vert" + , cssReq: { + left: 0 + , right: "auto" + , top: "auto" // DYNAMIC + , bottom: "auto" // DYNAMIC + , height: "auto" + // width: DYNAMIC + } + , pins: [] + } + , center: { + dir: "center" + , cssReq: { + left: "auto" // DYNAMIC + , right: "auto" // DYNAMIC + , top: "auto" // DYNAMIC + , bottom: "auto" // DYNAMIC + , height: "auto" + , width: "auto" + } + } + }; + + +/* + * ########################### + * INTERNAL HELPER FUNCTIONS + * ########################### + */ + + /** + * timer + * + * Manages all internal timers + */ + var timer = { + data: {} + , set: function (s, fn, ms) { timer.clear(s); timer.data[s] = setTimeout(fn, ms); } + , clear: function (s) { var t=timer.data; if (t[s]) {clearTimeout(t[s]); delete t[s];} } + }; + + /** + * isStr + * + * Returns true if passed param is EITHER a simple string OR a 'string object' - otherwise returns false + */ + var isStr = function (o) { + try { return typeof o == "string" + || (typeof o == "object" && o.constructor.toString().match(/string/i) !== null); } + catch (e) { return false; } + }; + + /** + * str + * + * Returns a simple string if passed EITHER a simple string OR a 'string object', + * else returns the original object + */ + var str = function (o) { // trim converts 'String object' to a simple string + return isStr(o) ? $.trim(o) : o == undefined || o == null ? "" : o; + }; + + /** + * min / max + * + * Aliases for Math methods to simplify coding + */ + var min = function (x,y) { return Math.min(x,y); }; + var max = function (x,y) { return Math.max(x,y); }; + + /** + * _transformData + * + * Processes the options passed in and transforms them into the format used by layout() + * Missing keys are added, and converts the data if passed in 'flat-format' (no sub-keys) + * In flat-format, pane-specific-settings are prefixed like: north__optName (2-underscores) + * To update effects, options MUST use nested-keys format, with an effects key ??? + * + * @callers initOptions() + * @params JSON d Data/options passed by user - may be a single level or nested levels + * @returns JSON Creates a data struture that perfectly matches 'options', ready to be imported + */ + var _transformData = function (d) { + var json = { cookie:{}, defaults:{fxSettings:{}}, north:{fxSettings:{}}, south:{fxSettings:{}}, east:{fxSettings:{}}, west:{fxSettings:{}}, center:{fxSettings:{}} }; + d = d || {}; + if (d.effects || d.cookie || d.defaults || d.north || d.south || d.west || d.east || d.center) + json = $.extend( true, json, d ); // already in json format - add to base keys + else + // convert 'flat' to 'nest-keys' format - also handles 'empty' user-options + $.each( d, function (key,val) { + a = key.split("__"); + if (!a[1] || json[a[0]]) // check for invalid keys + json[ a[1] ? a[0] : "defaults" ][ a[1] ? a[1] : a[0] ] = val; + }); + return json; + }; + + /** + * _queue + * + * Set an INTERNAL callback to avoid simultaneous animation + * Runs only if needed and only if all callbacks are not 'already set' + * Called by open() and close() when isLayoutBusy=true + * + * @param String action Either 'open' or 'close' + * @param String pane A valid border-pane name, eg 'west' + * @param Boolean param Extra param for callback (optional) + */ + var _queue = function (action, pane, param) { + var tried = []; + + // if isLayoutBusy, then some pane must be 'moving' + $.each(_c.borderPanes.split(","), function (i, p) { + if (_c[p].isMoving) { + bindCallback(p); // TRY to bind a callback + return false; // BREAK + } + }); + + // if pane does NOT have a callback, then add one, else follow the callback chain... + function bindCallback (p) { + var c = _c[p]; + if (!c.doCallback) { + c.doCallback = true; + c.callback = action +","+ pane +","+ (param ? 1 : 0); + } + else { // try to 'chain' this callback + tried.push(p); + var cbPane = c.callback.split(",")[1]; // 2nd param of callback is 'pane' + // ensure callback target NOT 'itself' and NOT 'target pane' and NOT already tried (avoid loop) + if (cbPane != pane && !$.inArray(cbPane, tried) >= 0) + bindCallback(cbPane); // RECURSE + } + } + }; + + /** + * _dequeue + * + * RUN the INTERNAL callback for this pane - if one exists + * + * @param String action Either 'open' or 'close' + * @param String pane A valid border-pane name, eg 'west' + * @param Boolean param Extra param for callback (optional) + */ + var _dequeue = function (pane) { + var c = _c[pane]; + + // RESET flow-control flags + _c.isLayoutBusy = false; + delete c.isMoving; + if (!c.doCallback || !c.callback) return; + + c.doCallback = false; // RESET logic flag + + // EXECUTE the callback + var + cb = c.callback.split(",") + , param = (cb[2] > 0 ? true : false) + ; + if (cb[0] == "open") + open( cb[1], param ); + else if (cb[0] == "close") + close( cb[1], param ); + + if (!c.doCallback) c.callback = null; // RESET - unless callback above enabled it again! + }; + + /** + * _execCallback + * + * Executes a Callback function after a trigger event, like resize, open or close + * + * @param String pane This is passed only so we can pass the 'pane object' to the callback + * @param String v_fn Accepts a function name, OR a comma-delimited array: [0]=function name, [1]=argument + */ + var _execCallback = function (pane, v_fn) { + if (!v_fn) return; + var fn; + try { + if (typeof v_fn == "function") + fn = v_fn; + else if (!isStr(v_fn)) + return; + else if (v_fn.match(/,/)) { + // function name cannot contain a comma, so must be a function name AND a 'name' parameter + var + args = v_fn.split(",") + , fn = eval(args[0]) + ; + if (typeof fn=="function" && args.length > 1) + return fn(args[1]); // pass the argument parsed from 'list' + } + else // just the name of an external function? + fn = eval(v_fn); + + if (typeof fn=="function") { + if (pane && $Ps[pane]) + // pass data: pane-name, pane-element, pane-state (copy), pane-options, and layout-name + return fn( pane, $Ps[pane], $.extend({},state[pane]), options[pane], options.name ); + else // must be a layout/container callback - pass suitable info + return fn( Instance, $.extend({},state), options, options.name ); + } + } + catch (ex) {} + }; + + /** + * _showInvisibly + * + * Returns hash container 'display' and 'visibility' + * + * @TODO: SEE $.swap() - swaps CSS, runs callback, resets CSS + */ + var _showInvisibly = function ($E, force) { + if (!$E) return {}; + if (!$E.jquery) $E = $($E); + var CSS = { + display: $E.css('display') + , visibility: $E.css('visibility') + }; + if (force || CSS.display == "none") { // only if not *already hidden* + $E.css({ display: "block", visibility: "hidden" }); // show element 'invisibly' so can be measured + return CSS; + } + else return {}; + }; + + /** + * _fixIframe + * + * cure iframe display issues in IE & other browsers + */ + var _fixIframe = function (pane) { + if (state.browser.mozilla) return; // skip FireFox - it auto-refreshes iframes onShow + var $P = $Ps[pane]; + // if the 'pane' is an iframe, do it + if (state[pane].tagName == "IFRAME") + $P.css(_c.hidden).css(_c.visible); + else // ditto for any iframes INSIDE the pane + $P.find('IFRAME').css(_c.hidden).css(_c.visible); + }; + + /** + * _cssNum + * + * Returns the 'current CSS numeric value' for an element - returns 0 if property does not exist + * + * @callers Called by many methods + * @param jQuery $Elem Must pass a jQuery object - first element is processed + * @param String property The name of the CSS property, eg: top, width, etc. + * @returns Variant Usually is used to get an integer value for position (top, left) or size (height, width) + */ + var _cssNum = function ($E, prop) { + if (!$E.jquery) $E = $($E); + var CSS = _showInvisibly($E); + var val = parseInt($.curCSS($E[0], prop, true), 10) || 0; + $E.css( CSS ); // RESET + return val; + }; + + var _borderWidth = function (E, side) { + if (E.jquery) E = E[0]; + var b = "border"+ side.substr(0,1).toUpperCase() + side.substr(1); // left => Left + return $.curCSS(E, b+"Style", true) == "none" ? 0 : (parseInt($.curCSS(E, b+"Width", true), 10) || 0); + }; + + /** + * cssW / cssH / cssSize / cssMinDims + * + * Contains logic to check boxModel & browser, and return the correct width/height for the current browser/doctype + * + * @callers initPanes(), sizeMidPanes(), initHandles(), sizeHandles() + * @param Variant el Can accept a 'pane' (east, west, etc) OR a DOM object OR a jQuery object + * @param Integer outerWidth/outerHeight (optional) Can pass a width, allowing calculations BEFORE element is resized + * @returns Integer Returns the innerWidth/Height of the elem by subtracting padding and borders + * + * @TODO May need additional logic for other browser/doctype variations? Maybe use more jQuery methods? + */ + var cssW = function (el, outerWidth) { + var + str = isStr(el) + , $E = str ? $Ps[el] : $(el) + ; + if (isNaN(outerWidth)) // not specified + outerWidth = str ? getPaneSize(el) : $E.outerWidth(); + + // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed + if (outerWidth <= 0) return 0; + + if (!state.browser.boxModel) return outerWidth; + + // strip border and padding from outerWidth to get CSS Width + var W = outerWidth + - _borderWidth($E, "Left") + - _borderWidth($E, "Right") + - _cssNum($E, "paddingLeft") + - _cssNum($E, "paddingRight") + ; + + return W > 0 ? W : 0; + }; + + var cssH = function (el, outerHeight) { + var + str = isStr(el) + , $E = str ? $Ps[el] : $(el) + ; + if (isNaN(outerHeight)) // not specified + outerHeight = str ? getPaneSize(el) : $E.outerHeight(); + + // a 'calculated' outerHeight can be passed so borders and/or padding are removed if needed + if (outerHeight <= 0) return 0; + + if (!state.browser.boxModel) return outerHeight; + + // strip border and padding from outerHeight to get CSS Height + var H = outerHeight + - _borderWidth($E, "Top") + - _borderWidth($E, "Bottom") + - _cssNum($E, "paddingTop") + - _cssNum($E, "paddingBottom") + ; + + return H > 0 ? H : 0; + }; + + var cssSize = function (pane, outerSize) { + if (_c[pane].dir=="horz") // pane = north or south + return cssH(pane, outerSize); + else // pane = east or west + return cssW(pane, outerSize); + }; + + var cssMinDims = function (pane) { + // minWidth/Height means CSS width/height = 1px + var + dir = _c[pane].dir + , d = { + minWidth: 1001 - cssW(pane, 1000) + , minHeight: 1001 - cssH(pane, 1000) + } + ; + if (dir == "horz") d.minSize = d.minHeight; + if (dir == "vert") d.minSize = d.minWidth; + return d; + }; + + // TODO: see if these methods can be made more useful... + // TODO: *maybe* return cssW/H from these so caller can use this info + + var setOuterWidth = function (el, outerWidth, autoHide) { + var $E = el, w; + if (isStr(el)) $E = $Ps[el]; // west + else if (!el.jquery) $E = $(el); + w = cssW($E, outerWidth); + $E.css({ width: w }); + if (w > 0) { + if (autoHide && $E.data('autoHidden') && $E.innerHeight() > 0) { + $E.show().data('autoHidden', false); + if (!state.browser.mozilla) // FireFox refreshes iframes - IE doesn't + // make hidden, then visible to 'refresh' display after animation + $E.css(_c.hidden).css(_c.visible); + } + } + else if (autoHide && !$E.data('autoHidden')) + $E.hide().data('autoHidden', true); + }; + + var setOuterHeight = function (el, outerHeight, autoHide) { + var $E = el; + if (isStr(el)) $E = $Ps[el]; // west + else if (!el.jquery) $E = $(el); + h = cssH($E, outerHeight); + $E.css({ height: h, visibility: "visible" }); // may have been 'hidden' by sizeContent + if (h > 0 && $E.innerWidth() > 0) { + if (autoHide && $E.data('autoHidden')) { + $E.show().data('autoHidden', false); + if (!state.browser.mozilla) // FireFox refreshes iframes - IE doesn't + $E.css(_c.hidden).css(_c.visible); + } + } + else if (autoHide && !$E.data('autoHidden')) + $E.hide().data('autoHidden', true); + }; + + var setOuterSize = function (el, outerSize, autoHide) { + if (_c[pane].dir=="horz") // pane = north or south + setOuterHeight(el, outerSize, autoHide); + else // pane = east or west + setOuterWidth(el, outerSize, autoHide); + }; + + + /** + * _parseSize + * + * Converts any 'size' params to a pixel/integer size, if not already + * If 'auto' or a decimal/percentage is passed as 'size', a pixel-size is calculated + * + * @returns Integer + */ + var _parseSize = function (pane, size, dir) { + if (!dir) dir = _c[pane].dir; + + if (isStr(size) && size.match(/%/)) + size = parseInt(size) / 100; // convert % to decimal + + if (size === 0) + return 0; + else if (size >= 1) + return parseInt(size,10); + else if (size > 0) { // percentage, eg: .25 + var o = options, avail; + if (dir=="horz") // north or south or center.minHeight + avail = sC.innerHeight - ($Ps.north ? o.north.spacing_open : 0) - ($Ps.south ? o.south.spacing_open : 0); + else if (dir=="vert") // east or west or center.minWidth + avail = sC.innerWidth - ($Ps.west ? o.west.spacing_open : 0) - ($Ps.east ? o.east.spacing_open : 0); + return Math.floor(avail * size); + } + else if (pane=="center") + return 0; + else { // size < 0 || size=='auto' || size==Missing || size==Invalid + // auto-size the pane + var + $P = $Ps[pane] + , dim = (dir == "horz" ? "height" : "width") + , vis = _showInvisibly($P) // show pane invisibly if hidden + , s = $P.css(dim); // SAVE current size + ; + $P.css(dim, "auto"); + size = (dim == "height") ? $P.outerHeight() : $P.outerWidth(); // MEASURE + $P.css(dim, s).css(vis); // RESET size & visibility + return size; + } + }; + + /** + * getPaneSize + * + * Calculates current 'size' (outer-width or outer-height) of a border-pane - optionally with 'pane-spacing' added + * + * @returns Integer Returns EITHER Width for east/west panes OR Height for north/south panes - adjusted for boxModel & browser + */ + var getPaneSize = function (pane, inclSpace) { + var + $P = $Ps[pane] + , o = options[pane] + , s = state[pane] + , oSp = (inclSpace ? o.spacing_open : 0) + , cSp = (inclSpace ? o.spacing_closed : 0) + ; + if (!$P || s.isHidden) + return 0; + else if (s.isClosed || (s.isSliding && inclSpace)) + return cSp; + else if (_c[pane].dir == "horz") + return $P.outerHeight() + oSp; + else // dir == "vert" + return $P.outerWidth() + oSp; + }; + + /** + * setSizeLimits + * + * Calculate min/max pane dimensions and limits for resizing + */ + var setSizeLimits = function (pane, slide) { + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , dir = c.dir + , side = c.side.toLowerCase() + , type = c.sizeType.toLowerCase() + , isSliding = (slide != undefined ? slide : s.isSliding) // only open() passes 'slide' param + , $P = $Ps[pane] + , paneSpacing = o.spacing_open + // measure the pane on the *opposite side* from this pane + , altPane = _c.altSide[pane] + , altS = state[altPane] + , $altP = $Ps[altPane] + , altPaneSize = (!$altP || altS.isVisible===false || altS.isSliding ? 0 : (dir=="horz" ? $altP.outerHeight() : $altP.outerWidth())) + , altPaneSpacing = ((!$altP || altS.isHidden ? 0 : options[altPane][ altS.isClosed !== false ? "spacing_closed" : "spacing_open" ]) || 0) + // limitSize prevents this pane from 'overlapping' opposite pane + , containerSize = (dir=="horz" ? sC.innerHeight : sC.innerWidth) + , minCenterDims = cssMinDims("center") + , minCenterSize = dir=="horz" ? max(options.center.minHeight, minCenterDims.minHeight) : max(options.center.minWidth, minCenterDims.minWidth) + // if pane is 'sliding', then ignore center and alt-pane sizes - because 'overlays' them + , limitSize = (containerSize - paneSpacing - (isSliding ? 0 : (_parseSize("center", minCenterSize, dir) + altPaneSize + altPaneSpacing))) + , minSize = s.minSize = max( _parseSize(pane, o.minSize), cssMinDims(pane).minSize ) + , maxSize = s.maxSize = min( (o.maxSize ? _parseSize(pane, o.maxSize) : 100000), limitSize ) + , r = s.resizerPosition = {} // used to set resizing limits + , top = sC.insetTop + , left = sC.insetLeft + , W = sC.innerWidth + , H = sC.innerHeight + , rW = o.spacing_open // subtract resizer-width to get top/left position for south/east + ; + switch (pane) { + case "north": r.min = top + minSize; + r.max = top + maxSize; + break; + case "west": r.min = left + minSize; + r.max = left + maxSize; + break; + case "south": r.min = top + H - maxSize - rW; + r.max = top + H - minSize - rW; + break; + case "east": r.min = left + W - maxSize - rW; + r.max = left + W - minSize - rW; + break; + }; + }; + + /** + * calcNewCenterPaneDims + * + * Returns data for setting the size/position of center pane. Also used to set Height for east/west panes + * + * @returns JSON Returns a hash of all dimensions: top, bottom, left, right, (outer) width and (outer) height + */ + var calcNewCenterPaneDims = function () { + var d = { + top: getPaneSize("north", true) // true = include 'spacing' value for pane + , bottom: getPaneSize("south", true) + , left: getPaneSize("west", true) + , right: getPaneSize("east", true) + , width: 0 + , height: 0 + }; + + with (d) { // NOTE: sC = state.container + // calc center-pane's outer dimensions + width = sC.innerWidth - left - right; // outerWidth + height = sC.innerHeight - bottom - top; // outerHeight + // add the 'container border/padding' to get final positions relative to the container + top += sC.insetTop; + bottom += sC.insetBottom; + left += sC.insetLeft; + right += sC.insetRight; + } + + return d; + }; + + + /** + * getElemDims + * + * Returns data for setting size of an element (container or a pane). + * + * @callers _create(), onWindowResize() for container, plus others for pane + * @returns JSON Returns a hash of all dimensions: top, bottom, left, right, outerWidth, innerHeight, etc + */ + var getElemDims = function ($E) { + var + d = {} // dimensions hash + , x = d.css = {} // CSS hash + , i = {} // TEMP insets + , b, p // TEMP border, padding + , off = $E.offset() + ; + d.offsetLeft = off.left; + d.offsetTop = off.top; + + $.each("Left,Right,Top,Bottom".split(","), function (idx, e) { + b = x["border" + e] = _borderWidth($E, e); + p = x["padding"+ e] = _cssNum($E, "padding"+e); + i[e] = b + p; // total offset of content from outer side + d["inset"+ e] = p; + /* WRONG ??? + // if BOX MODEL, then 'position' = PADDING (ignore borderWidth) + if ($E == $Container) + d["inset"+ e] = (state.browser.boxModel ? p : 0); + */ + }); + + d.offsetWidth = $E.innerWidth(true); // true=include Padding + d.offsetHeight = $E.innerHeight(true); + d.outerWidth = $E.outerWidth(); + d.outerHeight = $E.outerHeight(); + d.innerWidth = d.outerWidth - i.Left - i.Right; + d.innerHeight = d.outerHeight - i.Top - i.Bottom; + + // TESTING + x.width = $E.width(); + x.height = $E.height(); + + return d; + }; + + var getElemCSS = function ($E, list) { + var + CSS = {} + , style = $E[0].style + , props = list.split(",") + , sides = "Top,Bottom,Left,Right".split(",") + , attrs = "Color,Style,Width".split(",") + , p, s, a, i, j, k + ; + for (i=0; i < props.length; i++) { + p = props[i]; + if (p.match(/(border|padding|margin)$/)) + for (j=0; j < 4; j++) { + s = sides[j]; + if (p == "border") + for (k=0; k < 3; k++) { + a = attrs[k]; + CSS[p+s+a] = style[p+s+a]; + } + else + CSS[p+s] = style[p+s]; + } + else + CSS[p] = style[p]; + }; + return CSS + }; + + + var getHoverClasses = function (el, allStates) { + var + $El = $(el) + , type = $El.data("layoutRole") + , pane = $El.data("layoutEdge") + , o = options[pane] + , root = o[type +"Class"] + , _pane = "-"+ pane // eg: "-west" + , _open = "-open" + , _closed = "-closed" + , _slide = "-sliding" + , _hover = "-hover " // NOTE the trailing space + , _state = $El.hasClass(root+_closed) ? _closed : _open + , _alt = _state == _closed ? _open : _closed + , classes = (root+_hover) + (root+_pane+_hover) + (root+_state+_hover) + (root+_pane+_state+_hover) + ; + if (allStates) // when 'removing' classes, also remove alternate-state classes + classes += (root+_alt+_hover) + (root+_pane+_alt+_hover); + + if (type=="resizer" && $El.hasClass(root+_slide)) + classes += (root+_slide+_hover) + (root+_pane+_slide+_hover); + + return $.trim(classes); + }; + var addHover = function (evt, el) { + var e = el || this; + $(e).addClass( getHoverClasses(e) ); + //if (evt && $(e).data("layoutRole") == "toggler") evt.stopPropagation(); + }; + var removeHover = function (evt, el) { + var e = el || this; + $(e).removeClass( getHoverClasses(e, true) ); + }; + + var onResizerEnter = function (evt) { + $('body').disableSelection(); + addHover(evt, this); + }; + var onResizerLeave = function (evt, el) { + var + e = el || this // el is only passed when called by the timer + , pane = $(e).data("layoutEdge") + , name = pane +"ResizerLeave" + ; + timer.clear(name); + if (!el) { // 1st call - mouseleave event + removeHover(evt, this); // do this on initial call + // this method calls itself on a timer because it needs to allow + // enough time for dragging to kick-in and set the isResizing flag + // dragging has a 100ms delay set, so this delay must be higher + timer.set(name, function(){ onResizerLeave(evt, e); }, 200); + } + // if user is resizing, then dragStop will enableSelection() when done + else if (!state[pane].isResizing) // 2nd call - by timer + $('body').enableSelection(); + }; + +/* + * ########################### + * INITIALIZATION METHODS + * ########################### + */ + + /** + * _create + * + * Initialize the layout - called automatically whenever an instance of layout is created + * + * @callers none - triggered onInit + * @returns An object pointer to the instance created + */ + var _create = function () { + // initialize config/options + initOptions(); + var o = options; + + // onload will CANCEL resizing if returns false + if (false === _execCallback(null, o.onload)) return false; + + // a center pane is required, so make sure it exists + if (!getPane('center').length) { + alert( lang.errCenterPaneMissing ); + return null; + } + + // update options with saved state, if option enabled + if (o.useStateCookie && o.cookie.autoLoad) + loadCookie(); // Update options from state-cookie + + // set environment - can update code here if $.browser is phased out + state.browser = { + mozilla: $.browser.mozilla + , webkit: $.browser.webkit || $.browser.safari + , msie: $.browser.msie + , isIE6: $.browser.msie && $.browser.version == 6 + , boxModel: $.support.boxModel + //, version: $.browser.version - not used + }; + + // initialize all layout elements + initContainer(); // set CSS as needed and init state.container dimensions + initPanes(); // size & position all panes - calls initHandles() + //initHandles(); // create and position all resize bars & togglers buttons + initResizable(); // activate resizing on all panes where resizable=true + sizeContent(); // AFTER panes & handles have been initialized, size 'content' divs + + if (o.scrollToBookmarkOnLoad) + with (self.location) if (hash) replace( hash ); // scrollTo Bookmark + + // search for and bind custom-buttons + if (o.autoBindCustomButtons) initButtons(); + + // bind hotkey function - keyDown - if required + initHotkeys(); + + // bind resizeAll() for 'this layout instance' to window.resize event + if (o.resizeWithWindow && !$Container.data("layoutRole")) // skip if 'nested' inside a pane + $(window).bind("resize."+ sID, windowResize); + + // bind window.onunload + $(window).bind("unload."+ sID, unload); + + state.initialized = true; + }; + + var windowResize = function () { + var delay = Number(options.resizeWithWindowDelay) || 100; // there MUST be some delay! + if (delay > 0) { + // resizing uses a delay-loop because the resize event fires repeatly - except in FF, but delay anyway + timer.clear("winResize"); // if already running + timer.set("winResize", function(){ timer.clear("winResize"); timer.clear("winResizeRepeater"); resizeAll(); }, delay); + // ALSO set fixed-delay timer, if not already running + if (!timer.data["winResizeRepeater"]) setWindowResizeRepeater(); + } + }; + + var setWindowResizeRepeater = function () { + var delay = Number(options.resizeWithWindowMaxDelay); + if (delay > 0) + timer.set("winResizeRepeater", function(){ setWindowResizeRepeater(); resizeAll(); }, delay); + }; + + var unload = function () { + var o = options; + state.cookie = getState(); // save state in case onunload has custom state-management + if (o.useStateCookie && o.cookie.autoSave) saveCookie(); + + _execCallback(null, o.onunload); + }; + + /** + * initContainer + * + * Validate and initialize container CSS and events + * + * @callers _create() + */ + var initContainer = function () { + var + $C = $Container // alias + , tag = sC.tagName = $C.attr("tagName") + , fullPage = (tag == "BODY") + , props = "position,margin,padding,border" + , CSS = {} + ; + sC.selector = $C.selector.split(".slice")[0]; + sC.ref = tag +"/"+ sC.selector; // used in messages + + // the layoutContainer key is used to store the unique layoutID + $C + .data("layoutContainer", sID) // unique identifier for internal use + .data("layoutName", options.name) // add user's layout-name - even if blank! + ; + + // SAVE original container CSS for use in destroy() + if (!$C.data("layoutCSS")) { + // handle props like overflow different for BODY & HTML - has 'system default' values + if (fullPage) { + CSS = $.extend( getElemCSS($C, props), { + height: $C.css("height") + , overflow: $C.css("overflow") + , overflowX: $C.css("overflowX") + , overflowY: $C.css("overflowY") + }); + // ALSO SAVE <HTML> CSS + var $H = $("html"); + $H.data("layoutCSS", { + height: "auto" // FF would return a fixed px-size! + , overflow: $H.css("overflow") + , overflowX: $H.css("overflowX") + , overflowY: $H.css("overflowY") + }); + } + else // handle props normally for non-body elements + CSS = getElemCSS($C, props+",top,bottom,left,right,width,height,overflow,overflowX,overflowY"); + + $C.data("layoutCSS", CSS); + } + + try { // format html/body if this is a full page layout + if (fullPage) { + $("html").css({ + height: "100%" + , overflow: "hidden" + , overflowX: "hidden" + , overflowY: "hidden" + }); + $("body").css({ + position: "relative" + , height: "100%" + , overflow: "hidden" + , overflowX: "hidden" + , overflowY: "hidden" + , margin: 0 + , padding: 0 // TODO: test whether body-padding could be handled? + , border: "none" // a body-border creates problems because it cannot be measured! + }); + } + else { // set required CSS for overflow and position + var + CSS = { overflow: "hidden" } // make sure container will not 'scroll' + , p = $C.css("position") + , h = $C.css("height") + ; + // if this is a NESTED layout, then container/outer-pane ALREADY has position and height + if (!$C.data("layoutRole")) { + if (!p || !p.match(/fixed|absolute|relative/)) + CSS.position = "relative"; // container MUST have a 'position' + /* + if (!h || h=="auto") + CSS.height = "100%"; // container MUST have a 'height' + */ + } + $C.css( CSS ); + if ($C.is(":visible") && $C.innerHeight() < 2) + alert( lang.errContainerHeight.replace(/CONTAINER/, sC.ref) ); + } + } catch (ex) {} + + // set current layout-container dimensions + $.extend(state.container, getElemDims( $C )); + }; + + /** + * initHotkeys + * + * Bind layout hotkeys - if options enabled + * + * @callers _create() + */ + var initHotkeys = function () { + // bind keyDown to capture hotkeys, if option enabled for ANY pane + $.each(_c.borderPanes.split(","), function (i, pane) { + var o = options[pane]; + if (o.enableCursorHotkey || o.customHotkey) { + $(document).bind("keydown."+ sID, keyDown); // only need to bind this ONCE + return false; // BREAK - binding was done + } + }); + }; + + /** + * initOptions + * + * Build final OPTIONS data + * + * @callers _create() + */ + var initOptions = function () { + // simplify logic by making sure passed 'opts' var has basic keys + opts = _transformData( opts ); + + // TODO: create a compatibility add-on for new UI widget that will transform old option syntax + var newOpts = { + applyDefaultStyles: "applyDemoStyles" + }; + renameOpts(opts.defaults); + $.each(_c.allPanes.split(","), function (i, pane) { + renameOpts(opts[pane]); + }); + + // update default effects, if case user passed key + if (opts.effects) { + $.extend( effects, opts.effects ); + delete opts.effects; + } + $.extend( options.cookie, opts.cookie ); + + // see if any 'global options' were specified + var globals = "name,zIndex,scrollToBookmarkOnLoad,resizeWithWindow,resizeWithWindowDelay,resizeWithWindowMaxDelay,"+ + "onresizeall,onresizeall_start,onresizeall_end,onload,onunload,autoBindCustomButtons,useStateCookie"; + $.each(globals.split(","), function (i, key) { + if (opts[key] !== undefined) + options[key] = opts[key]; + else if (opts.defaults[key] !== undefined) { + options[key] = opts.defaults[key]; + delete opts.defaults[key]; + } + }); + + // remove any 'defaults' that MUST be set 'per-pane' + $.each("paneSelector,resizerCursor,customHotkey".split(","), + function (i, key) { delete opts.defaults[key]; } // is OK if key does not exist + ); + + // now update options.defaults + $.extend( true, options.defaults, opts.defaults ); + + // merge config for 'center-pane' - border-panes handled in the loop below + _c.center = $.extend( true, {}, _c.panes, _c.center ); + // update config.zIndex values if zIndex option specified + var z = options.zIndex; + if (z === 0 || z > 0) { + _c.zIndex.pane_normal = z; + _c.zIndex.resizer_normal = z+1; + _c.zIndex.iframe_mask = z+1; + } + + // merge options for 'center-pane' - border-panes handled in the loop below + $.extend( options.center, opts.center ); + // Most 'default options' do not apply to 'center', so add only those that DO + var o_Center = $.extend( true, {}, options.defaults, opts.defaults, options.center ); // TEMP data + var optionsCenter = ("paneClass,contentSelector,applyDemoStyles,triggerEventsOnLoad,showOverflowOnHover," + + "onresize,onresize_start,onresize_end,resizeNestedLayout,resizeContentWhileDragging," + + "onsizecontent,onsizecontent_start,onsizecontent_end").split(","); + $.each(optionsCenter, + function (i, key) { options.center[key] = o_Center[key]; } + ); + + var o, defs = options.defaults; + + // create a COMPLETE set of options for EACH border-pane + $.each(_c.borderPanes.split(","), function (i, pane) { + + // apply 'pane-defaults' to CONFIG.[PANE] + _c[pane] = $.extend( true, {}, _c.panes, _c[pane] ); + + // apply 'pane-defaults' + user-options to OPTIONS.PANE + o = options[pane] = $.extend( true, {}, options.defaults, options[pane], opts.defaults, opts[pane] ); + + // make sure we have base-classes + if (!o.paneClass) o.paneClass = "ui-layout-pane"; + if (!o.resizerClass) o.resizerClass = "ui-layout-resizer"; + if (!o.togglerClass) o.togglerClass = "ui-layout-toggler"; + + // create FINAL fx options for each pane, ie: options.PANE.fxName/fxSpeed/fxSettings[_open|_close] + $.each(["_open","_close",""], function (i,n) { + var + sName = "fxName"+n + , sSpeed = "fxSpeed"+n + , sSettings = "fxSettings"+n + ; + // recalculate fxName according to specificity rules + o[sName] = + opts[pane][sName] // opts.west.fxName_open + || opts[pane].fxName // opts.west.fxName + || opts.defaults[sName] // opts.defaults.fxName_open + || opts.defaults.fxName // opts.defaults.fxName + || o[sName] // options.west.fxName_open + || o.fxName // options.west.fxName + || defs[sName] // options.defaults.fxName_open + || defs.fxName // options.defaults.fxName + || "none" + ; + // validate fxName to be sure is a valid effect + var fxName = o[sName]; + if (fxName == "none" || !$.effects || !$.effects[fxName] || (!effects[fxName] && !o[sSettings] && !o.fxSettings)) + fxName = o[sName] = "none"; // effect not loaded, OR undefined FX AND fxSettings not passed + // set vars for effects subkeys to simplify logic + var + fx = effects[fxName] || {} // effects.slide + , fx_all = fx.all || {} // effects.slide.all + , fx_pane = fx[pane] || {} // effects.slide.west + ; + // RECREATE the fxSettings[_open|_close] keys using specificity rules + o[sSettings] = $.extend( + {} + , fx_all // effects.slide.all + , fx_pane // effects.slide.west + , defs.fxSettings || {} // options.defaults.fxSettings + , defs[sSettings] || {} // options.defaults.fxSettings_open + , o.fxSettings // options.west.fxSettings + , o[sSettings] // options.west.fxSettings_open + , opts.defaults.fxSettings // opts.defaults.fxSettings + , opts.defaults[sSettings] || {} // opts.defaults.fxSettings_open + , opts[pane].fxSettings // opts.west.fxSettings + , opts[pane][sSettings] || {} // opts.west.fxSettings_open + ); + // recalculate fxSpeed according to specificity rules + o[sSpeed] = + opts[pane][sSpeed] // opts.west.fxSpeed_open + || opts[pane].fxSpeed // opts.west.fxSpeed (pane-default) + || opts.defaults[sSpeed] // opts.defaults.fxSpeed_open + || opts.defaults.fxSpeed // opts.defaults.fxSpeed + || o[sSpeed] // options.west.fxSpeed_open + || o[sSettings].duration // options.west.fxSettings_open.duration + || o.fxSpeed // options.west.fxSpeed + || o.fxSettings.duration // options.west.fxSettings.duration + || defs.fxSpeed // options.defaults.fxSpeed + || defs.fxSettings.duration// options.defaults.fxSettings.duration + || fx_pane.duration // effects.slide.west.duration + || fx_all.duration // effects.slide.all.duration + || "normal" // DEFAULT + ; + }); + + }); + + function renameOpts (O) { + for (var key in newOpts) { + if (O[key] != undefined) { + O[newOpts[key]] = O[key]; + delete O[key]; + } + } + } + }; + + /** + * initPanes + * + * Initialize module objects, styling, size and position for all panes + * + * @callers _create() + */ + var getPane = function (pane) { + var sel = options[pane].paneSelector + if (sel.substr(0,1)==="#") // ID selector + // NOTE: elements selected 'by ID' DO NOT have to be 'children' + return $Container.find(sel).eq(0); + else { // class or other selector + var $P = $Container.children(sel).eq(0); + // look for the pane nested inside a 'form' element + return $P.length ? $P : $Container.children("form:first").children(sel).eq(0); + } + }; + var initPanes = function () { + // NOTE: do north & south FIRST so we can measure their height - do center LAST + $.each(_c.allPanes.split(","), function (idx, pane) { + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , fx = s.fx + , dir = c.dir + , spacing = o.spacing_open || 0 + , isCenter = (pane == "center") + , CSS = {} + , $P, $C + , size, minSize, maxSize + ; + $Cs[pane] = false; // init + + $P = $Ps[pane] = getPane(pane); + if (!$P.length) { + $Ps[pane] = false; // logic + return true; // SKIP to next + } + + // SAVE original Pane CSS + if (!$P.data("layoutCSS")) { + var props = "position,top,left,bottom,right,width,height,overflow,zIndex,display,backgroundColor,padding,margin,border"; + $P.data("layoutCSS", getElemCSS($P, props)); + } + + // add basic classes & attributes + $P + .data("layoutName", options.name) // add user's layout-name - even if blank! + .data("layoutRole", "pane") + .data("layoutEdge", pane) + .css(c.cssReq).css("zIndex", _c.zIndex.pane_normal) + .css(o.applyDemoStyles ? c.cssDemo : {}) // demo styles + .addClass( o.paneClass +" "+ o.paneClass+"-"+pane ) // default = "ui-layout-pane ui-layout-pane-west" - may be a dupe of 'paneSelector' + .bind("mouseenter."+ sID, addHover ) + .bind("mouseleave."+ sID, removeHover ) + ; + + // see if this pane has a 'scrolling-content element' + initContent(pane, false); // false = do NOT sizeContent() - called later + + if (!isCenter) { + // call _parseSize AFTER applying pane classes & styles - but before making visible (if hidden) + // if o.size is auto or not valid, then MEASURE the pane and use that as it's 'size' + size = s.size = _parseSize(pane, o.size); + minSize = _parseSize(pane,o.minSize) || 1; + maxSize = _parseSize(pane,o.maxSize) || 100000; + if (size > 0) size = max(min(size, maxSize), minSize); + } + + // init pane-logic vars + s.tagName = $P.attr("tagName"); + s.edge = pane // useful if pane is (or about to be) 'swapped' - easy find out where it is (or is going) + s.noRoom = false; // true = pane 'automatically' hidden due to insufficient room - will unhide automatically + s.isVisible = true; // false = pane is invisible - closed OR hidden - simplify logic + if (!isCenter) { + s.isClosed = false; // true = pane is closed + s.isSliding = false; // true = pane is currently open by 'sliding' over adjacent panes + s.isResizing= false; // true = pane is in process of being resized + s.isHidden = false; // true = pane is hidden - no spacing, resizer or toggler is visible! + } + + // set css-position to account for container borders & padding + switch (pane) { + case "north": CSS.top = sC.insetTop; + CSS.left = sC.insetLeft; + CSS.right = sC.insetRight; + break; + case "south": CSS.bottom = sC.insetBottom; + CSS.left = sC.insetLeft; + CSS.right = sC.insetRight; + break; + case "west": CSS.left = sC.insetLeft; // top, bottom & height set by sizeMidPanes() + break; + case "east": CSS.right = sC.insetRight; // ditto + break; + case "center": // top, left, width & height set by sizeMidPanes() + } + + if (dir == "horz") // north or south pane + CSS.height = max(1, cssH(pane, size)); + else if (dir == "vert") // east or west pane + CSS.width = max(1, cssW(pane, size)); + //else if (isCenter) {} + + $P.css(CSS); // apply size -- top, bottom & height will be set by sizeMidPanes + if (dir != "horz") sizeMidPanes(pane, true); // true = skipCallback + + // NOW make the pane visible - in case was initially hidden + $P.css({ visibility: "visible", display: "block" }); + + // close or hide the pane if specified in settings + if (o.initClosed && o.closable) + close(pane, true, true); // true, true = force, noAnimation + else if (o.initHidden || o.initClosed) + hide(pane); // will be completely invisible - no resizer or spacing + // ELSE setAsOpen() - called later by initHandles() + + // check option for auto-handling of pop-ups & drop-downs + if (o.showOverflowOnHover) + $P.hover( allowOverflow, resetOverflow ); + }); + + /* + * init the pane-handles NOW in case we have to hide or close the pane below + */ + initHandles(); + + // now that all panes have been initialized and initially-sized, + // make sure there is really enough space available for each pane + $.each(_c.borderPanes.split(","), function (i, pane) { + if ($Ps[pane] && state[pane].isVisible) { // pane is OPEN + setSizeLimits(pane); + makePaneFit(pane); // pane may be Closed, Hidden or Resized by makePaneFit() + } + }); + // size center-pane AGAIN in case we 'closed' a border-pane in loop above + sizeMidPanes("center"); + + // trigger onResize callbacks for all panes with triggerEventsOnLoad = true + $.each(_c.allPanes.split(","), function (i, pane) { + o = options[pane]; + if ($Ps[pane] && o.triggerEventsOnLoad && state[pane].isVisible) // pane is OPEN + _execCallback(pane, o.onresize_end || o.onresize); // call onresize + }); + + if ($Container.innerHeight() < 2) + alert( lang.errContainerHeight.replace(/CONTAINER/, sC.ref) ); + }; + + /** + * initHandles + * + * Initialize module objects, styling, size and position for all resize bars and toggler buttons + * + * @callers _create() + */ + var initHandles = function (panes) { + if (!panes || panes == "all") panes = _c.borderPanes; + + // create toggler DIVs for each pane, and set object pointers for them, eg: $R.north = north toggler DIV + $.each(panes.split(","), function (i, pane) { + var $P = $Ps[pane]; + $Rs[pane] = false; // INIT + $Ts[pane] = false; + if (!$P) return; // pane does not exist - skip + + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , rClass = o.resizerClass + , tClass = o.togglerClass + , side = c.side.toLowerCase() + , spacing = (s.isVisible ? o.spacing_open : o.spacing_closed) + , _pane = "-"+ pane // used for classNames + , _state = (s.isVisible ? "-open" : "-closed") // used for classNames + // INIT RESIZER BAR + , $R = $Rs[pane] = $("<div></div>") + // INIT TOGGLER BUTTON + , $T = (o.closable ? $Ts[pane] = $("<div></div>") : false) + ; + + if (s.isVisible && o.resizable) + ; // handled by initResizable + else if (!s.isVisible && o.slidable) + $R.attr("title", o.sliderTip).css("cursor", o.sliderCursor); + + $R + // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "paneLeft-resizer" + .attr("id", (o.paneSelector.substr(0,1)=="#" ? o.paneSelector.substr(1) + "-resizer" : "")) + .data("layoutRole", "resizer") + .data("layoutEdge", pane) + .css(_c.resizers.cssReq).css("zIndex", _c.zIndex.resizer_normal) + .css(o.applyDemoStyles ? _c.resizers.cssDemo : {}) // add demo styles + .addClass(rClass +" "+ rClass+_pane) + .appendTo($Container) // append DIV to container + ; + + if ($T) { + $T + // if paneSelector is an ID, then create a matching ID for the resizer, eg: "#paneLeft" => "#paneLeft-toggler" + .attr("id", (o.paneSelector.substr(0,1)=="#" ? o.paneSelector.substr(1) + "-toggler" : "")) + .data("layoutRole", "toggler") + .data("layoutEdge", pane) + .css(_c.togglers.cssReq) // add base/required styles + .css(o.applyDemoStyles ? _c.togglers.cssDemo : {}) // add demo styles + .addClass(tClass +" "+ tClass+_pane) + .appendTo($R) // append SPAN to resizer DIV + .click(function(evt){ toggle(pane); evt.stopPropagation(); }) + .hover( addHover, removeHover ) + ; + // ADD INNER-SPANS TO TOGGLER + if (o.togglerContent_open) // ui-layout-open + $("<span>"+ o.togglerContent_open +"</span>") + .data("layoutRole", "togglerContent") + .data("layoutEdge", pane) + .addClass("content content-open") + .css("display","none") + .appendTo( $T ) + .hover( addHover, removeHover ) + ; + if (o.togglerContent_closed) // ui-layout-closed + $("<span>"+ o.togglerContent_closed +"</span>") + .data("layoutRole", "togglerContent") + .data("layoutEdge", pane) + .addClass("content content-closed") + .css("display","none") + .appendTo( $T ) + .hover( addHover, removeHover ) + ; + } + + // ADD CLASSNAMES & SLIDE-BINDINGS - eg: class="resizer resizer-west resizer-open" + if (s.isVisible) + setAsOpen(pane); // onOpen will be called, but NOT onResize + else { + setAsClosed(pane); // onClose will be called + bindStartSlidingEvent(pane, true); // will enable events IF option is set + } + + }); + + // SET ALL HANDLE DIMENSIONS + sizeHandles("all"); + }; + + + /** + * initContent + * + * Initialize scrolling ui-layout-content div - if exists + * + * @callers initPane() - or externally after an Ajax injection + */ + var initContent = function (pane, resize) { + var + o = options[pane] + , sel = o.contentSelector + , $P = $Ps[pane] + , $C + ; + if (sel) $C = $Cs[pane] = (o.findNestedContent) + ? $P.find(sel).eq(0) // match 1-element only + : $P.children(sel).eq(0) + ; + if ($C && $C.length) { + $C.css( _c.content.cssReq ); + if (o.applyDemoStyles) { + $C.css( _c.content.cssDemo ); // add padding & overflow: auto to content-div + $P.css( _c.content.cssDemoPane ); // REMOVE padding/scrolling from pane + } + state[pane].content = {}; // init content state + if (resize !== false) sizeContent(pane); + // sizeContent() is called AFTER init of all elements + } + else + $Cs[pane] = false; + }; + + + /** + * initButtons + * + * Searches for .ui-layout-button-xxx elements and auto-binds them as layout-buttons + * + * @callers _create() + */ + var initButtons = function () { + var pre = "ui-layout-button-", name; + $.each("toggle,open,close,pin,toggle-slide,open-slide".split(","), function (i, action) { + $.each(_c.borderPanes.split(","), function (ii, pane) { + $("."+pre+action+"-"+pane).each(function(){ + // if button was previously 'bound', data.layoutName was set, but is blank if layout has no 'name' + name = $(this).data("layoutName") || $(this).attr("layoutName"); + if (name == undefined || name == options.name) { + if (action.substr("-slide") > 0) + bindButton(this, action.split("-")[0], pane, true) + else + bindButton(this, action, pane); + } + }); + }); + }); + }; + + /** + * initResizable + * + * Add resize-bars to all panes that specify it in options + * + * @dependancies $.fn.resizable - will skip if not found + * @callers _create() + */ + var initResizable = function (panes) { + var + draggingAvailable = (typeof $.fn.draggable == "function") + , $Frames, side // set in start() + ; + if (!panes || panes == "all") panes = _c.borderPanes; + + $.each(panes.split(","), function (idx, pane) { + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , side = (c.dir=="horz" ? "top" : "left") + , r, live // set in start because may change + ; + if (!draggingAvailable || !$Ps[pane] || !o.resizable) { + o.resizable = false; + return true; // skip to next + } + + var + $P = $Ps[pane] + , $R = $Rs[pane] + , base = o.resizerClass + // 'drag' classes are applied to the ORIGINAL resizer-bar while dragging is in process + , resizerClass = base+"-drag" // resizer-drag + , resizerPaneClass = base+"-"+pane+"-drag" // resizer-north-drag + // 'helper' class is applied to the CLONED resizer-bar while it is being dragged + , helperClass = base+"-dragging" // resizer-dragging + , helperPaneClass = base+"-"+pane+"-dragging" // resizer-north-dragging + , helperLimitClass = base+"-dragging-limit" // resizer-drag + , helperClassesSet = false // logic var + ; + + if (!s.isClosed) + $R + .attr("title", o.resizerTip) + .css("cursor", o.resizerCursor) // n-resize, s-resize, etc + ; + + $R.hover( onResizerEnter, onResizerLeave ); + + $R.draggable({ + containment: $Container[0] // limit resizing to layout container + , axis: (c.dir=="horz" ? "y" : "x") // limit resizing to horz or vert axis + , delay: 0 + , distance: 1 + // basic format for helper - style it using class: .ui-draggable-dragging + , helper: "clone" + , opacity: o.resizerDragOpacity + , addClasses: false // avoid ui-state-disabled class when disabled + //, iframeFix: o.draggableIframeFix // TODO: consider using when bug is fixed + , zIndex: _c.zIndex.resizer_drag + + , start: function (e, ui) { + // REFRESH options & state pointers in case we used swapPanes + o = options[pane]; + s = state[pane]; + // re-read options + live = o.resizeWhileDragging; + + // ondrag_start callback - will CANCEL hide if returns false + // TODO: dragging CANNOT be cancelled like this, so see if there is a way? + if (false === _execCallback(pane, o.ondrag_start)) return false; + + _c.isLayoutBusy = true; // used by sizePane() logic during a liveResize + s.isResizing = true; // prevent pane from closing while resizing + timer.clear(pane+"_closeSlider"); // just in case already triggered + + // SET RESIZER LIMITS - used in drag() + setSizeLimits(pane); // update pane/resizer state + r = s.resizerPosition; + + $R.addClass( resizerClass +" "+ resizerPaneClass ); // add drag classes + helperClassesSet = false; // reset logic var - see drag() + + // MASK PANES WITH IFRAMES OR OTHER TROUBLESOME ELEMENTS + $Frames = $(o.maskIframesOnResize === true ? "iframe" : o.maskIframesOnResize).filter(":visible"); + var id, i=0; // ID incrementer - used when 'resizing' masks during dynamic resizing + $Frames.each(function() { + id = "ui-layout-mask-"+ (++i); + $(this).data("layoutMaskID", id); // tag iframe with corresponding maskID + $('<div id="'+ id +'" class="ui-layout-mask ui-layout-mask-'+ pane +'"/>') + .css({ + background: "#fff" + , opacity: "0.001" + , zIndex: _c.zIndex.iframe_mask + , position: "absolute" + , width: this.offsetWidth+"px" + , height: this.offsetHeight+"px" + }) + .css($(this).position()) // top & left -- changed from offset() + .appendTo(this.parentNode) // put mask-div INSIDE pane to avoid zIndex issues + ; + }); + + // DISABLE TEXT SELECTION (though probably was already by resizer.mouseOver) + $('body').disableSelection(); + } + + , drag: function (e, ui) { + if (!helperClassesSet) { // can only add classes after clone has been added to the DOM + //$(".ui-draggable-dragging") + ui.helper + .addClass( helperClass +" "+ helperPaneClass ) // add helper classes + .children().css("visibility","hidden") // hide toggler inside dragged resizer-bar + ; + helperClassesSet = true; + // draggable bug!? RE-SET zIndex to prevent E/W resize-bar showing through N/S pane! + if (s.isSliding) $Ps[pane].css("zIndex", _c.zIndex.pane_sliding); + } + // CONTAIN RESIZER-BAR TO RESIZING LIMITS + var limit = 0; + if (ui.position[side] < r.min) { + ui.position[side] = r.min; + limit = -1; + } + else if (ui.position[side] > r.max) { + ui.position[side] = r.max; + limit = 1; + } + // ADD/REMOVE dragging-limit CLASS + if (limit) { + ui.helper.addClass( helperLimitClass ); // at dragging-limit + window.defaultStatus = "Panel has reached its " + + ((limit>0 && pane.match(/north|west/)) || (limit<0 && pane.match(/south|east/)) ? "maximum" : "minimum") +" size"; + } + else { + ui.helper.removeClass( helperLimitClass ); // not at dragging-limit + window.defaultStatus = ""; + } + // DYNAMICALLY RESIZE PANES IF OPTION ENABLED + if (live) resizePanes(e, ui, pane); + } + + , stop: function (e, ui) { + // RE-ENABLE TEXT SELECTION + $('body').enableSelection(); + window.defaultStatus = ""; // clear 'resizing limit' message from statusbar + $R.removeClass( resizerClass +" "+ resizerPaneClass +" "+ helperLimitClass ); // remove drag classes from Resizer + s.isResizing = false; + _c.isLayoutBusy = false; // set BEFORE resizePanes so other logic can pick it up + resizePanes(e, ui, pane, true); // true = resizingDone + } + + }); + + /** + * resizePanes + * + * Sub-routine called from stop() and optionally drag() + */ + var resizePanes = function (e, ui, pane, resizingDone) { + var + dragPos = ui.position + , c = _c[pane] + , resizerPos, newSize + , i = 0 // ID incrementer + ; + switch (pane) { + case "north": resizerPos = dragPos.top; break; + case "west": resizerPos = dragPos.left; break; + case "south": resizerPos = sC.offsetHeight - dragPos.top - o.spacing_open; break; + case "east": resizerPos = sC.offsetWidth - dragPos.left - o.spacing_open; break; + }; + + if (resizingDone) { + // Remove OR Resize MASK(S) created in drag.start + $("div.ui-layout-mask").each(function() { this.parentNode.removeChild(this); }); + //$("div.ui-layout-mask").remove(); // TODO: Is this less efficient? + + // ondrag_start callback - will CANCEL hide if returns false + if (false === _execCallback(pane, o.ondrag_end || o.ondrag)) return false; + } + else + $Frames.each(function() { + $("#"+ $(this).data("layoutMaskID")) // get corresponding mask by ID + .css($(this).position()) // update top & left + .css({ // update width & height + width: this.offsetWidth +"px" + , height: this.offsetHeight+"px" + }) + ; + }); + + // remove container margin from resizer position to get the pane size + newSize = resizerPos - sC["inset"+ c.side]; + manualSizePane(pane, newSize); + } + }); + }; + + + /** + * destroy + * + * Destroy this layout and reset all elements + */ + var destroy = function () { + // UNBIND layout events and remove global object + $(window).unbind("."+ sID); + $(document).unbind("."+ sID); + window[ sID ] = null; + + var + fullPage= (sC.tagName == "BODY") + // create list of ALL pane-classes that need to be removed + , root = o.paneClass // default="ui-layout-pane" + , _open = "-open" + , _sliding= "-sliding" + , _closed = "-closed" + , generic = [ root, root+_open, root+_closed, root+_sliding ] // generic classes + , $P, pRoot, pClasses // loop vars + ; + // loop all panes to remove layout classes, attributes and bindings + $.each(_c.allPanes.split(","), function (i, pane) { + $P = $Ps[pane]; + if (!$P) return true; // no pane - SKIP + + // REMOVE pane's resizer and toggler elements + if (pane != "center") { + if ($Ts[pane]) $Ts[pane].remove(); + $Rs[pane].remove(); + } + + pRoot = root+"-"+pane; // eg: "ui-layout-pane-west" + pClasses = []; // reset + pClasses.push( pRoot ); + pClasses.push( pRoot+_open ); + pClasses.push( pRoot+_closed ); + pClasses.push( pRoot+_sliding ); + + $.merge(pClasses, generic); // ADD generic classes + $.merge(pClasses, getHoverClasses($P, true)); // ADD hover-classes + + $P + .removeClass( pClasses.join(" ") ) // remove ALL pane-classes + .removeData("layoutRole") + .removeData("layoutEdge") + .unbind("."+ sID) // remove ALL Layout events + // TODO: remove these extra unbind commands when jQuery is fixed + .unbind("mouseenter") + .unbind("mouseleave") + ; + + // do NOT reset CSS if this pane is STILL the container of a nested layout! + // the nested layout will reset its 'container' when/if it is destroyed + if (!$P.data("layoutContainer")) + $P.css( $P.data("layoutCSS") ); + }); + + // reset layout-container + $Container.removeData("layoutContainer"); + + // do NOT reset container CSS if is a 'pane' in an outer-layout - ie, THIS layout is 'nested' + if (!$Container.data("layoutEdge")) + $Container.css( $Container.data("layoutCSS") ); // RESET CSS + // for full-page layouts, must also reset the <HTML> CSS + if (fullPage) + $("html").css( $("html").data("layoutCSS") ); // RESET CSS + + // trigger state-management and onunload callback + unload(); + + var n = options.name; // layout-name + if (n && window[n]) window[n] = null; // clear window object, if exists + }; + + +/* + * ########################### + * ACTION METHODS + * ########################### + */ + + /** + * hide / show + * + * Completely 'hides' a pane, including its spacing - as if it does not exist + * The pane is not actually 'removed' from the source, so can use 'show' to un-hide it + * + * @param String pane The pane being hidden, ie: north, south, east, or west + */ + var hide = function (pane, noAnimation) { + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + if (!$P || s.isHidden) return; // pane does not exist OR is already hidden + + // onhide_start callback - will CANCEL hide if returns false + if (state.initialized && false === _execCallback(pane, o.onhide_start)) return; + + s.isSliding = false; // just in case + + // now hide the elements + if ($R) $R.hide(); // hide resizer-bar + if (!state.initialized || s.isClosed) { + s.isClosed = true; // to trigger open-animation on show() + s.isHidden = true; + s.isVisible = false; + $P.hide(); // no animation when loading page + sizeMidPanes(_c[pane].dir == "horz" ? "all" : "center"); + if (state.initialized || o.triggerEventsOnLoad) + _execCallback(pane, o.onhide_end || o.onhide); + } + else { + s.isHiding = true; // used by onclose + close(pane, false, noAnimation); // adjust all panes to fit + } + }; + + var show = function (pane, openPane, noAnimation, noAlert) { + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + if (!$P || !s.isHidden) return; // pane does not exist OR is not hidden + + // onshow_start callback - will CANCEL show if returns false + if (false === _execCallback(pane, o.onshow_start)) return; + + s.isSliding = false; // just in case + s.isShowing = true; // used by onopen/onclose + //s.isHidden = false; - will be set by open/close - if not cancelled + + // now show the elements + //if ($R) $R.show(); - will be shown by open/close + if (openPane === false) + close(pane, true); // true = force + else + open(pane, false, noAnimation, noAlert); // adjust all panes to fit + }; + + + /** + * toggle + * + * Toggles a pane open/closed by calling either open or close + * + * @param String pane The pane being toggled, ie: north, south, east, or west + */ + var toggle = function (pane, slide) { + if (!isStr(pane)) { + pane.stopImmediatePropagation(); // pane = event + pane = $(this).data("layoutEdge"); // bound to $R.dblclick + } + var s = state[str(pane)]; + if (s.isHidden) + show(pane); // will call 'open' after unhiding it + else if (s.isClosed) + open(pane, !!slide); + else + close(pane); + }; + + + /** + * _closePane + * + * Utility method used during init or other auto-processes + * + * @param String pane The pane being closed + */ + var _closePane = function (pane, setHandles) { + var + $P = $Ps[pane] + , s = state[pane] + ; + $P.hide(); + s.isClosed = true; + s.isVisible = false; + // UNUSED: if (setHandles) setAsClosed(pane, true); // true = force + }; + + /** + * close + * + * Close the specified pane (animation optional), and resize all other panes as needed + * + * @param String pane The pane being closed, ie: north, south, east, or west + */ + var close = function (pane, force, noAnimation, skipCallback) { + if (!state.initialized) { + _closePane(pane) + return; + } + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , doFX = !noAnimation && !s.isClosed && (o.fxName_close != "none") + // transfer logic vars to temp vars + , isShowing = s.isShowing + , isHiding = s.isHiding + , wasSliding = s.isSliding + ; + // now clear the logic vars + delete s.isShowing; + delete s.isHiding; + + if (!$P || !o.closable) return; // invalid request // (!o.resizable && !o.closable) ??? + else if (!force && s.isClosed && !isShowing) return; // already closed + + if (_c.isLayoutBusy) { // layout is 'busy' - probably with an animation + _queue("close", pane, force); // set a callback for this action, if possible + return; // ABORT + } + + // onclose_start callback - will CANCEL hide if returns false + // SKIP if just 'showing' a hidden pane as 'closed' + if (!isShowing && false === _execCallback(pane, o.onclose_start)) return; + + // SET flow-control flags + _c[pane].isMoving = true; + _c.isLayoutBusy = true; + + s.isClosed = true; + s.isVisible = false; + // update isHidden BEFORE sizing panes + if (isHiding) s.isHidden = true; + else if (isShowing) s.isHidden = false; + + if (s.isSliding) // pane is being closed, so UNBIND trigger events + bindStopSlidingEvents(pane, false); // will set isSliding=false + else // resize panes adjacent to this one + sizeMidPanes(_c[pane].dir == "horz" ? "all" : "center", false); // false = NOT skipCallback + + // if this pane has a resizer bar, move it NOW - before animation + setAsClosed(pane); + + // ANIMATE 'CLOSE' - if no animation, then was ALREADY shown above + if (doFX) { + lockPaneForFX(pane, true); // need to set left/top so animation will work + $P.hide( o.fxName_close, o.fxSettings_close, o.fxSpeed_close, function () { + lockPaneForFX(pane, false); // undo + close_2(); + }); + } + else { + $P.hide(); // hide pane NOW + close_2(); + }; + + // SUBROUTINE + function close_2 () { + if (s.isClosed) { // make sure pane was not 'reopened' before animation finished! + + bindStartSlidingEvent(pane, true); // will enable if o.slidable = true + + // if opposite-pane was autoClosed, see if it can be autoOpened now + var altPane = _c.altSide[pane]; + if (state[ altPane ].noRoom) { + setSizeLimits( altPane ); + makePaneFit( altPane ); + } + + if (!skipCallback && (state.initialized || o.triggerEventsOnLoad)) { + // onclose callback - UNLESS just 'showing' a hidden pane as 'closed' + if (!isShowing && !wasSliding) _execCallback(pane, o.onclose_end || o.onclose); + // onhide OR onshow callback + if (isShowing) _execCallback(pane, o.onshow_end || o.onshow); + if (isHiding) _execCallback(pane, o.onhide_end || o.onhide); + } + } + // execute internal flow-control callback + _dequeue(pane); + } + }; + + var setAsClosed = function (pane) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side.toLowerCase() + , inset = "inset"+ _c[pane].side + , rClass = o.resizerClass + , tClass = o.togglerClass + , _pane = "-"+ pane // used for classNames + , _open = "-open" + , _sliding= "-sliding" + , _closed = "-closed" + ; + $R + .css(side, sC[inset]) // move the resizer + .removeClass( rClass+_open +" "+ rClass+_pane+_open ) + .removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + .addClass( rClass+_closed +" "+ rClass+_pane+_closed ) + .unbind("dblclick."+ sID) + ; + // DISABLE 'resizing' when closed - do this BEFORE bindStartSlidingEvent? + if (o.resizable && typeof $.fn.draggable == "function") + $R + .draggable("disable") + .removeClass("ui-state-disabled") // do NOT apply disabled styling - not suitable here + .css("cursor", "default") + .attr("title","") + ; + + // if pane has a toggler button, adjust that too + if ($T) { + $T + .removeClass( tClass+_open +" "+ tClass+_pane+_open ) + .addClass( tClass+_closed +" "+ tClass+_pane+_closed ) + .attr("title", o.togglerTip_closed) // may be blank + ; + // toggler-content - if exists + $T.children(".content-open").hide(); + $T.children(".content-closed").css("display","block"); + } + + // sync any 'pin buttons' + syncPinBtns(pane, false); + + if (state.initialized) { + // resize 'length' and position togglers for adjacent panes + sizeHandles("all"); + } + }; + + /** + * open + * + * Open the specified pane (animation optional), and resize all other panes as needed + * + * @param String pane The pane being opened, ie: north, south, east, or west + */ + var open = function (pane, slide, noAnimation, noAlert) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , doFX = !noAnimation && s.isClosed && (o.fxName_open != "none") + // transfer logic var to temp var + , isShowing = s.isShowing + ; + // now clear the logic var + delete s.isShowing; + + if (!$P || (!o.resizable && !o.closable)) return; // invalid request + else if (s.isVisible && !s.isSliding) return; // already open + + // pane can ALSO be unhidden by just calling show(), so handle this scenario + if (s.isHidden && !isShowing) { + show(pane, true); + return; + } + + if (_c.isLayoutBusy) { // layout is 'busy' - probably with an animation + _queue("open", pane, slide); // set a callback for this action, if possible + return; // ABORT + } + + // onopen_start callback - will CANCEL hide if returns false + if (false === _execCallback(pane, o.onopen_start)) return; + + // make sure there is enough space available to open the pane + setSizeLimits(pane, slide); // update pane-state + if (s.minSize > s.maxSize) { // INSUFFICIENT ROOM FOR PANE TO OPEN! + syncPinBtns(pane, false); // make sure pin-buttons are reset + if (!noAlert && o.noRoomToOpenTip) alert(o.noRoomToOpenTip); + return; // ABORT + } + + // SET flow-control flags + _c[pane].isMoving = true; + _c.isLayoutBusy = true; + + if (slide) // START Sliding - will set isSliding=true + bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane + else if (s.isSliding) // PIN PANE (stop sliding) - open pane 'normally' instead + bindStopSlidingEvents(pane, false); // UNBIND trigger events - will set isSliding=false + else if (o.slidable) + bindStartSlidingEvent(pane, false); // UNBIND trigger events + + s.noRoom = false; // will be reset by makePaneFit if 'noRoom' + makePaneFit(pane); + + s.isVisible = true; + s.isClosed = false; + // update isHidden BEFORE sizing panes - WHY??? Old? + if (isShowing) s.isHidden = false; + + if (doFX) { // ANIMATE + lockPaneForFX(pane, true); // need to set left/top so animation will work + $P.show( o.fxName_open, o.fxSettings_open, o.fxSpeed_open, function() { + lockPaneForFX(pane, false); // undo + open_2(); // continue + }); + } + else {// no animation + $P.show(); // just show pane and... + open_2(); // continue + }; + + // SUBROUTINE + function open_2 () { + if (s.isVisible) { // make sure pane was not closed or hidden before animation finished! + + // cure iframe display issues + _fixIframe(pane); + + // NOTE: if isSliding, then other panes are NOT 'resized' + if (!s.isSliding) // resize all panes adjacent to this one + sizeMidPanes(_c[pane].dir=="vert" ? "center" : "all", false); // false = NOT skipCallback + + // set classes, position handles and execute callbacks... + setAsOpen(pane); + } + + // internal flow-control callback + _dequeue(pane); + }; + + }; + + var setAsOpen = function (pane, skipCallback) { + var + $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , o = options[pane] + , s = state[pane] + , side = _c[pane].side.toLowerCase() + , inset = "inset"+ _c[pane].side + , rClass = o.resizerClass + , tClass = o.togglerClass + , _pane = "-"+ pane // used for classNames + , _open = "-open" + , _closed = "-closed" + , _sliding= "-sliding" + ; + $R + .css(side, sC[inset] + getPaneSize(pane)) // move the resizer + .removeClass( rClass+_closed +" "+ rClass+_pane+_closed ) + .addClass( rClass+_open +" "+ rClass+_pane+_open ) + ; + if (s.isSliding) + $R.addClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + else // in case 'was sliding' + $R.removeClass( rClass+_sliding +" "+ rClass+_pane+_sliding ) + + if (o.resizerDblClickToggle) + $R.bind("dblclick", toggle ); + removeHover( 0, $R ); // remove hover classes + if (o.resizable && typeof $.fn.draggable == "function") + $R + .draggable("enable") + .css("cursor", o.resizerCursor) + .attr("title", o.resizerTip) + ; + else if (!s.isSliding) + $R.css("cursor", "default"); // n-resize, s-resize, etc + + // if pane also has a toggler button, adjust that too + if ($T) { + $T + .removeClass( tClass+_closed +" "+ tClass+_pane+_closed ) + .addClass( tClass+_open +" "+ tClass+_pane+_open ) + .attr("title", o.togglerTip_open) // may be blank + ; + removeHover( 0, $T ); // remove hover classes + // toggler-content - if exists + $T.children(".content-closed").hide(); + $T.children(".content-open").css("display","block"); + } + + // sync any 'pin buttons' + syncPinBtns(pane, !s.isSliding); + + // update pane-state dimensions - BEFORE resizing content + $.extend(s, getElemDims($P)); + + if (state.initialized) { + // resize resizer & toggler sizes for all panes + sizeHandles("all"); + // resize content every time pane opens - to be sure + sizeContent(pane, true); // true = remeasure headers/footers, even if 'isLayoutBusy' + } + + if (!skipCallback && (state.initialized || o.triggerEventsOnLoad) && $P.is(":visible")) { + // onopen callback + _execCallback(pane, o.onopen_end || o.onopen); + // onshow callback - TODO: should this be here? + if (s.isShowing) _execCallback(pane, o.onshow_end || o.onshow); + // ALSO call onresize because layout-size *may* have changed while pane was closed + if (state.initialized) _execCallback(pane, o.onresize_end || o.onresize); // if (state.initialized) + } + }; + + + /** + * slideOpen / slideClose / slideToggle + * + * Pass-though methods for sliding + */ + var slideOpen = function (evt_or_pane) { + var + type = typeof evt_or_pane + , pane = (type == "string" ? evt_or_pane : $(this).data("layoutEdge")) + ; + // prevent event from triggering on NEW resizer binding created below + if (type == "object") { evt_or_pane.stopImmediatePropagation(); } + + if (state[pane].isClosed) + open(pane, true); // true = slide - ie, called from here! + else // skip 'open' if already open! + bindStopSlidingEvents(pane, true); // BIND trigger events to close sliding-pane + }; + + var slideClose = function (evt_or_pane) { + var + $E = (isStr(evt_or_pane) ? $Ps[evt_or_pane] : $(this)) + , pane= $E.data("layoutEdge") + , o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + ; + + if (s.isClosed || s.isResizing) + return; // skip if already closed OR in process of resizing + else if (o.slideTrigger_close == "click") + close_NOW(); // close immediately onClick + else if (o.preventQuickSlideClose && _c.isLayoutBusy) + return; // handle Chrome quick-close on slide-open + else // trigger = mouseleave - use a delay + timer.set(pane+"_closeSlider", close_NOW, 300); // .3 sec delay + + // SUBROUTINE for timed close + function close_NOW (e) { + if (s.isClosed) // skip 'close' if already closed! + bindStopSlidingEvents(pane, false); // UNBIND trigger events + else + close(pane); // close will handle unbinding + } + }; + + var slideToggle = function (pane) { toggle(pane, true); }; + + + /** + * lockPaneForFX + * + * Must set left/top on East/South panes so animation will work properly + * + * @param String pane The pane to lock, 'east' or 'south' - any other is ignored! + * @param Boolean doLock true = set left/top, false = remove + */ + var lockPaneForFX = function (pane, doLock) { + var $P = $Ps[pane]; + if (doLock) { + $P.css({ zIndex: _c.zIndex.pane_animate }); // overlay all elements during animation + if (pane=="south") + $P.css({ top: sC.insetTop + sC.innerHeight - $P.outerHeight() }); + else if (pane=="east") + $P.css({ left: sC.insetLeft + sC.innerWidth - $P.outerWidth() }); + } + else { // animation DONE - RESET CSS + // TODO: see if this can be deleted. It causes a quick-close when sliding in Chrome + //$P.css({ zIndex: (state[pane].isSliding ? _c.zIndex.pane_sliding : _c.zIndex.pane_normal) }); + if (pane=="south") + $P.css({ top: "auto" }); + else if (pane=="east") + $P.css({ left: "auto" }); + // fix anti-aliasing in IE - only needed for animations that change opacity + var o = options[pane]; + if (state.browser.msie && o.fxOpacityFix && o.fxName_open != "slide" && $P.css("filter") && $P.css("opacity") == 1) + $P[0].style.removeAttribute('filter'); + } + }; + + + /** + * bindStartSlidingEvent + * + * Toggle sliding functionality of a specific pane on/off by adding removing 'slide open' trigger + * + * @callers open(), close() + * @param String pane The pane to enable/disable, 'north', 'south', etc. + * @param Boolean enable Enable or Disable sliding? + */ + var bindStartSlidingEvent = function (pane, enable) { + var + o = options[pane] + , z = _c.zIndex + , $P = $Ps[pane] + , $R = $Rs[pane] + , trigger = o.slideTrigger_open + ; + if (!$R || !o.slidable) return; + + // make sure we have a valid event + if (trigger.match(/mouseover/)) + trigger = o.slideTrigger_open = "mouseenter"; + else if (!trigger.match(/click|dblclick|mouseenter/)) + trigger = o.slideTrigger_open = "click"; + + // RE/SET zIndex - increases when pane is opening, resets to normal after close + $R.css("zIndex", !enable ? z.pane_sliding : z.resizer_normal); + $P.css("zIndex", !enable ? z.pane_sliding : z.pane_normal); + + $R + // add or remove trigger event + [enable ? "bind" : "unbind"](trigger +'.'+ sID, slideOpen) + // set the appropriate cursor & title/tip + .css("cursor", enable ? o.sliderCursor : "default") + .attr("title", enable ? o.sliderTip : "") + ; + }; + + /** + * bindStopSlidingEvents + * + * Add or remove 'mouseleave' events to 'slide close' when pane is 'sliding' open or closed + * Also increases zIndex when pane is sliding open + * See bindStartSlidingEvent for code to control 'slide open' + * + * @callers slideOpen(), slideClose() + * @param String pane The pane to process, 'north', 'south', etc. + * @param Boolean enable Enable or Disable events? + */ + var bindStopSlidingEvents = function (pane, enable) { + var + o = options[pane] + , s = state[pane] + , trigger = o.slideTrigger_close + , action = (enable ? "bind" : "unbind") + , $P = $Ps[pane] + , $R = $Rs[pane] + ; + s.isSliding = enable; // logic + timer.clear(pane+"_closeSlider"); // just in case + + // remove 'slideOpen' trigger event from resizer + // ALSO will raise the zIndex of the pane & resizer + if (enable) bindStartSlidingEvent(pane, false); + + // make sure we have a valid event + if (!trigger.match(/click|mouseleave/)) + trigger = o.slideTrigger_close = "mouseleave"; // also catches 'mouseout' + + // add/remove slide triggers + $R[action](trigger, slideClose); // base event on resize + // need extra events for mouseleave + if (trigger == "mouseleave") { + // also close on pane.mouseleave + $P[action]("mouseleave."+ sID, slideClose); + // cancel timer when mouse moves between 'pane' and 'resizer' + $R[action]("mouseenter."+ sID, cancelMouseOut); + $P[action]("mouseenter."+ sID, cancelMouseOut); + } + + if (!enable) + timer.clear(pane+"_closeSlider"); + else if (trigger == "click" && !o.resizable) { + // IF pane is not resizable (which already has a cursor and tip) + // then set the a cursor & title/tip on resizer when sliding + $R.css("cursor", enable ? o.sliderCursor : "default"); + $R.attr("title", enable ? o.togglerTip_open : ""); // use Toggler-tip, eg: "Close Pane" + } + + // SUBROUTINE for mouseleave timer clearing + function cancelMouseOut (evt) { + timer.clear(pane+"_closeSlider"); + evt.stopPropagation(); + } + }; + + + /** + * makePaneFit + * + * Hides/closes a pane if there is insufficient room - reverses this when there is room again + * MUST have already called setSizeLimits() before calling this method + */ + var makePaneFit = function (pane, isOpening, skipCallback, force) { + var + o = options[pane] + , s = state[pane] + , c = _c[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , isSidePane = c.dir=="vert" + , hasRoom = false + ; + + // special handling for center pane + if (pane == "center" || (isSidePane && s.noVerticalRoom)) { + // see if there is enough room to display the center-pane + hasRoom = s.minHeight <= s.maxHeight && (isSidePane || s.minWidth <= s.maxWidth); + if (hasRoom && s.noRoom) { // previously hidden due to noRoom, so show now + $P.show(); + if ($R) $R.show(); + s.isVisible = true; + s.noRoom = false; + if (isSidePane) s.noVerticalRoom = false; + _fixIframe(pane); + } + else if (!hasRoom && !s.noRoom) { // not currently hidden, so hide now + $P.hide(); + if ($R) $R.hide(); + s.isVisible = false; + s.noRoom = true; + } + } + + // see if there is enough room to fit the border-pane + if (pane == "center") { + // ignore center in this block + } + else if (s.minSize <= s.maxSize) { // pane CAN fit + hasRoom = true; + if (s.size > s.maxSize) // pane is too big - shrink it + sizePane(pane, s.maxSize, skipCallback, force); + else if (s.size < s.minSize) // pane is too small - enlarge it + sizePane(pane, s.minSize, skipCallback, force); + else if ($R && $P.is(":visible")) { + // make sure resizer-bar is positioned correctly + // handles situation where nested layout was 'hidden' when initialized + var + side = c.side.toLowerCase() + , pos = s.size + sC["inset"+ c.side] + ; + if (_cssNum($R, side) != pos) $R.css( side, pos ); + } + + // if was previously hidden due to noRoom, then RESET because NOW there is room + if (s.noRoom) { + // s.noRoom state will be set by open or show + if (s.wasOpen && o.closable) { + if (o.autoReopen) + open(pane, false, true, true); // true = noAnimation, true = noAlert + else // leave the pane closed, so just update state + s.noRoom = false; + } + else + show(pane, s.wasOpen, true, true); // true = noAnimation, true = noAlert + } + } + else { // !hasRoom - pane CANNOT fit + if (!s.noRoom) { // pane not set as noRoom yet, so hide or close it now... + s.noRoom = true; // update state + s.wasOpen = !s.isClosed && !s.isSliding; + if (o.closable) // 'close' if possible + close(pane, true, true); // true = force, true = noAnimation + else // 'hide' pane if cannot just be closed + hide(pane, true); // true = noAnimation + } + } + }; + + + /** + * sizePane / manualSizePane + * + * sizePane is called only by internal methods whenever a pane needs to be resized + * manualSizePane is an exposed flow-through method allowing extra code when pane is 'manually resized' + * + * @param String pane The pane being resized + * @param Integer size The *desired* new size for this pane - will be validated + * @param Boolean skipCallback Should the onresize callback be run? + */ + var manualSizePane = function (pane, size, skipCallback) { + // ANY call to sizePane will disabled autoResize + var + o = options[pane] + // if resizing callbacks have been delayed and resizing is now DONE, force resizing to complete... + , forceResize = o.resizeWhileDragging && !_c.isLayoutBusy // && !o.triggerEventsWhileDragging + ; + o.autoResize = false; + // flow-through... + sizePane(pane, size, skipCallback, forceResize); + } + var sizePane = function (pane, size, skipCallback, force) { + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , side = _c[pane].side.toLowerCase() + , inset = "inset"+ _c[pane].side + , skipResizeWhileDragging = _c.isLayoutBusy && !o.triggerEventsWhileDragging + , oldSize + ; + // calculate 'current' min/max sizes + setSizeLimits(pane); // update pane-state + oldSize = s.size; + + size = _parseSize(pane, size); // handle percentages & auto + size = max(size, _parseSize(pane, o.minSize)); + size = min(size, s.maxSize); + if (size < s.minSize) { // not enough room for pane! + makePaneFit(pane, false, skipCallback); // will hide or close pane + return; + } + + // IF newSize is same as oldSize, then nothing to do - abort + if (!force && size == oldSize) return; + + // onresize_start callback CANNOT cancel resizing because this would break the layout! + if (!skipCallback && state.initialized && s.isVisible) + _execCallback(pane, o.onresize_start); + + // resize the pane, and make sure its visible + $P.css( _c[pane].sizeType.toLowerCase(), max(1, cssSize(pane, size)) ); + + // update pane-state dimensions + s.size = size; + $.extend(s, getElemDims($P)); + + // reposition the resizer-bar + if ($R && $P.is(":visible")) $R.css( side, size + sC[inset] ); + + sizeContent(pane); + + if (!skipCallback && !skipResizeWhileDragging && state.initialized && s.isVisible) { + _execCallback(pane, o.onresize_end || o.onresize); + // if Pane is the container for a nested layout, trigger resizeAll for that now + if (o.resizeNestedLayout && $P.data("layoutContainer")) + $P.layout().resizeAll(); + } + + // resize all the adjacent panes, and adjust their toggler buttons + // when skipCallback passed, it means the controlling method will handle 'other panes' + if (!skipCallback) { + // also no callback if live-resize is in progress and NOT triggerEventsWhileDragging + if (!s.isSliding) sizeMidPanes(_c[pane].dir=="horz" ? "all" : "center", skipResizeWhileDragging, force); + sizeHandles("all"); + } + + // if opposite-pane was autoClosed, see if it can be autoOpened now + var altPane = _c.altSide[pane]; + if (size < oldSize && state[ altPane ].noRoom) { + setSizeLimits( altPane ); + makePaneFit( altPane, false, skipCallback ); + } + }; + + /** + * sizeMidPanes + * + * @callers initPanes(), sizePane(), resizeAll(), open(), close(), hide() + */ + var sizeMidPanes = function (panes, skipCallback, force) { + if (!panes || panes == "all") panes = "east,west,center"; + + $.each(panes.split(","), function (i, pane) { + if (!$Ps[pane]) return; // NO PANE - skip + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , isCenter= (pane=="center") + , hasRoom = true + , CSS = {} + , d = calcNewCenterPaneDims() + ; + // update pane-state dimensions + $.extend(s, getElemDims($P)); + + if (pane == "center") { + if (!force && s.isVisible && d.width == s.outerWidth && d.height == s.outerHeight) + return true; // SKIP - pane already the correct size + // set state for makePaneFit() logic + $.extend(s, cssMinDims(pane), { + maxWidth: d.width + , maxHeight: d.height + }); + CSS = d; + // convert OUTER width/height to CSS width/height + CSS.width = cssW(pane, d.width); + CSS.height = cssH(pane, d.height); + hasRoom = CSS.width > 0 && CSS.height > 0; + + // during layout init, try to shrink east/west panes to make room for center + if (!hasRoom && !state.initialized && o.minWidth > 0) { + var + reqPx = o.minWidth - s.outerWidth + , minE = options.east.minSize || 0 + , minW = options.west.minSize || 0 + , sizeE = state.east.size + , sizeW = state.west.size + , newE = sizeE + , newW = sizeW + ; + if (reqPx > 0 && state.east.isVisible && sizeE > minE) { + newE = max( sizeE-minE, sizeE-reqPx ); + reqPx -= sizeE-newE; + } + if (reqPx > 0 && state.west.isVisible && sizeW > minW) { + newW = max( sizeW-minW, sizeW-reqPx ); + reqPx -= sizeW-newW; + } + // IF we found enough extra space, then resize the border panes as calculated + if (reqPx == 0) { + if (sizeE != minE) + sizePane('east', newE, true); // true = skipCallback - initPanes will handle when done + if (sizeW != minW) + sizePane('west', newW, true); + // now start over! + sizeMidPanes('center', skipCallback, force); + return; // abort this loop + } + } + } + else { // for east and west, set only the height, which is same as center height + // set state.min/maxWidth/Height for makePaneFit() logic + $.extend(s, getElemDims($P), cssMinDims(pane)) + if (!force && !s.noVerticalRoom && d.height == s.outerHeight) + return true; // SKIP - pane already the correct size + CSS.top = d.top; + CSS.bottom = d.bottom; + CSS.height = cssH(pane, d.height); + s.maxHeight = max(0, CSS.height); + hasRoom = (s.maxHeight > 0); + if (!hasRoom) s.noVerticalRoom = true; // makePaneFit() logic + } + + if (hasRoom) { + // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized + if (!skipCallback && state.initialized) + _execCallback(pane, o.onresize_start); + + $P.css(CSS); // apply the CSS to pane + $.extend(s, getElemDims($P)); // update pane dimensions + if (s.noRoom) makePaneFit(pane); // will re-open/show auto-closed/hidden pane + if (state.initialized) sizeContent(pane); // also resize the contents, if exists + } + else if (!s.noRoom && s.isVisible) // no room for pane + makePaneFit(pane); // will hide or close pane + + /* + * Extra CSS for IE6 or IE7 in Quirks-mode - add 'width' to NORTH/SOUTH panes + * Normally these panes have only 'left' & 'right' positions so pane auto-sizes + * ALSO required when pane is an IFRAME because will NOT default to 'full width' + */ + if (pane == "center") { // finished processing midPanes + var b = state.browser; + var fix = b.isIE6 || (b.msie && !b.boxModel); + if ($Ps.north && (fix || state.north.tagName=="IFRAME")) + $Ps.north.css("width", cssW($Ps.north, sC.innerWidth)); + if ($Ps.south && (fix || state.south.tagName=="IFRAME")) + $Ps.south.css("width", cssW($Ps.south, sC.innerWidth)); + } + + // resizeAll passes skipCallback because it triggers callbacks after ALL panes are resized + if (!skipCallback && state.initialized && s.isVisible) { + _execCallback(pane, o.onresize_end || o.onresize); + // if Pane is the container for a nested layout, trigger resizeAll for that now + if (o.resizeNestedLayout && $P.data("layoutContainer")) + $P.layout().resizeAll(); + } + }); + }; + + + /** + * resizeAll + * + * @callers window.onresize(), callbacks or custom code + */ + var resizeAll = function () { + var + oldW = sC.innerWidth + , oldH = sC.innerHeight + ; + $.extend( state.container, getElemDims( $Container ) ); // UPDATE container dimensions + if (!sC.outerHeight) return; // cannot size layout when 'container' is hidden or collapsed + + // onresizeall_start will CANCEL resizing if returns false + // state.container has already been set, so user can access this info for calcuations + if (false === _execCallback(null, options.onresizeall_start)) return false; + + var + // see if container is now 'smaller' than before + shrunkH = (sC.innerHeight < oldH) + , shrunkW = (sC.innerWidth < oldW) + , $P, o, s, dir + ; + // NOTE special order for sizing: S-N-E-W + $.each(["south","north","east","west"], function (i, pane) { + if (!$Ps[pane]) return; // no pane - SKIP + s = state[pane]; + o = options[pane]; + dir = _c[pane].dir; + + if (o.autoResize && s.size != o.size) // resize pane to original size set in options + sizePane(pane, o.size, true, true); // true=skipCallback, true=forceResize + else { + setSizeLimits(pane); + makePaneFit(pane, false, true, true); // true=skipCallback, true=forceResize + } + }); + + sizeMidPanes("all", true, true); // true=skipCallback, true=forceResize + sizeHandles("all"); // reposition the toggler elements + + // trigger all individual pane callbacks AFTER layout has finished resizing + o = options; // reuse alias + $.each(_c.allPanes.split(","), function (i, pane) { + $P = $Ps[pane]; + if (!$P) return; // SKIP + if (state[pane].isVisible) // undefined for non-existent panes + _execCallback(pane, o[pane].onresize_end || o[pane].onresize); // callback - if exists + // if Pane is the container for a nested layout, trigger resizeAll for that now + if (o[pane].resizeNestedLayout && $P.data("layoutContainer")) + $P.layout().resizeAll(); + }); + + _execCallback(null, o.onresizeall_end || o.onresizeall); // onresizeall callback, if exists + }; + + + /** + * sizeContent + * + * IF pane has a content-div, then resize all elements inside pane to fit pane-height + */ + var sizeContent = function (panes, remeasure) { + if (!panes || panes == "all") panes = _c.allPanes; + $.each(panes.split(","), function (idx, pane) { + var + $P = $Ps[pane] + , $C = $Cs[pane] + , o = options[pane] + , s = state[pane] + , m = s.content // m = measurements + ; + if (!$P || !$C || !$P.is(":visible")) return true; // NOT VISIBLE - skip + // skip re-measuring offsets if live-resizing + if (!_c.isLayoutBusy || m.top == undefined || remeasure || o.resizeContentWhileDragging) { + _measure(); + // if any footers are below pane-bottom, they may not measure correctly, + // so allow pane overflow and re-measure + if (m.hiddenFooters > 0 && $P.css("overflow") == "hidden") { + $P.css("overflow", "visible"); + _measure(); // remeasure while overflowing + $P.css("overflow", "hidden"); + } + } + // NOTE: spaceAbove/Below *includes* the pane's paddingTop/Bottom, but not pane.borders + var newH = s.innerHeight - (m.spaceAbove - s.css.paddingTop) - (m.spaceBelow - s.css.paddingBottom); + if (!$C.is(":visible") || m.height != newH) { + // size the Content element to fit new pane-size - will autoHide if not enough room + setOuterHeight($C, newH, true); // true=autoHide + m.height = newH; // save new height + }; + + function _below ($E) { + return max(s.css.paddingBottom, (parseInt($E.css("marginBottom")) || 0)); + }; + + function _measure () { + var + ignore = options[pane].contentIgnoreSelector + , $Fs = $C.nextAll().not(ignore || ':lt(0)') // not :lt(0) = ALL + , $Fs_vis = $Fs.filter(':visible') + , $F = $Fs_vis.filter(':last') + ; + m = { + top: $C[0].offsetTop + , height: $C.outerHeight() + , numFooters: $Fs.length + , hiddenFooters: $Fs.length - $Fs_vis.length + , spaceBelow: 0 // correct if no content footer ($E) + } + m.spaceAbove = m.top; // just for state - not used in calc + m.bottom = m.top + m.height; + if ($F.length) + //spaceBelow = (LastFooter.top + LastFooter.height) [footerBottom] - Content.bottom + max(LastFooter.marginBottom, pane.paddingBotom) + m.spaceBelow = ($F[0].offsetTop + $F.outerHeight()) - m.bottom + _below($F); + else // no footer - check marginBottom on Content element itself + m.spaceBelow = _below($C); + }; + }); + }; + + + /** + * sizeHandles + * + * Called every time a pane is opened, closed, or resized to slide the togglers to 'center' and adjust their length if necessary + * + * @callers initHandles(), open(), close(), resizeAll() + */ + var sizeHandles = function (panes) { + if (!panes || panes == "all") panes = _c.borderPanes; + + $.each(panes.split(","), function (i, pane) { + var + o = options[pane] + , s = state[pane] + , $P = $Ps[pane] + , $R = $Rs[pane] + , $T = $Ts[pane] + , $TC + ; + if (!$P || !$R) return; + + var + dir = _c[pane].dir + , _state = (s.isClosed ? "_closed" : "_open") + , spacing = o["spacing"+ _state] + , togAlign = o["togglerAlign"+ _state] + , togLen = o["togglerLength"+ _state] + , paneLen + , offset + , CSS = {} + ; + + if (spacing == 0) { + $R.hide(); + return; + } + else if (!s.noRoom && !s.isHidden) // skip if resizer was hidden for any reason + $R.show(); // in case was previously hidden + + // Resizer Bar is ALWAYS same width/height of pane it is attached to + if (dir == "horz") { // north/south + paneLen = $P.outerWidth(); // s.outerWidth || + s.resizerLength = paneLen; + $R.css({ + width: max(1, cssW($R, paneLen)) // account for borders & padding + , height: max(0, cssH($R, spacing)) // ditto + , left: _cssNum($P, "left") + }); + } + else { // east/west + paneLen = $P.outerHeight(); // s.outerHeight || + s.resizerLength = paneLen; + $R.css({ + height: max(1, cssH($R, paneLen)) // account for borders & padding + , width: max(0, cssW($R, spacing)) // ditto + , top: sC.insetTop + getPaneSize("north", true) // TODO: what if no North pane? + //, top: _cssNum($Ps["center"], "top") + }); + } + + // remove hover classes + removeHover( o, $R ); + + if ($T) { + if (togLen == 0 || (s.isSliding && o.hideTogglerOnSlide)) { + $T.hide(); // always HIDE the toggler when 'sliding' + return; + } + else + $T.show(); // in case was previously hidden + + if (!(togLen > 0) || togLen == "100%" || togLen > paneLen) { + togLen = paneLen; + offset = 0; + } + else { // calculate 'offset' based on options.PANE.togglerAlign_open/closed + if (isStr(togAlign)) { + switch (togAlign) { + case "top": + case "left": offset = 0; + break; + case "bottom": + case "right": offset = paneLen - togLen; + break; + case "middle": + case "center": + default: offset = Math.floor((paneLen - togLen) / 2); // 'default' catches typos + } + } + else { // togAlign = number + var x = parseInt(togAlign); // + if (togAlign >= 0) offset = x; + else offset = paneLen - togLen + x; // NOTE: x is negative! + } + } + + if (dir == "horz") { // north/south + var width = cssW($T, togLen); + $T.css({ + width: max(0, width) // account for borders & padding + , height: max(1, cssH($T, spacing)) // ditto + , left: offset // TODO: VERIFY that toggler positions correctly for ALL values + , top: 0 + }); + // CENTER the toggler content SPAN + $T.children(".content").each(function(){ + $TC = $(this); + $TC.css("marginLeft", Math.floor((width-$TC.outerWidth())/2)); // could be negative + }); + } + else { // east/west + var height = cssH($T, togLen); + $T.css({ + height: max(0, height) // account for borders & padding + , width: max(1, cssW($T, spacing)) // ditto + , top: offset // POSITION the toggler + , left: 0 + }); + // CENTER the toggler content SPAN + $T.children(".content").each(function(){ + $TC = $(this); + $TC.css("marginTop", Math.floor((height-$TC.outerHeight())/2)); // could be negative + }); + } + + // remove ALL hover classes + removeHover( 0, $T ); + } + + // DONE measuring and sizing this resizer/toggler, so can be 'hidden' now + if (!state.initialized && o.initHidden) { + $R.hide(); + if ($T) $T.hide(); + } + }); + }; + + + /** + * swapPanes + * + * Move a pane from source-side (eg, west) to target-side (eg, east) + * If pane exists on target-side, move that to source-side, ie, 'swap' the panes + */ + var swapPanes = function (pane1, pane2) { + // change state.edge NOW so callbacks can know where pane is headed... + state[pane1].edge = pane2; + state[pane2].edge = pane1; + // run these even if NOT state.initialized + var cancelled = false; + if (false === _execCallback(pane1, options[pane1].onswap_start)) cancelled = true; + if (!cancelled && false === _execCallback(pane2, options[pane2].onswap_start)) cancelled = true; + if (cancelled) { + state[pane1].edge = pane1; // reset + state[pane2].edge = pane2; + return; + } + + var + oPane1 = copy( pane1 ) + , oPane2 = copy( pane2 ) + , sizes = {} + ; + sizes[pane1] = oPane1 ? oPane1.state.size : 0; + sizes[pane2] = oPane2 ? oPane2.state.size : 0; + + // clear pointers & state + $Ps[pane1] = false; + $Ps[pane2] = false; + state[pane1] = {}; + state[pane2] = {}; + + // ALWAYS remove the resizer & toggler elements + if ($Ts[pane1]) $Ts[pane1].remove(); + if ($Ts[pane2]) $Ts[pane2].remove(); + if ($Rs[pane1]) $Rs[pane1].remove(); + if ($Rs[pane2]) $Rs[pane2].remove(); + $Rs[pane1] = $Rs[pane2] = $Ts[pane1] = $Ts[pane2] = false; + + // transfer element pointers and data to NEW Layout keys + move( oPane1, pane2 ); + move( oPane2, pane1 ); + + // cleanup objects + oPane1 = oPane2 = sizes = null; + + // make panes 'visible' again + if ($Ps[pane1]) $Ps[pane1].css(_c.visible); + if ($Ps[pane2]) $Ps[pane2].css(_c.visible); + + // fix any size discrepancies caused by swap + resizeAll(); + + // run these even if NOT state.initialized + _execCallback(pane1, options[pane1].onswap_end || options[pane1].onswap); + _execCallback(pane2, options[pane2].onswap_end || options[pane2].onswap); + + return; + + function copy (n) { // n = pane + var + $P = $Ps[n] + , $C = $Cs[n] + ; + return !$P ? false : { + pane: n + , P: $P ? $P[0] : false + , C: $C ? $C[0] : false + , state: $.extend({}, state[n]) + , options: $.extend({}, options[n]) + } + }; + + function move (oPane, pane) { + if (!oPane) return; + var + P = oPane.P + , C = oPane.C + , oldPane = oPane.pane + , c = _c[pane] + , side = c.side.toLowerCase() + , inset = "inset"+ c.side + // save pane-options that should be retained + , s = $.extend({}, state[pane]) + , o = options[pane] + // RETAIN side-specific FX Settings - more below + , fx = { resizerCursor: o.resizerCursor } + , re, size, pos + ; + $.each("fxName,fxSpeed,fxSettings".split(","), function (i, k) { + fx[k] = o[k]; + fx[k +"_open"] = o[k +"_open"]; + fx[k +"_close"] = o[k +"_close"]; + }); + + // update object pointers and attributes + $Ps[pane] = $(P) + .data("layoutEdge", pane) + .css(_c.hidden) + .css(c.cssReq) + ; + $Cs[pane] = C ? $(C) : false; + + // set options and state + options[pane] = $.extend({}, oPane.options, fx); + state[pane] = $.extend({}, oPane.state); + + // change classNames on the pane, eg: ui-layout-pane-east ==> ui-layout-pane-west + re = new RegExp(o.paneClass +"-"+ oldPane, "g"); + P.className = P.className.replace(re, o.paneClass +"-"+ pane); + + // ALWAYS regenerate the resizer & toggler elements + initHandles(pane); // create the required resizer & toggler + initResizable(pane); + + // if moving to different orientation, then keep 'target' pane size + if (c.dir != _c[oldPane].dir) { + size = sizes[pane] || 0; + setSizeLimits(pane); // update pane-state + size = max(size, state[pane].minSize); + // use manualSizePane to disable autoResize - not useful after panes are swapped + manualSizePane(pane, size, true); // true = skipCallback + } + else // move the resizer here + $Rs[pane].css(side, sC[inset] + (state[pane].isVisible ? getPaneSize(pane) : 0)); + + + // ADD CLASSNAMES & SLIDE-BINDINGS + if (oPane.state.isVisible && !s.isVisible) + setAsOpen(pane, true); // true = skipCallback + else { + setAsClosed(pane, true); // true = skipCallback + bindStartSlidingEvent(pane, true); // will enable events IF option is set + } + + // DESTROY the object + oPane = null; + }; + }; + + + /** + * keyDown + * + * Capture keys when enableCursorHotkey - toggle pane if hotkey pressed + * + * @callers document.keydown() + */ + function keyDown (evt) { + if (!evt) return true; + var code = evt.keyCode; + if (code < 33) return true; // ignore special keys: ENTER, TAB, etc + + var + PANE = { + 38: "north" // Up Cursor - $.ui.keyCode.UP + , 40: "south" // Down Cursor - $.ui.keyCode.DOWN + , 37: "west" // Left Cursor - $.ui.keyCode.LEFT + , 39: "east" // Right Cursor - $.ui.keyCode.RIGHT + } + , ALT = evt.altKey // no worky! + , SHIFT = evt.shiftKey + , CTRL = evt.ctrlKey + , CURSOR = (CTRL && code >= 37 && code <= 40) + , o, k, m, pane + ; + + if (CURSOR && options[PANE[code]].enableCursorHotkey) // valid cursor-hotkey + pane = PANE[code]; + else if (CTRL || SHIFT) // check to see if this matches a custom-hotkey + $.each(_c.borderPanes.split(","), function (i, p) { // loop each pane to check its hotkey + o = options[p]; + k = o.customHotkey; + m = o.customHotkeyModifier; // if missing or invalid, treated as "CTRL+SHIFT" + if ((SHIFT && m=="SHIFT") || (CTRL && m=="CTRL") || (CTRL && SHIFT)) { // Modifier matches + if (k && code == (isNaN(k) || k <= 9 ? k.toUpperCase().charCodeAt(0) : k)) { // Key matches + pane = p; + return false; // BREAK + } + } + }); + + // validate pane + if (!pane || !$Ps[pane] || !options[pane].closable || state[pane].isHidden) + return true; + + toggle(pane); + + evt.stopPropagation(); + evt.returnValue = false; // CANCEL key + return false; + }; + + +/* + * ###################################### + * UTILITY METHODS + * called externally or by initButtons + * ###################################### + */ + + /** + * allowOverflow / resetOverflow + * + * Change/reset a pane's overflow setting & zIndex to allow popups/drop-downs to work + * + * @param element elem Optional - can also be 'bound' to a click, mouseOver, or other event + */ + function allowOverflow (el) { + if (this && this.tagName) el = this; // BOUND to element + var $P; + if (isStr(el)) + $P = $Ps[el]; + else if ($(el).data("layoutRole")) + $P = $(el); + else + $(el).parents().each(function(){ + if ($(this).data("layoutRole")) { + $P = $(this); + return false; // BREAK + } + }); + if (!$P || !$P.length) return; // INVALID + + var + pane = $P.data("layoutEdge") + , s = state[pane] + ; + + // if pane is already raised, then reset it before doing it again! + // this would happen if allowOverflow is attached to BOTH the pane and an element + if (s.cssSaved) + resetOverflow(pane); // reset previous CSS before continuing + + // if pane is raised by sliding or resizing, or it's closed, then abort + if (s.isSliding || s.isResizing || s.isClosed) { + s.cssSaved = false; + return; + } + + var + newCSS = { zIndex: (_c.zIndex.pane_normal + 2) } + , curCSS = {} + , of = $P.css("overflow") + , ofX = $P.css("overflowX") + , ofY = $P.css("overflowY") + ; + // determine which, if any, overflow settings need to be changed + if (of != "visible") { + curCSS.overflow = of; + newCSS.overflow = "visible"; + } + if (ofX && !ofX.match(/visible|auto/)) { + curCSS.overflowX = ofX; + newCSS.overflowX = "visible"; + } + if (ofY && !ofY.match(/visible|auto/)) { + curCSS.overflowY = ofX; + newCSS.overflowY = "visible"; + } + + // save the current overflow settings - even if blank! + s.cssSaved = curCSS; + + // apply new CSS to raise zIndex and, if necessary, make overflow 'visible' + $P.css( newCSS ); + + // make sure the zIndex of all other panes is normal + $.each(_c.allPanes.split(","), function(i, p) { + if (p != pane) resetOverflow(p); + }); + + }; + + function resetOverflow (el) { + if (this && this.tagName) el = this; // BOUND to element + var $P; + if (isStr(el)) + $P = $Ps[el]; + else if ($(el).data("layoutRole")) + $P = $(el); + else + $(el).parents().each(function(){ + if ($(this).data("layoutRole")) { + $P = $(this); + return false; // BREAK + } + }); + if (!$P || !$P.length) return; // INVALID + + var + pane = $P.data("layoutEdge") + , s = state[pane] + , CSS = s.cssSaved || {} + ; + // reset the zIndex + if (!s.isSliding && !s.isResizing) + $P.css("zIndex", _c.zIndex.pane_normal); + + // reset Overflow - if necessary + $P.css( CSS ); + + // clear var + s.cssSaved = false; + }; + + + /** + * getBtn + * + * Helper function to validate params received by addButton utilities + * + * Two classes are added to the element, based on the buttonClass... + * The type of button is appended to create the 2nd className: + * - ui-layout-button-pin + * - ui-layout-pane-button-toggle + * - ui-layout-pane-button-open + * - ui-layout-pane-button-close + * + * @param String selector jQuery selector for button, eg: ".ui-layout-north .toggle-button" + * @param String pane Name of the pane the button is for: 'north', 'south', etc. + * @returns If both params valid, the element matching 'selector' in a jQuery wrapper - otherwise 'false' + */ + function getBtn(selector, pane, action) { + var $E = $(selector); + if (!$E.length) // element not found + alert(lang.errButton + lang.selector +": "+ selector); + else if (_c.borderPanes.indexOf(pane) == -1) // invalid 'pane' sepecified + alert(lang.errButton + lang.Pane.toLowerCase() +": "+ pane); + else { // VALID + var btn = options[pane].buttonClass +"-"+ action; + $E + .addClass( btn +" "+ btn +"-"+ pane ) + .data("layoutName", options.name) // add layout identifier - even if blank! + ; + return $E; + } + return false; // INVALID + }; + + + /** + * bindButton + * + * NEW syntax for binding layout-buttons - will eventually replace addToggleBtn, addOpenBtn, etc. + * + */ + function bindButton (selector, action, pane) { + switch (action.toLowerCase()) { + case "toggle": addToggleBtn(selector, pane); break; + case "open": addOpenBtn(selector, pane); break; + case "close": addCloseBtn(selector, pane); break; + case "pin": addPinBtn(selector, pane); break; + case "toggle-slide": addToggleBtn(selector, pane, true); break; + case "open-slide": addOpenBtn(selector, pane, true); break; + } + }; + + /** + * addToggleBtn + * + * Add a custom Toggler button for a pane + * + * @param String selector jQuery selector for button, eg: ".ui-layout-north .toggle-button" + * @param String pane Name of the pane the button is for: 'north', 'south', etc. + */ + function addToggleBtn (selector, pane, slide) { + var $E = getBtn(selector, pane, "toggle"); + if ($E) + $E.click(function (evt) { + toggle(pane, !!slide); + evt.stopPropagation(); + }); + }; + + /** + * addOpenBtn + * + * Add a custom Open button for a pane + * + * @param String selector jQuery selector for button, eg: ".ui-layout-north .open-button" + * @param String pane Name of the pane the button is for: 'north', 'south', etc. + */ + function addOpenBtn (selector, pane, slide) { + var $E = getBtn(selector, pane, "open"); + if ($E) + $E + .attr("title", lang.Open) + .click(function (evt) { + open(pane, !!slide); + evt.stopPropagation(); + }) + ; + }; + + /** + * addCloseBtn + * + * Add a custom Close button for a pane + * + * @param String selector jQuery selector for button, eg: ".ui-layout-north .close-button" + * @param String pane Name of the pane the button is for: 'north', 'south', etc. + */ + function addCloseBtn (selector, pane) { + var $E = getBtn(selector, pane, "close"); + if ($E) + $E + .attr("title", lang.Close) + .click(function (evt) { + close(pane); + evt.stopPropagation(); + }) + ; + }; + + /** + * addPinBtn + * + * Add a custom Pin button for a pane + * + * Four classes are added to the element, based on the paneClass for the associated pane... + * Assuming the default paneClass and the pin is 'up', these classes are added for a west-pane pin: + * - ui-layout-pane-pin + * - ui-layout-pane-west-pin + * - ui-layout-pane-pin-up + * - ui-layout-pane-west-pin-up + * + * @param String selector jQuery selector for button, eg: ".ui-layout-north .ui-layout-pin" + * @param String pane Name of the pane the pin is for: 'north', 'south', etc. + */ + function addPinBtn (selector, pane) { + var $E = getBtn(selector, pane, "pin"); + if ($E) { + var s = state[pane]; + $E.click(function (evt) { + setPinState($(this), pane, (s.isSliding || s.isClosed)); + if (s.isSliding || s.isClosed) open( pane ); // change from sliding to open + else close( pane ); // slide-closed + evt.stopPropagation(); + }); + // add up/down pin attributes and classes + setPinState ($E, pane, (!s.isClosed && !s.isSliding)); + // add this pin to the pane data so we can 'sync it' automatically + // PANE.pins key is an array so we can store multiple pins for each pane + _c[pane].pins.push( selector ); // just save the selector string + } + }; + + /** + * syncPinBtns + * + * INTERNAL function to sync 'pin buttons' when pane is opened or closed + * Unpinned means the pane is 'sliding' - ie, over-top of the adjacent panes + * + * @callers open(), close() + * @params pane These are the params returned to callbacks by layout() + * @params doPin True means set the pin 'down', False means 'up' + */ + function syncPinBtns (pane, doPin) { + $.each(_c[pane].pins, function (i, selector) { + setPinState($(selector), pane, doPin); + }); + }; + + /** + * setPinState + * + * Change the class of the pin button to make it look 'up' or 'down' + * + * @callers addPinBtn(), syncPinBtns() + * @param Element $Pin The pin-span element in a jQuery wrapper + * @param Boolean doPin True = set the pin 'down', False = set it 'up' + * @param String pinClass The root classname for pins - will add '-up' or '-down' suffix + */ + function setPinState ($Pin, pane, doPin) { + var updown = $Pin.attr("pin"); + if (updown && doPin == (updown=="down")) return; // already in correct state + var + pin = options[pane].buttonClass +"-pin" + , side = pin +"-"+ pane + , UP = pin +"-up "+ side +"-up" + , DN = pin +"-down "+side +"-down" + ; + $Pin + .attr("pin", doPin ? "down" : "up") // logic + .attr("title", doPin ? lang.Unpin : lang.Pin) + .removeClass( doPin ? UP : DN ) + .addClass( doPin ? DN : UP ) + ; + }; + + + /* + * LAYOUT STATE MANAGEMENT + * + * @example .layout({ cookie: { name: "myLayout", keys: "west.isClosed,east.isClosed" } }) + * @example .layout({ cookie__name: "myLayout", cookie__keys: "west.isClosed,east.isClosed" }) + * @example myLayout.getState( "west.isClosed,north.size,south.isHidden" ); + * @example myLayout.saveCookie( "west.isClosed,north.size,south.isHidden", {expires: 7} ); + * @example myLayout.deleteCookie(); + * @example myLayout.loadCookie(); + * @example var hSaved = myLayout.state.cookie; + */ + + function isCookiesEnabled () { + // TODO: is the cookieEnabled property common enough to be useful??? + return (navigator.cookieEnabled != 0); + }; + + /* + * getCookie + * + * Read & return data from the cookie - as JSON + */ + function getCookie (opts) { + var + o = $.extend( {}, options.cookie, opts || {} ) + , name = o.name || options.name || "Layout" + , c = document.cookie + , cs = c ? c.split(';') : [] + , pair // loop var + ; + for (var i=0, n=cs.length; i < n; i++) { + pair = $.trim(cs[i]).split('='); // name=value pair + if (pair[0] == name) // found the layout cookie + // convert cookie string back to a hash + return decodeJSON( decodeURIComponent(pair[1]) ); + } + return ""; + }; + + /* + * saveCookie + * + * Get the current layout state and save it to a cookie + */ + function saveCookie (keys, opts) { + var + o = $.extend( {}, options.cookie, opts || {} ) + , name = o.name || options.name || "Layout" + , params = '' + , date = '' + , clear = false + ; + if (o.expires.toUTCString) + date = o.expires; + else if (typeof o.expires == 'number') { + date = new Date(); + if (o.expires > 0) + date.setDate(date.getDate() + o.expires); + else { + date.setYear(1970); + clear = true; + } + } + if (date) params += ';expires='+ date.toUTCString(); + if (o.path) params += ';path='+ o.path; + if (o.domain) params += ';domain='+ o.domain; + if (o.secure) params += ';secure'; + + if (clear) { + state.cookie = {}; // clear data + document.cookie = name +'='+ params; // expire the cookie + } + else { + state.cookie = getState(keys || o.keys); // read current panes-state + document.cookie = name +'='+ encodeURIComponent( encodeJSON(state.cookie) ) + params; // write cookie + } + + return $.extend({}, state.cookie); // return COPY of state.cookie + }; + + /* + * deleteCookie + * + * Remove the state cookie + */ + function deleteCookie () { + saveCookie('', { expires: -1 }); + }; + + /* + * loadCookie + * + * Get data from the cookie and USE IT to loadState + */ + function loadCookie (opts) { + var o = getCookie(opts); // READ the cookie + if (o) { + state.cookie = $.extend({}, o); // SET state.cookie + loadState(o); // LOAD the retrieved state + } + return o; + }; + + /* + * loadState + * + * Update layout options from the cookie, if one exists + */ + function loadState (opts) { + $.extend( true, options, opts ); // update layout options + }; + + /* + * getState + * + * Get the *current layout state* and return it as a hash + */ + function getState (keys) { + var + data = {} + , alt = { isClosed: 'initClosed', isHidden: 'initHidden' } + , pair, pane, key, val + ; + if (!keys) keys = options.cookie.keys; // if called by user + if ($.isArray(keys)) keys = keys.join(","); + // convert keys to an array and change delimiters from '__' to '.' + keys = keys.replace(/__/g, ".").split(','); + // loop keys and create a data hash + for (var i=0,n=keys.length; i < n; i++) { + pair = keys[i].split("."); + pane = pair[0]; + key = pair[1]; + if (_c.allPanes.indexOf(pane) < 0) continue; // bad pane! + val = state[ pane ][ key ]; + if (val == undefined) continue; + if (key=="isClosed" && state[pane]["isSliding"]) + val = true; // if sliding, then *really* isClosed + ( data[pane] || (data[pane]={}) )[ alt[key] ? alt[key] : key ] = val; + } + return data; + }; + + /* + * encodeJSON + * + * Stringify a JSON hash so can save in a cookie or db-field + */ + function encodeJSON (JSON) { + return parse( JSON ); + function parse (h) { + var D=[], i=0, k, v, t; // k = key, v = value + for (k in h) { + v = h[k]; + t = typeof v; + if (t == 'string') // STRING - add quotes + v = '"'+ v +'"'; + else if (t == 'object') // SUB-KEY - recurse into it + v = parse(v); + D[i++] = '"'+ k +'":'+ v; + } + return "{"+ D.join(",") +"}"; + }; + }; + + /* + * decodeJSON + * + * Convert stringified JSON back to a hash object + */ + function decodeJSON (str) { + try { return window["eval"]("("+ str +")") || {}; } + catch (e) { return {}; } + }; + + +/* + * ##################### + * CREATE/RETURN LAYOUT + * ##################### + */ + + // validate that container exists + var $Container = $(this).eq(0); // FIRST matching Container element + if (!$Container.length) { + //alert( lang.errContainerMissing ); + return null; + }; + // return Instance (saved in window[state.id]) if layout has already been initialized + if ($Container.data("layoutContainer")) + return $.extend( {}, window[ $Container.data("layoutContainer") ] ); + + // init global vars + var + $Ps = {} // Panes x5 - set in initPanes() + , $Cs = {} // Content x5 - set in initPanes() + , $Rs = {} // Resizers x4 - set in initHandles() + , $Ts = {} // Togglers x4 - set in initHandles() + // aliases for code brevity + , sC = state.container // alias for easy access to 'container dimensions' + , sID = state.id // alias for unique layout ID/namespace - eg: "layout435" + ; + + // create the border layout NOW + _create(); + + // create Instance object to expose data & option Properties, and primary action Methods + var Instance = { + options: options // property - options hash + , state: state // property - dimensions hash + , container: $Container // property - object pointers for layout container + , panes: $Ps // property - object pointers for ALL Panes: panes.north, panes.center + , contents: $Cs // property - object pointers for ALL Content: content.north, content.center + , resizers: $Rs // property - object pointers for ALL Resizers, eg: resizers.north + , togglers: $Ts // property - object pointers for ALL Togglers, eg: togglers.north + , toggle: toggle // method - pass a 'pane' ("north", "west", etc) + , hide: hide // method - ditto + , show: show // method - ditto + , open: open // method - ditto + , close: close // method - ditto + , slideOpen: slideOpen // method - ditto + , slideClose: slideClose // method - ditto + , slideToggle: slideToggle // method - ditto + , initContent: initContent // method - ditto + , sizeContent: sizeContent // method - pass a 'pane' + , sizePane: manualSizePane // method - pass a 'pane' AND an 'outer-size' in pixels or percent, or 'auto' + , swapPanes: swapPanes // method - pass TWO 'panes' - will swap them + , resizeAll: resizeAll // method - no parameters + , destroy: destroy // method - no parameters + , setSizeLimits: setSizeLimits // method - pass a 'pane' - update state min/max data + , bindButton: bindButton // utility - pass element selector, 'action' and 'pane' (E, "toggle", "west") + , addToggleBtn: addToggleBtn // utility - pass element selector and 'pane' (E, "west") + , addOpenBtn: addOpenBtn // utility - ditto + , addCloseBtn: addCloseBtn // utility - ditto + , addPinBtn: addPinBtn // utility - ditto + , allowOverflow: allowOverflow // utility - pass calling element (this) + , resetOverflow: resetOverflow // utility - ditto + , encodeJSON: encodeJSON // method - pass a JSON object + , decodeJSON: decodeJSON // method - pass a string of encoded JSON + , getState: getState // method - returns hash of current layout-state + , getCookie: getCookie // method - update options from cookie - returns hash of cookie data + , saveCookie: saveCookie // method - optionally pass keys-list and cookie-options (hash) + , deleteCookie: deleteCookie // method + , loadCookie: loadCookie // method - update options from cookie - returns hash of cookie data + , loadState: loadState // method - pass a hash of state to use to update options + , cssWidth: cssW // utility - pass element and target outerWidth + , cssHeight: cssH // utility - ditto + }; + + // create a global instance pointer + window[ sID ] = Instance; + + // return the Instance object + return Instance; + +} +})( jQuery );
@@ -0,0 +1,345 @@+/*+ http://www.JSON.org/json_parse.js+ 2009-05-31++ Public Domain.++ NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.++ This file creates a json_parse function.++ json_parse(text, reviver)+ This method parses a JSON text to produce an object or array.+ It can throw a SyntaxError exception.++ The optional reviver parameter is a function that can filter and+ transform the results. It receives each of the keys and values,+ and its return value is used instead of the original value.+ If it returns what it received, then the structure is not modified.+ If it returns undefined then the member is deleted.++ Example:++ // Parse the text. Values that look like ISO date strings will+ // be converted to Date objects.++ myData = json_parse(text, function (key, value) {+ var a;+ if (typeof value === 'string') {+ a =+/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value);+ if (a) {+ return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],+ +a[5], +a[6]));+ }+ }+ return value;+ });++ This is a reference implementation. You are free to copy, modify, or+ redistribute.++ This code should be minified before deployment.+ See http://javascript.crockford.com/jsmin.html++ USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO+ NOT CONTROL.+*/++/*members "", "\"", "\/", "\\", at, b, call, charAt, f, fromCharCode,+ hasOwnProperty, message, n, name, push, r, t, text+*/++var json_parse = (function () {++// This is a function that can parse a JSON text, producing a JavaScript+// data structure. It is a simple, recursive descent parser. It does not use+// eval or regular expressions, so it can be used as a model for implementing+// a JSON parser in other languages.++// We are defining the function inside of another function to avoid creating+// global variables.++ var at, // The index of the current character+ ch, // The current character+ escapee = {+ '"': '"',+ '\\': '\\',+ '/': '/',+ b: '\b',+ f: '\f',+ n: '\n',+ r: '\r',+ t: '\t'+ },+ text,++ error = function (m) {++// Call error when something is wrong.++ throw {+ name: 'SyntaxError',+ message: m,+ at: at,+ text: text+ };+ },++ next = function (c) {++// If a c parameter is provided, verify that it matches the current character.++ if (c && c !== ch) {+ error("Expected '" + c + "' instead of '" + ch + "'");+ }++// Get the next character. When there are no more characters,+// return the empty string.++ ch = text.charAt(at);+ at += 1;+ return ch;+ },++ number = function () {++// Parse a number value.++ var number,+ string = '';++ if (ch === '-') {+ string = '-';+ next('-');+ }+ while (ch >= '0' && ch <= '9') {+ string += ch;+ next();+ }+ if (ch === '.') {+ string += '.';+ while (next() && ch >= '0' && ch <= '9') {+ string += ch;+ }+ }+ if (ch === 'e' || ch === 'E') {+ string += ch;+ next();+ if (ch === '-' || ch === '+') {+ string += ch;+ next();+ }+ while (ch >= '0' && ch <= '9') {+ string += ch;+ next();+ }+ }+ number = +string;+ if (isNaN(number)) {+ error("Bad number");+ } else {+ return number;+ }+ },++ string = function () {++// Parse a string value.++ var hex,+ i,+ string = '',+ uffff;++// When parsing for string values, we must look for " and \ characters.++ if (ch === '"') {+ while (next()) {+ if (ch === '"') {+ next();+ return string;+ } else if (ch === '\\') {+ next();+ if (ch === 'u') {+ uffff = 0;+ for (i = 0; i < 4; i += 1) {+ hex = parseInt(next(), 16);+ if (!isFinite(hex)) {+ break;+ }+ uffff = uffff * 16 + hex;+ }+ string += String.fromCharCode(uffff);+ } else if (typeof escapee[ch] === 'string') {+ string += escapee[ch];+ } else {+ break;+ }+ } else {+ string += ch;+ }+ }+ }+ error("Bad string");+ },++ white = function () {++// Skip whitespace.++ while (ch && ch <= ' ') {+ next();+ }+ },++ word = function () {++// true, false, or null.++ switch (ch) {+ case 't':+ next('t');+ next('r');+ next('u');+ next('e');+ return true;+ case 'f':+ next('f');+ next('a');+ next('l');+ next('s');+ next('e');+ return false;+ case 'n':+ next('n');+ next('u');+ next('l');+ next('l');+ return null;+ }+ error("Unexpected '" + ch + "'");+ },++ value, // Place holder for the value function.++ array = function () {++// Parse an array value.++ var array = [];++ if (ch === '[') {+ next('[');+ white();+ if (ch === ']') {+ next(']');+ return array; // empty array+ }+ while (ch) {+ array.push(value());+ white();+ if (ch === ']') {+ next(']');+ return array;+ }+ next(',');+ white();+ }+ }+ error("Bad array");+ },++ object = function () {++// Parse an object value.++ var key,+ object = {};++ if (ch === '{') {+ next('{');+ white();+ if (ch === '}') {+ next('}');+ return object; // empty object+ }+ while (ch) {+ key = string();+ white();+ next(':');+ if (Object.hasOwnProperty.call(object, key)) {+ error('Duplicate key "' + key + '"');+ }+ object[key] = value();+ white();+ if (ch === '}') {+ next('}');+ return object;+ }+ next(',');+ white();+ }+ }+ error("Bad object");+ };++ value = function () {++// Parse a JSON value. It could be an object, an array, a string, a number,+// or a word.++ white();+ switch (ch) {+ case '{':+ return object();+ case '[':+ return array();+ case '"':+ return string();+ case '-':+ return number();+ default:+ return ch >= '0' && ch <= '9' ? number() : word();+ }+ };++// Return the json_parse function. It will have access to all of the above+// functions and variables.++ return function (source, reviver) {+ var result;++ text = source;+ at = 0;+ ch = ' ';+ result = value();+ white();+ if (ch) {+ error("Syntax error");+ }++// If there is a reviver function, we recursively walk the new structure,+// passing each name/value pair to the reviver function for possible+// transformation, starting with a temporary root object that holds the result+// in an empty key. If there is not a reviver function, we simply return the+// result.++ return typeof reviver === 'function' ? (function walk(holder, key) {+ var k, v, value = holder[key];+ if (value && typeof value === 'object') {+ for (k in value) {+ if (Object.hasOwnProperty.call(value, k)) {+ v = walk(value, k);+ if (v !== undefined) {+ value[k] = v;+ } else {+ delete value[k];+ }+ }+ }+ }+ return reviver.call(holder, key, value);+ }({'': result}, '')) : result;+ };+}());
@@ -0,0 +1,9 @@+#tooltip { + position: absolute; + z-index: 3000; + border: 1px solid #111; + background-color: #eee; + padding: 5px;+ opacity: 0.85;+} +#tooltip h3, #tooltip div { margin: 0; }
@@ -0,0 +1,294 @@+/*+ * jQuery Tooltip plugin 1.3+ *+ * http://bassistance.de/jquery-plugins/jquery-plugin-tooltip/+ * http://docs.jquery.com/Plugins/Tooltip+ *+ * Copyright (c) 2006 - 2008 Jörn Zaefferer+ *+ * $Id: jquery.tooltip.js 5741 2008-06-21 15:22:16Z joern.zaefferer $+ * + * Dual licensed under the MIT and GPL licenses:+ * http://www.opensource.org/licenses/mit-license.php+ * http://www.gnu.org/licenses/gpl.html+ */+ +;(function($) {+ + // the tooltip element+ var helper = {},+ // the current tooltipped element+ current,+ // the title of the current element, used for restoring+ title,+ // timeout id for delayed tooltips+ tID,+ // IE 5.5 or 6+ IE = $.browser.msie && /MSIE\s(5\.5|6\.)/.test(navigator.userAgent),+ // flag for mouse tracking+ track = false;+ + $.tooltip = {+ blocked: false,+ defaults: {+ delay: 200,+ fade: false,+ showURL: true,+ extraClass: "",+ top: 15,+ left: 15,+ id: "tooltip"+ },+ block: function() {+ $.tooltip.blocked = !$.tooltip.blocked;+ }+ };+ + $.fn.extend({+ tooltip: function(settings) {+ settings = $.extend({}, $.tooltip.defaults, settings);+ createHelper(settings);+ return this.each(function() {+ $.data(this, "tooltip", settings);+ this.tOpacity = helper.parent.css("opacity");+ // copy tooltip into its own expando and remove the title+ this.tooltipText = this.title;+ $(this).removeAttr("title");+ // also remove alt attribute to prevent default tooltip in IE+ this.alt = "";+ })+ .mouseover(save)+ .mouseout(hide)+ .click(hide);+ },+ fixPNG: IE ? function() {+ return this.each(function () {+ var image = $(this).css('backgroundImage');+ if (image.match(/^url\(["']?(.*\.png)["']?\)$/i)) {+ image = RegExp.$1;+ $(this).css({+ 'backgroundImage': 'none',+ 'filter': "progid:DXImageTransform.Microsoft.AlphaImageLoader(enabled=true, sizingMethod=crop, src='" + image + "')"+ }).each(function () {+ var position = $(this).css('position');+ if (position != 'absolute' && position != 'relative')+ $(this).css('position', 'relative');+ });+ }+ });+ } : function() { return this; },+ unfixPNG: IE ? function() {+ return this.each(function () {+ $(this).css({'filter': '', backgroundImage: ''});+ });+ } : function() { return this; },+ hideWhenEmpty: function() {+ return this.each(function() {+ $(this)[ $(this).html() ? "show" : "hide" ]();+ });+ },+ url: function() {+ return this.attr('href') || this.attr('src');+ }+ });+ + function createHelper(settings) {+ // there can be only one tooltip helper+ if( helper.parent )+ return;+ // create the helper, h3 for title, div for url+ helper.parent = $('<div id="' + settings.id + '"><h3></h3><div class="body"></div><div class="url"></div></div>')+ // add to document+ .appendTo(document.body)+ // hide it at first+ .hide();+ + // apply bgiframe if available+ if ( $.fn.bgiframe )+ helper.parent.bgiframe();+ + // save references to title and url elements+ helper.title = $('h3', helper.parent);+ helper.body = $('div.body', helper.parent);+ helper.url = $('div.url', helper.parent);+ }+ + function settings(element) {+ return $.data(element, "tooltip");+ }+ + // main event handler to start showing tooltips+ function handle(event) {+ // show helper, either with timeout or on instant+ if( settings(this).delay )+ tID = setTimeout(show, settings(this).delay);+ else+ show();+ + // if selected, update the helper position when the mouse moves+ track = !!settings(this).track;+ $(document.body).bind('mousemove', update);+ + // update at least once+ update(event);+ }+ + // save elements title before the tooltip is displayed+ function save() {+ // if this is the current source, or it has no title (occurs with click event), stop+ if ( $.tooltip.blocked || this == current || (!this.tooltipText && !settings(this).bodyHandler) )+ return;++ // save current+ current = this;+ title = this.tooltipText;+ + if ( settings(this).bodyHandler ) {+ helper.title.hide();+ var bodyContent = settings(this).bodyHandler.call(this);+ if (bodyContent.nodeType || bodyContent.jquery) {+ helper.body.empty().append(bodyContent)+ } else {+ helper.body.html( bodyContent );+ }+ helper.body.show();+ } else if ( settings(this).showBody ) {+ var parts = title.split(settings(this).showBody);+ helper.title.html(parts.shift()).show();+ helper.body.empty();+ for(var i = 0, part; (part = parts[i]); i++) {+ if(i > 0)+ helper.body.append("<br/>");+ helper.body.append(part);+ }+ helper.body.hideWhenEmpty();+ } else {+ helper.title.html(title).show();+ helper.body.hide();+ }+ + // if element has href or src, add and show it, otherwise hide it+ if( settings(this).showURL && $(this).url() )+ helper.url.html( $(this).url().replace('http://', '') ).show();+ else + helper.url.hide();+ + // add an optional class for this tip+ helper.parent.addClass(settings(this).extraClass);++ // fix PNG background for IE+ if (settings(this).fixPNG )+ helper.parent.fixPNG();+ + handle.apply(this, arguments);+ }+ + // delete timeout and show helper+ function show() {+ tID = null;+ if ((!IE || !$.fn.bgiframe) && settings(current).fade) {+ if (helper.parent.is(":animated"))+ helper.parent.stop().show().fadeTo(settings(current).fade, current.tOpacity);+ else+ helper.parent.is(':visible') ? helper.parent.fadeTo(settings(current).fade, current.tOpacity) : helper.parent.fadeIn(settings(current).fade);+ } else {+ helper.parent.show();+ }+ update();+ }+ + /**+ * callback for mousemove+ * updates the helper position+ * removes itself when no current element+ */+ function update(event) {+ if($.tooltip.blocked)+ return;+ + if (event && event.target.tagName == "OPTION") {+ return;+ }+ + // stop updating when tracking is disabled and the tooltip is visible+ if ( !track && helper.parent.is(":visible")) {+ $(document.body).unbind('mousemove', update)+ }+ + // if no current element is available, remove this listener+ if( current == null ) {+ $(document.body).unbind('mousemove', update);+ return; + }+ + // remove position helper classes+ helper.parent.removeClass("viewport-right").removeClass("viewport-bottom");+ + var left = helper.parent[0].offsetLeft;+ var top = helper.parent[0].offsetTop;+ if (event) {+ // position the helper 15 pixel to bottom right, starting from mouse position+ left = event.pageX + settings(current).left;+ top = event.pageY + settings(current).top;+ var right='auto';+ if (settings(current).positionLeft) {+ right = $(window).width() - left;+ left = 'auto';+ }+ helper.parent.css({+ left: left,+ right: right,+ top: top+ });+ }+ + var v = viewport(),+ h = helper.parent[0];+ // check horizontal position+ if (v.x + v.cx < h.offsetLeft + h.offsetWidth) {+ left -= h.offsetWidth + 20 + settings(current).left;+ helper.parent.css({left: left + 'px'}).addClass("viewport-right");+ }+ // check vertical position+ if (v.y + v.cy < h.offsetTop + h.offsetHeight) {+ top -= h.offsetHeight + 20 + settings(current).top;+ helper.parent.css({top: top + 'px'}).addClass("viewport-bottom");+ }+ }+ + function viewport() {+ return {+ x: $(window).scrollLeft(),+ y: $(window).scrollTop(),+ cx: $(window).width(),+ cy: $(window).height()+ };+ }+ + // hide helper and restore added classes and the title+ function hide(event) {+ if($.tooltip.blocked)+ return;+ // clear timeout if possible+ if(tID)+ clearTimeout(tID);+ // no more current element+ current = null;+ + var tsettings = settings(this);+ function complete() {+ helper.parent.removeClass( tsettings.extraClass ).hide().css("opacity", "");+ }+ if ((!IE || !$.fn.bgiframe) && tsettings.fade) {+ if (helper.parent.is(':animated'))+ helper.parent.stop().fadeTo(tsettings.fade, 0, complete);+ else+ helper.parent.stop().fadeOut(tsettings.fade, complete);+ } else+ complete();+ + if( settings(this).fixPNG )+ helper.parent.unfixPNG();+ }+ +})(jQuery);
@@ -0,0 +1,104 @@+/* Copyright (c) 2006 Brandon Aaron (http://brandonaaron.net)+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) + * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.+ *+ * $LastChangedDate: 2007-06-20 03:23:36 +0200 (Mi, 20 Jun 2007) $+ * $Rev: 2110 $+ *+ * Version 2.1+ */++(function($){++/**+ * The bgiframe is chainable and applies the iframe hack to get + * around zIndex issues in IE6. It will only apply itself in IE + * and adds a class to the iframe called 'bgiframe'. The iframe+ * is appeneded as the first child of the matched element(s) + * with a tabIndex and zIndex of -1.+ * + * By default the plugin will take borders, sized with pixel units,+ * into account. If a different unit is used for the border's width,+ * then you will need to use the top and left settings as explained below.+ *+ * NOTICE: This plugin has been reported to cause perfromance problems+ * when used on elements that change properties (like width, height and+ * opacity) a lot in IE6. Most of these problems have been caused by + * the expressions used to calculate the elements width, height and + * borders. Some have reported it is due to the opacity filter. All + * these settings can be changed if needed as explained below.+ *+ * @example $('div').bgiframe();+ * @before <div><p>Paragraph</p></div>+ * @result <div><iframe class="bgiframe".../><p>Paragraph</p></div>+ *+ * @param Map settings Optional settings to configure the iframe.+ * @option String|Number top The iframe must be offset to the top+ * by the width of the top border. This should be a negative + * number representing the border-top-width. If a number is + * is used here, pixels will be assumed. Otherwise, be sure+ * to specify a unit. An expression could also be used. + * By default the value is "auto" which will use an expression + * to get the border-top-width if it is in pixels.+ * @option String|Number left The iframe must be offset to the left+ * by the width of the left border. This should be a negative + * number representing the border-left-width. If a number is + * is used here, pixels will be assumed. Otherwise, be sure+ * to specify a unit. An expression could also be used. + * By default the value is "auto" which will use an expression + * to get the border-left-width if it is in pixels.+ * @option String|Number width This is the width of the iframe. If+ * a number is used here, pixels will be assume. Otherwise, be sure+ * to specify a unit. An experssion could also be used.+ * By default the value is "auto" which will use an experssion+ * to get the offsetWidth.+ * @option String|Number height This is the height of the iframe. If+ * a number is used here, pixels will be assume. Otherwise, be sure+ * to specify a unit. An experssion could also be used.+ * By default the value is "auto" which will use an experssion+ * to get the offsetHeight.+ * @option Boolean opacity This is a boolean representing whether or not+ * to use opacity. If set to true, the opacity of 0 is applied. If+ * set to false, the opacity filter is not applied. Default: true.+ * @option String src This setting is provided so that one could change + * the src of the iframe to whatever they need.+ * Default: "javascript:false;"+ *+ * @name bgiframe+ * @type jQuery+ * @cat Plugins/bgiframe+ * @author Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)+ */+$.fn.bgIframe = $.fn.bgiframe = function(s) {+ // This is only for IE6+ if ( $.browser.msie && parseInt($.browser.version) <= 6 ) {+ s = $.extend({+ top : 'auto', // auto == .currentStyle.borderTopWidth+ left : 'auto', // auto == .currentStyle.borderLeftWidth+ width : 'auto', // auto == offsetWidth+ height : 'auto', // auto == offsetHeight+ opacity : true,+ src : 'javascript:false;'+ }, s || {});+ var prop = function(n){return n&&n.constructor==Number?n+'px':n;},+ html = '<iframe class="bgiframe"frameborder="0"tabindex="-1"src="'+s.src+'"'++ 'style="display:block;position:absolute;z-index:-1;'++ (s.opacity !== false?'filter:Alpha(Opacity=\'0\');':'')++ 'top:'+(s.top=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderTopWidth)||0)*-1)+\'px\')':prop(s.top))+';'++ 'left:'+(s.left=='auto'?'expression(((parseInt(this.parentNode.currentStyle.borderLeftWidth)||0)*-1)+\'px\')':prop(s.left))+';'++ 'width:'+(s.width=='auto'?'expression(this.parentNode.offsetWidth+\'px\')':prop(s.width))+';'++ 'height:'+(s.height=='auto'?'expression(this.parentNode.offsetHeight+\'px\')':prop(s.height))+';'++ '"/>';+ return this.each(function() {+ if ( $('> iframe.bgiframe', this).length == 0 )+ this.insertBefore( document.createElement(html), this.firstChild );+ });+ }+ return this;+};++// Add browser.version if it doesn't exist+if (!$.browser.version)+ $.browser.version = navigator.userAgent.toLowerCase().match(/.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/)[1];++})(jQuery);
@@ -0,0 +1,506 @@+/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)+ * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)+ * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.+ *+ * $LastChangedDate: 2007-06-22 04:38:37 +0200 (Fr, 22 Jun 2007) $+ * $Rev: 2141 $+ *+ * Version: 1.0b2+ */++(function($){++// store a copy of the core height and width methods+var height = $.fn.height,+ width = $.fn.width;++$.fn.extend({+ /**+ * If used on document, returns the document's height (innerHeight)+ * If used on window, returns the viewport's (window) height+ * See core docs on height() to see what happens when used on an element.+ *+ * @example $("#testdiv").height()+ * @result 200+ *+ * @example $(document).height()+ * @result 800+ *+ * @example $(window).height()+ * @result 400+ *+ * @name height+ * @type Object+ * @cat Plugins/Dimensions+ */+ height: function() {+ if ( this[0] == window )+ return self.innerHeight ||+ $.boxModel && document.documentElement.clientHeight || + document.body.clientHeight;+ + if ( this[0] == document )+ return Math.max( document.body.scrollHeight, document.body.offsetHeight );+ + return height.apply(this, arguments);+ },+ + /**+ * If used on document, returns the document's width (innerWidth)+ * If used on window, returns the viewport's (window) width+ * See core docs on height() to see what happens when used on an element.+ *+ * @example $("#testdiv").width()+ * @result 200+ *+ * @example $(document).width()+ * @result 800+ *+ * @example $(window).width()+ * @result 400+ *+ * @name width+ * @type Object+ * @cat Plugins/Dimensions+ */+ width: function() {+ if ( this[0] == window )+ return self.innerWidth ||+ $.boxModel && document.documentElement.clientWidth ||+ document.body.clientWidth;++ if ( this[0] == document )+ return Math.max( document.body.scrollWidth, document.body.offsetWidth );++ return width.apply(this, arguments);+ },+ + /**+ * Returns the inner height value (without border) for the first matched element.+ * If used on document, returns the document's height (innerHeight)+ * If used on window, returns the viewport's (window) height+ *+ * @example $("#testdiv").innerHeight()+ * @result 800+ *+ * @name innerHeight+ * @type Number+ * @cat Plugins/Dimensions+ */+ innerHeight: function() {+ return this[0] == window || this[0] == document ?+ this.height() :+ this.is(':visible') ?+ this[0].offsetHeight - num(this, 'borderTopWidth') - num(this, 'borderBottomWidth') :+ this.height() + num(this, 'paddingTop') + num(this, 'paddingBottom');+ },+ + /**+ * Returns the inner width value (without border) for the first matched element.+ * If used on document, returns the document's Width (innerWidth)+ * If used on window, returns the viewport's (window) width+ *+ * @example $("#testdiv").innerWidth()+ * @result 1000+ *+ * @name innerWidth+ * @type Number+ * @cat Plugins/Dimensions+ */+ innerWidth: function() {+ return this[0] == window || this[0] == document ?+ this.width() :+ this.is(':visible') ?+ this[0].offsetWidth - num(this, 'borderLeftWidth') - num(this, 'borderRightWidth') :+ this.width() + num(this, 'paddingLeft') + num(this, 'paddingRight');+ },+ + /**+ * Returns the outer height value (including border) for the first matched element.+ * Cannot be used on document or window.+ *+ * @example $("#testdiv").outerHeight()+ * @result 1000+ *+ * @name outerHeight+ * @type Number+ * @cat Plugins/Dimensions+ */+ outerHeight: function() {+ return this[0] == window || this[0] == document ?+ this.height() :+ this.is(':visible') ?+ this[0].offsetHeight :+ this.height() + num(this,'borderTopWidth') + num(this, 'borderBottomWidth') + num(this, 'paddingTop') + num(this, 'paddingBottom');+ },+ + /**+ * Returns the outer width value (including border) for the first matched element.+ * Cannot be used on document or window.+ *+ * @example $("#testdiv").outerHeight()+ * @result 1000+ *+ * @name outerHeight+ * @type Number+ * @cat Plugins/Dimensions+ */+ outerWidth: function() {+ return this[0] == window || this[0] == document ?+ this.width() :+ this.is(':visible') ?+ this[0].offsetWidth :+ this.width() + num(this, 'borderLeftWidth') + num(this, 'borderRightWidth') + num(this, 'paddingLeft') + num(this, 'paddingRight');+ },+ + /**+ * Returns how many pixels the user has scrolled to the right (scrollLeft).+ * Works on containers with overflow: auto and window/document.+ *+ * @example $("#testdiv").scrollLeft()+ * @result 100+ *+ * @name scrollLeft+ * @type Number+ * @cat Plugins/Dimensions+ */+ /**+ * Sets the scrollLeft property and continues the chain.+ * Works on containers with overflow: auto and window/document.+ *+ * @example $("#testdiv").scrollLeft(10).scrollLeft()+ * @result 10+ *+ * @name scrollLeft+ * @param Number value A positive number representing the desired scrollLeft.+ * @type jQuery+ * @cat Plugins/Dimensions+ */+ scrollLeft: function(val) {+ if ( val != undefined )+ // set the scroll left+ return this.each(function() {+ if (this == window || this == document)+ window.scrollTo( val, $(window).scrollTop() );+ else+ this.scrollLeft = val;+ });+ + // return the scroll left offest in pixels+ if ( this[0] == window || this[0] == document )+ return self.pageXOffset ||+ $.boxModel && document.documentElement.scrollLeft ||+ document.body.scrollLeft;+ + return this[0].scrollLeft;+ },+ + /**+ * Returns how many pixels the user has scrolled to the bottom (scrollTop).+ * Works on containers with overflow: auto and window/document.+ *+ * @example $("#testdiv").scrollTop()+ * @result 100+ *+ * @name scrollTop+ * @type Number+ * @cat Plugins/Dimensions+ */+ /**+ * Sets the scrollTop property and continues the chain.+ * Works on containers with overflow: auto and window/document.+ *+ * @example $("#testdiv").scrollTop(10).scrollTop()+ * @result 10+ *+ * @name scrollTop+ * @param Number value A positive number representing the desired scrollTop.+ * @type jQuery+ * @cat Plugins/Dimensions+ */+ scrollTop: function(val) {+ if ( val != undefined )+ // set the scroll top+ return this.each(function() {+ if (this == window || this == document)+ window.scrollTo( $(window).scrollLeft(), val );+ else+ this.scrollTop = val;+ });+ + // return the scroll top offset in pixels+ if ( this[0] == window || this[0] == document )+ return self.pageYOffset ||+ $.boxModel && document.documentElement.scrollTop ||+ document.body.scrollTop;++ return this[0].scrollTop;+ },+ + /** + * Returns the top and left positioned offset in pixels.+ * The positioned offset is the offset between a positioned+ * parent and the element itself.+ *+ * @example $("#testdiv").position()+ * @result { top: 100, left: 100 }+ * + * @name position+ * @param Map options Optional settings to configure the way the offset is calculated.+ * @option Boolean margin Should the margin of the element be included in the calculations? False by default.+ * @option Boolean border Should the border of the element be included in the calculations? False by default.+ * @option Boolean padding Should the padding of the element be included in the calculations? False by default.+ * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the+ * chain will not be broken and the result will be assigned to this object.+ * @type Object+ * @cat Plugins/Dimensions+ */+ position: function(options, returnObject) {+ var elem = this[0], parent = elem.parentNode, op = elem.offsetParent,+ options = $.extend({ margin: false, border: false, padding: false, scroll: false }, options || {}),+ x = elem.offsetLeft,+ y = elem.offsetTop, + sl = elem.scrollLeft, + st = elem.scrollTop;+ + // Mozilla and IE do not add the border+ if ($.browser.mozilla || $.browser.msie) {+ // add borders to offset+ x += num(elem, 'borderLeftWidth');+ y += num(elem, 'borderTopWidth');+ }++ if ($.browser.mozilla) {+ do {+ // Mozilla does not add the border for a parent that has overflow set to anything but visible+ if ($.browser.mozilla && parent != elem && $.css(parent, 'overflow') != 'visible') {+ x += num(parent, 'borderLeftWidth');+ y += num(parent, 'borderTopWidth');+ }++ if (parent == op) break; // break if we are already at the offestParent+ } while ((parent = parent.parentNode) && (parent.tagName.toLowerCase() != 'body' || parent.tagName.toLowerCase() != 'html'));+ }+ + var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);+ + if (returnObject) { $.extend(returnObject, returnValue); return this; }+ else { return returnValue; }+ },+ + /**+ * Returns the location of the element in pixels from the top left corner of the viewport.+ *+ * For accurate readings make sure to use pixel values for margins, borders and padding.+ * + * Known issues:+ * - Issue: A div positioned relative or static without any content before it and its parent will report an offsetTop of 0 in Safari+ * Workaround: Place content before the relative div ... and set height and width to 0 and overflow to hidden+ *+ * @example $("#testdiv").offset()+ * @result { top: 100, left: 100, scrollTop: 10, scrollLeft: 10 }+ *+ * @example $("#testdiv").offset({ scroll: false })+ * @result { top: 90, left: 90 }+ *+ * @example var offset = {}+ * $("#testdiv").offset({ scroll: false }, offset)+ * @result offset = { top: 90, left: 90 }+ *+ * @name offset+ * @param Map options Optional settings to configure the way the offset is calculated.+ * @option Boolean margin Should the margin of the element be included in the calculations? True by default.+ * @option Boolean border Should the border of the element be included in the calculations? False by default.+ * @option Boolean padding Should the padding of the element be included in the calculations? False by default.+ * @option Boolean scroll Should the scroll offsets of the parent elements be included in the calculations? True by default.+ * When true it adds the totla scroll offets of all parents to the total offset and also adds two properties+ * to the returned object, scrollTop and scrollLeft. + * @options Boolean lite Will use offsetLite instead of offset when set to true. False by default.+ * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the+ * chain will not be broken and the result will be assigned to this object.+ * @type Object+ * @cat Plugins/Dimensions+ */+ offset: function(options, returnObject) {+ var x = 0, y = 0, sl = 0, st = 0,+ elem = this[0], parent = this[0], op, parPos, elemPos = $.css(elem, 'position'),+ mo = $.browser.mozilla, ie = $.browser.msie, sf = $.browser.safari, oa = $.browser.opera,+ absparent = false, relparent = false, + options = $.extend({ margin: true, border: false, padding: false, scroll: true, lite: false }, options || {});+ + // Use offsetLite if lite option is true+ if (options.lite) return this.offsetLite(options, returnObject);+ + if (elem.tagName.toLowerCase() == 'body') {+ // Safari is the only one to get offsetLeft and offsetTop properties of the body "correct"+ // Except they all mess up when the body is positioned absolute or relative+ x = elem.offsetLeft;+ y = elem.offsetTop;+ // Mozilla ignores margin and subtracts border from body element+ if (mo) {+ x += num(elem, 'marginLeft') + (num(elem, 'borderLeftWidth')*2);+ y += num(elem, 'marginTop') + (num(elem, 'borderTopWidth') *2);+ } else+ // Opera ignores margin+ if (oa) {+ x += num(elem, 'marginLeft');+ y += num(elem, 'marginTop');+ } else+ // IE does not add the border in Standards Mode+ if (ie && jQuery.boxModel) {+ x += num(elem, 'borderLeftWidth');+ y += num(elem, 'borderTopWidth');+ }+ } else {+ do {+ parPos = $.css(parent, 'position');+ + x += parent.offsetLeft;+ y += parent.offsetTop;++ // Mozilla and IE do not add the border+ if (mo || ie) {+ // add borders to offset+ x += num(parent, 'borderLeftWidth');+ y += num(parent, 'borderTopWidth');++ // Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent+ if (mo && parPos == 'absolute') absparent = true;+ // IE does not include the border on the body if an element is position static and without an absolute or relative parent+ if (ie && parPos == 'relative') relparent = true;+ }++ op = parent.offsetParent;+ if (options.scroll || mo) {+ do {+ if (options.scroll) {+ // get scroll offsets+ sl += parent.scrollLeft;+ st += parent.scrollTop;+ }+ + // Mozilla does not add the border for a parent that has overflow set to anything but visible+ if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {+ x += num(parent, 'borderLeftWidth');+ y += num(parent, 'borderTopWidth');+ }+ + parent = parent.parentNode;+ } while (parent != op);+ }+ parent = op;++ if(!parent) break;++ if (parent.tagName.toLowerCase() == 'body' || parent.tagName.toLowerCase() == 'html') {+ // Safari and IE Standards Mode doesn't add the body margin for elments positioned with static or relative+ if ((sf || (ie && $.boxModel)) && elemPos != 'absolute' && elemPos != 'fixed') {+ x += num(parent, 'marginLeft');+ y += num(parent, 'marginTop');+ }+ // Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent+ // IE does not include the border on the body if an element is positioned static and without an absolute or relative parent+ if ( (mo && !absparent && elemPos != 'fixed') || + (ie && elemPos == 'static' && !relparent) ) {+ x += num(parent, 'borderLeftWidth');+ y += num(parent, 'borderTopWidth');+ }+ break; // Exit the loop+ }+ } while (parent);+ }++ var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);++ if (returnObject) { $.extend(returnObject, returnValue); return this; }+ else { return returnValue; }+ },+ + /**+ * Returns the location of the element in pixels from the top left corner of the viewport.+ * This method is much faster than offset but not as accurate. This method can be invoked+ * by setting the lite option to true in the offset method.+ *+ * @name offsetLite+ * @param Map options Optional settings to configure the way the offset is calculated.+ * @option Boolean margin Should the margin of the element be included in the calculations? True by default.+ * @option Boolean border Should the border of the element be included in the calculations? False by default.+ * @option Boolean padding Should the padding of the element be included in the calculations? False by default.+ * @option Boolean scroll Should the scroll offsets of the parent elements be included in the calculations? True by default.+ * When true it adds the totla scroll offets of all parents to the total offset and also adds two properties+ * to the returned object, scrollTop and scrollLeft. + * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the+ * chain will not be broken and the result will be assigned to this object.+ * @type Object+ * @cat Plugins/Dimensions+ */+ offsetLite: function(options, returnObject) {+ var x = 0, y = 0, sl = 0, st = 0, parent = this[0], op, + options = $.extend({ margin: true, border: false, padding: false, scroll: true }, options || {});+ + do {+ x += parent.offsetLeft;+ y += parent.offsetTop;++ op = parent.offsetParent;+ if (options.scroll) {+ // get scroll offsets+ do {+ sl += parent.scrollLeft;+ st += parent.scrollTop;+ parent = parent.parentNode;+ } while(parent != op);+ }+ parent = op;+ } while (parent && parent.tagName.toLowerCase() != 'body' && parent.tagName.toLowerCase() != 'html');++ var returnValue = handleOffsetReturn(this[0], options, x, y, sl, st);++ if (returnObject) { $.extend(returnObject, returnValue); return this; }+ else { return returnValue; }+ }+});++/**+ * Handles converting a CSS Style into an Integer.+ * @private+ */+var num = function(el, prop) {+ return parseInt($.css(el.jquery?el[0]:el,prop))||0;+};++/**+ * Handles the return value of the offset and offsetLite methods.+ * @private+ */+var handleOffsetReturn = function(elem, options, x, y, sl, st) {+ if ( !options.margin ) {+ x -= num(elem, 'marginLeft');+ y -= num(elem, 'marginTop');+ }++ // Safari and Opera do not add the border for the element+ if ( options.border && ($.browser.safari || $.browser.opera) ) {+ x += num(elem, 'borderLeftWidth');+ y += num(elem, 'borderTopWidth');+ } else if ( !options.border && !($.browser.safari || $.browser.opera) ) {+ x -= num(elem, 'borderLeftWidth');+ y -= num(elem, 'borderTopWidth');+ }++ if ( options.padding ) {+ x += num(elem, 'paddingLeft');+ y += num(elem, 'paddingTop');+ }+ + // do not include scroll offset on the element+ if ( options.scroll ) {+ sl -= elem.scrollLeft;+ st -= elem.scrollTop;+ }++ return options.scroll ? { top: y - st, left: x - sl, scrollTop: st, scrollLeft: sl }+ : { top: y, left: x };+};++})(jQuery);
@@ -0,0 +1,714 @@+/*+ * jQuery UI Effects 1.8.2+ *+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)+ * Dual licensed under the MIT (MIT-LICENSE.txt)+ * and GPL (GPL-LICENSE.txt) licenses.+ *+ * http://docs.jquery.com/UI/Effects/+ */+;jQuery.effects || (function($) {++$.effects = {};++++/******************************************************************************/+/****************************** COLOR ANIMATIONS ******************************/+/******************************************************************************/++// override the animation for color styles+$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',+ 'borderRightColor', 'borderTopColor', 'color', 'outlineColor'],+function(i, attr) {+ $.fx.step[attr] = function(fx) {+ if (!fx.colorInit) {+ fx.start = getColor(fx.elem, attr);+ fx.end = getRGB(fx.end);+ fx.colorInit = true;+ }++ fx.elem.style[attr] = 'rgb(' ++ Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' ++ Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' ++ Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';+ };+});++// Color Conversion functions from highlightFade+// By Blair Mitchelmore+// http://jquery.offput.ca/highlightFade/++// Parse strings looking for color tuples [255,255,255]+function getRGB(color) {+ var result;++ // Check if we're already dealing with an array of colors+ if ( color && color.constructor == Array && color.length == 3 )+ return color;++ // Look for rgb(num,num,num)+ if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))+ return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];++ // Look for rgb(num%,num%,num%)+ if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))+ return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];++ // Look for #a0b1c2+ if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))+ return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];++ // Look for #fff+ if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))+ return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];++ // Look for rgba(0, 0, 0, 0) == transparent in Safari 3+ if (result = /rgba\(0, 0, 0, 0\)/.exec(color))+ return colors['transparent'];++ // Otherwise, we're most likely dealing with a named color+ return colors[$.trim(color).toLowerCase()];+}++function getColor(elem, attr) {+ var color;++ do {+ color = $.curCSS(elem, attr);++ // Keep going until we find an element that has color, or we hit the body+ if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )+ break;++ attr = "backgroundColor";+ } while ( elem = elem.parentNode );++ return getRGB(color);+};++// Some named colors to work with+// From Interface by Stefan Petre+// http://interface.eyecon.ro/++var colors = {+ aqua:[0,255,255],+ azure:[240,255,255],+ beige:[245,245,220],+ black:[0,0,0],+ blue:[0,0,255],+ brown:[165,42,42],+ cyan:[0,255,255],+ darkblue:[0,0,139],+ darkcyan:[0,139,139],+ darkgrey:[169,169,169],+ darkgreen:[0,100,0],+ darkkhaki:[189,183,107],+ darkmagenta:[139,0,139],+ darkolivegreen:[85,107,47],+ darkorange:[255,140,0],+ darkorchid:[153,50,204],+ darkred:[139,0,0],+ darksalmon:[233,150,122],+ darkviolet:[148,0,211],+ fuchsia:[255,0,255],+ gold:[255,215,0],+ green:[0,128,0],+ indigo:[75,0,130],+ khaki:[240,230,140],+ lightblue:[173,216,230],+ lightcyan:[224,255,255],+ lightgreen:[144,238,144],+ lightgrey:[211,211,211],+ lightpink:[255,182,193],+ lightyellow:[255,255,224],+ lime:[0,255,0],+ magenta:[255,0,255],+ maroon:[128,0,0],+ navy:[0,0,128],+ olive:[128,128,0],+ orange:[255,165,0],+ pink:[255,192,203],+ purple:[128,0,128],+ violet:[128,0,128],+ red:[255,0,0],+ silver:[192,192,192],+ white:[255,255,255],+ yellow:[255,255,0],+ transparent: [255,255,255]+};++++/******************************************************************************/+/****************************** CLASS ANIMATIONS ******************************/+/******************************************************************************/++var classAnimationActions = ['add', 'remove', 'toggle'],+ shorthandStyles = {+ border: 1,+ borderBottom: 1,+ borderColor: 1,+ borderLeft: 1,+ borderRight: 1,+ borderTop: 1,+ borderWidth: 1,+ margin: 1,+ padding: 1+ };++function getElementStyles() {+ var style = document.defaultView+ ? document.defaultView.getComputedStyle(this, null)+ : this.currentStyle,+ newStyle = {},+ key,+ camelCase;++ // webkit enumerates style porperties+ if (style && style.length && style[0] && style[style[0]]) {+ var len = style.length;+ while (len--) {+ key = style[len];+ if (typeof style[key] == 'string') {+ camelCase = key.replace(/\-(\w)/g, function(all, letter){+ return letter.toUpperCase();+ });+ newStyle[camelCase] = style[key];+ }+ }+ } else {+ for (key in style) {+ if (typeof style[key] === 'string') {+ newStyle[key] = style[key];+ }+ }+ }+ + return newStyle;+}++function filterStyles(styles) {+ var name, value;+ for (name in styles) {+ value = styles[name];+ if (+ // ignore null and undefined values+ value == null ||+ // ignore functions (when does this occur?)+ $.isFunction(value) ||+ // shorthand styles that need to be expanded+ name in shorthandStyles ||+ // ignore scrollbars (break in IE)+ (/scrollbar/).test(name) ||++ // only colors or values that can be converted to numbers+ (!(/color/i).test(name) && isNaN(parseFloat(value)))+ ) {+ delete styles[name];+ }+ }+ + return styles;+}++function styleDifference(oldStyle, newStyle) {+ var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459+ name;++ for (name in newStyle) {+ if (oldStyle[name] != newStyle[name]) {+ diff[name] = newStyle[name];+ }+ }++ return diff;+}++$.effects.animateClass = function(value, duration, easing, callback) {+ if ($.isFunction(easing)) {+ callback = easing;+ easing = null;+ }++ return this.each(function() {++ var that = $(this),+ originalStyleAttr = that.attr('style') || ' ',+ originalStyle = filterStyles(getElementStyles.call(this)),+ newStyle,+ className = that.attr('className');++ $.each(classAnimationActions, function(i, action) {+ if (value[action]) {+ that[action + 'Class'](value[action]);+ }+ });+ newStyle = filterStyles(getElementStyles.call(this));+ that.attr('className', className);++ that.animate(styleDifference(originalStyle, newStyle), duration, easing, function() {+ $.each(classAnimationActions, function(i, action) {+ if (value[action]) { that[action + 'Class'](value[action]); }+ });+ // work around bug in IE by clearing the cssText before setting it+ if (typeof that.attr('style') == 'object') {+ that.attr('style').cssText = '';+ that.attr('style').cssText = originalStyleAttr;+ } else {+ that.attr('style', originalStyleAttr);+ }+ if (callback) { callback.apply(this, arguments); }+ });+ });+};++$.fn.extend({+ _addClass: $.fn.addClass,+ addClass: function(classNames, speed, easing, callback) {+ return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);+ },++ _removeClass: $.fn.removeClass,+ removeClass: function(classNames,speed,easing,callback) {+ return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);+ },++ _toggleClass: $.fn.toggleClass,+ toggleClass: function(classNames, force, speed, easing, callback) {+ if ( typeof force == "boolean" || force === undefined ) {+ if ( !speed ) {+ // without speed parameter;+ return this._toggleClass(classNames, force);+ } else {+ return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);+ }+ } else {+ // without switch parameter;+ return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);+ }+ },++ switchClass: function(remove,add,speed,easing,callback) {+ return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);+ }+});++++/******************************************************************************/+/*********************************** EFFECTS **********************************/+/******************************************************************************/++$.extend($.effects, {+ version: "1.8.2",++ // Saves a set of properties in a data storage+ save: function(element, set) {+ for(var i=0; i < set.length; i++) {+ if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);+ }+ },++ // Restores a set of previously saved properties from a data storage+ restore: function(element, set) {+ for(var i=0; i < set.length; i++) {+ if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));+ }+ },++ setMode: function(el, mode) {+ if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle+ return mode;+ },++ getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value+ // this should be a little more flexible in the future to handle a string & hash+ var y, x;+ switch (origin[0]) {+ case 'top': y = 0; break;+ case 'middle': y = 0.5; break;+ case 'bottom': y = 1; break;+ default: y = origin[0] / original.height;+ };+ switch (origin[1]) {+ case 'left': x = 0; break;+ case 'center': x = 0.5; break;+ case 'right': x = 1; break;+ default: x = origin[1] / original.width;+ };+ return {x: x, y: y};+ },++ // Wraps the element around a wrapper that copies position properties+ createWrapper: function(element) {++ // if the element is already wrapped, return it+ if (element.parent().is('.ui-effects-wrapper')) {+ return element.parent();+ }++ // wrap the element+ var props = {+ width: element.outerWidth(true),+ height: element.outerHeight(true),+ 'float': element.css('float')+ },+ wrapper = $('<div></div>')+ .addClass('ui-effects-wrapper')+ .css({+ fontSize: '100%',+ background: 'transparent',+ border: 'none',+ margin: 0,+ padding: 0+ });++ element.wrap(wrapper);+ wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element++ // transfer positioning properties to the wrapper+ if (element.css('position') == 'static') {+ wrapper.css({ position: 'relative' });+ element.css({ position: 'relative' });+ } else {+ $.extend(props, {+ position: element.css('position'),+ zIndex: element.css('z-index')+ });+ $.each(['top', 'left', 'bottom', 'right'], function(i, pos) {+ props[pos] = element.css(pos);+ if (isNaN(parseInt(props[pos], 10))) {+ props[pos] = 'auto';+ }+ });+ element.css({position: 'relative', top: 0, left: 0 });+ }++ return wrapper.css(props).show();+ },++ removeWrapper: function(element) {+ if (element.parent().is('.ui-effects-wrapper'))+ return element.parent().replaceWith(element);+ return element;+ },++ setTransition: function(element, list, factor, value) {+ value = value || {};+ $.each(list, function(i, x){+ unit = element.cssUnit(x);+ if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];+ });+ return value;+ }+});+++function _normalizeArguments(effect, options, speed, callback) {+ // shift params for method overloading+ if (typeof effect == 'object') {+ callback = options;+ speed = null;+ options = effect;+ effect = options.effect;+ }+ if ($.isFunction(options)) {+ callback = options;+ speed = null;+ options = {};+ }+ if ($.isFunction(speed)) {+ callback = speed;+ speed = null;+ }+ if (typeof options == 'number' || $.fx.speeds[options]) {+ callback = speed;+ speed = options;+ options = {};+ }++ options = options || {};++ speed = speed || options.duration;+ speed = $.fx.off ? 0 : typeof speed == 'number'+ ? speed : $.fx.speeds[speed] || $.fx.speeds._default;++ callback = callback || options.complete;++ return [effect, options, speed, callback];+}++$.fn.extend({+ effect: function(effect, options, speed, callback) {+ var args = _normalizeArguments.apply(this, arguments),+ // TODO: make effects takes actual parameters instead of a hash+ args2 = {+ options: args[1],+ duration: args[2],+ callback: args[3]+ },+ effectMethod = $.effects[effect];+ + return effectMethod && !$.fx.off ? effectMethod.call(this, args2) : this;+ },++ _show: $.fn.show,+ show: function(speed) {+ if (!speed || typeof speed == 'number' || $.fx.speeds[speed]) {+ return this._show.apply(this, arguments);+ } else {+ var args = _normalizeArguments.apply(this, arguments);+ args[1].mode = 'show';+ return this.effect.apply(this, args);+ }+ },++ _hide: $.fn.hide,+ hide: function(speed) {+ if (!speed || typeof speed == 'number' || $.fx.speeds[speed]) {+ return this._hide.apply(this, arguments);+ } else {+ var args = _normalizeArguments.apply(this, arguments);+ args[1].mode = 'hide';+ return this.effect.apply(this, args);+ }+ },++ // jQuery core overloads toggle and create _toggle+ __toggle: $.fn.toggle,+ toggle: function(speed) {+ if (!speed || typeof speed == 'number' || $.fx.speeds[speed] ||+ typeof speed == 'boolean' || $.isFunction(speed)) {+ return this.__toggle.apply(this, arguments);+ } else {+ var args = _normalizeArguments.apply(this, arguments);+ args[1].mode = 'toggle';+ return this.effect.apply(this, args);+ }+ },++ // helper functions+ cssUnit: function(key) {+ var style = this.css(key), val = [];+ $.each( ['em','px','%','pt'], function(i, unit){+ if(style.indexOf(unit) > 0)+ val = [parseFloat(style), unit];+ });+ return val;+ }+});++++/******************************************************************************/+/*********************************** EASING ***********************************/+/******************************************************************************/++/*+ * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/+ *+ * Uses the built in easing capabilities added In jQuery 1.1+ * to offer multiple easing options+ *+ * TERMS OF USE - jQuery Easing+ *+ * Open source under the BSD License.+ *+ * Copyright 2008 George McGinley Smith+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without modification,+ * are permitted provided that the following conditions are met:+ *+ * Redistributions of source code must retain the above copyright notice, this list of+ * conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright notice, this list+ * of conditions and the following disclaimer in the documentation and/or other materials+ * provided with the distribution.+ *+ * Neither the name of the author nor the names of contributors may be used to endorse+ * or promote products derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED+ * OF THE POSSIBILITY OF SUCH DAMAGE.+ *+*/++// t: current time, b: begInnIng value, c: change In value, d: duration+$.easing.jswing = $.easing.swing;++$.extend($.easing,+{+ def: 'easeOutQuad',+ swing: function (x, t, b, c, d) {+ //alert($.easing.default);+ return $.easing[$.easing.def](x, t, b, c, d);+ },+ easeInQuad: function (x, t, b, c, d) {+ return c*(t/=d)*t + b;+ },+ easeOutQuad: function (x, t, b, c, d) {+ return -c *(t/=d)*(t-2) + b;+ },+ easeInOutQuad: function (x, t, b, c, d) {+ if ((t/=d/2) < 1) return c/2*t*t + b;+ return -c/2 * ((--t)*(t-2) - 1) + b;+ },+ easeInCubic: function (x, t, b, c, d) {+ return c*(t/=d)*t*t + b;+ },+ easeOutCubic: function (x, t, b, c, d) {+ return c*((t=t/d-1)*t*t + 1) + b;+ },+ easeInOutCubic: function (x, t, b, c, d) {+ if ((t/=d/2) < 1) return c/2*t*t*t + b;+ return c/2*((t-=2)*t*t + 2) + b;+ },+ easeInQuart: function (x, t, b, c, d) {+ return c*(t/=d)*t*t*t + b;+ },+ easeOutQuart: function (x, t, b, c, d) {+ return -c * ((t=t/d-1)*t*t*t - 1) + b;+ },+ easeInOutQuart: function (x, t, b, c, d) {+ if ((t/=d/2) < 1) return c/2*t*t*t*t + b;+ return -c/2 * ((t-=2)*t*t*t - 2) + b;+ },+ easeInQuint: function (x, t, b, c, d) {+ return c*(t/=d)*t*t*t*t + b;+ },+ easeOutQuint: function (x, t, b, c, d) {+ return c*((t=t/d-1)*t*t*t*t + 1) + b;+ },+ easeInOutQuint: function (x, t, b, c, d) {+ if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;+ return c/2*((t-=2)*t*t*t*t + 2) + b;+ },+ easeInSine: function (x, t, b, c, d) {+ return -c * Math.cos(t/d * (Math.PI/2)) + c + b;+ },+ easeOutSine: function (x, t, b, c, d) {+ return c * Math.sin(t/d * (Math.PI/2)) + b;+ },+ easeInOutSine: function (x, t, b, c, d) {+ return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;+ },+ easeInExpo: function (x, t, b, c, d) {+ return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;+ },+ easeOutExpo: function (x, t, b, c, d) {+ return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;+ },+ easeInOutExpo: function (x, t, b, c, d) {+ if (t==0) return b;+ if (t==d) return b+c;+ if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;+ return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;+ },+ easeInCirc: function (x, t, b, c, d) {+ return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;+ },+ easeOutCirc: function (x, t, b, c, d) {+ return c * Math.sqrt(1 - (t=t/d-1)*t) + b;+ },+ easeInOutCirc: function (x, t, b, c, d) {+ if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;+ return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;+ },+ easeInElastic: function (x, t, b, c, d) {+ var s=1.70158;var p=0;var a=c;+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;+ if (a < Math.abs(c)) { a=c; var s=p/4; }+ else var s = p/(2*Math.PI) * Math.asin (c/a);+ return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;+ },+ easeOutElastic: function (x, t, b, c, d) {+ var s=1.70158;var p=0;var a=c;+ if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;+ if (a < Math.abs(c)) { a=c; var s=p/4; }+ else var s = p/(2*Math.PI) * Math.asin (c/a);+ return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;+ },+ easeInOutElastic: function (x, t, b, c, d) {+ var s=1.70158;var p=0;var a=c;+ if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);+ if (a < Math.abs(c)) { a=c; var s=p/4; }+ else var s = p/(2*Math.PI) * Math.asin (c/a);+ if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;+ return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;+ },+ easeInBack: function (x, t, b, c, d, s) {+ if (s == undefined) s = 1.70158;+ return c*(t/=d)*t*((s+1)*t - s) + b;+ },+ easeOutBack: function (x, t, b, c, d, s) {+ if (s == undefined) s = 1.70158;+ return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;+ },+ easeInOutBack: function (x, t, b, c, d, s) {+ if (s == undefined) s = 1.70158;+ if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;+ return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;+ },+ easeInBounce: function (x, t, b, c, d) {+ return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;+ },+ easeOutBounce: function (x, t, b, c, d) {+ if ((t/=d) < (1/2.75)) {+ return c*(7.5625*t*t) + b;+ } else if (t < (2/2.75)) {+ return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;+ } else if (t < (2.5/2.75)) {+ return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;+ } else {+ return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;+ }+ },+ easeInOutBounce: function (x, t, b, c, d) {+ if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;+ return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;+ }+});++/*+ *+ * TERMS OF USE - EASING EQUATIONS+ *+ * Open source under the BSD License.+ *+ * Copyright 2001 Robert Penner+ * All rights reserved.+ *+ * Redistribution and use in source and binary forms, with or without modification,+ * are permitted provided that the following conditions are met:+ *+ * Redistributions of source code must retain the above copyright notice, this list of+ * conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright notice, this list+ * of conditions and the following disclaimer in the documentation and/or other materials+ * provided with the distribution.+ *+ * Neither the name of the author nor the names of contributors may be used to endorse+ * or promote products derived from this software without specific prior written permission.+ *+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED+ * OF THE POSSIBILITY OF SUCH DAMAGE.+ *+ */++})(jQuery);
@@ -0,0 +1,216 @@+/*!+ * jQuery UI 1.8.2+ *+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)+ * Dual licensed under the MIT (MIT-LICENSE.txt)+ * and GPL (GPL-LICENSE.txt) licenses.+ *+ * http://docs.jquery.com/UI+ */++(function($) {++// prevent duplicate loading+// this is only a problem because we proxy existing functions+// and we don't want to double proxy them+$.ui = $.ui || {};+if ($.ui.version) {+ return;+}++//Helper functions and ui object+$.extend($.ui, {+ version: "1.8.2",++ // $.ui.plugin is deprecated. Use the proxy pattern instead.+ plugin: {+ add: function(module, option, set) {+ var proto = $.ui[module].prototype;+ for(var i in set) {+ proto.plugins[i] = proto.plugins[i] || [];+ proto.plugins[i].push([option, set[i]]);+ }+ },+ call: function(instance, name, args) {+ var set = instance.plugins[name];+ if(!set || !instance.element[0].parentNode) { return; }++ for (var i = 0; i < set.length; i++) {+ if (instance.options[set[i][0]]) {+ set[i][1].apply(instance.element, args);+ }+ }+ }+ },++ contains: function(a, b) {+ return document.compareDocumentPosition+ ? a.compareDocumentPosition(b) & 16+ : a !== b && a.contains(b);+ },++ hasScroll: function(el, a) {++ //If overflow is hidden, the element might have extra content, but the user wants to hide it+ if ($(el).css('overflow') == 'hidden') { return false; }++ var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',+ has = false;++ if (el[scroll] > 0) { return true; }++ // TODO: determine which cases actually cause this to happen+ // if the element doesn't have the scroll set, see if it's possible to+ // set the scroll+ el[scroll] = 1;+ has = (el[scroll] > 0);+ el[scroll] = 0;+ return has;+ },++ isOverAxis: function(x, reference, size) {+ //Determines when x coordinate is over "b" element axis+ return (x > reference) && (x < (reference + size));+ },++ isOver: function(y, x, top, left, height, width) {+ //Determines when x, y coordinates is over "b" element+ return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);+ },++ keyCode: {+ ALT: 18,+ BACKSPACE: 8,+ CAPS_LOCK: 20,+ COMMA: 188,+ COMMAND: 91,+ COMMAND_LEFT: 91, // COMMAND+ COMMAND_RIGHT: 93,+ CONTROL: 17,+ DELETE: 46,+ DOWN: 40,+ END: 35,+ ENTER: 13,+ ESCAPE: 27,+ HOME: 36,+ INSERT: 45,+ LEFT: 37,+ MENU: 93, // COMMAND_RIGHT+ NUMPAD_ADD: 107,+ NUMPAD_DECIMAL: 110,+ NUMPAD_DIVIDE: 111,+ NUMPAD_ENTER: 108,+ NUMPAD_MULTIPLY: 106,+ NUMPAD_SUBTRACT: 109,+ PAGE_DOWN: 34,+ PAGE_UP: 33,+ PERIOD: 190,+ RIGHT: 39,+ SHIFT: 16,+ SPACE: 32,+ TAB: 9,+ UP: 38,+ WINDOWS: 91 // COMMAND+ }+});++//jQuery plugins+$.fn.extend({+ _focus: $.fn.focus,+ focus: function(delay, fn) {+ return typeof delay === 'number'+ ? this.each(function() {+ var elem = this;+ setTimeout(function() {+ $(elem).focus();+ (fn && fn.call(elem));+ }, delay);+ })+ : this._focus.apply(this, arguments);+ },+ + enableSelection: function() {+ return this+ .attr('unselectable', 'off')+ .css('MozUserSelect', '');+ },++ disableSelection: function() {+ return this+ .attr('unselectable', 'on')+ .css('MozUserSelect', 'none');+ },++ scrollParent: function() {+ var scrollParent;+ if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {+ scrollParent = this.parents().filter(function() {+ return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));+ }).eq(0);+ } else {+ scrollParent = this.parents().filter(function() {+ return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));+ }).eq(0);+ }++ return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;+ },++ zIndex: function(zIndex) {+ if (zIndex !== undefined) {+ return this.css('zIndex', zIndex);+ }+ + if (this.length) {+ var elem = $(this[0]), position, value;+ while (elem.length && elem[0] !== document) {+ // Ignore z-index if position is set to a value where z-index is ignored by the browser+ // This makes behavior of this function consistent across browsers+ // WebKit always returns auto if the element is positioned+ position = elem.css('position');+ if (position == 'absolute' || position == 'relative' || position == 'fixed')+ {+ // IE returns 0 when zIndex is not specified+ // other browsers return a string+ // we ignore the case of nested elements with an explicit value of 0+ // <div style="z-index: -10;"><div style="z-index: 0;"></div></div>+ value = parseInt(elem.css('zIndex'));+ if (!isNaN(value) && value != 0) {+ return value;+ }+ }+ elem = elem.parent();+ }+ }++ return 0;+ }+});+++//Additional selectors+$.extend($.expr[':'], {+ data: function(elem, i, match) {+ return !!$.data(elem, match[3]);+ },++ focusable: function(element) {+ var nodeName = element.nodeName.toLowerCase(),+ tabIndex = $.attr(element, 'tabindex');+ return (/input|select|textarea|button|object/.test(nodeName)+ ? !element.disabled+ : 'a' == nodeName || 'area' == nodeName+ ? element.href || !isNaN(tabIndex)+ : !isNaN(tabIndex))+ // the element and all of its ancestors must be visible+ // the browser may report that the area is hidden+ && !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;+ },++ tabbable: function(element) {+ var tabIndex = $.attr(element, 'tabindex');+ return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');+ }+});++})(jQuery);
@@ -0,0 +1,797 @@+/*+ * jQuery UI Draggable 1.8.2+ *+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)+ * Dual licensed under the MIT (MIT-LICENSE.txt)+ * and GPL (GPL-LICENSE.txt) licenses.+ *+ * http://docs.jquery.com/UI/Draggables+ *+ * Depends:+ * jquery.ui.core.js+ * jquery.ui.mouse.js+ * jquery.ui.widget.js+ */+(function($) {++$.widget("ui.draggable", $.ui.mouse, {+ widgetEventPrefix: "drag",+ options: {+ addClasses: true,+ appendTo: "parent",+ axis: false,+ connectToSortable: false,+ containment: false,+ cursor: "auto",+ cursorAt: false,+ grid: false,+ handle: false,+ helper: "original",+ iframeFix: false,+ opacity: false,+ refreshPositions: false,+ revert: false,+ revertDuration: 500,+ scope: "default",+ scroll: true,+ scrollSensitivity: 20,+ scrollSpeed: 20,+ snap: false,+ snapMode: "both",+ snapTolerance: 20,+ stack: false,+ zIndex: false+ },+ _create: function() {++ if (this.options.helper == 'original' && !(/^(?:r|a|f)/).test(this.element.css("position")))+ this.element[0].style.position = 'relative';++ (this.options.addClasses && this.element.addClass("ui-draggable"));+ (this.options.disabled && this.element.addClass("ui-draggable-disabled"));++ this._mouseInit();++ },++ destroy: function() {+ if(!this.element.data('draggable')) return;+ this.element+ .removeData("draggable")+ .unbind(".draggable")+ .removeClass("ui-draggable"+ + " ui-draggable-dragging"+ + " ui-draggable-disabled");+ this._mouseDestroy();++ return this;+ },++ _mouseCapture: function(event) {++ var o = this.options;++ // among others, prevent a drag on a resizable-handle+ if (this.helper || o.disabled || $(event.target).is('.ui-resizable-handle'))+ return false;++ //Quit if we're not on a valid handle+ this.handle = this._getHandle(event);+ if (!this.handle)+ return false;++ return true;++ },++ _mouseStart: function(event) {++ var o = this.options;++ //Create and append the visible helper+ this.helper = this._createHelper(event);++ //Cache the helper size+ this._cacheHelperProportions();++ //If ddmanager is used for droppables, set the global draggable+ if($.ui.ddmanager)+ $.ui.ddmanager.current = this;++ /*+ * - Position generation -+ * This block generates everything position related - it's the core of draggables.+ */++ //Cache the margins of the original element+ this._cacheMargins();++ //Store the helper's css position+ this.cssPosition = this.helper.css("position");+ this.scrollParent = this.helper.scrollParent();++ //The element's absolute position on the page minus margins+ this.offset = this.positionAbs = this.element.offset();+ this.offset = {+ top: this.offset.top - this.margins.top,+ left: this.offset.left - this.margins.left+ };++ $.extend(this.offset, {+ click: { //Where the click happened, relative to the element+ left: event.pageX - this.offset.left,+ top: event.pageY - this.offset.top+ },+ parent: this._getParentOffset(),+ relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper+ });++ //Generate the original position+ this.originalPosition = this.position = this._generatePosition(event);+ this.originalPageX = event.pageX;+ this.originalPageY = event.pageY;++ //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied+ (o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));++ //Set a containment if given in the options+ if(o.containment)+ this._setContainment();++ //Trigger event + callbacks+ if(this._trigger("start", event) === false) {+ this._clear();+ return false;+ }++ //Recache the helper size+ this._cacheHelperProportions();++ //Prepare the droppable offsets+ if ($.ui.ddmanager && !o.dropBehaviour)+ $.ui.ddmanager.prepareOffsets(this, event);++ this.helper.addClass("ui-draggable-dragging");+ this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position+ return true;+ },++ _mouseDrag: function(event, noPropagation) {++ //Compute the helpers position+ this.position = this._generatePosition(event);+ this.positionAbs = this._convertPositionTo("absolute");++ //Call plugins and callbacks and use the resulting position if something is returned+ if (!noPropagation) {+ var ui = this._uiHash();+ if(this._trigger('drag', event, ui) === false) {+ this._mouseUp({});+ return false;+ }+ this.position = ui.position;+ }++ if(!this.options.axis || this.options.axis != "y") this.helper[0].style.left = this.position.left+'px';+ if(!this.options.axis || this.options.axis != "x") this.helper[0].style.top = this.position.top+'px';+ if($.ui.ddmanager) $.ui.ddmanager.drag(this, event);++ return false;+ },++ _mouseStop: function(event) {++ //If we are using droppables, inform the manager about the drop+ var dropped = false;+ if ($.ui.ddmanager && !this.options.dropBehaviour)+ dropped = $.ui.ddmanager.drop(this, event);++ //if a drop comes from outside (a sortable)+ if(this.dropped) {+ dropped = this.dropped;+ this.dropped = false;+ }+ + //if the original element is removed, don't bother to continue+ if(!this.element[0] || !this.element[0].parentNode)+ return false;++ if((this.options.revert == "invalid" && !dropped) || (this.options.revert == "valid" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {+ var self = this;+ $(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {+ if(self._trigger("stop", event) !== false) {+ self._clear();+ }+ });+ } else {+ if(this._trigger("stop", event) !== false) {+ this._clear();+ }+ }++ return false;+ },+ + cancel: function() {+ + if(this.helper.is(".ui-draggable-dragging")) {+ this._mouseUp({});+ } else {+ this._clear();+ }+ + return this;+ + },++ _getHandle: function(event) {++ var handle = !this.options.handle || !$(this.options.handle, this.element).length ? true : false;+ $(this.options.handle, this.element)+ .find("*")+ .andSelf()+ .each(function() {+ if(this == event.target) handle = true;+ });++ return handle;++ },++ _createHelper: function(event) {++ var o = this.options;+ var helper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event])) : (o.helper == 'clone' ? this.element.clone() : this.element);++ if(!helper.parents('body').length)+ helper.appendTo((o.appendTo == 'parent' ? this.element[0].parentNode : o.appendTo));++ if(helper[0] != this.element[0] && !(/(fixed|absolute)/).test(helper.css("position")))+ helper.css("position", "absolute");++ return helper;++ },++ _adjustOffsetFromHelper: function(obj) {+ if (typeof obj == 'string') {+ obj = obj.split(' ');+ }+ if ($.isArray(obj)) {+ obj = {left: +obj[0], top: +obj[1] || 0};+ }+ if ('left' in obj) {+ this.offset.click.left = obj.left + this.margins.left;+ }+ if ('right' in obj) {+ this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;+ }+ if ('top' in obj) {+ this.offset.click.top = obj.top + this.margins.top;+ }+ if ('bottom' in obj) {+ this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;+ }+ },++ _getParentOffset: function() {++ //Get the offsetParent and cache its position+ this.offsetParent = this.helper.offsetParent();+ var po = this.offsetParent.offset();++ // This is a special case where we need to modify a offset calculated on start, since the following happened:+ // 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent+ // 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that+ // the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag+ if(this.cssPosition == 'absolute' && this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) {+ po.left += this.scrollParent.scrollLeft();+ po.top += this.scrollParent.scrollTop();+ }++ if((this.offsetParent[0] == document.body) //This needs to be actually done for all browsers, since pageX/pageY includes this information+ || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() == 'html' && $.browser.msie)) //Ugly IE fix+ po = { top: 0, left: 0 };++ return {+ top: po.top + (parseInt(this.offsetParent.css("borderTopWidth"),10) || 0),+ left: po.left + (parseInt(this.offsetParent.css("borderLeftWidth"),10) || 0)+ };++ },++ _getRelativeOffset: function() {++ if(this.cssPosition == "relative") {+ var p = this.element.position();+ return {+ top: p.top - (parseInt(this.helper.css("top"),10) || 0) + this.scrollParent.scrollTop(),+ left: p.left - (parseInt(this.helper.css("left"),10) || 0) + this.scrollParent.scrollLeft()+ };+ } else {+ return { top: 0, left: 0 };+ }++ },++ _cacheMargins: function() {+ this.margins = {+ left: (parseInt(this.element.css("marginLeft"),10) || 0),+ top: (parseInt(this.element.css("marginTop"),10) || 0)+ };+ },++ _cacheHelperProportions: function() {+ this.helperProportions = {+ width: this.helper.outerWidth(),+ height: this.helper.outerHeight()+ };+ },++ _setContainment: function() {++ var o = this.options;+ if(o.containment == 'parent') o.containment = this.helper[0].parentNode;+ if(o.containment == 'document' || o.containment == 'window') this.containment = [+ 0 - this.offset.relative.left - this.offset.parent.left,+ 0 - this.offset.relative.top - this.offset.parent.top,+ $(o.containment == 'document' ? document : window).width() - this.helperProportions.width - this.margins.left,+ ($(o.containment == 'document' ? document : window).height() || document.body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top+ ];++ if(!(/^(document|window|parent)$/).test(o.containment) && o.containment.constructor != Array) {+ var ce = $(o.containment)[0]; if(!ce) return;+ var co = $(o.containment).offset();+ var over = ($(ce).css("overflow") != 'hidden');++ this.containment = [+ co.left + (parseInt($(ce).css("borderLeftWidth"),10) || 0) + (parseInt($(ce).css("paddingLeft"),10) || 0) - this.margins.left,+ co.top + (parseInt($(ce).css("borderTopWidth"),10) || 0) + (parseInt($(ce).css("paddingTop"),10) || 0) - this.margins.top,+ co.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css("borderLeftWidth"),10) || 0) - (parseInt($(ce).css("paddingRight"),10) || 0) - this.helperProportions.width - this.margins.left,+ co.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css("borderTopWidth"),10) || 0) - (parseInt($(ce).css("paddingBottom"),10) || 0) - this.helperProportions.height - this.margins.top+ ];+ } else if(o.containment.constructor == Array) {+ this.containment = o.containment;+ }++ },++ _convertPositionTo: function(d, pos) {++ if(!pos) pos = this.position;+ var mod = d == "absolute" ? 1 : -1;+ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);++ return {+ top: (+ pos.top // The absolute mouse position+ + this.offset.relative.top * mod // Only for relative positioned nodes: Relative offset from element to offset parent+ + this.offset.parent.top * mod // The offsetParent's offset without borders (offset + border)+ - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)+ ),+ left: (+ pos.left // The absolute mouse position+ + this.offset.relative.left * mod // Only for relative positioned nodes: Relative offset from element to offset parent+ + this.offset.parent.left * mod // The offsetParent's offset without borders (offset + border)+ - ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)+ )+ };++ },++ _generatePosition: function(event) {++ var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);+ var pageX = event.pageX;+ var pageY = event.pageY;++ /*+ * - Position constraining -+ * Constrain the position to a mix of grid, containment.+ */++ if(this.originalPosition) { //If we are not dragging yet, we won't check for options++ if(this.containment) {+ if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;+ if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;+ if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;+ if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;+ }++ if(o.grid) {+ var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];+ pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;++ var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];+ pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;+ }++ }++ return {+ top: (+ pageY // The absolute mouse position+ - this.offset.click.top // Click offset (relative to the element)+ - this.offset.relative.top // Only for relative positioned nodes: Relative offset from element to offset parent+ - this.offset.parent.top // The offsetParent's offset without borders (offset + border)+ + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))+ ),+ left: (+ pageX // The absolute mouse position+ - this.offset.click.left // Click offset (relative to the element)+ - this.offset.relative.left // Only for relative positioned nodes: Relative offset from element to offset parent+ - this.offset.parent.left // The offsetParent's offset without borders (offset + border)+ + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))+ )+ };++ },++ _clear: function() {+ this.helper.removeClass("ui-draggable-dragging");+ if(this.helper[0] != this.element[0] && !this.cancelHelperRemoval) this.helper.remove();+ //if($.ui.ddmanager) $.ui.ddmanager.current = null;+ this.helper = null;+ this.cancelHelperRemoval = false;+ },++ // From now on bulk stuff - mainly helpers++ _trigger: function(type, event, ui) {+ ui = ui || this._uiHash();+ $.ui.plugin.call(this, type, [event, ui]);+ if(type == "drag") this.positionAbs = this._convertPositionTo("absolute"); //The absolute position has to be recalculated after plugins+ return $.Widget.prototype._trigger.call(this, type, event, ui);+ },++ plugins: {},++ _uiHash: function(event) {+ return {+ helper: this.helper,+ position: this.position,+ originalPosition: this.originalPosition,+ offset: this.positionAbs+ };+ }++});++$.extend($.ui.draggable, {+ version: "1.8.2"+});++$.ui.plugin.add("draggable", "connectToSortable", {+ start: function(event, ui) {++ var inst = $(this).data("draggable"), o = inst.options,+ uiSortable = $.extend({}, ui, { item: inst.element });+ inst.sortables = [];+ $(o.connectToSortable).each(function() {+ var sortable = $.data(this, 'sortable');+ if (sortable && !sortable.options.disabled) {+ inst.sortables.push({+ instance: sortable,+ shouldRevert: sortable.options.revert+ });+ sortable._refreshItems(); //Do a one-time refresh at start to refresh the containerCache+ sortable._trigger("activate", event, uiSortable);+ }+ });++ },+ stop: function(event, ui) {++ //If we are still over the sortable, we fake the stop event of the sortable, but also remove helper+ var inst = $(this).data("draggable"),+ uiSortable = $.extend({}, ui, { item: inst.element });++ $.each(inst.sortables, function() {+ if(this.instance.isOver) {++ this.instance.isOver = 0;++ inst.cancelHelperRemoval = true; //Don't remove the helper in the draggable instance+ this.instance.cancelHelperRemoval = false; //Remove it in the sortable instance (so sortable plugins like revert still work)++ //The sortable revert is supported, and we have to set a temporary dropped variable on the draggable to support revert: 'valid/invalid'+ if(this.shouldRevert) this.instance.options.revert = true;++ //Trigger the stop of the sortable+ this.instance._mouseStop(event);++ this.instance.options.helper = this.instance.options._helper;++ //If the helper has been the original item, restore properties in the sortable+ if(inst.options.helper == 'original')+ this.instance.currentItem.css({ top: 'auto', left: 'auto' });++ } else {+ this.instance.cancelHelperRemoval = false; //Remove the helper in the sortable instance+ this.instance._trigger("deactivate", event, uiSortable);+ }++ });++ },+ drag: function(event, ui) {++ var inst = $(this).data("draggable"), self = this;++ var checkPos = function(o) {+ var dyClick = this.offset.click.top, dxClick = this.offset.click.left;+ var helperTop = this.positionAbs.top, helperLeft = this.positionAbs.left;+ var itemHeight = o.height, itemWidth = o.width;+ var itemTop = o.top, itemLeft = o.left;++ return $.ui.isOver(helperTop + dyClick, helperLeft + dxClick, itemTop, itemLeft, itemHeight, itemWidth);+ };++ $.each(inst.sortables, function(i) {+ + //Copy over some variables to allow calling the sortable's native _intersectsWith+ this.instance.positionAbs = inst.positionAbs;+ this.instance.helperProportions = inst.helperProportions;+ this.instance.offset.click = inst.offset.click;+ + if(this.instance._intersectsWith(this.instance.containerCache)) {++ //If it intersects, we use a little isOver variable and set it once, so our move-in stuff gets fired only once+ if(!this.instance.isOver) {++ this.instance.isOver = 1;+ //Now we fake the start of dragging for the sortable instance,+ //by cloning the list group item, appending it to the sortable and using it as inst.currentItem+ //We can then fire the start event of the sortable with our passed browser event, and our own helper (so it doesn't create a new one)+ this.instance.currentItem = $(self).clone().appendTo(this.instance.element).data("sortable-item", true);+ this.instance.options._helper = this.instance.options.helper; //Store helper option to later restore it+ this.instance.options.helper = function() { return ui.helper[0]; };++ event.target = this.instance.currentItem[0];+ this.instance._mouseCapture(event, true);+ this.instance._mouseStart(event, true, true);++ //Because the browser event is way off the new appended portlet, we modify a couple of variables to reflect the changes+ this.instance.offset.click.top = inst.offset.click.top;+ this.instance.offset.click.left = inst.offset.click.left;+ this.instance.offset.parent.left -= inst.offset.parent.left - this.instance.offset.parent.left;+ this.instance.offset.parent.top -= inst.offset.parent.top - this.instance.offset.parent.top;++ inst._trigger("toSortable", event);+ inst.dropped = this.instance.element; //draggable revert needs that+ //hack so receive/update callbacks work (mostly)+ inst.currentItem = inst.element;+ this.instance.fromOutside = inst;++ }++ //Provided we did all the previous steps, we can fire the drag event of the sortable on every draggable drag, when it intersects with the sortable+ if(this.instance.currentItem) this.instance._mouseDrag(event);++ } else {++ //If it doesn't intersect with the sortable, and it intersected before,+ //we fake the drag stop of the sortable, but make sure it doesn't remove the helper by using cancelHelperRemoval+ if(this.instance.isOver) {++ this.instance.isOver = 0;+ this.instance.cancelHelperRemoval = true;+ + //Prevent reverting on this forced stop+ this.instance.options.revert = false;+ + // The out event needs to be triggered independently+ this.instance._trigger('out', event, this.instance._uiHash(this.instance));+ + this.instance._mouseStop(event, true);+ this.instance.options.helper = this.instance.options._helper;++ //Now we remove our currentItem, the list group clone again, and the placeholder, and animate the helper back to it's original size+ this.instance.currentItem.remove();+ if(this.instance.placeholder) this.instance.placeholder.remove();++ inst._trigger("fromSortable", event);+ inst.dropped = false; //draggable revert needs that+ }++ };++ });++ }+});++$.ui.plugin.add("draggable", "cursor", {+ start: function(event, ui) {+ var t = $('body'), o = $(this).data('draggable').options;+ if (t.css("cursor")) o._cursor = t.css("cursor");+ t.css("cursor", o.cursor);+ },+ stop: function(event, ui) {+ var o = $(this).data('draggable').options;+ if (o._cursor) $('body').css("cursor", o._cursor);+ }+});++$.ui.plugin.add("draggable", "iframeFix", {+ start: function(event, ui) {+ var o = $(this).data('draggable').options;+ $(o.iframeFix === true ? "iframe" : o.iframeFix).each(function() {+ $('<div class="ui-draggable-iframeFix" style="background: #fff;"></div>')+ .css({+ width: this.offsetWidth+"px", height: this.offsetHeight+"px",+ position: "absolute", opacity: "0.001", zIndex: 1000+ })+ .css($(this).offset())+ .appendTo("body");+ });+ },+ stop: function(event, ui) {+ $("div.ui-draggable-iframeFix").each(function() { this.parentNode.removeChild(this); }); //Remove frame helpers+ }+});++$.ui.plugin.add("draggable", "opacity", {+ start: function(event, ui) {+ var t = $(ui.helper), o = $(this).data('draggable').options;+ if(t.css("opacity")) o._opacity = t.css("opacity");+ t.css('opacity', o.opacity);+ },+ stop: function(event, ui) {+ var o = $(this).data('draggable').options;+ if(o._opacity) $(ui.helper).css('opacity', o._opacity);+ }+});++$.ui.plugin.add("draggable", "scroll", {+ start: function(event, ui) {+ var i = $(this).data("draggable");+ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') i.overflowOffset = i.scrollParent.offset();+ },+ drag: function(event, ui) {++ var i = $(this).data("draggable"), o = i.options, scrolled = false;++ if(i.scrollParent[0] != document && i.scrollParent[0].tagName != 'HTML') {++ if(!o.axis || o.axis != 'x') {+ if((i.overflowOffset.top + i.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity)+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop + o.scrollSpeed;+ else if(event.pageY - i.overflowOffset.top < o.scrollSensitivity)+ i.scrollParent[0].scrollTop = scrolled = i.scrollParent[0].scrollTop - o.scrollSpeed;+ }++ if(!o.axis || o.axis != 'y') {+ if((i.overflowOffset.left + i.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity)+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft + o.scrollSpeed;+ else if(event.pageX - i.overflowOffset.left < o.scrollSensitivity)+ i.scrollParent[0].scrollLeft = scrolled = i.scrollParent[0].scrollLeft - o.scrollSpeed;+ }++ } else {++ if(!o.axis || o.axis != 'x') {+ if(event.pageY - $(document).scrollTop() < o.scrollSensitivity)+ scrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);+ else if($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity)+ scrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);+ }++ if(!o.axis || o.axis != 'y') {+ if(event.pageX - $(document).scrollLeft() < o.scrollSensitivity)+ scrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);+ else if($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity)+ scrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);+ }++ }++ if(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour)+ $.ui.ddmanager.prepareOffsets(i, event);++ }+});++$.ui.plugin.add("draggable", "snap", {+ start: function(event, ui) {++ var i = $(this).data("draggable"), o = i.options;+ i.snapElements = [];++ $(o.snap.constructor != String ? ( o.snap.items || ':data(draggable)' ) : o.snap).each(function() {+ var $t = $(this); var $o = $t.offset();+ if(this != i.element[0]) i.snapElements.push({+ item: this,+ width: $t.outerWidth(), height: $t.outerHeight(),+ top: $o.top, left: $o.left+ });+ });++ },+ drag: function(event, ui) {++ var inst = $(this).data("draggable"), o = inst.options;+ var d = o.snapTolerance;++ var x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,+ y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;++ for (var i = inst.snapElements.length - 1; i >= 0; i--){++ var l = inst.snapElements[i].left, r = l + inst.snapElements[i].width,+ t = inst.snapElements[i].top, b = t + inst.snapElements[i].height;++ //Yes, I know, this is insane ;)+ if(!((l-d < x1 && x1 < r+d && t-d < y1 && y1 < b+d) || (l-d < x1 && x1 < r+d && t-d < y2 && y2 < b+d) || (l-d < x2 && x2 < r+d && t-d < y1 && y1 < b+d) || (l-d < x2 && x2 < r+d && t-d < y2 && y2 < b+d))) {+ if(inst.snapElements[i].snapping) (inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));+ inst.snapElements[i].snapping = false;+ continue;+ }++ if(o.snapMode != 'inner') {+ var ts = Math.abs(t - y2) <= d;+ var bs = Math.abs(b - y1) <= d;+ var ls = Math.abs(l - x2) <= d;+ var rs = Math.abs(r - x1) <= d;+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t - inst.helperProportions.height, left: 0 }).top - inst.margins.top;+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b, left: 0 }).top - inst.margins.top;+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l - inst.helperProportions.width }).left - inst.margins.left;+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r }).left - inst.margins.left;+ }++ var first = (ts || bs || ls || rs);++ if(o.snapMode != 'outer') {+ var ts = Math.abs(t - y1) <= d;+ var bs = Math.abs(b - y2) <= d;+ var ls = Math.abs(l - x1) <= d;+ var rs = Math.abs(r - x2) <= d;+ if(ts) ui.position.top = inst._convertPositionTo("relative", { top: t, left: 0 }).top - inst.margins.top;+ if(bs) ui.position.top = inst._convertPositionTo("relative", { top: b - inst.helperProportions.height, left: 0 }).top - inst.margins.top;+ if(ls) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: l }).left - inst.margins.left;+ if(rs) ui.position.left = inst._convertPositionTo("relative", { top: 0, left: r - inst.helperProportions.width }).left - inst.margins.left;+ }++ if(!inst.snapElements[i].snapping && (ts || bs || ls || rs || first))+ (inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));+ inst.snapElements[i].snapping = (ts || bs || ls || rs || first);++ };++ }+});++$.ui.plugin.add("draggable", "stack", {+ start: function(event, ui) {++ var o = $(this).data("draggable").options;++ var group = $.makeArray($(o.stack)).sort(function(a,b) {+ return (parseInt($(a).css("zIndex"),10) || 0) - (parseInt($(b).css("zIndex"),10) || 0);+ });+ if (!group.length) { return; }+ + var min = parseInt(group[0].style.zIndex) || 0;+ $(group).each(function(i) {+ this.style.zIndex = min + i;+ });++ this[0].style.zIndex = min + group.length;++ }+});++$.ui.plugin.add("draggable", "zIndex", {+ start: function(event, ui) {+ var t = $(ui.helper), o = $(this).data("draggable").options;+ if(t.css("zIndex")) o._zIndex = t.css("zIndex");+ t.css('zIndex', o.zIndex);+ },+ stop: function(event, ui) {+ var o = $(this).data("draggable").options;+ if(o._zIndex) $(ui.helper).css('zIndex', o._zIndex);+ }+});++})(jQuery);
@@ -0,0 +1,151 @@+/*!+ * jQuery UI Mouse 1.8.2+ *+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)+ * Dual licensed under the MIT (MIT-LICENSE.txt)+ * and GPL (GPL-LICENSE.txt) licenses.+ *+ * http://docs.jquery.com/UI/Mouse+ *+ * Depends:+ * jquery.ui.widget.js+ */+(function($) {++$.widget("ui.mouse", {+ options: {+ cancel: ':input,option',+ distance: 1,+ delay: 0+ },+ _mouseInit: function() {+ var self = this;++ this.element+ .bind('mousedown.'+this.widgetName, function(event) {+ return self._mouseDown(event);+ })+ .bind('click.'+this.widgetName, function(event) {+ if(self._preventClickEvent) {+ self._preventClickEvent = false;+ event.stopImmediatePropagation();+ return false;+ }+ });++ this.started = false;+ },++ // TODO: make sure destroying one instance of mouse doesn't mess with+ // other instances of mouse+ _mouseDestroy: function() {+ this.element.unbind('.'+this.widgetName);+ },++ _mouseDown: function(event) {+ // don't let more than one widget handle mouseStart+ // TODO: figure out why we have to use originalEvent+ event.originalEvent = event.originalEvent || {};+ if (event.originalEvent.mouseHandled) { return; }++ // we may have missed mouseup (out of window)+ (this._mouseStarted && this._mouseUp(event));++ this._mouseDownEvent = event;++ var self = this,+ btnIsLeft = (event.which == 1),+ elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);+ if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {+ return true;+ }++ this.mouseDelayMet = !this.options.delay;+ if (!this.mouseDelayMet) {+ this._mouseDelayTimer = setTimeout(function() {+ self.mouseDelayMet = true;+ }, this.options.delay);+ }++ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {+ this._mouseStarted = (this._mouseStart(event) !== false);+ if (!this._mouseStarted) {+ event.preventDefault();+ return true;+ }+ }++ // these delegates are required to keep context+ this._mouseMoveDelegate = function(event) {+ return self._mouseMove(event);+ };+ this._mouseUpDelegate = function(event) {+ return self._mouseUp(event);+ };+ $(document)+ .bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)+ .bind('mouseup.'+this.widgetName, this._mouseUpDelegate);++ // preventDefault() is used to prevent the selection of text here -+ // however, in Safari, this causes select boxes not to be selectable+ // anymore, so this fix is needed+ ($.browser.safari || event.preventDefault());++ event.originalEvent.mouseHandled = true;+ return true;+ },++ _mouseMove: function(event) {+ // IE mouseup check - mouseup happened when mouse was out of window+ if ($.browser.msie && !event.button) {+ return this._mouseUp(event);+ }++ if (this._mouseStarted) {+ this._mouseDrag(event);+ return event.preventDefault();+ }++ if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {+ this._mouseStarted =+ (this._mouseStart(this._mouseDownEvent, event) !== false);+ (this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));+ }++ return !this._mouseStarted;+ },++ _mouseUp: function(event) {+ $(document)+ .unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)+ .unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);++ if (this._mouseStarted) {+ this._mouseStarted = false;+ this._preventClickEvent = (event.target == this._mouseDownEvent.target);+ this._mouseStop(event);+ }++ return false;+ },++ _mouseDistanceMet: function(event) {+ return (Math.max(+ Math.abs(this._mouseDownEvent.pageX - event.pageX),+ Math.abs(this._mouseDownEvent.pageY - event.pageY)+ ) >= this.options.distance+ );+ },++ _mouseDelayMet: function(event) {+ return this.mouseDelayMet;+ },++ // These are placeholder methods, to be overriden by extending plugin+ _mouseStart: function(event) {},+ _mouseDrag: function(event) {},+ _mouseStop: function(event) {},+ _mouseCapture: function(event) { return true; }+});++})(jQuery);
@@ -0,0 +1,729 @@+/*+ * jQuery UI Tabs 1.8.2+ *+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)+ * Dual licensed under the MIT (MIT-LICENSE.txt)+ * and GPL (GPL-LICENSE.txt) licenses.+ *+ * http://docs.jquery.com/UI/Tabs+ *+ * Depends:+ * jquery.ui.core.js+ * jquery.ui.widget.js+ */+(function($) {++var tabId = 0,+ listId = 0;++function getNextTabId() {+ return ++tabId;+}++function getNextListId() {+ return ++listId;+}++$.widget("ui.tabs", {+ options: {+ add: null,+ ajaxOptions: null,+ cache: false,+ cookie: null, // e.g. { expires: 7, path: '/', domain: 'jquery.com', secure: true }+ collapsible: false,+ disable: null,+ disabled: [],+ enable: null,+ event: 'click',+ fx: null, // e.g. { height: 'toggle', opacity: 'toggle', duration: 200 }+ idPrefix: 'ui-tabs-',+ load: null,+ panelTemplate: '<div></div>',+ remove: null,+ select: null,+ show: null,+ spinner: '<em>Loading…</em>',+ tabTemplate: '<li><a href="#{href}"><span>#{label}</span></a></li>'+ },+ _create: function() {+ this._tabify(true);+ },++ _setOption: function(key, value) {+ if (key == 'selected') {+ if (this.options.collapsible && value == this.options.selected) {+ return;+ }+ this.select(value);+ }+ else {+ this.options[key] = value;+ this._tabify();+ }+ },++ _tabId: function(a) {+ return a.title && a.title.replace(/\s/g, '_').replace(/[^A-Za-z0-9\-_:\.]/g, '') ||+ this.options.idPrefix + getNextTabId();+ },++ _sanitizeSelector: function(hash) {+ return hash.replace(/:/g, '\\:'); // we need this because an id may contain a ":"+ },++ _cookie: function() {+ var cookie = this.cookie || (this.cookie = this.options.cookie.name || 'ui-tabs-' + getNextListId());+ return $.cookie.apply(null, [cookie].concat($.makeArray(arguments)));+ },++ _ui: function(tab, panel) {+ return {+ tab: tab,+ panel: panel,+ index: this.anchors.index(tab)+ };+ },++ _cleanup: function() {+ // restore all former loading tabs labels+ this.lis.filter('.ui-state-processing').removeClass('ui-state-processing')+ .find('span:data(label.tabs)')+ .each(function() {+ var el = $(this);+ el.html(el.data('label.tabs')).removeData('label.tabs');+ });+ },++ _tabify: function(init) {++ this.list = this.element.find('ol,ul').eq(0);+ this.lis = $('li:has(a[href])', this.list);+ this.anchors = this.lis.map(function() { return $('a', this)[0]; });+ this.panels = $([]);++ var self = this, o = this.options;++ var fragmentId = /^#.+/; // Safari 2 reports '#' for an empty hash+ this.anchors.each(function(i, a) {+ var href = $(a).attr('href');++ // For dynamically created HTML that contains a hash as href IE < 8 expands+ // such href to the full page url with hash and then misinterprets tab as ajax.+ // Same consideration applies for an added tab with a fragment identifier+ // since a[href=#fragment-identifier] does unexpectedly not match.+ // Thus normalize href attribute...+ var hrefBase = href.split('#')[0], baseEl;+ if (hrefBase && (hrefBase === location.toString().split('#')[0] ||+ (baseEl = $('base')[0]) && hrefBase === baseEl.href)) {+ href = a.hash;+ a.href = href;+ }++ // inline tab+ if (fragmentId.test(href)) {+ self.panels = self.panels.add(self._sanitizeSelector(href));+ }++ // remote tab+ else if (href != '#') { // prevent loading the page itself if href is just "#"+ $.data(a, 'href.tabs', href); // required for restore on destroy++ // TODO until #3808 is fixed strip fragment identifier from url+ // (IE fails to load from such url)+ $.data(a, 'load.tabs', href.replace(/#.*$/, '')); // mutable data++ var id = self._tabId(a);+ a.href = '#' + id;+ var $panel = $('#' + id);+ if (!$panel.length) {+ $panel = $(o.panelTemplate).attr('id', id).addClass('ui-tabs-panel ui-widget-content ui-corner-bottom')+ .insertAfter(self.panels[i - 1] || self.list);+ $panel.data('destroy.tabs', true);+ }+ self.panels = self.panels.add($panel);+ }++ // invalid tab href+ else {+ o.disabled.push(i);+ }+ });++ // initialization from scratch+ if (init) {++ // attach necessary classes for styling+ this.element.addClass('ui-tabs ui-widget ui-widget-content ui-corner-all');+ this.list.addClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all');+ this.lis.addClass('ui-state-default ui-corner-top');+ this.panels.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom');++ // Selected tab+ // use "selected" option or try to retrieve:+ // 1. from fragment identifier in url+ // 2. from cookie+ // 3. from selected class attribute on <li>+ if (o.selected === undefined) {+ if (location.hash) {+ this.anchors.each(function(i, a) {+ if (a.hash == location.hash) {+ o.selected = i;+ return false; // break+ }+ });+ }+ if (typeof o.selected != 'number' && o.cookie) {+ o.selected = parseInt(self._cookie(), 10);+ }+ if (typeof o.selected != 'number' && this.lis.filter('.ui-tabs-selected').length) {+ o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected'));+ }+ o.selected = o.selected || (this.lis.length ? 0 : -1);+ }+ else if (o.selected === null) { // usage of null is deprecated, TODO remove in next release+ o.selected = -1;+ }++ // sanity check - default to first tab...+ o.selected = ((o.selected >= 0 && this.anchors[o.selected]) || o.selected < 0) ? o.selected : 0;++ // Take disabling tabs via class attribute from HTML+ // into account and update option properly.+ // A selected tab cannot become disabled.+ o.disabled = $.unique(o.disabled.concat(+ $.map(this.lis.filter('.ui-state-disabled'),+ function(n, i) { return self.lis.index(n); } )+ )).sort();++ if ($.inArray(o.selected, o.disabled) != -1) {+ o.disabled.splice($.inArray(o.selected, o.disabled), 1);+ }++ // highlight selected tab+ this.panels.addClass('ui-tabs-hide');+ this.lis.removeClass('ui-tabs-selected ui-state-active');+ if (o.selected >= 0 && this.anchors.length) { // check for length avoids error when initializing empty list+ this.panels.eq(o.selected).removeClass('ui-tabs-hide');+ this.lis.eq(o.selected).addClass('ui-tabs-selected ui-state-active');++ // seems to be expected behavior that the show callback is fired+ self.element.queue("tabs", function() {+ self._trigger('show', null, self._ui(self.anchors[o.selected], self.panels[o.selected]));+ });+ + this.load(o.selected);+ }++ // clean up to avoid memory leaks in certain versions of IE 6+ $(window).bind('unload', function() {+ self.lis.add(self.anchors).unbind('.tabs');+ self.lis = self.anchors = self.panels = null;+ });++ }+ // update selected after add/remove+ else {+ o.selected = this.lis.index(this.lis.filter('.ui-tabs-selected'));+ }++ // update collapsible+ this.element[o.collapsible ? 'addClass' : 'removeClass']('ui-tabs-collapsible');++ // set or update cookie after init and add/remove respectively+ if (o.cookie) {+ this._cookie(o.selected, o.cookie);+ }++ // disable tabs+ for (var i = 0, li; (li = this.lis[i]); i++) {+ $(li)[$.inArray(i, o.disabled) != -1 &&+ !$(li).hasClass('ui-tabs-selected') ? 'addClass' : 'removeClass']('ui-state-disabled');+ }++ // reset cache if switching from cached to not cached+ if (o.cache === false) {+ this.anchors.removeData('cache.tabs');+ }++ // remove all handlers before, tabify may run on existing tabs after add or option change+ this.lis.add(this.anchors).unbind('.tabs');++ if (o.event != 'mouseover') {+ var addState = function(state, el) {+ if (el.is(':not(.ui-state-disabled)')) {+ el.addClass('ui-state-' + state);+ }+ };+ var removeState = function(state, el) {+ el.removeClass('ui-state-' + state);+ };+ this.lis.bind('mouseover.tabs', function() {+ addState('hover', $(this));+ });+ this.lis.bind('mouseout.tabs', function() {+ removeState('hover', $(this));+ });+ this.anchors.bind('focus.tabs', function() {+ addState('focus', $(this).closest('li'));+ });+ this.anchors.bind('blur.tabs', function() {+ removeState('focus', $(this).closest('li'));+ });+ }++ // set up animations+ var hideFx, showFx;+ if (o.fx) {+ if ($.isArray(o.fx)) {+ hideFx = o.fx[0];+ showFx = o.fx[1];+ }+ else {+ hideFx = showFx = o.fx;+ }+ }++ // Reset certain styles left over from animation+ // and prevent IE's ClearType bug...+ function resetStyle($el, fx) {+ $el.css({ display: '' });+ if (!$.support.opacity && fx.opacity) {+ $el[0].style.removeAttribute('filter');+ }+ }++ // Show a tab...+ var showTab = showFx ?+ function(clicked, $show) {+ $(clicked).closest('li').addClass('ui-tabs-selected ui-state-active');+ $show.hide().removeClass('ui-tabs-hide') // avoid flicker that way+ .animate(showFx, showFx.duration || 'normal', function() {+ resetStyle($show, showFx);+ self._trigger('show', null, self._ui(clicked, $show[0]));+ });+ } :+ function(clicked, $show) {+ $(clicked).closest('li').addClass('ui-tabs-selected ui-state-active');+ $show.removeClass('ui-tabs-hide');+ self._trigger('show', null, self._ui(clicked, $show[0]));+ };++ // Hide a tab, $show is optional...+ var hideTab = hideFx ?+ function(clicked, $hide) {+ $hide.animate(hideFx, hideFx.duration || 'normal', function() {+ self.lis.removeClass('ui-tabs-selected ui-state-active');+ $hide.addClass('ui-tabs-hide');+ resetStyle($hide, hideFx);+ self.element.dequeue("tabs");+ });+ } :+ function(clicked, $hide, $show) {+ self.lis.removeClass('ui-tabs-selected ui-state-active');+ $hide.addClass('ui-tabs-hide');+ self.element.dequeue("tabs");+ };++ // attach tab event handler, unbind to avoid duplicates from former tabifying...+ this.anchors.bind(o.event + '.tabs', function() {+ var el = this, $li = $(this).closest('li'), $hide = self.panels.filter(':not(.ui-tabs-hide)'),+ $show = $(self._sanitizeSelector(this.hash));++ // If tab is already selected and not collapsible or tab disabled or+ // or is already loading or click callback returns false stop here.+ // Check if click handler returns false last so that it is not executed+ // for a disabled or loading tab!+ if (($li.hasClass('ui-tabs-selected') && !o.collapsible) ||+ $li.hasClass('ui-state-disabled') ||+ $li.hasClass('ui-state-processing') ||+ self._trigger('select', null, self._ui(this, $show[0])) === false) {+ this.blur();+ return false;+ }++ o.selected = self.anchors.index(this);++ self.abort();++ // if tab may be closed+ if (o.collapsible) {+ if ($li.hasClass('ui-tabs-selected')) {+ o.selected = -1;++ if (o.cookie) {+ self._cookie(o.selected, o.cookie);+ }++ self.element.queue("tabs", function() {+ hideTab(el, $hide);+ }).dequeue("tabs");+ + this.blur();+ return false;+ }+ else if (!$hide.length) {+ if (o.cookie) {+ self._cookie(o.selected, o.cookie);+ }+ + self.element.queue("tabs", function() {+ showTab(el, $show);+ });++ self.load(self.anchors.index(this)); // TODO make passing in node possible, see also http://dev.jqueryui.com/ticket/3171+ + this.blur();+ return false;+ }+ }++ if (o.cookie) {+ self._cookie(o.selected, o.cookie);+ }++ // show new tab+ if ($show.length) {+ if ($hide.length) {+ self.element.queue("tabs", function() {+ hideTab(el, $hide);+ });+ }+ self.element.queue("tabs", function() {+ showTab(el, $show);+ });+ + self.load(self.anchors.index(this));+ }+ else {+ throw 'jQuery UI Tabs: Mismatching fragment identifier.';+ }++ // Prevent IE from keeping other link focussed when using the back button+ // and remove dotted border from clicked link. This is controlled via CSS+ // in modern browsers; blur() removes focus from address bar in Firefox+ // which can become a usability and annoying problem with tabs('rotate').+ if ($.browser.msie) {+ this.blur();+ }++ });++ // disable click in any case+ this.anchors.bind('click.tabs', function(){return false;});++ },++ destroy: function() {+ var o = this.options;++ this.abort();+ + this.element.unbind('.tabs')+ .removeClass('ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible')+ .removeData('tabs');++ this.list.removeClass('ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all');++ this.anchors.each(function() {+ var href = $.data(this, 'href.tabs');+ if (href) {+ this.href = href;+ }+ var $this = $(this).unbind('.tabs');+ $.each(['href', 'load', 'cache'], function(i, prefix) {+ $this.removeData(prefix + '.tabs');+ });+ });++ this.lis.unbind('.tabs').add(this.panels).each(function() {+ if ($.data(this, 'destroy.tabs')) {+ $(this).remove();+ }+ else {+ $(this).removeClass([+ 'ui-state-default',+ 'ui-corner-top',+ 'ui-tabs-selected',+ 'ui-state-active',+ 'ui-state-hover',+ 'ui-state-focus',+ 'ui-state-disabled',+ 'ui-tabs-panel',+ 'ui-widget-content',+ 'ui-corner-bottom',+ 'ui-tabs-hide'+ ].join(' '));+ }+ });++ if (o.cookie) {+ this._cookie(null, o.cookie);+ }++ return this;+ },++ add: function(url, label, index) {+ if (index === undefined) {+ index = this.anchors.length; // append by default+ }++ var self = this, o = this.options,+ $li = $(o.tabTemplate.replace(/#\{href\}/g, url).replace(/#\{label\}/g, label)),+ id = !url.indexOf('#') ? url.replace('#', '') : this._tabId($('a', $li)[0]);++ $li.addClass('ui-state-default ui-corner-top').data('destroy.tabs', true);++ // try to find an existing element before creating a new one+ var $panel = $('#' + id);+ if (!$panel.length) {+ $panel = $(o.panelTemplate).attr('id', id).data('destroy.tabs', true);+ }+ $panel.addClass('ui-tabs-panel ui-widget-content ui-corner-bottom ui-tabs-hide');++ if (index >= this.lis.length) {+ $li.appendTo(this.list);+ $panel.appendTo(this.list[0].parentNode);+ }+ else {+ $li.insertBefore(this.lis[index]);+ $panel.insertBefore(this.panels[index]);+ }++ o.disabled = $.map(o.disabled,+ function(n, i) { return n >= index ? ++n : n; });++ this._tabify();++ if (this.anchors.length == 1) { // after tabify+ o.selected = 0;+ $li.addClass('ui-tabs-selected ui-state-active');+ $panel.removeClass('ui-tabs-hide');+ this.element.queue("tabs", function() {+ self._trigger('show', null, self._ui(self.anchors[0], self.panels[0]));+ });+ + this.load(0);+ }++ // callback+ this._trigger('add', null, this._ui(this.anchors[index], this.panels[index]));+ return this;+ },++ remove: function(index) {+ var o = this.options, $li = this.lis.eq(index).remove(),+ $panel = this.panels.eq(index).remove();++ // If selected tab was removed focus tab to the right or+ // in case the last tab was removed the tab to the left.+ if ($li.hasClass('ui-tabs-selected') && this.anchors.length > 1) {+ this.select(index + (index + 1 < this.anchors.length ? 1 : -1));+ }++ o.disabled = $.map($.grep(o.disabled, function(n, i) { return n != index; }),+ function(n, i) { return n >= index ? --n : n; });++ this._tabify();++ // callback+ this._trigger('remove', null, this._ui($li.find('a')[0], $panel[0]));+ return this;+ },++ enable: function(index) {+ var o = this.options;+ if ($.inArray(index, o.disabled) == -1) {+ return;+ }++ this.lis.eq(index).removeClass('ui-state-disabled');+ o.disabled = $.grep(o.disabled, function(n, i) { return n != index; });++ // callback+ this._trigger('enable', null, this._ui(this.anchors[index], this.panels[index]));+ return this;+ },++ disable: function(index) {+ var self = this, o = this.options;+ if (index != o.selected) { // cannot disable already selected tab+ this.lis.eq(index).addClass('ui-state-disabled');++ o.disabled.push(index);+ o.disabled.sort();++ // callback+ this._trigger('disable', null, this._ui(this.anchors[index], this.panels[index]));+ }++ return this;+ },++ select: function(index) {+ if (typeof index == 'string') {+ index = this.anchors.index(this.anchors.filter('[href$=' + index + ']'));+ }+ else if (index === null) { // usage of null is deprecated, TODO remove in next release+ index = -1;+ }+ if (index == -1 && this.options.collapsible) {+ index = this.options.selected;+ }++ this.anchors.eq(index).trigger(this.options.event + '.tabs');+ return this;+ },++ load: function(index) {+ var self = this, o = this.options, a = this.anchors.eq(index)[0], url = $.data(a, 'load.tabs');++ this.abort();++ // not remote or from cache+ if (!url || this.element.queue("tabs").length !== 0 && $.data(a, 'cache.tabs')) {+ this.element.dequeue("tabs");+ return;+ }++ // load remote from here on+ this.lis.eq(index).addClass('ui-state-processing');++ if (o.spinner) {+ var span = $('span', a);+ span.data('label.tabs', span.html()).html(o.spinner);+ }++ this.xhr = $.ajax($.extend({}, o.ajaxOptions, {+ url: url,+ success: function(r, s) {+ $(self._sanitizeSelector(a.hash)).html(r);++ // take care of tab labels+ self._cleanup();++ if (o.cache) {+ $.data(a, 'cache.tabs', true); // if loaded once do not load them again+ }++ // callbacks+ self._trigger('load', null, self._ui(self.anchors[index], self.panels[index]));+ try {+ o.ajaxOptions.success(r, s);+ }+ catch (e) {}+ },+ error: function(xhr, s, e) {+ // take care of tab labels+ self._cleanup();++ // callbacks+ self._trigger('load', null, self._ui(self.anchors[index], self.panels[index]));+ try {+ // Passing index avoid a race condition when this method is+ // called after the user has selected another tab.+ // Pass the anchor that initiated this request allows+ // loadError to manipulate the tab content panel via $(a.hash)+ o.ajaxOptions.error(xhr, s, index, a);+ }+ catch (e) {}+ }+ }));++ // last, so that load event is fired before show...+ self.element.dequeue("tabs");++ return this;+ },++ abort: function() {+ // stop possibly running animations+ this.element.queue([]);+ this.panels.stop(false, true);++ // "tabs" queue must not contain more than two elements,+ // which are the callbacks for the latest clicked tab...+ this.element.queue("tabs", this.element.queue("tabs").splice(-2, 2));++ // terminate pending requests from other tabs+ if (this.xhr) {+ this.xhr.abort();+ delete this.xhr;+ }++ // take care of tab labels+ this._cleanup();+ return this;+ },++ url: function(index, url) {+ this.anchors.eq(index).removeData('cache.tabs').data('load.tabs', url);+ return this;+ },++ length: function() {+ return this.anchors.length;+ }++});++$.extend($.ui.tabs, {+ version: '1.8.2'+});++/*+ * Tabs Extensions+ */++/*+ * Rotate+ */+$.extend($.ui.tabs.prototype, {+ rotation: null,+ rotate: function(ms, continuing) {++ var self = this, o = this.options;+ + var rotate = self._rotate || (self._rotate = function(e) {+ clearTimeout(self.rotation);+ self.rotation = setTimeout(function() {+ var t = o.selected;+ self.select( ++t < self.anchors.length ? t : 0 );+ }, ms);+ + if (e) {+ e.stopPropagation();+ }+ });+ + var stop = self._unrotate || (self._unrotate = !continuing ?+ function(e) {+ if (e.clientX) { // in case of a true click+ self.rotate(null);+ }+ } :+ function(e) {+ t = o.selected;+ rotate();+ });++ // start rotation+ if (ms) {+ this.element.bind('tabsshow', rotate);+ this.anchors.bind(o.event + '.tabs', stop);+ rotate();+ }+ // stop rotation+ else {+ clearTimeout(self.rotation);+ this.element.unbind('tabsshow', rotate);+ this.anchors.unbind(o.event + '.tabs', stop);+ delete this._rotate;+ delete this._unrotate;+ }++ return this;+ }+});++})(jQuery);
@@ -0,0 +1,236 @@+/*!+ * jQuery UI Widget 1.8.2+ *+ * Copyright (c) 2010 AUTHORS.txt (http://jqueryui.com/about)+ * Dual licensed under the MIT (MIT-LICENSE.txt)+ * and GPL (GPL-LICENSE.txt) licenses.+ *+ * http://docs.jquery.com/UI/Widget+ */+(function( $ ) {++var _remove = $.fn.remove;++$.fn.remove = function( selector, keepData ) {+ return this.each(function() {+ if ( !keepData ) {+ if ( !selector || $.filter( selector, [ this ] ).length ) {+ $( "*", this ).add( this ).each(function() {+ $( this ).triggerHandler( "remove" );+ });+ }+ }+ return _remove.call( $(this), selector, keepData );+ });+};++$.widget = function( name, base, prototype ) {+ var namespace = name.split( "." )[ 0 ],+ fullName;+ name = name.split( "." )[ 1 ];+ fullName = namespace + "-" + name;++ if ( !prototype ) {+ prototype = base;+ base = $.Widget;+ }++ // create selector for plugin+ $.expr[ ":" ][ fullName ] = function( elem ) {+ return !!$.data( elem, name );+ };++ $[ namespace ] = $[ namespace ] || {};+ $[ namespace ][ name ] = function( options, element ) {+ // allow instantiation without initializing for simple inheritance+ if ( arguments.length ) {+ this._createWidget( options, element );+ }+ };++ var basePrototype = new base();+ // we need to make the options hash a property directly on the new instance+ // otherwise we'll modify the options hash on the prototype that we're+ // inheriting from+// $.each( basePrototype, function( key, val ) {+// if ( $.isPlainObject(val) ) {+// basePrototype[ key ] = $.extend( {}, val );+// }+// });+ basePrototype.options = $.extend( {}, basePrototype.options );+ $[ namespace ][ name ].prototype = $.extend( true, basePrototype, {+ namespace: namespace,+ widgetName: name,+ widgetEventPrefix: $[ namespace ][ name ].prototype.widgetEventPrefix || name,+ widgetBaseClass: fullName+ }, prototype );++ $.widget.bridge( name, $[ namespace ][ name ] );+};++$.widget.bridge = function( name, object ) {+ $.fn[ name ] = function( options ) {+ var isMethodCall = typeof options === "string",+ args = Array.prototype.slice.call( arguments, 1 ),+ returnValue = this;++ // allow multiple hashes to be passed on init+ options = !isMethodCall && args.length ?+ $.extend.apply( null, [ true, options ].concat(args) ) :+ options;++ // prevent calls to internal methods+ if ( isMethodCall && options.substring( 0, 1 ) === "_" ) {+ return returnValue;+ }++ if ( isMethodCall ) {+ this.each(function() {+ var instance = $.data( this, name ),+ methodValue = instance && $.isFunction( instance[options] ) ?+ instance[ options ].apply( instance, args ) :+ instance;+ if ( methodValue !== instance && methodValue !== undefined ) {+ returnValue = methodValue;+ return false;+ }+ });+ } else {+ this.each(function() {+ var instance = $.data( this, name );+ if ( instance ) {+ if ( options ) {+ instance.option( options );+ }+ instance._init();+ } else {+ $.data( this, name, new object( options, this ) );+ }+ });+ }++ return returnValue;+ };+};++$.Widget = function( options, element ) {+ // allow instantiation without initializing for simple inheritance+ if ( arguments.length ) {+ this._createWidget( options, element );+ }+};++$.Widget.prototype = {+ widgetName: "widget",+ widgetEventPrefix: "",+ options: {+ disabled: false+ },+ _createWidget: function( options, element ) {+ // $.widget.bridge stores the plugin instance, but we do it anyway+ // so that it's stored even before the _create function runs+ this.element = $( element ).data( this.widgetName, this );+ this.options = $.extend( true, {},+ this.options,+ $.metadata && $.metadata.get( element )[ this.widgetName ],+ options );++ var self = this;+ this.element.bind( "remove." + this.widgetName, function() {+ self.destroy();+ });++ this._create();+ this._init();+ },+ _create: function() {},+ _init: function() {},++ destroy: function() {+ this.element+ .unbind( "." + this.widgetName )+ .removeData( this.widgetName );+ this.widget()+ .unbind( "." + this.widgetName )+ .removeAttr( "aria-disabled" )+ .removeClass(+ this.widgetBaseClass + "-disabled " ++ "ui-state-disabled" );+ },++ widget: function() {+ return this.element;+ },++ option: function( key, value ) {+ var options = key,+ self = this;++ if ( arguments.length === 0 ) {+ // don't return a reference to the internal hash+ return $.extend( {}, self.options );+ }++ if (typeof key === "string" ) {+ if ( value === undefined ) {+ return this.options[ key ];+ }+ options = {};+ options[ key ] = value;+ }++ $.each( options, function( key, value ) {+ self._setOption( key, value );+ });++ return self;+ },+ _setOption: function( key, value ) {+ this.options[ key ] = value;++ if ( key === "disabled" ) {+ this.widget()+ [ value ? "addClass" : "removeClass"](+ this.widgetBaseClass + "-disabled" + " " ++ "ui-state-disabled" )+ .attr( "aria-disabled", value );+ }++ return this;+ },++ enable: function() {+ return this._setOption( "disabled", false );+ },+ disable: function() {+ return this._setOption( "disabled", true );+ },++ _trigger: function( type, event, data ) {+ var callback = this.options[ type ];++ event = $.Event( event );+ event.type = ( type === this.widgetEventPrefix ?+ type :+ this.widgetEventPrefix + type ).toLowerCase();+ data = data || {};++ // copy original event properties over to the new event+ // this would happen if we could call $.event.fix instead of $.Event+ // but we don't have a way to force an event to be fixed multiple times+ if ( event.originalEvent ) {+ for ( var i = $.event.props.length, prop; i; ) {+ prop = $.event.props[ --i ];+ event[ prop ] = event.originalEvent[ prop ];+ }+ }++ this.element.trigger( event, data );++ return !( $.isFunction(callback) &&+ callback.call( this.element[0], event, data ) === false ||+ event.isDefaultPrevented() );+ }+};++})( jQuery );
@@ -0,0 +1,579 @@+{-# OPTIONS -fglasgow-exts -cpp #-}+{-# LINE 1 "src/Scyther/Theory/Lexer.x" #-}++{-# OPTIONS_GHC -fno-warn-name-shadowing -fno-warn-unused-matches -fno-warn-unused-binds -fno-warn-missing-signatures #-}+module Scyther.Theory.Lexer where+++#if __GLASGOW_HASKELL__ >= 603+#include "ghcconfig.h"+#elif defined(__GLASGOW_HASKELL__)+#include "config.h"+#endif+#if __GLASGOW_HASKELL__ >= 503+import Data.Array+import Data.Char (ord)+import Data.Array.Base (unsafeAt)+#else+import Array+import Char (ord)+#endif+#if __GLASGOW_HASKELL__ >= 503+import GHC.Exts+#else+import GlaExts+#endif+alex_base :: AlexAddr+alex_base = AlexA# "\x01\x00\x00\x00\xdb\x00\x00\x00\x28\x00\x00\x00\x2d\x00\x00\x00\x38\x00\x00\x00\x39\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2a\x01\x00\x00\xfa\x01\x00\x00\xca\x02\x00\x00\x9a\x03\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x6a\x04\x00\x00\x3a\x05\x00\x00\x0a\x06\x00\x00\xda\x06\x00\x00\xaa\x07\x00\x00\x7a\x08\x00\x00\x4a\x09\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x1a\x0a\x00\x00\xea\x0a\x00\x00\xba\x0b\x00\x00\x8a\x0c\x00\x00\x5a\x0d\x00\x00\x2a\x0e\x00\x00\xfa\x0e\x00\x00\xca\x0f\x00\x00\x9a\x10\x00\x00\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x11\x00\x00\xcf\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3a\x12\x00\x00\x00\x00\x00\x00\xc8\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x0a\x13\x00\x00\xda\x13\x00\x00\xaa\x14\x00\x00"#++alex_table :: AlexAddr+alex_table = AlexA# "\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x03\x00\xff\xff\x40\x00\x46\x00\x45\x00\xff\xff\x4b\x00\x3f\x00\x08\x00\x3a\x00\x47\x00\x50\x00\x39\x00\x4f\x00\x4d\x00\x06\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x44\x00\xff\xff\x48\x00\x43\x00\x49\x00\x4a\x00\xff\xff\xff\xff\xff\xff\x0d\x00\x07\x00\x09\x00\x0e\x00\x03\x00\x04\x00\x2d\x00\x13\x00\x19\x00\x03\x00\x22\x00\x2f\x00\x37\x00\x53\x00\x32\x00\x52\x00\x54\x00\x00\x00\x55\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3b\x00\xff\xff\x3c\x00\x42\x00\x4e\x00\xff\xff\x00\x00\x00\x00\x00\x00\x51\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x1a\x00\x14\x00\x33\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3d\x00\x4c\x00\x3e\x00\x41\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\x00\x00\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x0a\x00\x11\x00\x0c\x00\x11\x00\x11\x00\x11\x00\x11\x00\x0f\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x12\x00\x11\x00\x11\x00\x11\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x15\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x16\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x17\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x1b\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x23\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x1c\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x1d\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x1e\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x1f\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x20\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x24\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x25\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x26\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x27\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x28\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x29\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x2a\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x2b\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x35\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00"#++alex_check :: AlexAddr+alex_check = AlexA# "\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x0a\x00\x0a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x20\x00\x2f\x00\x2a\x00\x2a\x00\x2a\x00\x20\x00\x2a\x00\x80\x00\x88\x00\x3e\x00\x83\x00\x2d\x00\x2d\x00\xff\xff\x2d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\xff\xff\xff\xff\xff\xff\x3e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x29\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2f\x00\x73\x00\x74\x00\xa7\x00\xa8\x00\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\x7d\x00\xff\xff\xc2\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd7\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe2\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf7\x00\xff\xff\xff\xff\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x88\x00\x89\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xac\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00"#++alex_deflt :: AlexAddr+alex_deflt = AlexA# "\x56\x00\xff\xff\xff\xff\xff\xff\x05\x00\x05\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#++alex_accept = listArray (0::Int,88) [[],[],[],[(AlexAccSkip)],[(AlexAccSkip)],[(AlexAccSkip)],[],[(AlexAcc (alex_action_2))],[(AlexAcc (alex_action_21))],[(AlexAcc (alex_action_3))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_4))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_5))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_7))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_9))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[],[(AlexAcc (alex_action_10))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[],[(AlexAcc (alex_action_11))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[],[(AlexAcc (alex_action_12))],[(AlexAcc (alex_action_13))],[(AlexAcc (alex_action_14))],[(AlexAcc (alex_action_49))],[],[(AlexAcc (alex_action_15))],[(AlexAcc (alex_action_16))],[(AlexAcc (alex_action_17))],[(AlexAcc (alex_action_18))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_19))],[],[(AlexAcc (alex_action_20))],[(AlexAcc (alex_action_22))],[(AlexAcc (alex_action_23))],[(AlexAcc (alex_action_24))],[(AlexAcc (alex_action_25))],[(AlexAcc (alex_action_26))],[(AlexAcc (alex_action_27))],[(AlexAcc (alex_action_28))],[(AlexAcc (alex_action_29))],[(AlexAcc (alex_action_30))],[(AlexAcc (alex_action_31))],[(AlexAcc (alex_action_32))],[(AlexAcc (alex_action_33))],[(AlexAcc (alex_action_34))],[(AlexAcc (alex_action_35))],[(AlexAcc (alex_action_36))],[(AlexAcc (alex_action_37))],[(AlexAcc (alex_action_38))],[(AlexAcc (alex_action_39))],[(AlexAcc (alex_action_40))],[(AlexAcc (alex_action_41))],[(AlexAcc (alex_action_42))],[(AlexAcc (alex_action_43))],[(AlexAcc (alex_action_44))],[(AlexAcc (alex_action_45))],[(AlexAcc (alex_action_46))],[(AlexAcc (alex_action_47))],[],[(AlexAcc (alex_action_48))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))]]+{-# LINE 75 "src/Scyther/Theory/Lexer.x" #-}+++-- | Lex a keyword+keyword :: Keyword -> AlexAction Keyword+keyword kw input len = return kw++-- | Lex an identifier+scanIdent :: AlexAction Keyword+scanIdent (_,_,input) len = return $ IDENT (take len input)++{-+-- | Scan a string until EOF is encountered.+alexScanTokens :: String -> Either String [Keyword]+alexScanTokens inp = runAlex inp gather+ where+ gather = do+ t <- alexMonadScan+ case trace (show t) t of+ EOF -> return [EOF]+ _ -> (t:) `liftM` gather++-- | Scan a file.+scanFile f = do+ inp <- readFile f+ return $ alexScanTokens inp+-}++-- | Lexable Keywords+data Keyword =+ IDENT String+ | SQUOTE+ | DQUOTE+ | RIGHTARROW+ | LEFTARROW+ | LONGRIGHTARROW+ | LONGLEFTARROW+ | COMMA+ | DOT+ | COLON+ | QUESTIONMARK+ | AND+ | MID+ | DOLLAR+ | SHARP+ | LPAREN+ | RPAREN+ | LBRACKET+ | RBRACKET+ | LBRACE + | RBRACE+ | TILDE+ | HAT+ | STAR+ | UNDERSCORE+ | MINUS+ | PLUS+ | EQUAL+ | LESS+ | GREATER+ | EOF+ | FORALL+ | EXISTS+ | LAND+ | LOR+ | LNOT+ | APPROX+ -- dummy keyword to get rid of overlapping pattern matches+ | DUMMY_KEYWORD+ deriving( Eq )++instance Show Keyword where+ show kw = case kw of + IDENT i -> identifier i+ SQUOTE -> symbol "'"+ DQUOTE -> symbol "\""+ RIGHTARROW -> symbol "->"+ LEFTARROW -> symbol "<-"+ LONGRIGHTARROW -> symbol "-->"+ LONGLEFTARROW -> symbol "<--"+ COMMA -> symbol ","+ DOT -> symbol "."+ COLON -> symbol ":"+ QUESTIONMARK -> symbol "?"+ AND -> symbol "&"+ MID -> symbol "|"+ DOLLAR -> symbol "$"+ SHARP -> symbol "#"+ LPAREN -> symbol "("+ RPAREN -> symbol ")"+ LBRACKET -> symbol "["+ RBRACKET -> symbol "]"+ LBRACE -> symbol "{"+ RBRACE -> symbol "}"+ TILDE -> symbol "~"+ HAT -> symbol "^"+ STAR -> symbol "*"+ UNDERSCORE -> symbol "_"+ MINUS -> symbol "-"+ PLUS -> symbol "+"+ EQUAL -> symbol "="+ LESS -> symbol "<"+ GREATER -> symbol ">"+ EOF -> "end of file"+ FORALL -> symbol "∀" + EXISTS -> symbol "∃" + LAND -> symbol "∧" + LOR -> symbol "∨" + LNOT -> symbol "¬" + APPROX -> symbol "≈" + DUMMY_KEYWORD -> "DUMMY_KEYWORD (this should not occur!)"+ where+ identifier i = "identifier `" ++ i ++ "'"+ symbol s = "symbol `" ++ s ++ "'"+ keyword s = "keyword `" ++ s ++ "'"++-- -----------------------------------------------------------------------------+-- Alex wrapper code.+--+-- This code is in the PUBLIC DOMAIN; you may copy it freely and use+-- it for any purpose whatsoever.++-- -----------------------------------------------------------------------------+-- The input type+++type AlexInput = (AlexPosn, -- current position,+ Char, -- previous char+ String) -- current input string++alexInputPrevChar :: AlexInput -> Char+alexInputPrevChar (p,c,s) = c++alexGetChar :: AlexInput -> Maybe (Char,AlexInput)+alexGetChar (p,c,[]) = Nothing+alexGetChar (p,_,(c:s)) = let p' = alexMove p c in p' `seq`+ Just (c, (p', c, s))+++-- -----------------------------------------------------------------------------+-- Token positions++-- `Posn' records the location of a token in the input text. It has three+-- fields: the address (number of chacaters preceding the token), line number+-- and column of a token within the file. `start_pos' gives the position of the+-- start of the file and `eof_pos' a standard encoding for the end of file.+-- `move_pos' calculates the new position after traversing a given character,+-- assuming the usual eight character tab stops.++data AlexPosn = AlexPn !Int !Int !Int+ deriving (Eq)++instance Show AlexPosn where+ show (AlexPn _ l c) = "line "++show l++" column "++show c++alexStartPos :: AlexPosn+alexStartPos = AlexPn 0 1 1++alexMove :: AlexPosn -> Char -> AlexPosn+alexMove (AlexPn a l c) '\t' = AlexPn (a+1) l (((c+7) `div` 8)*8+1)+alexMove (AlexPn a l c) '\n' = AlexPn (a+1) (l+1) 1+alexMove (AlexPn a l c) _ = AlexPn (a+1) l (c+1)+++-- -----------------------------------------------------------------------------+-- Default monad+++data AlexState = AlexState {+ alex_pos :: !AlexPosn, -- position at current input location+ alex_inp :: String, -- the current input+ alex_chr :: !Char, -- the character before the input+ alex_scd :: !Int, -- the current startcode+ alex_ocd :: !Int, -- the old startcode before the comment started+ alex_cmt :: [String] -- stack of begin comment identifiers+ }++-- Compile with -funbox-strict-fields for best results!++runAlex :: String -> Alex a -> Either String a+runAlex input (Alex f) + = case f (AlexState {alex_pos = alexStartPos,+ alex_inp = input, + alex_chr = '\n',+ alex_scd = 0,+ alex_ocd = 0,+ alex_cmt = []+ }) of + Left msg -> Left msg+ Right ( _, a ) -> Right a++newtype Alex a = Alex { unAlex :: AlexState -> Either String (AlexState, a) }++instance Monad Alex where+ m >>= k = Alex $ \s -> case unAlex m s of + Left msg -> Left msg+ Right (s',a) -> unAlex (k a) s'+ return a = Alex $ \s -> Right (s,a)++alexGetPos :: Alex AlexPosn+alexGetPos = Alex $ \s@AlexState{alex_pos=pos} -> Right (s, pos)++alexGetInput :: Alex AlexInput+alexGetInput+ = Alex $ \s@AlexState{alex_pos=pos,alex_chr=c,alex_inp=inp} -> + Right (s, (pos,c,inp))++alexSetInput :: AlexInput -> Alex ()+alexSetInput (pos,c,inp)+ = Alex $ \s -> case s{alex_pos=pos,alex_chr=c,alex_inp=inp} of+ s@(AlexState{}) -> Right (s, ())++alexError :: String -> Alex a+alexError message = Alex $ \s -> Left $ message ++ " in " ++ show (alex_pos s)++alexGetStartCode :: Alex Int+alexGetStartCode = Alex $ \s@AlexState{alex_scd=sc} -> Right (s, sc)++alexSetStartCode :: Int -> Alex ()+alexSetStartCode sc = Alex $ \s -> Right (s{alex_scd=sc}, ())++alexGetOldStartCode :: Alex Int+alexGetOldStartCode = Alex $ \s@AlexState{alex_ocd=sc} -> Right (s, sc)++alexSetOldStartCode :: Int -> Alex ()+alexSetOldStartCode sc = Alex $ \s -> Right (s{alex_ocd=sc}, ())++alexGetComments :: Alex [String]+alexGetComments = Alex $ \s -> Right (s, alex_cmt s)++alexSetComments :: [String] -> Alex ()+alexSetComments cmt = Alex $ \s -> Right (s{alex_cmt=cmt}, ())++alexMonadScan = do+ inp <- alexGetInput+ sc <- alexGetStartCode+ case alexScan inp sc of+ AlexEOF -> alexEOF+ AlexError inp' -> alexError "lexical error"+ AlexSkip inp' len -> do+ alexSetInput inp'+ alexMonadScan+ AlexToken inp' len action -> do+ alexSetInput inp'+ action inp len++-- -----------------------------------------------------------------------------+-- Useful token actions++type AlexAction result = AlexInput -> Int -> Alex result++-- just ignore this token and scan another one+skip :: AlexAction Keyword+skip input len = alexMonadScan++-- ignore this token, but set the start code to a new value+begin :: Int -> AlexAction Keyword+begin code input len = do alexSetStartCode code; alexMonadScan++-- | Begin a comment starting with the given sign.+beginComment :: String -> Int -> AlexAction Keyword+beginComment cmtBegin code input len = do+ cmts <- alexGetComments+ alexSetComments $ cmtBegin : cmts+ if null cmts+ then alexGetStartCode >>= alexSetOldStartCode+ else return ()+ alexSetStartCode code+ alexMonadScan++-- | End a comment that started with the given begin comment sign.+endComment :: String -> AlexAction Keyword+endComment cmtBegin input len = do+ cmts <- alexGetComments+ case cmts of+ [] -> alexError $ "comment ended but no beginning '"++cmtBegin++"' marked."+ (cmt:cmts') -> do+ if cmt == cmtBegin + then do+ alexSetComments cmts'+ if null cmts' + then alexGetOldStartCode >>= alexSetStartCode + else return ()+ else return ()+ alexMonadScan++-- perform an action for this token, and set the start code to a new value+-- andBegin :: AlexAction result -> Int -> AlexAction result+(action `andBegin` code) input len = do alexSetStartCode code; action input len++alexEOF :: Alex Keyword+alexEOF = return EOF++++++comment :: Int+comment = 1+alex_action_2 = beginComment "(*" comment +alex_action_3 = beginComment "(*" comment +alex_action_4 = endComment "(*" +alex_action_5 = beginComment "/*" comment +alex_action_6 = beginComment "/*" comment +alex_action_7 = endComment "/*" +alex_action_8 = skip +alex_action_9 = beginComment "{*" comment +alex_action_10 = beginComment "{*" comment +alex_action_11 = beginComment "{*" comment +alex_action_12 = beginComment "{*" comment +alex_action_13 = endComment "{*" +alex_action_14 = keyword FORALL +alex_action_15 = keyword EXISTS +alex_action_16 = keyword LAND +alex_action_17 = keyword LOR +alex_action_18 = keyword LNOT +alex_action_19 = keyword APPROX +alex_action_20 = keyword COMMA +alex_action_21 = keyword LPAREN +alex_action_22 = keyword RPAREN +alex_action_23 = keyword LBRACKET +alex_action_24 = keyword RBRACKET +alex_action_25 = keyword LBRACE +alex_action_26 = keyword RBRACE +alex_action_27 = keyword SQUOTE +alex_action_28 = keyword DQUOTE +alex_action_29 = keyword TILDE +alex_action_30 = keyword HAT +alex_action_31 = keyword EQUAL +alex_action_32 = keyword COLON +alex_action_33 = keyword DOLLAR +alex_action_34 = keyword SHARP +alex_action_35 = keyword STAR +alex_action_36 = keyword LESS +alex_action_37 = keyword GREATER +alex_action_38 = keyword QUESTIONMARK +alex_action_39 = keyword AND +alex_action_40 = keyword MID +alex_action_41 = keyword DOT +alex_action_42 = keyword UNDERSCORE +alex_action_43 = keyword MINUS +alex_action_44 = keyword PLUS +alex_action_45 = keyword RIGHTARROW +alex_action_46 = keyword LEFTARROW +alex_action_47 = keyword LONGRIGHTARROW +alex_action_48 = keyword LONGLEFTARROW +alex_action_49 = scanIdent +{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "<eingebaut>" #-}+{-# LINE 1 "<Kommandozeile>" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+-- -----------------------------------------------------------------------------+-- ALEX TEMPLATE+--+-- This code is in the PUBLIC DOMAIN; you may copy it freely and use+-- it for any purpose whatsoever.++-- -----------------------------------------------------------------------------+-- INTERNALS and main scanner engine++{-# LINE 35 "templates/GenericTemplate.hs" #-}++{-# LINE 45 "templates/GenericTemplate.hs" #-}+++data AlexAddr = AlexA# Addr#++#if __GLASGOW_HASKELL__ < 503+uncheckedShiftL# = shiftL#+#endif++{-# INLINE alexIndexInt16OffAddr #-}+alexIndexInt16OffAddr (AlexA# arr) off =+#ifdef WORDS_BIGENDIAN+ narrow16Int# i+ where+ i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)+ high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))+ low = int2Word# (ord# (indexCharOffAddr# arr off'))+ off' = off *# 2#+#else+ indexInt16OffAddr# arr off+#endif++++++{-# INLINE alexIndexInt32OffAddr #-}+alexIndexInt32OffAddr (AlexA# arr) off = +#ifdef WORDS_BIGENDIAN+ narrow32Int# i+ where+ i = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#`+ (b2 `uncheckedShiftL#` 16#) `or#`+ (b1 `uncheckedShiftL#` 8#) `or#` b0)+ b3 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#)))+ b2 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#)))+ b1 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))+ b0 = int2Word# (ord# (indexCharOffAddr# arr off'))+ off' = off *# 4#+#else+ indexInt32OffAddr# arr off+#endif++++++#if __GLASGOW_HASKELL__ < 503+quickIndex arr i = arr ! i+#else+-- GHC >= 503, unsafeAt is available from Data.Array.Base.+quickIndex = unsafeAt+#endif+++++-- -----------------------------------------------------------------------------+-- Main lexing routines++data AlexReturn a+ = AlexEOF+ | AlexError !AlexInput+ | AlexSkip !AlexInput !Int+ | AlexToken !AlexInput !Int a++-- alexScan :: AlexInput -> StartCode -> AlexReturn a+alexScan input (I# (sc))+ = alexScanUser undefined input (I# (sc))++alexScanUser user input (I# (sc))+ = case alex_scan_tkn user input 0# input sc AlexNone of+ (AlexNone, input') ->+ case alexGetChar input of+ Nothing -> ++++ AlexEOF+ Just _ ->++++ AlexError input'++ (AlexLastSkip input len, _) ->++++ AlexSkip input len++ (AlexLastAcc k input len, _) ->++++ AlexToken input len k+++-- Push the input through the DFA, remembering the most recent accepting+-- state it encountered.++alex_scan_tkn user orig_input len input s last_acc =+ input `seq` -- strict in the input+ let + new_acc = check_accs (alex_accept `quickIndex` (I# (s)))+ in+ new_acc `seq`+ case alexGetChar input of+ Nothing -> (new_acc, input)+ Just (c, new_input) -> ++++ let+ base = alexIndexInt32OffAddr alex_base s+ (I# (ord_c)) = ord c+ offset = (base +# ord_c)+ check = alexIndexInt16OffAddr alex_check offset+ + new_s = if (offset >=# 0#) && (check ==# ord_c)+ then alexIndexInt16OffAddr alex_table offset+ else alexIndexInt16OffAddr alex_deflt s+ in+ case new_s of + -1# -> (new_acc, input)+ -- on an error, we want to keep the input *before* the+ -- character that failed, not after.+ _ -> alex_scan_tkn user orig_input (len +# 1#) + new_input new_s new_acc++ where+ check_accs [] = last_acc+ check_accs (AlexAcc a : _) = AlexLastAcc a input (I# (len))+ check_accs (AlexAccSkip : _) = AlexLastSkip input (I# (len))+ check_accs (AlexAccPred a pred : rest)+ | pred user orig_input (I# (len)) input+ = AlexLastAcc a input (I# (len))+ check_accs (AlexAccSkipPred pred : rest)+ | pred user orig_input (I# (len)) input+ = AlexLastSkip input (I# (len))+ check_accs (_ : rest) = check_accs rest++data AlexLastAcc a+ = AlexNone+ | AlexLastAcc a !AlexInput !Int+ | AlexLastSkip !AlexInput !Int++data AlexAcc a user+ = AlexAcc a+ | AlexAccSkip+ | AlexAccPred a (AlexAccPred user)+ | AlexAccSkipPred (AlexAccPred user)++type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool++-- -----------------------------------------------------------------------------+-- Predicates on a rule++alexAndPred p1 p2 user in1 len in2+ = p1 user in1 len in2 && p2 user in1 len in2++--alexPrevCharIsPred :: Char -> AlexAccPred _ +alexPrevCharIs c _ input _ _ = c == alexInputPrevChar input++--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _ +alexPrevCharIsOneOf arr _ input _ _ = arr ! alexInputPrevChar input++--alexRightContext :: Int -> AlexAccPred _+alexRightContext (I# (sc)) user _ _ input = + case alex_scan_tkn user input 0# input sc AlexNone of+ (AlexNone, _) -> False+ _ -> True+ -- TODO: there's no need to find the longest+ -- match when checking the right context, just+ -- the first match will do.++-- used by wrappers+iUnbox (I# (i)) = i
@@ -0,0 +1,579 @@+{-# OPTIONS -fglasgow-exts -cpp #-}+{-# LINE 1 "src/Scyther/Theory/Lexer.x" #-}++{-# OPTIONS_GHC -fno-warn-name-shadowing -fno-warn-unused-matches -fno-warn-unused-binds -fno-warn-missing-signatures #-}+module Scyther.Theory.Lexer where+++#if __GLASGOW_HASKELL__ >= 603+#include "ghcconfig.h"+#elif defined(__GLASGOW_HASKELL__)+#include "config.h"+#endif+#if __GLASGOW_HASKELL__ >= 503+import Data.Array+import Data.Char (ord)+import Data.Array.Base (unsafeAt)+#else+import Array+import Char (ord)+#endif+#if __GLASGOW_HASKELL__ >= 503+import GHC.Exts+#else+import GlaExts+#endif+alex_base :: AlexAddr+alex_base = AlexA# "\x01\x00\x00\x00\xdb\x00\x00\x00\x28\x00\x00\x00\x2d\x00\x00\x00\x38\x00\x00\x00\x39\x00\x00\x00\x1a\x00\x00\x00\x00\x00\x00\x00\x1b\x00\x00\x00\x00\x00\x00\x00\x1c\x00\x00\x00\x00\x00\x00\x00\x44\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1d\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x20\x00\x00\x00\x00\x00\x00\x00\x2a\x01\x00\x00\xfa\x01\x00\x00\xca\x02\x00\x00\x9a\x03\x00\x00\x21\x00\x00\x00\x00\x00\x00\x00\x6a\x04\x00\x00\x3a\x05\x00\x00\x0a\x06\x00\x00\xda\x06\x00\x00\xaa\x07\x00\x00\x7a\x08\x00\x00\x4a\x09\x00\x00\x22\x00\x00\x00\x00\x00\x00\x00\x1a\x0a\x00\x00\xea\x0a\x00\x00\xba\x0b\x00\x00\x8a\x0c\x00\x00\x5a\x0d\x00\x00\x2a\x0e\x00\x00\xfa\x0e\x00\x00\xca\x0f\x00\x00\x9a\x10\x00\x00\x24\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x6a\x11\x00\x00\xcf\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3a\x12\x00\x00\x00\x00\x00\x00\xc8\xff\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x26\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x27\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x29\x00\x00\x00\x00\x00\x00\x00\x13\x00\x00\x00\x00\x00\x00\x00\x0a\x13\x00\x00\xda\x13\x00\x00\xaa\x14\x00\x00"#++alex_table :: AlexAddr+alex_table = AlexA# "\x00\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x03\x00\xff\xff\x40\x00\x46\x00\x45\x00\xff\xff\x4b\x00\x3f\x00\x08\x00\x3a\x00\x47\x00\x50\x00\x39\x00\x4f\x00\x4d\x00\x06\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x03\x00\x44\x00\xff\xff\x48\x00\x43\x00\x49\x00\x4a\x00\xff\xff\xff\xff\xff\xff\x0d\x00\x07\x00\x09\x00\x0e\x00\x03\x00\x04\x00\x2d\x00\x13\x00\x19\x00\x03\x00\x22\x00\x2f\x00\x37\x00\x53\x00\x32\x00\x52\x00\x54\x00\x00\x00\x55\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3b\x00\xff\xff\x3c\x00\x42\x00\x4e\x00\xff\xff\x00\x00\x00\x00\x00\x00\x51\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0b\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x10\x00\x1a\x00\x14\x00\x33\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x3d\x00\x4c\x00\x3e\x00\x41\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2e\x00\x00\x00\x36\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x30\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\x00\x00\x00\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x0a\x00\x11\x00\x0c\x00\x11\x00\x11\x00\x11\x00\x11\x00\x0f\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x11\x00\x12\x00\x11\x00\x11\x00\x11\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x15\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x16\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x17\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x1b\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x23\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x1c\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x1d\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x1e\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x1f\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x20\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x21\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x24\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x25\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x26\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x27\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x28\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x29\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x2a\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x2b\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x2c\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x00\x38\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x35\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x00\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00\x57\x00"#++alex_check :: AlexAddr+alex_check = AlexA# "\xff\xff\x00\x00\x01\x00\x02\x00\x03\x00\x04\x00\x05\x00\x06\x00\x07\x00\x08\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x0e\x00\x0f\x00\x10\x00\x11\x00\x12\x00\x13\x00\x14\x00\x15\x00\x16\x00\x17\x00\x18\x00\x19\x00\x1a\x00\x1b\x00\x1c\x00\x1d\x00\x1e\x00\x1f\x00\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x0a\x00\x0a\x00\x2a\x00\x2a\x00\x2a\x00\x2a\x00\x20\x00\x2f\x00\x2a\x00\x2a\x00\x2a\x00\x20\x00\x2a\x00\x80\x00\x88\x00\x3e\x00\x83\x00\x2d\x00\x2d\x00\xff\xff\x2d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\xff\xff\xff\xff\xff\xff\x3e\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x29\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x2f\x00\x73\x00\x74\x00\xa7\x00\xa8\x00\xff\xff\xff\xff\xff\xff\xff\xff\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x7f\x00\x80\x00\x81\x00\x82\x00\x83\x00\x84\x00\x85\x00\x86\x00\x87\x00\x88\x00\x89\x00\x8a\x00\x8b\x00\x8c\x00\x8d\x00\x8e\x00\x8f\x00\x90\x00\x91\x00\x92\x00\x93\x00\x94\x00\x95\x00\x96\x00\x97\x00\x98\x00\x99\x00\x9a\x00\x9b\x00\x9c\x00\x9d\x00\x9e\x00\x9f\x00\xa0\x00\xa1\x00\xa2\x00\xa3\x00\xa4\x00\xa5\x00\xa6\x00\xa7\x00\xa8\x00\xa9\x00\xaa\x00\xab\x00\xac\x00\xad\x00\xae\x00\xaf\x00\xb0\x00\xb1\x00\xb2\x00\xb3\x00\xb4\x00\xb5\x00\xb6\x00\xb7\x00\xb8\x00\xb9\x00\xba\x00\xbb\x00\xbc\x00\xbd\x00\xbe\x00\xbf\x00\x7d\x00\xff\xff\xc2\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xd7\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xe2\x00\x09\x00\x0a\x00\x0b\x00\x0c\x00\x0d\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xf7\x00\xff\xff\xff\xff\x20\x00\x21\x00\x22\x00\x23\x00\x24\x00\x25\x00\x26\x00\x27\x00\x28\x00\x29\x00\x2a\x00\x2b\x00\x2c\x00\x2d\x00\x2e\x00\x2f\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\x3a\x00\x3b\x00\x3c\x00\x3d\x00\x3e\x00\x3f\x00\x40\x00\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\x5b\x00\x5c\x00\x5d\x00\x5e\x00\x5f\x00\x60\x00\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\x7c\x00\x7d\x00\x7e\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\x7b\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x88\x00\x89\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xac\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00\x30\x00\x31\x00\x32\x00\x33\x00\x34\x00\x35\x00\x36\x00\x37\x00\x38\x00\x39\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x41\x00\x42\x00\x43\x00\x44\x00\x45\x00\x46\x00\x47\x00\x48\x00\x49\x00\x4a\x00\x4b\x00\x4c\x00\x4d\x00\x4e\x00\x4f\x00\x50\x00\x51\x00\x52\x00\x53\x00\x54\x00\x55\x00\x56\x00\x57\x00\x58\x00\x59\x00\x5a\x00\xff\xff\xff\xff\xff\xff\xff\xff\x5f\x00\xff\xff\x61\x00\x62\x00\x63\x00\x64\x00\x65\x00\x66\x00\x67\x00\x68\x00\x69\x00\x6a\x00\x6b\x00\x6c\x00\x6d\x00\x6e\x00\x6f\x00\x70\x00\x71\x00\x72\x00\x73\x00\x74\x00\x75\x00\x76\x00\x77\x00\x78\x00\x79\x00\x7a\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xc0\x00\xc1\x00\xc2\x00\xc3\x00\xc4\x00\xc5\x00\xc6\x00\xc7\x00\xc8\x00\xc9\x00\xca\x00\xcb\x00\xcc\x00\xcd\x00\xce\x00\xcf\x00\xd0\x00\xd1\x00\xd2\x00\xd3\x00\xd4\x00\xd5\x00\xd6\x00\xff\xff\xd8\x00\xd9\x00\xda\x00\xdb\x00\xdc\x00\xdd\x00\xde\x00\xdf\x00\xe0\x00\xe1\x00\xe2\x00\xe3\x00\xe4\x00\xe5\x00\xe6\x00\xe7\x00\xe8\x00\xe9\x00\xea\x00\xeb\x00\xec\x00\xed\x00\xee\x00\xef\x00\xf0\x00\xf1\x00\xf2\x00\xf3\x00\xf4\x00\xf5\x00\xf6\x00\xff\xff\xf8\x00\xf9\x00\xfa\x00\xfb\x00\xfc\x00\xfd\x00\xfe\x00\xff\x00"#++alex_deflt :: AlexAddr+alex_deflt = AlexA# "\x56\x00\xff\xff\xff\xff\xff\xff\x05\x00\x05\x00\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"#++alex_accept = listArray (0::Int,88) [[],[],[],[(AlexAccSkip)],[(AlexAccSkip)],[(AlexAccSkip)],[],[(AlexAcc (alex_action_2))],[(AlexAcc (alex_action_21))],[(AlexAcc (alex_action_3))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_4))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_5))],[(AlexAcc (alex_action_6))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_7))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_8))],[(AlexAcc (alex_action_9))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[],[(AlexAcc (alex_action_10))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[],[(AlexAcc (alex_action_11))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[],[(AlexAcc (alex_action_12))],[(AlexAcc (alex_action_13))],[(AlexAcc (alex_action_14))],[(AlexAcc (alex_action_49))],[],[(AlexAcc (alex_action_15))],[(AlexAcc (alex_action_16))],[(AlexAcc (alex_action_17))],[(AlexAcc (alex_action_18))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_19))],[],[(AlexAcc (alex_action_20))],[(AlexAcc (alex_action_22))],[(AlexAcc (alex_action_23))],[(AlexAcc (alex_action_24))],[(AlexAcc (alex_action_25))],[(AlexAcc (alex_action_26))],[(AlexAcc (alex_action_27))],[(AlexAcc (alex_action_28))],[(AlexAcc (alex_action_29))],[(AlexAcc (alex_action_30))],[(AlexAcc (alex_action_31))],[(AlexAcc (alex_action_32))],[(AlexAcc (alex_action_33))],[(AlexAcc (alex_action_34))],[(AlexAcc (alex_action_35))],[(AlexAcc (alex_action_36))],[(AlexAcc (alex_action_37))],[(AlexAcc (alex_action_38))],[(AlexAcc (alex_action_39))],[(AlexAcc (alex_action_40))],[(AlexAcc (alex_action_41))],[(AlexAcc (alex_action_42))],[(AlexAcc (alex_action_43))],[(AlexAcc (alex_action_44))],[(AlexAcc (alex_action_45))],[(AlexAcc (alex_action_46))],[(AlexAcc (alex_action_47))],[],[(AlexAcc (alex_action_48))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))],[(AlexAcc (alex_action_49))]]+{-# LINE 75 "src/Scyther/Theory/Lexer.x" #-}+++-- | Lex a keyword+keyword :: Keyword -> AlexAction Keyword+keyword kw input len = return kw++-- | Lex an identifier+scanIdent :: AlexAction Keyword+scanIdent (_,_,input) len = return $ IDENT (take len input)++{-+-- | Scan a string until EOF is encountered.+alexScanTokens :: String -> Either String [Keyword]+alexScanTokens inp = runAlex inp gather+ where+ gather = do+ t <- alexMonadScan+ case trace (show t) t of+ EOF -> return [EOF]+ _ -> (t:) `liftM` gather++-- | Scan a file.+scanFile f = do+ inp <- readFile f+ return $ alexScanTokens inp+-}++-- | Lexable Keywords+data Keyword =+ IDENT String+ | SQUOTE+ | DQUOTE+ | RIGHTARROW+ | LEFTARROW+ | LONGRIGHTARROW+ | LONGLEFTARROW+ | COMMA+ | DOT+ | COLON+ | QUESTIONMARK+ | AND+ | MID+ | DOLLAR+ | SHARP+ | LPAREN+ | RPAREN+ | LBRACKET+ | RBRACKET+ | LBRACE + | RBRACE+ | TILDE+ | HAT+ | STAR+ | UNDERSCORE+ | MINUS+ | PLUS+ | EQUAL+ | LESS+ | GREATER+ | EOF+ | FORALL+ | EXISTS+ | LAND+ | LOR+ | LNOT+ | APPROX+ -- dummy keyword to get rid of overlapping pattern matches+ | DUMMY_KEYWORD+ deriving( Eq )++instance Show Keyword where+ show kw = case kw of + IDENT i -> identifier i+ SQUOTE -> symbol "'"+ DQUOTE -> symbol "\""+ RIGHTARROW -> symbol "->"+ LEFTARROW -> symbol "<-"+ LONGRIGHTARROW -> symbol "-->"+ LONGLEFTARROW -> symbol "<--"+ COMMA -> symbol ","+ DOT -> symbol "."+ COLON -> symbol ":"+ QUESTIONMARK -> symbol "?"+ AND -> symbol "&"+ MID -> symbol "|"+ DOLLAR -> symbol "$"+ SHARP -> symbol "#"+ LPAREN -> symbol "("+ RPAREN -> symbol ")"+ LBRACKET -> symbol "["+ RBRACKET -> symbol "]"+ LBRACE -> symbol "{"+ RBRACE -> symbol "}"+ TILDE -> symbol "~"+ HAT -> symbol "^"+ STAR -> symbol "*"+ UNDERSCORE -> symbol "_"+ MINUS -> symbol "-"+ PLUS -> symbol "+"+ EQUAL -> symbol "="+ LESS -> symbol "<"+ GREATER -> symbol ">"+ EOF -> "end of file"+ FORALL -> symbol "∀" + EXISTS -> symbol "∃" + LAND -> symbol "∧" + LOR -> symbol "∨" + LNOT -> symbol "¬" + APPROX -> symbol "≈" + DUMMY_KEYWORD -> "DUMMY_KEYWORD (this should not occur!)"+ where+ identifier i = "identifier `" ++ i ++ "'"+ symbol s = "symbol `" ++ s ++ "'"+ keyword s = "keyword `" ++ s ++ "'"++-- -----------------------------------------------------------------------------+-- Alex wrapper code.+--+-- This code is in the PUBLIC DOMAIN; you may copy it freely and use+-- it for any purpose whatsoever.++-- -----------------------------------------------------------------------------+-- The input type+++type AlexInput = (AlexPosn, -- current position,+ Char, -- previous char+ String) -- current input string++alexInputPrevChar :: AlexInput -> Char+alexInputPrevChar (p,c,s) = c++alexGetChar :: AlexInput -> Maybe (Char,AlexInput)+alexGetChar (p,c,[]) = Nothing+alexGetChar (p,_,(c:s)) = let p' = alexMove p c in p' `seq`+ Just (c, (p', c, s))+++-- -----------------------------------------------------------------------------+-- Token positions++-- `Posn' records the location of a token in the input text. It has three+-- fields: the address (number of chacaters preceding the token), line number+-- and column of a token within the file. `start_pos' gives the position of the+-- start of the file and `eof_pos' a standard encoding for the end of file.+-- `move_pos' calculates the new position after traversing a given character,+-- assuming the usual eight character tab stops.++data AlexPosn = AlexPn !Int !Int !Int+ deriving (Eq)++instance Show AlexPosn where+ show (AlexPn _ l c) = "line "++show l++" column "++show c++alexStartPos :: AlexPosn+alexStartPos = AlexPn 0 1 1++alexMove :: AlexPosn -> Char -> AlexPosn+alexMove (AlexPn a l c) '\t' = AlexPn (a+1) l (((c+7) `div` 8)*8+1)+alexMove (AlexPn a l c) '\n' = AlexPn (a+1) (l+1) 1+alexMove (AlexPn a l c) _ = AlexPn (a+1) l (c+1)+++-- -----------------------------------------------------------------------------+-- Default monad+++data AlexState = AlexState {+ alex_pos :: !AlexPosn, -- position at current input location+ alex_inp :: String, -- the current input+ alex_chr :: !Char, -- the character before the input+ alex_scd :: !Int, -- the current startcode+ alex_ocd :: !Int, -- the old startcode before the comment started+ alex_cmt :: [String] -- stack of begin comment identifiers+ }++-- Compile with -funbox-strict-fields for best results!++runAlex :: String -> Alex a -> Either String a+runAlex input (Alex f) + = case f (AlexState {alex_pos = alexStartPos,+ alex_inp = input, + alex_chr = '\n',+ alex_scd = 0,+ alex_ocd = 0,+ alex_cmt = []+ }) of + Left msg -> Left msg+ Right ( _, a ) -> Right a++newtype Alex a = Alex { unAlex :: AlexState -> Either String (AlexState, a) }++instance Monad Alex where+ m >>= k = Alex $ \s -> case unAlex m s of + Left msg -> Left msg+ Right (s',a) -> unAlex (k a) s'+ return a = Alex $ \s -> Right (s,a)++alexGetPos :: Alex AlexPosn+alexGetPos = Alex $ \s@AlexState{alex_pos=pos} -> Right (s, pos)++alexGetInput :: Alex AlexInput+alexGetInput+ = Alex $ \s@AlexState{alex_pos=pos,alex_chr=c,alex_inp=inp} -> + Right (s, (pos,c,inp))++alexSetInput :: AlexInput -> Alex ()+alexSetInput (pos,c,inp)+ = Alex $ \s -> case s{alex_pos=pos,alex_chr=c,alex_inp=inp} of+ s@(AlexState{}) -> Right (s, ())++alexError :: String -> Alex a+alexError message = Alex $ \s -> Left $ message ++ " in " ++ show (alex_pos s)++alexGetStartCode :: Alex Int+alexGetStartCode = Alex $ \s@AlexState{alex_scd=sc} -> Right (s, sc)++alexSetStartCode :: Int -> Alex ()+alexSetStartCode sc = Alex $ \s -> Right (s{alex_scd=sc}, ())++alexGetOldStartCode :: Alex Int+alexGetOldStartCode = Alex $ \s@AlexState{alex_ocd=sc} -> Right (s, sc)++alexSetOldStartCode :: Int -> Alex ()+alexSetOldStartCode sc = Alex $ \s -> Right (s{alex_ocd=sc}, ())++alexGetComments :: Alex [String]+alexGetComments = Alex $ \s -> Right (s, alex_cmt s)++alexSetComments :: [String] -> Alex ()+alexSetComments cmt = Alex $ \s -> Right (s{alex_cmt=cmt}, ())++alexMonadScan = do+ inp <- alexGetInput+ sc <- alexGetStartCode+ case alexScan inp sc of+ AlexEOF -> alexEOF+ AlexError inp' -> alexError "lexical error"+ AlexSkip inp' len -> do+ alexSetInput inp'+ alexMonadScan+ AlexToken inp' len action -> do+ alexSetInput inp'+ action inp len++-- -----------------------------------------------------------------------------+-- Useful token actions++type AlexAction result = AlexInput -> Int -> Alex result++-- just ignore this token and scan another one+skip :: AlexAction Keyword+skip input len = alexMonadScan++-- ignore this token, but set the start code to a new value+begin :: Int -> AlexAction Keyword+begin code input len = do alexSetStartCode code; alexMonadScan++-- | Begin a comment starting with the given sign.+beginComment :: String -> Int -> AlexAction Keyword+beginComment cmtBegin code input len = do+ cmts <- alexGetComments+ alexSetComments $ cmtBegin : cmts+ if null cmts+ then alexGetStartCode >>= alexSetOldStartCode+ else return ()+ alexSetStartCode code+ alexMonadScan++-- | End a comment that started with the given begin comment sign.+endComment :: String -> AlexAction Keyword+endComment cmtBegin input len = do+ cmts <- alexGetComments+ case cmts of+ [] -> alexError $ "comment ended but no beginning '"++cmtBegin++"' marked."+ (cmt:cmts') -> do+ if cmt == cmtBegin + then do+ alexSetComments cmts'+ if null cmts' + then alexGetOldStartCode >>= alexSetStartCode + else return ()+ else return ()+ alexMonadScan++-- perform an action for this token, and set the start code to a new value+-- andBegin :: AlexAction result -> Int -> AlexAction result+(action `andBegin` code) input len = do alexSetStartCode code; action input len++alexEOF :: Alex Keyword+alexEOF = return EOF++++++comment :: Int+comment = 1+alex_action_2 = beginComment "(*" comment +alex_action_3 = beginComment "(*" comment +alex_action_4 = endComment "(*" +alex_action_5 = beginComment "/*" comment +alex_action_6 = beginComment "/*" comment +alex_action_7 = endComment "/*" +alex_action_8 = skip +alex_action_9 = beginComment "{*" comment +alex_action_10 = beginComment "{*" comment +alex_action_11 = beginComment "{*" comment +alex_action_12 = beginComment "{*" comment +alex_action_13 = endComment "{*" +alex_action_14 = keyword FORALL +alex_action_15 = keyword EXISTS +alex_action_16 = keyword LAND +alex_action_17 = keyword LOR +alex_action_18 = keyword LNOT +alex_action_19 = keyword APPROX +alex_action_20 = keyword COMMA +alex_action_21 = keyword LPAREN +alex_action_22 = keyword RPAREN +alex_action_23 = keyword LBRACKET +alex_action_24 = keyword RBRACKET +alex_action_25 = keyword LBRACE +alex_action_26 = keyword RBRACE +alex_action_27 = keyword SQUOTE +alex_action_28 = keyword DQUOTE +alex_action_29 = keyword TILDE +alex_action_30 = keyword HAT +alex_action_31 = keyword EQUAL +alex_action_32 = keyword COLON +alex_action_33 = keyword DOLLAR +alex_action_34 = keyword SHARP +alex_action_35 = keyword STAR +alex_action_36 = keyword LESS +alex_action_37 = keyword GREATER +alex_action_38 = keyword QUESTIONMARK +alex_action_39 = keyword AND +alex_action_40 = keyword MID +alex_action_41 = keyword DOT +alex_action_42 = keyword UNDERSCORE +alex_action_43 = keyword MINUS +alex_action_44 = keyword PLUS +alex_action_45 = keyword RIGHTARROW +alex_action_46 = keyword LEFTARROW +alex_action_47 = keyword LONGRIGHTARROW +alex_action_48 = keyword LONGLEFTARROW +alex_action_49 = scanIdent +{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+{-# LINE 1 "<eingebaut>" #-}+{-# LINE 1 "<Kommandozeile>" #-}+{-# LINE 1 "templates/GenericTemplate.hs" #-}+-- -----------------------------------------------------------------------------+-- ALEX TEMPLATE+--+-- This code is in the PUBLIC DOMAIN; you may copy it freely and use+-- it for any purpose whatsoever.++-- -----------------------------------------------------------------------------+-- INTERNALS and main scanner engine++{-# LINE 35 "templates/GenericTemplate.hs" #-}++{-# LINE 45 "templates/GenericTemplate.hs" #-}+++data AlexAddr = AlexA# Addr#++#if __GLASGOW_HASKELL__ < 503+uncheckedShiftL# = shiftL#+#endif++{-# INLINE alexIndexInt16OffAddr #-}+alexIndexInt16OffAddr (AlexA# arr) off =+#ifdef WORDS_BIGENDIAN+ narrow16Int# i+ where+ i = word2Int# ((high `uncheckedShiftL#` 8#) `or#` low)+ high = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))+ low = int2Word# (ord# (indexCharOffAddr# arr off'))+ off' = off *# 2#+#else+ indexInt16OffAddr# arr off+#endif++++++{-# INLINE alexIndexInt32OffAddr #-}+alexIndexInt32OffAddr (AlexA# arr) off = +#ifdef WORDS_BIGENDIAN+ narrow32Int# i+ where+ i = word2Int# ((b3 `uncheckedShiftL#` 24#) `or#`+ (b2 `uncheckedShiftL#` 16#) `or#`+ (b1 `uncheckedShiftL#` 8#) `or#` b0)+ b3 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 3#)))+ b2 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 2#)))+ b1 = int2Word# (ord# (indexCharOffAddr# arr (off' +# 1#)))+ b0 = int2Word# (ord# (indexCharOffAddr# arr off'))+ off' = off *# 4#+#else+ indexInt32OffAddr# arr off+#endif++++++#if __GLASGOW_HASKELL__ < 503+quickIndex arr i = arr ! i+#else+-- GHC >= 503, unsafeAt is available from Data.Array.Base.+quickIndex = unsafeAt+#endif+++++-- -----------------------------------------------------------------------------+-- Main lexing routines++data AlexReturn a+ = AlexEOF+ | AlexError !AlexInput+ | AlexSkip !AlexInput !Int+ | AlexToken !AlexInput !Int a++-- alexScan :: AlexInput -> StartCode -> AlexReturn a+alexScan input (I# (sc))+ = alexScanUser undefined input (I# (sc))++alexScanUser user input (I# (sc))+ = case alex_scan_tkn user input 0# input sc AlexNone of+ (AlexNone, input') ->+ case alexGetChar input of+ Nothing -> ++++ AlexEOF+ Just _ ->++++ AlexError input'++ (AlexLastSkip input len, _) ->++++ AlexSkip input len++ (AlexLastAcc k input len, _) ->++++ AlexToken input len k+++-- Push the input through the DFA, remembering the most recent accepting+-- state it encountered.++alex_scan_tkn user orig_input len input s last_acc =+ input `seq` -- strict in the input+ let + new_acc = check_accs (alex_accept `quickIndex` (I# (s)))+ in+ new_acc `seq`+ case alexGetChar input of+ Nothing -> (new_acc, input)+ Just (c, new_input) -> ++++ let+ base = alexIndexInt32OffAddr alex_base s+ (I# (ord_c)) = ord c+ offset = (base +# ord_c)+ check = alexIndexInt16OffAddr alex_check offset+ + new_s = if (offset >=# 0#) && (check ==# ord_c)+ then alexIndexInt16OffAddr alex_table offset+ else alexIndexInt16OffAddr alex_deflt s+ in+ case new_s of + -1# -> (new_acc, input)+ -- on an error, we want to keep the input *before* the+ -- character that failed, not after.+ _ -> alex_scan_tkn user orig_input (len +# 1#) + new_input new_s new_acc++ where+ check_accs [] = last_acc+ check_accs (AlexAcc a : _) = AlexLastAcc a input (I# (len))+ check_accs (AlexAccSkip : _) = AlexLastSkip input (I# (len))+ check_accs (AlexAccPred a pred : rest)+ | pred user orig_input (I# (len)) input+ = AlexLastAcc a input (I# (len))+ check_accs (AlexAccSkipPred pred : rest)+ | pred user orig_input (I# (len)) input+ = AlexLastSkip input (I# (len))+ check_accs (_ : rest) = check_accs rest++data AlexLastAcc a+ = AlexNone+ | AlexLastAcc a !AlexInput !Int+ | AlexLastSkip !AlexInput !Int++data AlexAcc a user+ = AlexAcc a+ | AlexAccSkip+ | AlexAccPred a (AlexAccPred user)+ | AlexAccSkipPred (AlexAccPred user)++type AlexAccPred user = user -> AlexInput -> Int -> AlexInput -> Bool++-- -----------------------------------------------------------------------------+-- Predicates on a rule++alexAndPred p1 p2 user in1 len in2+ = p1 user in1 len in2 && p2 user in1 len in2++--alexPrevCharIsPred :: Char -> AlexAccPred _ +alexPrevCharIs c _ input _ _ = c == alexInputPrevChar input++--alexPrevCharIsOneOfPred :: Array Char Bool -> AlexAccPred _ +alexPrevCharIsOneOf arr _ input _ _ = arr ! alexInputPrevChar input++--alexRightContext :: Int -> AlexAccPred _+alexRightContext (I# (sc)) user _ _ input = + case alex_scan_tkn user input 0# input sc AlexNone of+ (AlexNone, _) -> False+ _ -> True+ -- TODO: there's no need to find the longest+ -- match when checking the right context, just+ -- the first match will do.++-- used by wrappers+iUnbox (I# (i)) = i
@@ -0,0 +1,29 @@+module Paths_scyther_proof (+ version,+ getBinDir, getLibDir, getDataDir, getLibexecDir,+ getDataFileName+ ) where++import Data.Version (Version(..))+import System.Environment (getEnv)++version :: Version+version = Version {versionBranch = [0,3,0], versionTags = []}++bindir, libdir, datadir, libexecdir :: FilePath++bindir = "."+libdir = "."+datadir = "data"+libexecdir = "."++getBinDir, getLibDir, getDataDir, getLibexecDir :: IO FilePath+getBinDir = catch (getEnv "scyther_proof_bindir") (\_ -> return bindir)+getLibDir = catch (getEnv "scyther_proof_libdir") (\_ -> return libdir)+getDataDir = catch (getEnv "scyther_proof_datadir") (\_ -> return datadir)+getLibexecDir = catch (getEnv "scyther_proof_libexecdir") (\_ -> return libexecdir)++getDataFileName :: FilePath -> IO FilePath+getDataFileName name = do+ dir <- getDataDir+ return (dir ++ "/" ++ name)
@@ -0,0 +1,226 @@+build-type: Simple+name: scyther-proof+version: 0.3.0+license: GPL+license-file: LICENSE+category: Security, Theorem Provers+author: Simon Meier <simon.meier@inf.ethz.ch>+maintainer: Simon Meier <simon.meier@inf.ethz.ch>+copyright: Simon Meier, ETH Zurich, 2009-2011+synopsis: Automatic generation of Isabelle/HOL correctness proofs for security protocols.+description:+ scyther-proof is a security protocol verification tool based on a similar+ algorithm as the Scyther tool developed by Cas Cremers+ (http://people.inf.ethz.ch/cremersc/scyther/index.html). The theory underlying scyther-proof+ is described in the paper "Strong Invariants for the Efficient Construction+ of Machine-Checked Protocol Security Proofs" by Meier, Cremers, and Basin.++ Parts of the infrastructure underlying scyther-proof are reused in other+ projects by the same author. Therefore, most of its modules are exported in+ the corresponding scyther-proof library. However, this library is not yet thought for+ general use. Please contact the author, if you would like to build upon/extend scyther-proof.++homepage: http://www.infsec.ethz.ch/people/meiersi/+stability: Beta+cabal-version: >= 1.8+data-dir: data+data-files:+ HTML_TEMPLATE+ index.html+ js/jquery.js+ js/ui/jquery.ui.core.js+ js/ui/jquery.ui.widget.js+ js/ui/jquery.ui.tabs.js+ js/ui/jquery.ui.mouse.js+ js/ui/jquery.ui.draggable.js+ js/ui/jquery.effects.core.js+ js/jquery.layout.js+ js/tooltip/jquery.tooltip.css+ js/tooltip/lib/jquery.bgiframe.js+ js/tooltip/lib/jquery.dimensions.js+ js/tooltip/jquery.tooltip.js+ js/json_parse.js+ css/scyther-proof.css+ css/ui-lightness/jquery.ui.all.css+ css/ui-lightness/jquery.ui.button.css+ css/ui-lightness/jquery.ui.dialog.css+ css/ui-lightness/jquery.ui.selectable.css+ css/ui-lightness/jquery.ui.theme.css+ css/ui-lightness/jquery-ui-1.8.2.custom.css+ css/ui-lightness/jquery.ui.autocomplete.css+ css/ui-lightness/jquery.ui.core.css+ css/ui-lightness/jquery.ui.progressbar.css+ css/ui-lightness/jquery.ui.slider.css+ css/ui-lightness/jquery.ui.accordion.css+ css/ui-lightness/jquery.ui.base.css+ css/ui-lightness/jquery.ui.datepicker.css+ css/ui-lightness/jquery.ui.resizable.css+ css/ui-lightness/jquery.ui.tabs.css+ css/ui-lightness/images/ui-anim_basic_16x16.gif+ css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png+ css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png+ css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png+ css/ui-lightness/images/ui-icons_ef8c08_256x240.png+ css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png+ css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png+ css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png+ css/ui-lightness/images/ui-icons_222222_256x240.png+ css/ui-lightness/images/ui-icons_ffd27a_256x240.png+ css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png+ css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png+ css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png+ css/ui-lightness/images/ui-icons_228ef1_256x240.png+ css/ui-lightness/images/ui-icons_ffffff_256x240.png++ examples/OVERVIEW+ examples/Makefile+ examples/classic/*.spthy+ examples/iso9798/*.spthy+ examples/iso9798/isabelle-proofs/*.thy+ examples/iso9798/isabelle-parallel-proofs/*.thy++ isabelle/AUTHORS + isabelle/document/root.tex + isabelle/IsaMakefile + isabelle/Makefile + isabelle/README + isabelle/ROOT.ML + isabelle/src/isar-keywords.el+ isabelle/src/*.thy+ isabelle/src/ESPLogic/*.thy+ isabelle/src/ESPLogic/*.ML+ isabelle/src/compromising_adversaries/*.thy+++extra-source-files:+ .ghci+ interactive-only-src/Paths_scyther_proof.hs+ README+++flag threaded+ default: True+ description: Build with support for multithreaded execution++library+ build-depends:+ base == 4.* , + array == 0.3.* , + containers >= 0.3 && < 0.5 ,+ safe >= 0.2 && < 0.3 ,+ + mtl == 2.0.* ,+ + filepath >= 1.1 && < 1.3 ,+ directory >= 1.0 && < 1.2 ,+ process == 1.0.* , + time >= 1.1 && < 1.3 ,++ parsec == 3.1.* ,+ pretty == 1.0.* ,+ tagsoup == 0.12.* ,+ json == 0.4.* ,+ uniplate == 1.6.*++ build-tools: alex+ extensions: MultiParamTypeClasses, GeneralizedNewtypeDeriving++ hs-source-dirs:+ src++ exposed-modules:+ Extension.Prelude+ Data.Color + Data.Table+ Data.DAG.Simple+ Data.UnionFind+ Control.Basics+ Control.Monad.BoundedDFS+ Control.Monad.Label+ Control.Concurrent.ManagedThreads+ Text.Isar+ Text.Dot+ Text.PrettyPrint.Class+ System.Isabelle+ System.Timing++ Scyther.Protocol+ Scyther.Message+ Scyther.Equalities+ Scyther.Event+ Scyther.Typing+ Scyther.Formula+ Scyther.Facts+ Scyther.Sequent+ Scyther.Proof+ Scyther.Theory+ Scyther.Theory.Lexer+ Scyther.Theory.Parser+ Scyther.Theory.Pretty+ Scyther.Theory.Html+ Scyther.Theory.Dot+ ++executable scyther-proof+ build-depends:+ base == 4.* , + array == 0.3.* , + containers >= 0.3 && < 0.5 ,+ safe >= 0.2 && < 0.4 ,+ + mtl == 2.0.* ,+ + cmdargs >= 0.6.8 && < 0.7 ,+ filepath >= 1.1 && < 1.3 ,+ directory >= 1.0 && < 1.2 ,+ process == 1.0.* , + time >= 1.1 && < 1.3 ,+ + parsec == 3.1.* ,+ pretty == 1.0.* ,+ tagsoup == 0.12.* ,+ json == 0.4.* ,+ uniplate == 1.6.*+++ if flag(threaded)+ ghc-options: -threaded++ main-is: Main.hs+ hs-source-dirs: src++ other-modules:+ Extension.Prelude+ Data.Color + Data.Table+ Data.DAG.Simple+ Data.UnionFind+ Control.Basics+ Control.Monad.BoundedDFS+ Control.Monad.Label+ Control.Concurrent.ManagedThreads+ Text.Isar+ Text.Dot+ Text.PrettyPrint.Class+ System.Isabelle+ System.Timing++ Scyther.Protocol+ Scyther.Message+ Scyther.Equalities+ Scyther.Event+ Scyther.Typing+ Scyther.Formula+ Scyther.Facts+ Scyther.Sequent+ Scyther.Proof+ Scyther.Theory+ Scyther.Theory.Lexer+ Scyther.Theory.Parser+ Scyther.Theory.Pretty+ Scyther.Theory.Html+ Scyther.Theory.Dot++ Scyther.GoalFlow++
@@ -0,0 +1,10 @@+-- | Re-export basic control structures for easier imports.+module Control.Basics (+ module Control.Arrow+ , module Control.Applicative+ , module Control.Monad+) where++import Control.Arrow+import Control.Applicative+import Control.Monad
@@ -0,0 +1,165 @@+-- NOTE: The first part of this module is based on Chapter 24 from +-- "Real World Haskell Programming" cf:+-- (http://book.realworldhaskell.org/read/concurrent-and-multicore-programming.html)++module Control.Concurrent.ManagedThreads (+ ThreadManager+ , newManager+ , forkManaged+ , getStatus+ , waitFor+ , waitAll++ , nParSequenceIO+ , nParSequenceIO_+ , nParMapIO+ , nParMapIO_+ , nParCmd_+ , parCmd_+) where++import Data.Ord (comparing)+import Data.List (sortBy)+import qualified Data.Map as M++import Control.Monad++import Control.Concurrent+import Control.Exception (IOException, try)++import GHC.Conc (numCapabilities)+++------------------------------------------------------------------------------+-- Thread Manager+------------------------------------------------------------------------------++data ThreadStatus = Running+ | Finished -- terminated normally+ | Threw IOException -- killed by uncaught exception+ deriving (Show)++newtype ThreadManager =+ Mgr (MVar (M.Map ThreadId (MVar ThreadStatus)))+ deriving (Eq)++-- | Create a new thread manager.+newManager :: IO ThreadManager+newManager = Mgr `fmap` newMVar M.empty++-- | Create a new managed thread.+forkManaged :: ThreadManager -> IO () -> IO ThreadId+forkManaged (Mgr mgr) body =+ modifyMVar mgr $ \m -> do+ state <- newEmptyMVar+ tid <- forkIO $ do+ result <- try body+ putMVar state (either Threw (const Finished) result)+ return (M.insert tid state m, tid)++-- | Immediately return the status of a managed thread.+getStatus :: ThreadManager -> ThreadId -> IO (Maybe ThreadStatus)+getStatus (Mgr mgr) tid =+ modifyMVar mgr $ \m ->+ case M.lookup tid m of+ Nothing -> return (m, Nothing)+ Just st -> tryTakeMVar st >>= \mst -> case mst of+ Nothing -> return (m, Just Running)+ Just sth -> return (M.delete tid m, Just sth)++-- | Block until a specific managed thread terminates.+waitFor :: ThreadManager -> ThreadId -> IO (Maybe ThreadStatus)+waitFor (Mgr mgr) tid =+ join . modifyMVar mgr $ \m ->+ return $ case M.updateLookupWithKey (\_ _ -> Nothing) tid m of+ (Nothing, _) -> (m, return Nothing)+ (Just st, m') -> (m', Just `fmap` takeMVar st)++-- | Block until all managed threads terminate.+waitAll :: ThreadManager -> IO ()+waitAll (Mgr mgr) = modifyMVar mgr elems >>= mapM_ takeMVar+ where elems m = return (M.empty, M.elems m)+++------------------------------------------------------------------------------+-- Parallel Sequence+------------------------------------------------------------------------------++-- | Extract the head of the list in the MVar if possible.+takeHead :: MVar [a] -> IO (Maybe a)+takeHead v = + modifyMVar v (return . extract)+ where+ extract [] = ([], Nothing)+ extract (x:xs) = (xs, Just x)++-- | Do a parallel sequencing of a list of IO commands using n worker threads+-- and gather their results in a list again.+nParSequenceIO :: Int -> [IO a] -> IO [a] +nParSequenceIO n ios = do+ inMv <- newMVar $ zip [(1::Int)..] ios+ resMv <- newMVar []+ mgr <- newManager+ mapM_ (forkManaged mgr) (replicate (max 1 n) $ worker inMv resMv)+ waitAll mgr+ (map snd . sortBy (comparing fst)) `liftM` takeMVar resMv+ where+ worker inMv resMv = do+ nextJob <- takeHead inMv+ case nextJob of+ Nothing -> return ()+ Just (i, io) -> do+ out <- io+ modifyMVar_ resMv (\res -> return $ (i,out) : res)+ worker inMv resMv++-- | Do a parallel sequencing of a list of IO commands using n worker threads.+nParSequenceIO_ :: Int -> [IO a] -> IO ()+nParSequenceIO_ n ios = do+ inMv <- newMVar ios+ mgr <- newManager+ mapM_ (forkManaged mgr) (replicate n $ worker inMv)+ waitAll mgr+ where+ worker inMv = do+ nextJob <- takeHead inMv+ case nextJob of+ Nothing -> return ()+ Just io -> io >> worker inMv++-- | Do a parallel map of an IO cmd over a list using n worker threads.+nParMapIO :: Int -> (a -> IO b) -> [a] -> IO [b]+nParMapIO n f = nParSequenceIO n . map f++-- | Do a parallel map of an IO cmd over a list using n worker threads while+-- ignoring the results.+nParMapIO_ :: Int -> (a -> IO b) -> [a] -> IO ()+nParMapIO_ n f = nParSequenceIO_ n . map f++-- | Parallel execution of a command using n worker threads. The channel+-- argument can be used to report exactly one (!) progress value to the display+-- function.+-- NOTE: If the executed command is blocking, then you need to use the threaded+-- runtime+nParCmd_ :: Int -> (Int -> Int -> b -> IO ()) -> [Chan b -> IO a] -> IO ()+nParCmd_ nThreads display cmds = do+ chan <- newChan+ mgr <- newManager+ _ <- forkManaged mgr (displayThread chan 1)+ _ <- forkManaged mgr (nParMapIO_ nThreads (\cmd -> cmd chan) cmds)+ waitAll mgr+ where+ nCmds = length cmds+ displayThread ch i + | nCmds < i = do return ()+ | otherwise = do msg <- readChan ch+ display nCmds i msg+ displayThread ch (succ i)++-- | Like @nParCmd_@ but uses the number of processing cores+1 as a default for+-- the number of worker treads. You can change their number by adding to the+-- command line of a program linked with the threaded library: +-- +RTS -N<no-of-cores> -RTS+parCmd_ :: (Int -> Int -> b -> IO ()) -> [Chan b -> IO a] -> IO ()+parCmd_ display cmds = nParCmd_ (numCapabilities+1) display cmds+
@@ -0,0 +1,160 @@+{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts, + FunctionalDependencies, GeneralizedNewtypeDeriving #-}+-- | A monad for implemented bounded depth-first-search and branch-and-bound+-- search.+module Control.Monad.BoundedDFS (+ -- * Costful operations+ MonadCost(..)++ -- * Unbounded depth-first-search + , UnboundedDFS(..)++ -- * Bounded depth-first-search+ , BoundedDFS(..)+ , runBoundedDFS+ , evalBoundedDFS+ , execBoundedDFS++ -- * Branch-and-bound search+ , BranchAndBound(..)+ , runBranchAndBound+ , evalBranchAndBound+ , execBranchAndBound+) where+++import Control.Monad+import Control.Monad.State+import Control.Monad.Reader+++++-- A typeclass for costful operations+------------------------------------------------------------------------------++-- | A monad with integer operation cost recording.+class Monad m => MonadCost c m | m -> c where+ -- | Mark the cost of the current operation.+ updateCost :: (c -> c) -> m ()++-- | An unbounded depth-first search monad for searches formulated using+-- MonadPlus.+newtype UnboundedDFS c a = UnboundedDFS { runUnboundedDFS :: Maybe a }+ deriving( Monad )++instance MonadCost c (UnboundedDFS c) where+ updateCost _ = return ()++instance MonadPlus (UnboundedDFS c) where+ mzero = UnboundedDFS $ mzero+ (UnboundedDFS m1) `mplus` (UnboundedDFS m2) = UnboundedDFS $ m1 `mplus` m2++-- | A cost bounded depth-first search monad.+--+-- All choices are handled committing and there is no differentiation between+-- failure due to cost overrun and other failures.+newtype BoundedDFS c a = BoundedDFS { unBoundedDFS :: ReaderT (c -> Bool) (StateT c Maybe) a }+ deriving( Monad )++instance MonadCost c (BoundedDFS c) where+ updateCost f = BoundedDFS $ do+ cond <- ask+ b <- get+ let b' = f b+ guard (cond b')+ put b'++instance MonadPlus (BoundedDFS c) where+ mzero = BoundedDFS mzero+ m `mplus` _ = m++-- | Run a cost bounded depth-first search.+runBoundedDFS :: BoundedDFS c a -> (c -> Bool) -> c -> Maybe (a, c)+runBoundedDFS m cond = runStateT (runReaderT (unBoundedDFS m) cond)++-- | Evaluate a cost bounded depth-first search.+evalBoundedDFS :: BoundedDFS c a -> (c -> Bool) -> c -> Maybe a+evalBoundedDFS m cond = fmap fst . runBoundedDFS m cond++-- | Execute a cost bounded depth-first search.+execBoundedDFS :: BoundedDFS c a -> (c -> Bool) -> c -> Maybe c+execBoundedDFS m cond = fmap snd . runBoundedDFS m cond++-- | A branch and bound monad for finding results with the smallest costs.+newtype BranchAndBound c a = + BranchAndBound { + unBranchAndBound :: ReaderT (c -> Bool) (StateT c Maybe) a + }+ deriving( Monad )++-- | Run a branch and bound search.+runBranchAndBound :: Cost c => BranchAndBound c a -> c -> Maybe (a, c)+runBranchAndBound m bound + | zeroCost `lessEqCost` bound = + runStateT (runReaderT (unBranchAndBound m) (`lessEqCost` bound)) zeroCost+ | otherwise = mzero++-- | Evaluate a branch and bound search.+evalBranchAndBound :: Cost c => BranchAndBound c a -> c -> Maybe a+evalBranchAndBound m = fmap fst . runBranchAndBound m++-- | Execute a branch and bound search.+execBranchAndBound :: Cost c => BranchAndBound c a -> c -> Maybe c+execBranchAndBound m = fmap snd . runBranchAndBound m++instance MonadCost c (BranchAndBound c) where+ updateCost f = BranchAndBound $ do+ cond <- ask+ b <- get+ let b' = f b+ guard (cond b')+ put b'++class Eq c => Cost c where+ zeroCost :: c+ addCosts :: c -> c -> c+ subtractCosts :: c -> c -> c+ lessCost :: c -> c -> Bool+ lessEqCost :: c -> c -> Bool++ lessCost c1 c2 = lessEqCost c1 c2 && c1 /= c2+ lessEqCost c1 c2 = lessCost c1 c2 || c1 == c2++instance (Ord a, Num a) => Cost (Maybe a) where+ zeroCost = return 0+ addCosts = liftM2 (+)+ subtractCosts Nothing Nothing = error "Cost (Maybe a): subtractCosts: cannot subtract infinity from infinity"+ subtractCosts Nothing _ = Nothing+ subtractCosts (Just x) (Just y) = Just (x - y)+ subtractCosts _ Nothing = error "Cost (Maybe a): subtractCosts: cannot subtract infinity"+ lessCost Nothing Nothing = error "Cost (Maybe a): lessCost: cannot compare infinity with infinity"+ lessCost _ Nothing = True+ lessCost (Just x) (Just y) = x < y+ lessCost _ _ = error "Cost (Maybe a): lessCost: does this make sense?"+ lessEqCost Nothing Nothing = error "Cost (Maybe a): lessEqCost: cannot compare infinity with infinity"+ lessEqCost _ Nothing = True+ lessEqCost (Just x) (Just y) = x <= y+ lessEqCost _ _ = error "Cost (Maybe a): lessEqcost: does this make sense?"++instance Cost c => MonadPlus (BranchAndBound c) where+ mzero = BranchAndBound $ mzero+ m1 `mplus` m2 = BranchAndBound $ + (do -- see if m1 get's through+ used <- get+ x1 <- unBranchAndBound m1+ m1Used <- get+ -- m1 did it, check if m2 gets through with new bound+ (local (const (`lessCost` (m1Used `subtractCosts` used))) $ do+ put zeroCost+ x2 <- unBranchAndBound m2+ modify (used `addCosts`)+ return x2+ `mplus`+ -- m2 didn't do it, return result of m1+ return x1)+ `mplus`+ -- m1 didn't do it, try m2+ unBranchAndBound m2)+ +
@@ -0,0 +1,90 @@+{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances, MultiParamTypeClasses #-}+--+-- | A monad supporting labeling of values and a monad transformer supporting+-- the consistent labeling of keys.+--+-- TODO: Split module into transformer part and type class instance part along+-- the lines of the transformers package.+module Control.Monad.Label where++import qualified Data.Map as M++import Control.Applicative hiding (empty)+import Control.Monad.Identity+import Control.Monad.State+import Control.Monad.Reader+++------------------------------------------------------------------------------+-- MonadLabel typeclass+------------------------------------------------------------------------------++-- | A monad allowing for labelling keys.+class (Applicative m, Monad m) => MonadLabel k l m where+ label :: k -> m l++-- Instances for other monad tranforerms+-- TODO: Add more++instance (MonadLabel k l m) => MonadLabel k l (StateT s m) where+ label = lift . label++instance (MonadLabel k l m) => MonadLabel k l (ReaderT r m) where+ label = lift . label+++------------------------------------------------------------------------------+-- ConsistentLabelsT: Monad transformer for consistent labeling.+------------------------------------------------------------------------------++-- | A monad transformer implementing consistent (equal keys get equal labels)+-- labeling of keys with a sequence of labels.+newtype ConsistentLabelsT k l m a = ConsistentLabelsT {+ unConsistentLabelsT :: StateT ([l], M.Map k l) m a+ }+ deriving( Functor, Applicative, Monad, MonadTrans )++instance (Ord k, Applicative m, Monad m) => MonadLabel k l (ConsistentLabelsT k l m) where+ label k = ConsistentLabelsT $ do+ (ls, labelMap) <- get+ case M.lookup k labelMap of+ Just i -> return i+ Nothing -> case ls of+ [] -> error "ConsistentLabelsT: label: no more labels left."+ (l:ls') -> do put (ls', M.insert k l labelMap)+ return l++-- | Run a computation requiring consistent labels.+runConsistentLabelsT :: ConsistentLabelsT k l m a -> [l] -> m (a, ([l], M.Map k l))+runConsistentLabelsT m labels = runStateT (unConsistentLabelsT m) (labels, M.empty)++-- | Evaluate a computation requiring consistent labels.+evalConsistentLabelsT :: Functor m => ConsistentLabelsT k l m a -> [l] -> m a+evalConsistentLabelsT m labels = fst <$> runConsistentLabelsT m labels++-- | Execute a computation requiring consistent labels.+execConsistentLabelsT :: Functor m => ConsistentLabelsT k l m a -> [l] -> m ([l], M.Map k l)+execConsistentLabelsT m labels = snd <$> runConsistentLabelsT m labels+++-- Default instance+-------------------++type ConsistentLabels k l = ConsistentLabelsT k l Identity++-- | Run a computation requiring consistent labels.+runConsistentLabels :: ConsistentLabels k l a -> [l] -> (a, ([l], M.Map k l))+runConsistentLabels m = runIdentity . runConsistentLabelsT m++-- | Evaluate a computation requiring consistent labels.+evalConsistentLabels :: ConsistentLabels k l a -> [l] -> a+evalConsistentLabels m = fst . runConsistentLabels m++-- | Execute a computation requiring consistent labels.+execConsistentLabels :: ConsistentLabels k l a -> [l] -> ([l], M.Map k l)+execConsistentLabels m = snd . runConsistentLabels m +++++
@@ -0,0 +1,246 @@+{-# OPTIONS_GHC -fno-warn-type-defaults #-}+-- remove the two benign defaults++-- | A simple color module for handling RGB and HSV representations of colors.+module Data.Color (+ -- * Datatypes+ RGB(..)+ , HSV(..)+ , rgbToHex+ , hsvToHex++ -- ** Predefined colors+ , red+ , green+ , blue+ + -- ** Conversions+ , rgbToGray+ , hsvToGray+ , rgbToHSV+ , hsvToRGB++ -- * Color Palettes+ , colorGroups+ , lightColorGroups++) where++{- IDEA: Provide color datastructure together with nice and usable color+ - palettes for reporting various data+ -}++import Numeric (showHex)++-- import Text.XHtml.Strict+-- import Text.XHtml.Table++data RGB a = RGB {+ rgbR :: !a+ , rgbG :: !a+ , rgbB :: !a+ }+ deriving( Eq, Ord )++instance Show a => Show (RGB a) where+ show (RGB r g b) = "RGB("++show r++", "++show g++", "++show b++")"++instance Functor RGB where+ fmap f (RGB r g b) = RGB (f r) (f g) (f b)++red, green, blue :: Fractional t => RGB t+red = RGB 1.0 0.0 0.0+green = RGB 0.0 1.0 0.0+blue = RGB 0.0 0.0 1.0++data HSV a = HSV {+ hsvH :: !a+ , hsvS :: !a+ , hsvV :: !a+ }+ deriving( Eq, Ord )++instance Show a => Show (HSV a) where+ show (HSV h s v) = "HSV("++show h++", "++show s++", "++show v++")"++instance Functor HSV where+ fmap f (HSV h s v) = HSV (f h) (f s) (f v)+++------------------------------------------------------------------------------+-- Colorspace conversion+------------------------------------------------------------------------------++-- | RGB to HSV conversion.+-- Pre: 0 <= r,g,b <= 1+-- (Source: http://de.wikipedia.org/wiki/HSV-Farbraum)+rgbToHSV :: (Fractional t, Ord t) => RGB t -> HSV t+rgbToHSV (RGB r g b) = HSV h' s v+ where+ ub = max r (max g b)+ lb = min r (min g b)++ h | ub == lb = 0+ | ub == r = 60 * ( (g-b)/(ub-lb))+ | ub == g = 60 * (2 + (b-r)/(ub-lb))+ | otherwise = 60 * (4 + (r-g)/(ub-lb))++ h' | h < 0 = h + 360 + | otherwise = h++ s | ub == 0 = 0+ | otherwise = (ub-lb)/ub++ v = ub++-- | HSV to RGB conversion.+-- Pre: 0 <= h <= 360 and 0 <= s,v <= 1+-- (Source: http://de.wikipedia.org/wiki/HSV-Farbraum)+hsvToRGB :: RealFrac t => HSV t -> RGB t+hsvToRGB (HSV h s v) = case hIdx of+ 0 -> RGB v t p+ 1 -> RGB q v p+ 2 -> RGB p v t+ 3 -> RGB p q v+ 4 -> RGB t p v+ 5 -> RGB v p q+ _ -> error "hsvToRGB: hue outside of range [0..360]"+ where+ hIdx = floor (h / 60)+ f = h/60 - fromIntegral (hIdx::Int)+ p = v*(1-s)+ q = v*(1-s*f)+ t = v*(1-s*(1-f))++hsvToGray :: Num t => HSV t -> HSV t+hsvToGray (HSV h _ v) = HSV h 0 v++rgbToGray :: Ord t => RGB t -> t+rgbToGray (RGB r g b) = max r (max g b)++------------------------------------------------------------------------------+-- String output+------------------------------------------------------------------------------++-- | Hexadecimal representation of an RGB value+rgbToHex :: RealFrac t => RGB t -> String+rgbToHex (RGB r g b) = ('#':) . showHex' r . showHex' g . showHex' b $ ""+ where showHex' f+ | i <= 15 = ('0':) . showHex i+ | otherwise = showHex i+ where + i :: Int+ i = max 0 (min 255 (floor (256 * f)))++-- | Hexadecimal representation of an HSV value; i.e., of its corresponding RGB+-- value.+hsvToHex :: RealFrac t => HSV t -> [Char]+hsvToHex = rgbToHex . hsvToRGB+++------------------------------------------------------------------------------+-- HSV Color Palettes+------------------------------------------------------------------------------++data ColorParams t = ColorParams {+ cpScale :: !t+ , cpZeroHue :: !t+ , cpVBottom :: !t+ , cpVRange :: !t+ , cpSBottom :: !t+ , cpSRange :: !t+ }+ deriving( Eq, Ord, Show )++-- | From a list of group sizes build a function assigning every element a+-- unique color, nicely distributed such that they are well differentiated both+-- using color and monochrome displays.+genColorGroups :: RealFrac t => + ColorParams t + -> [Int] -- ^ List of group sizes.+ -> [((Int,Int),(HSV t))]+genColorGroups (ColorParams { + cpScale = scale + , cpZeroHue = zeroHue + , cpVBottom = vBot, cpVRange = vRan+ , cpSBottom = sBot, cpSRange = sRan+ }) groups = + do+ (groupIdx, groupSize) <- zip [0.. ] groups+ elemIdx <- [0..groupSize - 1]+ let h = toShiftedGroupHue groupIdx (fromIntegral elemIdx / fromIntegral groupSize)+ v = vBot + vRan * toGroupHue groupIdx (fromIntegral elemIdx / fromIntegral groupSize)+ s = sBot + sRan * toGroupHue groupIdx (fromIntegral elemIdx / fromIntegral groupSize)+ color = HSV (360*h) s v + return ((groupIdx, elemIdx), color)+ where+ nGroups :: Int+ nGroups = length groups++ toGroupHue g h = (+ fromIntegral g + -- base position+ 0.5 * (1 - scale) + -- left margin+ (h * scale) -- position in margin+ ) / (fromIntegral nGroups)+ + toShiftedGroupHue g h =+ snd . properFraction $ toGroupHue g h + 1 + + (zeroHue/360) - toGroupHue 0 0.5+++-- | A good default style for the 'genColorGroups' color palette function. The+-- parameter shifts the hue for the first group.+colorGroupStyle :: Double -> ColorParams Double+colorGroupStyle zeroHue = ColorParams {+ cpScale = 0.6+ , cpZeroHue = zeroHue+ , cpVBottom = 0.75, cpVRange = 0.2+ , cpSBottom = 0.4, cpSRange = 0.00+ }++-- | Build color groups according to the list of group sizes using the default+-- 'colorGroupStyle' for the function 'genColorGroups'.+colorGroups :: Double -> [Int] -> [((Int, Int), HSV Double)]+colorGroups zeroHue = genColorGroups (colorGroupStyle zeroHue)+++-- | A good light color style for the @genColorGroups@ color palette+-- function. The parameter shifts the hue for the first group.+lightColorGroupStyle :: Double -> ColorParams Double+lightColorGroupStyle zeroHue = ColorParams {+ cpScale = 0.6+ , cpZeroHue = zeroHue+ , cpVBottom = 0.8, cpVRange = 0.15+ , cpSBottom = 0.3, cpSRange = 0.00+ }++-- | Build color groups according to the list of group sizes using the+-- default light 'lightColorGroupStyle' for the function+-- 'genColorGroups'.+lightColorGroups :: Double -> [Int] -> [((Int, Int), HSV Double)]+lightColorGroups zeroHue = genColorGroups (lightColorGroupStyle zeroHue)+++------------------------------------------------------------------------------+-- Testing: Html Table with group colors+------------------------------------------------------------------------------++{-++colorTable :: Double -> (HSV Double -> HSV Double) -> [Int] -> Html+colorTable zeroHue conv groups = + table . toHtml . besides $ map col [0..length groups-1]+ where+ col i = aboves [cell $ (td ! [getStyle i j]) (stringToHtml (show (i,j)))+ | j <- [0..(groups !! i) - 1] ]+ color = colorGroups zeroHue groups+ getStyle i j = thestyle ("background-color: "++ hsvToHex (conv $ color i j))++colorFile :: Double -> FilePath -> [Int] -> IO ()+colorFile zeroHue outF groups = do+ let html = colorTable zeroHue id groups ++++ colorTable zeroHue hsvToGray groups+ writeFile outF $ prettyHtml html++-}+
@@ -0,0 +1,60 @@+-- | Simple vertice list based representation of DAGs and some common operations on it.+module Data.DAG.Simple (+ toposort+ , reachableSet+ , cyclic+) where+++import Data.List+import qualified Data.Set as S++import Control.Basics+import Control.Monad.Writer+++-- | Produce a topological sorting of the given relation. If the relation is+-- cyclic, then the result is at least some permutation of all elements of+-- the given relation.+toposort :: Ord a => [(a, a)] -> [a]+toposort dag = + execWriter . foldM visit S.empty $ map fst dag ++ map snd dag+ where + visit visited x + | x `S.member` visited = return visited+ | otherwise =+ foldM visit (S.insert x visited) preds <* tell (pure x)+ where+ preds = [ e | (e,e') <- dag, e' == x ]+++-- | Compute the set of nodes reachable from the given set of nodes.+reachableSet :: Ord a => [a] -> [(a,a)] -> S.Set a+reachableSet start dag = + foldl' visit S.empty start+ where + visit visited x + | x `S.member` visited = visited+ | otherwise =+ foldl' visit (S.insert x visited) succs+ where+ succs = [ e' | (e,e') <- dag, e == x ]++-- | Is the relation cyclic.+cyclic :: Ord a => [(a,a)] -> Bool+cyclic rel = + maybe True (const False) $ foldM visitForest S.empty $ map fst rel+ where + visitForest visited x+ | x `S.member` visited = return visited+ | otherwise = findLoop S.empty visited x++ findLoop parents visited x + | x `S.member` parents = mzero+ | x `S.member` visited = return visited+ | otherwise = + S.insert x <$> foldM (findLoop parents') visited next+ where+ next = [ e' | (e,e') <- rel, e == x ]+ parents' = S.insert x parents+
@@ -0,0 +1,268 @@+-- | Simple table representation. This module is meant to be imported qualified.+module Data.Table (+ -- * Datatypes+ Alignment(..)+ , Table++ -- ** Queries+ , toList+ , alignments+ , defaultAlignment+ , columns+ , rows++ -- ** Construction/Modification+ , empty+ , fromList+ , newRow+ , setAlignment+ , appendCell+ , appendNumCell++ -- ** Cell based access+ , getCell+ , setCell+ , headerLastCell+ , alignLastCell++ -- ** Pretty Printing+ , toLaTeX+) where++import Safe+import Data.List+import qualified Data.IntMap as IM++import Extension.Prelude++------------------------------------------------------------------------------+-- Helper functions+------------------------------------------------------------------------------++-- | Round a number to the given amount of decimals.+roundDecimal :: RealFrac a + => Int -- ^ Number of decimals after the decimal point+ -> a -> a+roundDecimal d n = fromIntegral ((round (multiplier * n))::Integer) / multiplier+ where + multiplier :: RealFrac a => a+ multiplier = 10 ^^ d++-- | The maximum key of an 'IntMap', if there is one.+maxKey :: IM.IntMap a -> Maybe Int+maxKey = fmap (fst.fst) . IM.maxViewWithKey++-- | The minimal length of an array indexable by indices from '0' to 'maxKey'.+denseLength :: IM.IntMap a -> Int+denseLength = maybe 0 succ . maxKey++-- | Convert the sparse intmap to a dense list, filling the gaps with the given+-- default element.+toDenseList :: a -> IM.IntMap a -> [a]+toDenseList def m = case maxKey m of+ Just k -> merge [0..k] (IM.toList m)+ Nothing -> []+ where+ merge [] vs = map snd vs+ merge ks [] = replicate (length ks) def+ merge ks@(k:ks') vs@((idx,v):vs') = case compare k idx of+ LT -> def : merge ks' vs+ EQ -> v : merge ks' vs'+ GT -> v : merge ks vs'++-- | Convert a dense list to an 'IntMap' assuming the list has consecutive+-- indexes starting from '0'.+fromDenseList :: [a] -> IM.IntMap a +fromDenseList = IM.fromList . zip [0..]++------------------------------------------------------------------------------+-- Table datatype+------------------------------------------------------------------------------++type Cells a = IM.IntMap (IM.IntMap a)++-- | A column alignment.+data Alignment = AlignLeft | AlignRight+ deriving( Eq, Ord, Show )++-- | A table with aligned rows.+data Table a = Table { + alignments :: IM.IntMap Alignment -- ^ The alignment for each column+ , headers :: IM.IntMap a -- ^ The headers for each column+ , getCells :: Cells a -- ^ Cells indexed first by rows then by columns+ }+ deriving( Eq, Ord, Show )++instance Functor Table where+ fmap f = mapCellsAndHeaders (IM.map (IM.map f)) (IM.map f)++------------------------------------------------------------------------------+-- Queries+------------------------------------------------------------------------------++-- | The default alignment to be used for a row.+defaultAlignment :: Alignment+defaultAlignment = AlignLeft++-- | The number of columns of the table.+columns :: Table a -> Int+columns = maximumDef 0 . map (denseLength . snd) . IM.toList . getCells++-- | The number of rows of the table.+rows :: Table a -> Int+rows = denseLength . getCells++-- | Retrieve the contents of a cell if it exists.+getCell :: (Int,Int) -> Table a -> Maybe a+getCell (rowIdx, colIdx) = (IM.lookup colIdx =<<) . IM.lookup rowIdx . getCells+ +-- | View the index and the contents of the last cell.+viewLastCell :: Table a -> Maybe ((Int, Int), a)+viewLastCell t = do+ ((rowIdx,row), _) <- IM.maxViewWithKey $ getCells t+ ((colIdx,cell), _) <- IM.maxViewWithKey $ row+ return ((rowIdx, colIdx), cell)++-- | Retrieve the index of the last cell.+lastCellIndex :: Table a -> Maybe (Int, Int)+lastCellIndex = fmap fst . viewLastCell++toList :: a -> Table a -> [[a]]+toList def = map (toDenseList def) . toDenseList IM.empty . getCells++------------------------------------------------------------------------------+-- Table construction+------------------------------------------------------------------------------++-- Internal helper functions+----------------------------++-- | Updtate the alignments.+mapAlignments :: (IM.IntMap Alignment -> IM.IntMap Alignment) -> Table a -> Table a+mapAlignments f t = t { alignments = f (alignments t) }++-- | Updtate the headers.+mapHeaders :: (IM.IntMap a -> IM.IntMap a) -> Table a -> Table a+mapHeaders f = mapCellsAndHeaders id f++-- | Update the cells.+mapCells :: (Cells a -> Cells a) -> Table a -> Table a+mapCells f = mapCellsAndHeaders f id++-- | Updtate the headers and the cells+mapCellsAndHeaders :: (Cells a -> Cells b) + -> (IM.IntMap a -> IM.IntMap b) + -> Table a -> Table b+mapCellsAndHeaders fCells fHeaders t = + t { headers = fHeaders (headers t), getCells = fCells (getCells t) }+++-- Externally available functions+---------------------------------++-- | Emtpy table.+empty :: Table a+empty = Table IM.empty IM.empty IM.empty++-- | Convert a list of rows to a table.+fromList :: [[a]] -> Table a+fromList = Table IM.empty IM.empty . fromDenseList . map fromDenseList++-- | Set the alignment of the given column.+setAlignment :: Int -> Alignment -> Table a -> Table a+setAlignment colIdx alignment = mapAlignments (IM.insert colIdx alignment)++-- | Set the header of the given column.+setHeader :: Int -> a -> Table a -> Table a+setHeader colIdx header = mapHeaders (IM.insert colIdx header)++-- | Set the contents of a cell.+setCell :: (Int,Int) -> a -> Table a -> Table a+setCell idx@(rowIdx, colIdx) x + | rowIdx < 0 || colIdx < 0 = error $ "setCell: index out of range" ++ show idx+ | otherwise = mapCells (IM.alter changeRow rowIdx)+ where+ changeRow Nothing = Just $ IM.singleton colIdx x+ changeRow (Just row) = Just $ IM.insert colIdx x row++-- | Add a new empty row to the table.+newRow :: Table a -> Table a+newRow = mapCells $ \cells -> case maxKey cells of+ Just rowIdx -> IM.insert (succ rowIdx) IM.empty cells+ Nothing -> IM.singleton 0 IM.empty++-- | Append a cell at the end of the last row +appendCell :: a -> Table a -> Table a+appendCell cell = mapCells $ \cells -> + case IM.maxViewWithKey cells of+ Just ((rowIdx,row),cellsNoRow) ->+ case maxKey row of+ Just colIdx -> IM.insert rowIdx (IM.insert (succ colIdx) cell row) cellsNoRow+ Nothing -> IM.insert rowIdx (IM.singleton 0 cell) cellsNoRow+ Nothing -> IM.singleton 0 (IM.singleton 0 cell)++-- | Set the alignemnt of the last cell.+alignLastCell :: Alignment -> Table a -> Table a+alignLastCell al t = case lastCellIndex t of+ Just (_, colIdx) -> setAlignment colIdx al t+ Nothing -> t++headerLastCell :: a -> Table a -> Table a+headerLastCell header t = case lastCellIndex t of+ Just (_, colIdx) -> setHeader colIdx header t+ Nothing -> t++-- | Append a cell containing a number; i.e. round and right align.+appendNumCell :: RealFrac a + => Int -- ^ Number of digits after the decimal point+ -> a -> Table String -> Table String+appendNumCell dec x = + alignLastCell AlignRight . appendCell (show $ roundDecimal dec x)+++------------------------------------------------------------------------------+-- Pretty printing+------------------------------------------------------------------------------++type Aligner a = Int -- ^ The length to achieve.+ -> [a] -- ^ The current list.+ -> [a] -- ^ The aligned list.++-- | Align the number of elements in each list using the given alignment function.+alignBy :: Aligner a -> [[a]] -> [[a]]+alignBy _ [] = []+alignBy expand rs = map (expand maxLength) rs+ where+ maxLength = maximum $ map length rs++-- | Align the contents of each cell using the given aligment for each row.+alignCellsBy :: [Aligner a] -> [[[a]]] -> [[[a]]]+alignCellsBy expanders = + transpose . zipWith alignBy (cycle expanders) . transpose . alignBy (flushLeftBy [[]])++-- | Convert a table to the body of a LaTeX table.+toLaTeX :: (a -> String) -> Table a -> String+toLaTeX toStr t = + formatLines . map formatLine . alignCells . addHeaders . toList "" . fmap toStr $ t+ where+ addHeaders+ | IM.null $ headers t = id+ | otherwise = ((toDenseList "" . IM.map toStr $ headers t):)+ doAlign AlignLeft = flushLeft+ doAlign AlignRight = flushRight+ aligns = toDenseList defaultAlignment (alignments t) ++ repeat defaultAlignment+ alignCells = alignCellsBy (map doAlign aligns)+ formatLine = (++"\\\\") . concat . intersperse " & "+ formatLines = unlines+++------------------------------------------------------------------------------+-- Some (manual) testing+------------------------------------------------------------------------------++{-+test = fromList $ [["simon","where","a"],["new","","world"],[],["order"]]+test1 = setHeader 1 "URGH" .setHeader 1 "WORDL" . appendNumCell 2 10.2 . alignLastCell AlignRight . appendCell "w" $ test++latex = putStrLn . toLaTeX id +-}
@@ -0,0 +1,115 @@+{-# LANGUAGE DeriveDataTypeable #-}+-- | A persistent, but not so efficient union-find structure.+module Data.UnionFind where++import Prelude hiding (map)++import Control.Arrow+import Control.Applicative hiding (empty)++import Data.Maybe+import Data.Monoid+import qualified Data.List as L+import qualified Data.Map as M+import Data.Data+++-- We store a map from every element to the representative of its equivalence+-- class which is the minimal element of the class.+newtype UnionFind a = UnionFind { unUnionFind :: M.Map a a }+ deriving( Eq, Ord, Show, Typeable )++instance Ord a => Monoid (UnionFind a) where+ mempty = empty+ mappend = union++instance (Data a, Ord a) => Data (UnionFind a) where+ gfoldl k z (UnionFind a) = z (unionFind) `k` a++ gunfold k z c = case constrIndex c of+ 1 -> k (z (unionFind))+ _ -> error "Data (UnionFind a): impossible"++ toConstr (UnionFind _) = con_UnionFind++ dataTypeOf _ = ty_T++con_UnionFind :: Constr+con_UnionFind = mkConstr ty_T "UnionFind" [] Prefix++ty_T :: DataType+ty_T = mkDataType "Data.UnionFind.UnionFind" [con_UnionFind]++-- | Smart constructor from a 'M.Map' to a union-find structure.+unionFind :: Ord a => M.Map a a -> UnionFind a+unionFind = fromList . M.toList++map :: (Ord a, Ord b) => (a -> b) -> UnionFind a -> UnionFind b+map f = fromList . fmap (f *** f) . toList++-- | @empty@ is the syntactic identity equivalence relation.+empty :: UnionFind a+empty = UnionFind M.empty++-- | @size uf@ returns the number of stored equalities.+size :: UnionFind a -> Int+size = M.size . unUnionFind++-- | @equate x y uf@ inserts the equality @x = y@ into @uf@.+equate :: Ord a => a -> a -> UnionFind a -> UnionFind a+equate x y (UnionFind uf) + | x == y = UnionFind uf+ | otherwise = UnionFind $ + case (M.lookup x uf, M.lookup y uf) of+ (Nothing, Nothing)+ | x <= y -> M.insert y x uf+ | otherwise -> M.insert x y uf+ + (Just xr, Nothing)+ | xr <= x -> M.insert y xr uf+ | otherwise -> M.insert y x $ update xr x uf+ + (Nothing, Just yr)+ | yr <= y -> M.insert x yr uf+ | otherwise -> M.insert x y $ update yr y uf++ (Just xr, Just yr)+ | xr <= yr -> update yr xr uf+ | otherwise -> update xr yr uf+ where+ update old_rep new_rep = M.map upd+ where+ upd rep | rep == old_rep = new_rep+ | otherwise = rep++fromList :: Ord a => [(a,a)] -> UnionFind a +fromList = equateList empty++equateList :: Ord a => UnionFind a -> [(a,a)] -> UnionFind a+equateList = L.foldl' (flip $ uncurry equate)++toList :: UnionFind a -> [(a,a)]+toList = M.toList . unUnionFind++union :: Ord a => UnionFind a -> UnionFind a -> UnionFind a+union uf1 uf2 + | size uf1 < size uf2 = equateList uf2 $ toList uf1+ | otherwise = equateList uf1 $ toList uf2++-- | @find x uf@ returns the representative of the equivalence class that @x@+-- belongs to in @uf@, if there is any.+find :: Ord a => a -> UnionFind a -> Maybe a+find x = M.lookup x . unUnionFind++-- | @findWithDefault def x uf@ returns the representative of the equivalence+-- class that @x@ belongs to in @uf@ or @def@, if there is no representative.+findWithDefault :: Ord a => a -> a -> UnionFind a -> a+findWithDefault def x = M.findWithDefault def x . unUnionFind++-- | @(x,y) `equiv` uf@ iff @x@ and @y@ are in the same equivalence class with+-- respect to @uf@.+equiv :: Ord a => (a,a) -> UnionFind a -> Bool+equiv (x, y) uf =+ x == y || (fromMaybe False $ (==) <$> find x uf <*> find y uf)++
@@ -0,0 +1,217 @@+-- Functions that could/should have made it into the Prelude or one of the base libraries+module Extension.Prelude where++import Data.Maybe+import Data.List+import qualified Data.Set as S+import qualified Data.Map as M+import Data.Ord (comparing)+import Data.Function (on)+import Data.Foldable (asum)++import Control.Basics++import System.IO++++-- Bool --+----------++implies :: Bool -> Bool -> Bool+implies True p = p+implies False _ = True+++-- Lists --+-----------++singleton :: a -> [a]+singleton x = [x]++-- | check whether the given list contains no duplicates+unique :: Eq a => [a] -> Bool+unique [] = True+unique (x:xs) = x `notElem` xs && unique xs++-- | Sort list and remove duplicates. O(n*log n)+sortednub :: Ord a => [a] -> [a]+sortednub = map head . group . sort++-- | //O(n*log n).// Sort list and remove duplicates with respect to a+-- projection. +sortednubOn :: Ord b => (a -> b) -> [a] -> [a]+sortednubOn proj = map head . groupOn proj . sortOn proj++-- | Keep only the first element of elements having the same projected value+nubOn :: Eq b => (a -> b) -> [a] -> [a]+nubOn proj = nubBy ((==) `on` proj)++-- | //O(n).// Group on a projection of the data to group+groupOn :: Eq b => (a -> b) -> [a] -> [[a]]+groupOn proj = groupBy ((==) `on` proj)++-- | sort on a projection of the data to sort+sortOn :: Ord b => (a -> b) -> [a] -> [a]+sortOn proj = sortBy (comparing proj)++-- | sort on a projection of the data to sort, memorizing the results of the+-- projection in order to avoid recomputation.+sortOnMemo :: Ord b => (a -> b) -> [a] -> [a]+sortOnMemo proj = map fst . sortOn snd . map (id &&& proj)++-- | sort and group on a projection+groupSortOn :: Ord b => (a -> b) -> [a] -> [[a]]+groupSortOn proj = groupOn proj . sortOn proj++-- | partition the given set into equality classes with respect+-- to the representative given by the projection function+eqClasses :: (Eq b, Ord b) => (a -> b) -> [a] -> [[a]]+eqClasses = eqClassesBy ord+ where ord x y | x == y = EQ | x < y = LT | otherwise = GT++eqClassesBy :: (b -> b -> Ordering) -> (a -> b) -> [a] -> [[a]]+eqClassesBy ord proj = groupBy eq . sortBy ord'+ where ord' x y = ord (proj x) (proj y)+ eq x y = ord' x y == EQ++-- | split a list into sublists whenever the predicate identifies an element as+-- a separator. Note that the separator is not retained and a separator at the+-- very end is ignored.+splitBy :: (a -> Bool) -> [a] -> [[a]]+splitBy p = unfoldr split+ where split [] = Nothing+ split xs = let ~(w,r) = break p xs in case r of+ [] -> Just $ (w,[])+ (_:rest) -> Just $ (w,rest)+++-- | the list of all permutations of a given list+-- permutations :: [a] -> [[a]]+-- permutations [] = [[]]+-- permutations zs = aux zs []+ -- where aux [] _ = []+ -- aux (x:xs) ys = [x:p | p <- permutations (xs++ys)] ++ aux xs (x:ys)++-- | the list of all combinations of n elements of a list. +-- E.g. choose 2 [1,2,3] = [[1,2],[1,3],[2,3]]+choose :: Int -> [a] -> [[a]]+choose 0 _ = [[]]+choose _ [] = []+choose n (x:xs) = [x:xs' | xs' <- choose (n-1) xs] ++ choose n xs++-- | build the list of lists each leaving another element out. +-- (From left to right)+leaveOneOut :: [a] -> [[a]]+leaveOneOut xs = + zipWith (++) (map init . tail . inits $ xs) (map tail . init . tails $ xs)+++-- | An element masks another element if the predicate is true. This function+-- keeps only the elements not masked by a previous element in the list.+keepFirst :: (a -> a -> Bool) -> [a] -> [a]+keepFirst _ [] = []+keepFirst mask (x:xs) = x : keepFirst mask (filter (not . mask x) xs)++-- Pairs --+-----------++-- | These functions were inspired by the ML library accompanying the +-- Isabelle theorem prover (<http://isabelle.in.tum.de/>)++-- | swap the elements of a pair+swap :: (a, b) -> (b, a)+swap (x, y) = (y, x)++-- | sort the elements of a pair+sortPair :: Ord a => (a,a) -> (a,a)+sortPair p@(x,y) | x <= y = p | otherwise = swap p+++-- Either --+------------++isRight :: Either a b -> Bool+isRight (Right _) = True+isRight _ = False++isLeft :: Either a b -> Bool+isLeft (Left _) = True+isLeft _ = False++-- Strings --+-------------++-- | Name values of a given type+type Named a = (String, a)++-- | Extend a list with the given separators to be flushed right.+flushRightBy :: [a] -> Int -> [a] -> [a]+flushRightBy sep n str = take (max 0 (n - length str)) (cycle sep) ++ str++-- | Extend a string with spaces to be flushed right.+flushRight :: Int -> String -> String+flushRight = flushRightBy " "++-- | Extend a list with the given separators to be flushed left.+flushLeftBy :: [a] -> Int -> [a] -> [a]+flushLeftBy sep n str = str ++ take (max 0 (n - length str)) (cycle sep)++-- | Extend a string with spaces to be flushed left.+flushLeft :: Int -> String -> String+flushLeft = flushLeftBy " "+++-- IO --+--------+++-- | marks a string as being a warning+warning :: String -> String+warning s = "warning: "++s++-- | abbreviation to print to stderr+putErr :: String -> IO ()+putErr = hPutStr stderr++-- | abbreviation to println to stderr+putErrLn :: String -> IO ()+putErrLn = hPutStrLn stderr++-- Applicative --+-----------------++-- | Inject the elements of a list as alternatives.+oneOfList :: Alternative f => [a] -> f a+oneOfList = asum . map pure++-- | Inject the elements of a set as alternatives.+oneOfSet :: Alternative f => S.Set a -> f a+oneOfSet = oneOfList . S.toList++-- | Inject the elements of a map as alternatives.+oneOfMap :: Alternative f => M.Map k v -> f (k, v)+oneOfMap = oneOfList . M.toList+++-- Monads --+------------++-- | A monadic if statement+ifM :: Monad m => m Bool -> m a -> m a -> m a+ifM p pos neg = do+ b <- p+ if b then pos else neg++-- | Gather all error free computations.+errorFree :: MonadPlus m => [m a] -> m [a]+errorFree ms = + catMaybes `liftM` sequence [(Just `liftM` m) `mplus` return Nothing | m <- ms]++-- | Gather all error free computations and ensure that at least one was error+-- free.+errorFree1 :: MonadPlus m => [m a] -> m [a]+errorFree1 ms = do+ ms' <- errorFree ms+ if null ms' then mzero else return ms'+
@@ -0,0 +1,857 @@+{-# LANGUAGE DeriveDataTypeable #-}+module Main where++import Data.Maybe+import Data.Char+import Data.List+import Data.Time.Clock+import Data.Time.Format ()+import qualified Data.Table as T+import Data.Version (showVersion)+import Data.Typeable (Typeable)++import Control.Basics+import Control.Monad.Identity+import Control.Monad.Reader+import Control.Exception as E+import Control.Concurrent.MVar++import qualified Text.Isar as Isar++import System.Exit+import System.IO+import System.FilePath+import System.Directory+import System.Isabelle+import System.Info+import System.Timeout+import System.Timing+import System.Environment+import System.Process++import System.Console.CmdArgs.Explicit+import System.Console.CmdArgs.Text++import Extension.Prelude++-- import Logic.FOL.Sorted.TPTP+-- import Scyther.Theory.FOL++import Scyther.Facts hiding (MVar, empty)+import Scyther.Sequent+import Scyther.Proof+import Scyther.Theory+import Scyther.Theory.Parser+import Scyther.Theory.Pretty+import Scyther.Theory.Html++import Scyther.GoalFlow++import Paths_scyther_proof++------------------------------------------------------------------------------+-- Version information and global constants+------------------------------------------------------------------------------++-- | Program name+programName :: String+programName = "scyther-proof"++-- | Version string+versionStr :: String+versionStr = concat+ [ programName+ , " "+ , showVersion version+ , ", (C) Simon Meier, ETH Zurich, 2009-2011"+ ]++-- | Version string with HTML markup.+htmlVersionStr :: String+htmlVersionStr = concat+ [ link "http://people.inf.ethz.ch/meiersi/espl" programName+ , " "+ , showVersion version+ , ", © "+ , link "http://people.inf.ethz.ch/meiersi" "Simon Meier"+ , ", ETH Zurich, 2009-2011"+ ]+ where+ link href name = + "<a href=\"" ++ href ++ "\" target=\"new\">" ++ name ++ "</a>"++-- | Line width to use.+lineWidth :: Int+lineWidth = 110++-- | ESPL Theory directory.+esplTheoryDir :: IO String+esplTheoryDir = getDataFileName "isabelle"+++------------------------------------------------------------------------------+-- Argument parsing helpers+------------------------------------------------------------------------------++type Arguments = [(String,String)]++argExists :: String -> Arguments -> Bool+argExists a = isJust . findArg a++findArg :: MonadPlus m => String -> Arguments -> m String+findArg a' as = msum [ return v | (a,v) <- as, a == a' ]++findCheckedArg :: (Read a, MonadPlus m) => (a -> Bool) -> String -> Arguments -> m a+findCheckedArg p a as = do+ x <- read `liftM` findArg a as+ guard (p x)+ return x++getArg :: String -> Arguments -> String+getArg a = + fromMaybe (error $ "getArg: argument '" ++ a ++ "' not found") . findArg a++addArg :: String -> String -> Arguments -> Arguments+addArg a v = ((a,v):)++withArguments :: Mode Arguments -> (Arguments -> IO ()) -> IO ()+withArguments argMode io = do+ processArgs argMode >>= run+ where+ run as+ | argExists "help" as = print $ helpText HelpFormatAll argMode+ | argExists "version" as = putStrLn versionStr+ | otherwise = io as++ +------------------------------------------------------------------------------+-- Argument Parsing+------------------------------------------------------------------------------+ +-- | ProofStrategy that should be used for selecting the desired proof.+data ProofStrategy = + NoProof+ -- ^ Don't prove anything.+ | Shortest+ -- ^ Search proof with the fewest number of chain rule applications.+ | First+ -- ^ Return the first found proof.+ deriving( Show, Eq )++-- | Determine how proven lemmas should be reused.+data Reuse =+ NoReuse+ -- ^ Do not reuse any lemmas.+ | ContradictionReuse+ -- ^ Reuse implications with 'FFalse' as conclusion.+ | AllReuse+ -- ^ Reuse all lemmas if possible.+ -- conclusion.+ deriving( Show, Eq )++-- | Print mode to be used for the output.+data PrintMode =+ SPTheory -- ^ Output as a security protocol theory.+ | IsarXSymbol -- ^ Output as an Isabelle theory using XSymbol symbols.+ | IsarASCII -- ^ Output as an Isabelle theory using ASCII symbols.+ deriving( Show, Eq )++data Command = + Translate {+ fstrategy :: ProofStrategy+ , fbound :: Int+ , freuse :: Reuse+ , fnoMinimize :: Bool+ , fnoSoundness :: Bool+ , fnoAttackSearch :: Bool+ , foverview :: Bool+ -- , ffol :: Bool+ , fisabelle :: Bool+ , fisabelleCores :: Int+ , fnoGeneration :: Bool+ , fmaxTime :: Int+ , fhide :: String+ , fhtml :: Bool+ , flineWidth :: Int+ , fprintMode :: PrintMode+ , foutputFile :: FilePath+ , foutputDir :: FilePath+ , freportFile :: FilePath+ , ffiles :: [FilePath]+ }+ deriving( Show )++-- | Main mode.+setupMainMode :: IO (Mode [(String,String)])+setupMainMode = do+ examplePath <- getDataFileName "examples"+ readmePath <- getDataFileName "isabelle/README"+ isabellePath <- esplTheoryDir+ return $ + ( defaultMode programName+ "Automatic generation of machine-checked proofs for security protocols."+ [ "Additional information:"+ , " Path to example protocol models: '" ++ examplePath ++ "'"+ , " Path to Isabelle/HOL security protocol theory: '" ++ isabellePath ++ "'"+ , " "+ , " The '--html' flag requires the 'dot' tool from GraphViz available at:"+ , " " ++ "http://www.graphviz.org/"+ , " "+ , " The '--isabelle' flag requires the 'Isabelle-2009-1' release of Isabelle/HOL:"+ , " " ++ "http://isabelle.in.tum.de/website-Isabelle2009-1/download_x86-linux.html"+ , ""+ , " Check the '" ++ readmePath ++ "' file for instructions on how to load the generated theory files in Isabelle's interactive mode."+ ]+ )+ { modeCheck = upd "mode" "translate"+ , modeArgs = Just $ flagArg (upd "inFile") "FILES"+ , modeGroupFlags = Group + { groupUnnamed =+ [ flagNone ["first", "f"] (addArg "strategy" "first")+ "Return the first found proof."++ , flagNone ["shortest", "s"] (addArg "strategy" "shortest")+ "Return the shortest proof w.r.t number of chain rule applications."++ , flagOpt "5" ["bound", "b"] (upd "bound") "INT"+ "Bound the depth of the proofs (0 for no bound)."++ , flagNone ["no-reuse"] (addArg "reuse" "none")+ "Do not reuse any previously proven properties."++ , flagNone ["secrecy-reuse"] (addArg "reuse" "secrecy")+ "Reuse serecy properties only."++ , flagNone ["no-minimize"] (addEmpty "noMinimize")+ "Do not minimize the number of forward resolutions."++ , flagNone ["no-soundness-check"] (addEmpty "noSoundness")+ "Do not output a list of properties with unsound proofs."++ , flagNone ["no-attack-search"] (addEmpty "noAttackSearch")+ "Do not search for attacks before attempting a proof."++ , flagNone ["overview"] (addEmpty "overview")+ "Generate a protocol overview."++ , flagNone ["compose-parallel"] (addEmpty "composeParallel")+ "Compose all security protocols in the theory in parallel."++ , flagOpt "isabelle" ["isabelle","i"] (upd "isabelle") "PATH"+ "Check resulting proof script using the 'isabelle' tool from Isabelle/HOL."++ , flagOpt "0" ["isabelle-threads"] (upd "isabelleThreads") "INT"+ "Number of parellel threads to be used for proof checking. \+ \(The default is to use as many threads as there are cores.)"++ , flagNone ["no-generation"] (addEmpty "noGeneration")+ "Do not generate the theory files, but check the results using Isabelle."++ , flagOpt "0" ["timeout"] (upd "timeout") "SECONDS"+ "Timeout in seconds for proof generation and checking."++ , flagOpt "" ["hide-prefix"] (upd "hidePrefix") "VALUE"+ "Hide non-referenced properties with this prefix (default=auto)."++ , flagOpt "dot" ["html"] (upd "html") "PATH"+ "Output Html files visualizing the theory and its proofs using the 'dot' tool from Graphviz. This flag requires an output directory to be set."++ , flagOpt "100" ["chars-per-line"] (upd "charsPerLine") "INT"+ "Characters per line (default=100)."++ , flagNone ["XSymbol", "X"] (addArg "printMode" "XSymbol")+ "Output as an Isabelle theory using XSymbol symbols."++ , flagNone ["ASCII", "A"] (addArg "printMode" "ASCII")+ "Output as an Isabelle theory using ASCII symbols."++ , flagOpt "-" ["report"] (upd "report") "FILE"+ "Write a report file (use - for stdout)."++ ] +++ outputFlags+ , groupHidden = []+ , groupNamed =+ [ ("About"+ , [ flagHelpSimple (addEmpty "help")+ , flagVersion (addEmpty "version")+ ] )+ ]+ }+ }+ where + upd a v = Right . addArg a v+ addEmpty a = addArg a ""++ defaultMode name help helpSuffix = Mode+ { modeGroupModes = toGroup []+ , modeNames = [name] + , modeValue = [] + , modeCheck = upd "mode" name+ , modeReform = const Nothing-- no reform possibility+ , modeHelp = help+ , modeHelpSuffix = helpSuffix+ , modeArgs = Nothing -- no positional arguments+ , modeGroupFlags = toGroup [] -- no flags+ }++ outputFlags = + [ flagOpt "" ["output","o"] (upd "outFile") "FILE" "Output file"+ , flagOpt "" ["Output","O"] (upd "outDir") "DIR" "Output directory"+ ]+++-- | Disply help message and exit.+errHelpExit :: String -> IO ()+errHelpExit msg = do+ mainMode <- setupMainMode+ putStrLn $ "error: " ++ msg+ putStrLn $ ""+ putStrLn $ showText (Wrap 100) + $ helpText HelpFormatDefault mainMode+ exitFailure+++-- | Main function.+main :: IO ()+main = do+ mainMode <- setupMainMode+ withArguments mainMode selectMode+ where+ selectMode as = case findArg "mode" as of+ Just "translate" -> translate as+ Just m -> error $ "main: unknown mode '" ++ m ++ "'"+ Nothing -> error $ "main: no mode given"+++------------------------------------------------------------------------------+-- Translate mode execution+------------------------------------------------------------------------------++-- | Entry point fro executing a translation.+translate :: Arguments -> IO ()+translate as = do+ templateFile <- getDataFileName "HTML_TEMPLATE"+ reportVar <- newMVar T.empty+ translateWorker as templateFile reportVar+++-- | Execute a translation.+translateWorker :: Arguments + -> FilePath -- ^ Path to HTML template file.+ -> MVar (T.Table String) -- ^ Empty MVar for building the report.+ -> IO ()+translateWorker as templateFile reportVar+ | null inFiles = errHelpExit "no input iles given"+ | otherwise = do+ -- check required tools+ when (not dryRun && html) (ensureGraphVizDot dotTool)+ when (not dryRun && isabelle) (ensureIsabelleESPL isabelleTool)+ + -- translate all input files and ensure report is written with a special+ -- interrupted marker when an exception like Ctrl-C happened+ unless (n <= 1) (putInfoLn $ "processing "++show n++" files:")+ bracket_ (return ()) writeReport $+ bracketOnError_ (return ())+ (updateReport (T.appendCell "interrupted"))+ (sequence_ . intersperse reportNewRow $ map translateOneFile inFiles )+ putInfoLn ""+ where+ -- Tool paths+ -----------------------+ isabelleTool = fromMaybe "isabelle" $ findArg "isabelle" as+ dotTool = fromMaybe "dot" $ findArg "html" as++ -- Input files+ -----------------------+ inFiles = findArg "inFile" as+ n = length inFiles++ maxFileNameLength :: Int+ maxFileNameLength = maximum $ map length inFiles++ -- Output files+ ---------------+ dryRun = outFile == "" && outDir == ""+ reportFile = fromMaybe "" $ findArg "report" as+ outFile = fromMaybe "" $ findArg "outFile" as + outDir = fromMaybe "" $ findArg "outDir" as + ++ -- automatically generate the filename for output+ mkAutoPath :: FilePath -> String -> FilePath+ mkAutoPath dir name+ | html = dir </> name+ | otherwise = dir </> addExtension (name ++ "_cert_auto") "thy"++ mkOutPath :: FilePath -- ^ Input file name.+ -> FilePath -- ^ Output file name.+ mkOutPath inFile = + case outFile of+ "" -> case outDir of+ "" -> error "outPath: undefined in dry-run mode"+ dir -> mkAutoPath dir (takeBaseName inFile)+ path -> path++++ -- hidden security properties+ ----------------------+ hide = fromMaybe "auto" $ findArg "hidePrefix" as++ isHidden :: String -> Bool+ isHidden | hide == "" = const False+ | otherwise = (hide `isPrefixOf`)++ removeHiddenItems :: Theory -> Theory+ removeHiddenItems = shrinkTheory (not . isHidden)++ -- protocol composition+ -----------------------+ composeProtos :: Theory -> Theory+ composeProtos + | argExists "composeParallel" as = composeParallel+ | otherwise = id++ -- timeout handling+ -------------------+ maxTime :: Maybe Int+ maxTime = findCheckedArg (0 <) "timeout" as++ execWithTimeout :: IO a -> IO a+ execWithTimeout io = case maxTime of+ Nothing -> io+ Just t -> do+ res <- timeout (t * 1000000) io+ case res of + Nothing -> do+ updateReport (T.appendCell $ "timeout: "++show maxTime++"s")+ throw CustomTimeout+ Just x -> return x++ ignoringTimeout :: IO () -> IO ()+ ignoringTimeout io = E.catch io handler+ where+ handler :: CustomTimeout -> IO ()+ handler _ = return ()++ -- progress output for batch mode+ ---------------------------------+ putInfo msg = unless dryRun (putStr msg >> hFlush stdout)+ putInfoLn msg = unless dryRun (putStrLn msg >> hFlush stdout)++ -- report generation+ --------------------+ reportNewRow :: IO ()+ reportNewRow = updateReport T.newRow >> putInfoLn ""++ reportNumber :: Show a => String -> a -> IO ()+ reportNumber header x = + updateReport (T.headerLastCell header . T.alignLastCell T.AlignRight. T.appendCell (show x))++ reportString :: String -> String -> IO ()+ reportString header msg = + updateReport (T.headerLastCell header . T.appendCell msg)+ + updateReport :: (T.Table String -> T.Table String) -> IO ()+ updateReport + | null reportFile = const $ return () -- no report will be produced => don't update it+ | otherwise = modifyMVar_ reportVar . (return .)++ reportProofSize :: ProofSize -> IO ()+ reportProofSize s = do+ reportNumber "#chain rules" nChains+ reportNumber "#forward resolutions" nForward+ reportNumber "#missing proofs" nMissing+ where + (nChains, nForward, nMissing) = getProofSize s++ reportProperties :: Theory -> IO ()+ reportProperties thy = do+ reportNumber "#sec." nSec+ reportNumber "#auth." nAuth+ reportNumber "#other" nOther+ where+ (nSec, nAuth, nOther) = classifyProperties (not . isHidden) thy++ mkReport :: IO String+ mkReport = do+ table <- readMVar reportVar+ time <- getCurrentTime+ cmdLine <- getCommandLine+ revisions <- (concat . intersperse ", " . nub)+ `liftM` mapM getSvnRevision inFiles+ let header = unlines $ map ("% "++) [+ "generator: " ++ versionStr+ , "command: " ++ cmdLine+ , "date: " ++ show time+ , "system: " ++ arch ++ "/" ++ os+ , "input revs.: " ++ revisions+ ]+ return . concat $ [+ "\n\n"+ , header + , "\n"+ , T.toLaTeX (filter (/='\t')) table+ ]++ writeReport :: IO ()+ writeReport = case reportFile of+ "" -> return ()+ "-" -> mkReport >>= putStrLn+ _ -> mkReport >>= appendFile reportFile+ + -- HTML generation+ ------------------+ generateHtml :: FilePath -- ^ Input file+ -> Theory -- ^ Theory to pretty print+ -> IO ()+ generateHtml inFile thy = do+ cmdLine <- getCommandLine+ time <- getCurrentTime+ cpu <- getCpuModel+ theoryToHtml $ GenerationInput {+ giHeader = "Generated by " ++ htmlVersionStr+ , giTime = time+ , giSystem = cpu+ , giInputFile = inFile+ , giTemplate = templateFile+ , giOutDir = mkOutPath inFile+ , giMarkup = thyToDoc printMode thy+ , giProofScript = + \outPath -> renderDoc . runIdentity . + thyToDoc (ensureIsabellePrintMode printMode) $+ adaptTheoryName outPath thy+ , giCmdLine = cmdLine+ , giDotTool = dotTool+ , giIsabelle = + if isabelle + then Just $ checkTheoryFile isabelleTool isabelleThreads 0 "ESPL"+ else Nothing+ }++ -- Theory input+ ---------------+ overview = argExists "overview" as++ makeOverview :: Theory -> Theory+ makeOverview | overview = protocolsOnly -- theoryOverview+ | otherwise = id+ where+ protocolsOnly (Theory name items) = + Theory name [x | x@(ThyProtocol _) <- items ]++ thyToOverviewDoc :: Theory -> Isar.Doc+ thyToOverviewDoc = goalFlowAnalysis++ readThy :: FilePath -> IO Theory+ readThy inFile = do+ putInfo (flushLeft maxFileNameLength inFile)+ reportString "Protocol" (takeBaseName inFile)+ reportString "Revision" =<< getSvnRevision inFile+ thy <- (makeOverview . ensureUniqueRoleNames) `liftM` parseTheory inFile+ reportProperties thy+ return . + removeHiddenItems .+ proveThy . + composeProtos .+ addMissingTypingInvariants .+ -- if no reuse is done, then remove the hidden items before proving+ -- (but still add missing typing invariants afterwards)+ (if noReuse then removeHiddenItems else id) $+ thy++ -- proving+ ----------+ bound :: Maybe Int+ bound = findCheckedArg (0 <) "bound" as++ noMinimize = argExists "noMinimize" as+ noSoundness = argExists "noSoundness" as+ noAttackSearch = argExists "noAttackSearch" as+ noReuse = Just "noReuse" == findArg "reuse" as++ reuseSelector :: Sequent -> Named Proof -> Bool+ reuseSelector = case findArg "reuse" as of+ Just "noReuse" -> mkReuse $ const False+ Just "secrecyReuse" -> mkReuse $ \th ->+ (complete $ thmProof th) && (FAtom AFalse == seConcl (thmSequent th))+ _ -> mkReuse $ (complete . thmProof)+ where+ mkReuse thmSel se th+ | isTypingFormula $ seConcl se = + -- we do not support reusing in weak atomicity and typing proofs+ -- because the ISAR pretty printer cannot handle it yet correctly.+ False+ | otherwise = + -- type invariants and axioms are always reused+ isAxiom th || (isTypingFormula . seConcl $ thmSequent th) || thmSel th+ + minimizer :: Proof -> Proof+ minimizer | noMinimize = id+ | otherwise = minimizeProof++ proveThy :: Theory -> Theory+ proveThy = case findArg "strategy" as of+ Just "first" -> allClaims $ dfsProof bound oldestOpenMessages+ Just "shortest" -> allClaims $ shortestProof bound oldestOpenMessages+ _ -> id+ where+ allClaims prover0 = + proveSequents reuseSelector prover+ where+ prover toReuse se = fmap minimizer $+ (do guard (not noAttackSearch && bound == Nothing) + -- TODO: Make attack search respect bound.+ existsPossibleAttack oldestOpenMessages toReuse se+ `mplus` + prover0 toReuse se)+ ++ -- Theory output+ ----------------+ noGeneration = argExists "noGeneration" as+ html = argExists "html" as+ isabelle = argExists "isabelle" as + width = maybe lineWidth read $ findArg "charsPerLine" as++ isabelleThreads :: Maybe Int+ isabelleThreads = findCheckedArg (0 <) "isabelleThreads" as++ ensureIsabellePrintMode SPTheory = IsarASCII+ ensureIsabellePrintMode pmode = pmode++ printMode = case findArg "printMode" as of+ Just "ASCII" -> IsarASCII+ Just "XSymbol" -> IsarXSymbol+ Just other -> error $ "internal: unknown printmode '" ++ other ++ "'"+ Nothing | isabelle && not html -> IsarASCII+ | otherwise -> SPTheory++ thyToDoc :: MarkupMonad m => PrintMode -> Theory -> m Isar.Doc+ thyToDoc pmode thy0 = case pmode of+ SPTheory -> runTaggedIdentityT SlimOutput thyDoc + IsarXSymbol -> runReaderT thyDoc (Isar.defaultIsarConf { Isar.isarStyle = Isar.XSymbol })+ IsarASCII -> runReaderT thyDoc Isar.defaultIsarConf+ where+ -- for html output we rename the TID quantifiers in the conclusion+ -- to be clash-free+ thy | html = mapTheorySequents uniqueTIDQuantifiers thy0+ | otherwise = thy0++ thyDoc :: PrettyMonad m => m Isar.Doc+ thyDoc | noSoundness = prettyTheory thy+ | otherwise = prettyTheory thy Isar.$-$ prettySoundness thy++ renderDoc = Isar.renderStyle (Isar.style { Isar.lineLength = width })++ thyToString :: Theory -> String+ thyToString + | html = renderDoc . evalHtmlMarkup . thyToDoc printMode+ -- | fol = render . tptpProblem . toTPTP+ | overview = renderDoc . thyToOverviewDoc+ | otherwise = renderDoc . runIdentity . thyToDoc printMode+ where++ writeThyFile :: FilePath -> Theory -> IO ()+ writeThyFile outPath thy = do+ if not noGeneration + then do+ tGen <- execWithTimeout . timed_ . writeFile outPath .+ thyToString $ adaptTheoryName outPath thy+ let prfSize = theoryProofSize thy+ reportNumber "Generation Time" tGen+ reportProofSize prfSize+ putInfo ('\t' : (flushLeft 9 . show $ prfSize))+ putInfo ('\t' : show tGen)+ else do+ -- ensure columns of report are in line with generatin branch+ reportString "Generation Time" "--no-generation"+ sequence_ . replicate 3 $ reportString "-" "--n"+ if isabelle+ then do+ -- let isabelleTimeout = maxTime * 10^6 -- in microseconds+ let isabelleTimeout = 0 -- because timeout construction for Isabelle is buggy currently+ ((_, result), tCheck) <- timed $ checkTheoryFile isabelleTool isabelleThreads isabelleTimeout "ESPL" outPath+ reportNumber "Checking Time" tCheck+ case result of+ Nothing -> do+ mapM_ (putInfo . ('\t':)) ["successfully checked", show tCheck, ""]+ reportString "Isabelle Status" "checked"+ reportString "Isabelle Message" ""+ Just msg -> do+ mapM_ (putInfo . ('\t':)) ["CHECK FAILED", show tCheck, show msg]+ reportString "Isabelle Status" "check failed"+ reportString "Isabelle Message" (show msg)+ else + return ()++ -- Translate one theory file+ ----------------------------+ -- NOTE: For the timeout mechanism to work you have to take care that+ -- all IO actions forcing this theory are done under the timeout in+ -- writeThyFile. I didn't do this once, which cost me quite some+ -- debugging time.+ processThy :: FilePath -> Theory -> IO ()+ processThy inFile thy + | dryRun = putStrLn (thyToString thy)+ | html = do+ generateHtml inFile thy+ | otherwise = do+ handle (\(ErrorCall errMsg) -> putInfo $ "error: "++errMsg) $+ handle (\(PatternMatchFail errMsg) -> putInfo $ "error: "++errMsg) $ do+ createDirectoryIfMissing True (takeDirectory outPath)+ writeThyFile outPath thy+ where+ outPath = mkOutPath inFile++ translateOneFile :: FilePath -> IO ()+ translateOneFile inFile = ignoringTimeout (readThy inFile >>= processThy inFile)+++------------------------------------------------------------------------------+-- Utility Functions+------------------------------------------------------------------------------++-- | Version of bracket on error with constant error handler and inner IO+-- function.+bracketOnError_ :: IO a -> IO b -> IO c -> IO c+bracketOnError_ aquire onError io = bracketOnError aquire (const onError) (const io)++-- | Custom timeout exception for the use with execWithTimeout+data CustomTimeout = CustomTimeout+ deriving (Show, Typeable)++instance Exception CustomTimeout++-- | Get the string constituting the command line.+getCommandLine :: IO String+getCommandLine = commandLine programName <$> getArgs++-- | Build the command line corresponding to a program arguments tuple.+commandLine :: String -> [String] -> String+commandLine prog args = concat $ intersperse " " $ prog : args++-- | Read the SVN revision of the given file using the SVN command.+getSvnRevision :: FilePath -> IO String+getSvnRevision file = + handle handler $ do+ (_, info, _) <- readProcessWithExitCode "svn" ["info",file] []+ return $ maybe "unversioned"+ (takeWhile isNumber . dropWhile (not.isNumber))+ (find ("Revision:" `isPrefixOf`) $ lines info)+ where+ handler :: IOException -> IO String+ handler _ = return "svn error"++-- | Read the cpu info using a call to cat /proc/cpuinfo+getCpuModel :: IO String+getCpuModel = + handle handler $ do+ (_, info, _) <- readProcessWithExitCode "cat" ["/proc/cpuinfo"] []+ return $ maybe errMsg+ (("Linux running on an "++) . drop 2 . dropWhile (/=':'))+ (find (isPrefixOf "model name") $ lines info)+ where+ errMsg = "could not extract CPU model"+ handler :: IOException -> IO String+ handler _ = return errMsg+++-- | Test if a process is executable and check its response. This is used to+-- determine the versions and capabilities of tools that we depend on.+testProcess :: (String -> String -> Either String String) + -- ^ Analysis of stdout, stderr. Use 'Left' to report error.+ -> String -- ^ Test description to display.+ -> FilePath -- ^ Process to start+ -> [String] -- ^ Arguments+ -> String -- ^ Stdin+ -> IO Bool -- ^ True, if test was successful+testProcess check testName prog args inp = do+ putStr testName+ hFlush stdout+ handle handler $ do+ (exitCode, out, err) <- readProcessWithExitCode prog args inp+ let errMsg reason = do+ putStrLn reason+ putStrLn $ "command: " ++ commandLine prog args+ putStrLn $ "stdin: " ++ inp+ putStrLn $ "stdout: " ++ out+ putStrLn $ "stderr: " ++ err+ return False++ case exitCode of+ ExitFailure code -> errMsg $ "failed with exit code " ++ show code+ ExitSuccess -> + case check out err of+ Left msg -> errMsg msg+ Right msg -> do putStrLn msg+ return True+ where+ handler :: IOException -> IO Bool+ handler _ = do putStrLn "caught exception while executing:"+ putStrLn $ commandLine prog args+ putStrLn $ "with input: " ++ inp+ return False++-- | Ensure a suitable version of the Graphviz dot tool is installed.+ensureGraphVizDot :: FilePath -- ^ Path to the 'dot' tool.+ -> IO ()+ensureGraphVizDot dot = do+ putStrLn $ "checking suitability of GraphViz tool: '" ++ dot ++ "'"+ _ <- testProcess check " checking version: " dot ["-V"] ""+ putStrLn ""+ where+ check _ err+ | "Graphviz" `isInfixOf` err = Right $ init err ++ ". OK."+ | otherwise = Left $ unlines $+ [ "WARNING:"+ , ""+ , " The dot tool seems not to be provided by Graphviz."+ , " Graph generation might not work."+ , " Please download an official version from:"+ , " http://www.graphviz.org/"+ ]+++-- | Ensure a suitable version of the Isabelle/HOL 'isabelle' tool is installed+-- and the 'ESPL' head is compiled.+ensureIsabelleESPL :: FilePath -- ^ Path to the 'isabelle' tool.+ -> IO ()+ensureIsabelleESPL isabelle = do+ putStrLn $ "checking suitability of Isabelle tool: '" ++ isabelle ++ "'"+ _ <- testProcess checkVersion " version: " isabelle ["version"] ""+ success <- testProcess checkLogics " installed logics: " isabelle ["findlogics"] ""+ unless success buildESPL+ putStrLn ""+ where+ checkVersion out _+ | "Isabelle2009-1" `isInfixOf` out = Right $ init out ++ ". OK."+ | otherwise = Left $ unlines $+ [ "WARNING:"+ , ""+ , " " ++ programName ++ " requires Isabelle2009-1."+ , " Proof checking is likely not to work."+ , " Please download Isabelle2009-1 from:"+ , " http://isabelle.in.tum.de/website-Isabelle2009-1/download_x86-linux.html"+ ]++ checkLogics out _+ | "ESPL" `isInfixOf` out = Right $ init out ++ ". OK."+ | otherwise = Left $ init out ++ ". WARNING: ESPL logic not installed."++ buildESPL = do+ putStrLn "---"+ putStrLn "Attempting to build ESPL logic (this may take several minutes):"+ theoryDir <- esplTheoryDir+ hProc <- runProcess isabelle ["make"] (Just theoryDir) Nothing Nothing Nothing Nothing+ exitCode <- waitForProcess hProc+ case exitCode of+ ExitSuccess -> putStrLn "Sucess! :-)\n---"+ ExitFailure code -> putStrLn $ unlines + [ " Logic building failed with code: " ++ show code+ , " Proof checking is likely not to work."+ , " To investigate the problem try manually loading/building the theories in"+ , " '" ++ theoryDir ++ "'"+ ]+
@@ -0,0 +1,697 @@+{-# LANGUAGE DeriveDataTypeable #-}+module Scyther.Equalities (+-- * Single Equalities+ TIDEq+ , TIDRoleEq+ , RoleEq+ , AgentEqRHS+ , AgentEq+ , AVarEq+ , MVarEq+ , MsgEq+ , AnyEq(..)++ , agentEqToMsgEq+ , mvarEqToMsgEq++-- * Compound Equalities+ , Equalities++ -- ** Construction+ , empty+ , solve+ , trimTIDEqs+ , trimAgentEqs++ -- ** Destruction+ , getTIDEqs+ , getTIDRoleEqs+ , getAgentEqs+ , getAVarEqs+ , getMVarEqs+ , getPostEqs+ , toAnyEqs+ , anyEqTIDs++ -- ** Substitution+ , substTID+ , substLocalId+ , substAVar+ , substMVar+ , substAgentId+ , substAgentEqRHS+ , substMsg+ , substAnyEq++ -- ** Additional Queries+ , threadRole+ , maxMappedTID+ , maxMappedAgentId+ , reflexive+ , null++-- * Mapping Logical Variables+ , Mapping(..)+ , emptyMapping+ , mkMapping+ , addTIDMapping+ , addAgentIdMapping+ , addTIDRoleMapping+ , deleteTIDMapping+ , deleteAgentIdMapping++-- * Pretty Printing+ , sptAnyEq+) where++import Prelude hiding (null)++import qualified Data.Map as M+import qualified Data.UnionFind as U+import Data.Data++import Control.Arrow ( (***) )+import Control.Monad++import Text.Isar++import Scyther.Protocol+import Scyther.Message+++------------------------------------------------------------------------------+-- Equalities+------------------------------------------------------------------------------++-- | Equalities over thread identifers. +--+-- Logically these are equalities between logical thread identifier variables.+type TIDEq = (TID, TID)+type TIDEqs = M.Map TID TID++-- | A thread to role assignment.+type TIDRoleEq = (TID, Role)+type TIDRoleEqs = M.Map TID Role++-- | The role equalities serve a double function:+type RoleEq = (Role, Role)++type AgentEqRHS = Either AgentId AVar+type AgentEq = (AgentId, AgentEqRHS)++-- | Like role equalities, the agent equalities specify both quantification and+-- equalities. Recall that an agent id is a logical variable denoting some+-- agent name. Such an agent name is either equal to another agent id or the+-- content of an agent variable of a thread.+type AgentEqs = M.Map AgentId AgentEqRHS++-- | Equalities between different agent variables. +--+-- We do not have to reason about equalities between an agent variable and some+-- other message because our semantics guarantees that agent variables are only+-- instantiated with agent names. Hence, they can only be equal to other agent+-- variables or message variables. In the latter case, we store the equality+-- the other way round; assigning the agent variable to the message variable.+type AVarEq = (AVar, AVar)+type AVarEqs = M.Map AVar AVar++-- | Equalities between message variables and arbitrary messages.+type MVarEq = (MVar, Message)+type MVarEqs = M.Map MVar Message++-- | Equalities between messages.+type MsgEq = (Message, Message)+type MsgEqs = U.UnionFind Message ++-- | Some representable equality.+data AnyEq = + TIDEq !TIDEq+ | TIDRoleEq !TIDRoleEq+ | RoleEq !RoleEq+ | AgentEq !AgentEq+ | AVarEq !AVarEq+ | MVarEq !MVarEq+ | MsgEq !MsgEq+ deriving( Eq, Ord, Show, Data, Typeable )++-- | A conjunction of equality facts.+--+-- Invariants for a value @eqs = Equalities tideqs roleeqs avareqs mvareqs agnteqs@:+--+-- 1. Domain and range normalized with respect to equalities. Note that this implies+-- substitution must always consider TID substitution first.+--+-- forall tid : ran(tideqs). substTID eqs tid = tid+-- forall tid : dom(roleeqs). substTID eqs tid = tid+-- forall (lid, lid') : avareqs. substLocalId eqs lid = lid +-- & substAVar eqs lid' = lid'+-- forall (lid, m) : mvareqs. substLocalId eqs lid = lid +-- & substMsg eqs m = m+-- +-- TODO: Complete properties for Agent ID's+--+-- forall aid : dom(agnteqs). substAgentId eqs aid = Just (Left aid)+-- forall : dom(agnteqs). substAgentId eqs aid = Just (Left aid)+--+--+-- 2. Origin always greater than image for symmetric eqs.+--+-- forall (tid, tid') : tideqs. tid > tid'+-- forall (lid, lid') : avareqs. lid > lid'+--+-- 3. Range of message variable equalities normalized with respect to key inversion.+--+-- forall m : ran(mvareqs). normMsg m = m+--+-- 4. All thread identifiers are in the domain of roleeqs.+--+-- 5. All agent identifiers are in the domain of agnteqs.+--+-- 6. No cycles.+--+data Equalities = Equalities {+ tidEqs :: TIDEqs -- ^ Thread identifier equalities.+ , roleEqs :: TIDRoleEqs -- ^ Thread to role assignments.+ , avarEqs :: AVarEqs -- ^ Equalities between agent variables.+ , mvarEqs :: MVarEqs -- ^ Equalities between message variables and arbitrary messages.+ , agntEqs :: AgentEqs -- ^ Equalities between agent names and agent names or agent variables.+ , postEqs :: MsgEqs -- ^ Postponed equalities that stem from equalities involving+ -- bi-directional keys and cannot be solved without+ -- splitting in their most general form @KShr a b = KShr c d@. We+ -- try to exploit these postponed equalities after+ -- every regular unification.+ }+ deriving( Eq, Ord, Show, Data, Typeable {-! NFData !-} )++-- | Empty equality premises.+empty :: Equalities+empty = Equalities M.empty M.empty M.empty M.empty M.empty U.empty++-- | True if no equalities are present.+null :: Equalities -> Bool+null = (==) empty++-- Substitution+---------------++-- NOTE: Here we exploit that range of equalities does not contain any+-- identifier from the domain.++-- | Substitute a thread identifier according to thread identifier equalities.+substTID :: Equalities -> TID -> TID+substTID eqs tid = M.findWithDefault tid tid (tidEqs eqs)++-- | Substitute a local identifier according to thread identifier equalities.+substLocalId :: Equalities -> LocalId -> LocalId+substLocalId eqs (LocalId (i, tid)) = (LocalId (i, substTID eqs tid))++-- | Substitute a local identifier belonging to an agent variable.+substAVar :: Equalities -> AVar -> AVar+substAVar eqs av = M.findWithDefault av' av' (avarEqs eqs)+ where av' = mapAVar (substLocalId eqs) av++-- | Substitute a local identifier belonging to a message variable.+substMVar :: Equalities -> MVar -> Message+substMVar eqs mv = M.findWithDefault (MMVar mv') mv' (mvarEqs eqs)+ where mv' = mapMVar (substLocalId eqs) mv++-- | Substitute an agent id representing an arbitrary agent name.+substAgentId :: Equalities -> AgentId -> AgentEqRHS+substAgentId eqs aid = M.findWithDefault (Left aid) aid (agntEqs eqs)++-- | Substitute the right-hand-side of an agent id equality.+substAgentEqRHS :: Equalities -> AgentEqRHS -> AgentEqRHS+substAgentEqRHS eqs = either (substAgentId eqs) (Right . substAVar eqs)++-- | Substitute message constituents according to equalities.+--+-- POST: Message normalized w.r.t. 'normMsg'.+substMsg :: Equalities -> Message -> Message+substMsg eqs = normMsg . go+ where+ go m@(MConst _) = m+ go (MFresh fr) = MFresh (mapFresh (substLocalId eqs) fr)+ go (MAVar av) = MAVar (substAVar eqs av)+ go (MMVar mv) = substMVar eqs mv+ go (MAgent aid) = either MAgent MAVar (substAgentId eqs aid)+ go (MHash m) = MHash (go m)+ go (MTup m1 m2) = MTup (go m1) (go m2)+ go (MEnc m1 m2) = MEnc (go m1) (go m2)+ go (MSymK m1 m2) = MSymK (go m1) (go m2)+ go (MShrK m1 m2) = + U.findWithDefault m' m' $ postEqs eqs + where+ m' = MShrK (go m1) (go m2)+ go (MAsymPK m) = MAsymPK (go m)+ go (MAsymSK m) = MAsymSK (go m)+ go (MInvKey m) = MInvKey (go m)++-- | Substitute a thread id equalitiy.+substTIDEq :: Equalities -> TIDEq -> TIDEq+substTIDEq eqs = substTID eqs *** substTID eqs++-- | Substitute a thread id to role equality.+substTIDRoleEq :: Equalities -> TIDRoleEq -> AnyEq+substTIDRoleEq eqs (tid, role) = case threadRole tid' eqs of+ Just role' -> RoleEq (role, role')+ Nothing -> TIDRoleEq (tid', role)+ where+ tid' = substTID eqs tid++-- | Substitute an agent equality.+substAgentEq :: Equalities -> AgentEq -> MsgEq+substAgentEq eqs =+ substMsgEq eqs . agentEqToMsgEq++-- | Substitute an agent variable equality.+substAVarEq :: Equalities -> AVarEq -> AVarEq+substAVarEq eqs = substAVar eqs *** substAVar eqs++-- | Substitute a message variable equality.+substMVarEq :: Equalities -> MVarEq -> MsgEq+substMVarEq eqs = substMVar eqs *** substMsg eqs++-- | Substitute a message equality.+substMsgEq :: Equalities -> MsgEq -> MsgEq+substMsgEq eqs = substMsg eqs *** substMsg eqs++-- | Substitute both sides of a representable equality.+substAnyEq :: Equalities -> AnyEq -> AnyEq+substAnyEq eqs eq0 = case eq0 of+ TIDEq eq -> TIDEq $ substTIDEq eqs eq+ TIDRoleEq eq -> substTIDRoleEq eqs eq+ RoleEq _ -> eq0+ AgentEq eq -> MsgEq $ substAgentEq eqs eq+ AVarEq eq -> AVarEq $ substAVarEq eqs eq+ MVarEq eq -> MsgEq $ substMVarEq eqs eq+ MsgEq eq -> MsgEq $ substMsgEq eqs eq+++-- Checking for reflexivity+---------------------------++-- | Convert an agent equality to a message equality.+agentEqToMsgEq :: AgentEq -> MsgEq+agentEqToMsgEq (aid, rhs) = (MAgent aid, either MAgent MAVar rhs)++-- | Convert a message variable equallity to a message equality.+mvarEqToMsgEq :: MVarEq -> MsgEq+mvarEqToMsgEq (v, m) = (MMVar v, m)++-- | Check if an equality is reflexive.+reflexive :: AnyEq -> Bool+reflexive eq0 = case eq0 of+ TIDEq eq -> uncurry (==) eq+ TIDRoleEq _ -> False+ RoleEq eq -> uncurry (==) eq+ AgentEq eq -> reflexive . MsgEq $ agentEqToMsgEq eq+ AVarEq eq -> uncurry (==) eq+ MVarEq eq -> reflexive . MsgEq $ mvarEqToMsgEq eq+ MsgEq eq -> uncurry (==) eq++-- Deconstruction+-----------------++-- | The list of thread identifier equalities.+getTIDEqs :: Equalities -> [TIDEq]+getTIDEqs = M.toList . tidEqs++-- | The list of role equalities.+getTIDRoleEqs :: Equalities -> [TIDRoleEq]+getTIDRoleEqs = M.toList . roleEqs++-- | The list of agent variable equalities.+getAgentEqs :: Equalities -> [AgentEq]+getAgentEqs = M.toList . agntEqs++-- | The list of agent variable equalities.+getAVarEqs :: Equalities -> [AVarEq]+getAVarEqs = M.toList . avarEqs++-- | The list of message variable equalities.+getMVarEqs :: Equalities -> [MVarEq]+getMVarEqs = M.toList . mvarEqs++-- | The list of postponed message equalities.+getPostEqs :: Equalities -> [MsgEq]+getPostEqs = U.toList . postEqs++-- | Convert a set of equalities ot the tuple with lists for each individual+-- equality type.+toLists :: Equalities -> ([TIDEq], [TIDRoleEq], [AgentEq], [AVarEq], [MVarEq], [MsgEq])+toLists eqs = + (getTIDEqs eqs, getTIDRoleEqs eqs, getAgentEqs eqs+ , getAVarEqs eqs, getMVarEqs eqs, getPostEqs eqs)++-- | Convert a set of equalities to a list of equalities.+--+-- POST: Order of equalities equal to order in result of 'toLists'.+toAnyEqs :: Equalities -> [AnyEq]+toAnyEqs eqs = + map TIDEq a ++ map TIDRoleEq b ++ map AgentEq c ++ map AVarEq d ++ + map MVarEq e ++ map MsgEq f+ where (a, b, c, d, e, f) = toLists eqs++-- | The threads occurring in an equality.+anyEqTIDs :: AnyEq -> [TID]+anyEqTIDs eq = case eq of+ TIDEq (tid, _) -> return tid+ TIDRoleEq (tid, _) -> return tid+ RoleEq (_, _) -> mzero+ AgentEq (_, rhs) -> either (const mzero) (return . avarTID) rhs+ AVarEq (a1, a2) -> return (avarTID a1) `mplus` return (avarTID a2)+ MVarEq (v, m) -> return (mvarTID v) `mplus` msgTIDs m+ MsgEq (m1, m2) -> msgTIDs m1 `mplus` msgTIDs m2+++-- Unification+--------------++-- | Substitute and normalize the postponed equalities with respect to the+-- other equalities.+normPostEqs :: Equalities -> Equalities+normPostEqs eqs0 = + eqs { postEqs = U.map (substMsg eqs) (postEqs eqs0) }+ where+ eqs = eqs0 { postEqs = U.empty }++-- | Solve a list of unification equations.+--+-- The unification is performed modulo key inversion and thread identifier+-- equalities. Additional thread identifier equalities may result from+-- equalities over fresh messages. Bidirectional keys are handled by delaying+-- their solution until only one solution is possible.+solve :: Monad m => [AnyEq] -> Equalities -> m Equalities+solve ueqs eqs = + -- trace ("SOLVE: " ++ render (fsep $ punctuate comma $ map sptAnyEq ueqs)) $ + fst `liftM` solveRepeated ueqs eqs False++-- | Repeatedly solve unification equations until the solution doesn't change+-- anymore. Postponed equations are tried to be solved again after each full+-- iteration.+--+-- A return value @(neweqs, improvedsolution)@ is to be interpreted such that+-- @improvedsolution@ denotes that something apart from the postponed+-- equalities has changed.+solveRepeated :: Monad m => [AnyEq] -> Equalities -> Bool -> m (Equalities, Bool)+solveRepeated [] eqs False = return (eqs, False)+solveRepeated [] eqs True = + solveRepeated (map MsgEq $ getPostEqs eqs) eqs False+solveRepeated (ueq:ueqs) eqs improved = do+ (ueqs', eqs', improved') <- solve1 ueq eqs+ solveRepeated (ueqs ++ ueqs') (normPostEqs eqs') (improved || improved')++-- | Solve a single unification equation. Equalities are only return when+-- changed.+solve1 :: Monad m => AnyEq -> Equalities -> m ([AnyEq], Equalities, Bool)+solve1 ueq eqs@(Equalities tideqs roleeqs aveqs mveqs agnteqs posteqs) = + -- trace ("solve1: " ++ show (sptAnyEq ueq)) $+ case ueq of+ TIDEq (tid1, tid2) ->+ let tid1' = substTID eqs tid1+ tid2' = substTID eqs tid2+ elimTID x y = return+ ( mkAnyEqs TIDRoleEq roleeqs ++ mkAnyEqs AgentEq agnteqs ++ + mkAnyEqs AVarEq aveqs ++ mkAnyEqs MVarEq mveqs +++ map MsgEq (U.toList posteqs)+ , empty { tidEqs = M.insert x y tideqs }+ , True+ )+ where+ mkAnyEqs :: ((k, v) -> AnyEq) -> M.Map k v -> [AnyEq]+ mkAnyEqs constr = map constr . M.toList+ in+ elimVarEqVar elimTID (tid1', tid1') (tid2', tid2')++ TIDRoleEq (tid, role) ->+ let tid' = substTID eqs tid+ in+ case M.lookup tid' roleeqs of+ Just role' | role' /= role -> different "role" role role'+ _ -> + updateSolution (eqs { roleEqs = M.insert tid' role roleeqs })++ RoleEq (role1, role2)+ | role1 == role2 -> skipEq+ | otherwise -> different "role" role1 role2+ + AVarEq (av1, av2) ->+ let av1' = substAVar eqs av1+ av2' = substAVar eqs av2+ elimAVar x y = updateSolution (eqs {+ mvarEqs = M.map (substMsg elimEqs) mveqs+ , agntEqs = M.map (substAgentEqRHS elimEqs) agnteqs+ , avarEqs = M.insert x y $ M.map (substAVar elimEqs) aveqs+ })+ where elimEqs = empty { avarEqs = M.singleton x y }+ in+ elimVarEqVar elimAVar (av1', av1') (av2', av2')++ AgentEq (lhs, rhs) ->+ let elimAgentId x y = updateSolution (eqs {+ mvarEqs = M.map (substMsg elimEqs) mveqs+ , agntEqs = M.insert x y $ M.map (substAgentEqRHS elimEqs) agnteqs+ })+ where elimEqs = empty { agntEqs = M.singleton x y }+ in+ case (substAgentId eqs lhs, substAgentEqRHS eqs rhs) of+ (lhs'@(Left aid1), rhs'@(Left aid2)) ->+ elimVarEqVar elimAgentId (aid1, lhs') (aid2, rhs')+ (lhs'@(Right _ ), (Left aid2)) -> elimAgentId aid2 lhs'+ ( (Left aid1), rhs'@(Right _ )) -> elimAgentId aid1 rhs'+ ( (Right av1), (Right av2)) -> newEqs [AVarEq (av1, av2)]+ + MVarEq (lhs, rhs) ->+ let elimMVar x y + | x `elem` msgFMV y = + noUnifier $ "occurs check failed for '"++show x++"' in '"++show y++"'"+ | otherwise = + updateSolution (eqs {+ mvarEqs = M.insert x y $ M.map (substMsg elimEqs) mveqs+ })+ where elimEqs = empty { mvarEqs = M.singleton x y }+ in+ case (substMVar eqs lhs, substMsg eqs rhs) of+ (lhs'@(MMVar mv1), rhs'@(MMVar mv2)) ->+ elimVarEqVar elimMVar (mv1, lhs') (mv2, rhs')+ (lhs' , (MMVar mv2)) -> elimMVar mv2 lhs'+ ( (MMVar mv1), rhs' ) -> elimMVar mv1 rhs'+ (lhs' , rhs' ) -> newEqs [MsgEq (lhs', rhs')]+ + MsgEq eq -> case eq of+ (MMVar mv1, rhs) -> newEqs [MVarEq (mv1, rhs)]+ (lhs, MMVar mv2) -> newEqs [MVarEq (mv2, lhs)]++ (MInvKey x, MInvKey y ) -> newEqs [MsgEq (x, y)]+ (MInvKey x, MAsymPK m1) -> newEqs [MsgEq (x, MAsymSK m1)]+ (MAsymPK m1, MInvKey x ) -> newEqs [MsgEq (x, MAsymSK m1)]+ (MInvKey x, MAsymSK m1) -> newEqs [MsgEq (x, MAsymPK m1)]+ (MAsymSK m1, MInvKey x ) -> newEqs [MsgEq (x, MAsymPK m1)]+ (m1, MInvKey x ) -> newEqs [MsgEq (x, m1)]+ (MInvKey x, m1 ) -> newEqs [MsgEq (x, m1)]++ (MAgent aid1, MAgent aid2) -> newEqs [AgentEq (aid1, Left aid2)]+ (MAgent aid1, MAVar av2 ) -> newEqs [AgentEq (aid1, Right av2)]+ (MAVar av1, MAgent aid2) -> newEqs [AgentEq (aid2, Right av1)]++ (MAVar av1, MAVar av2) -> newEqs [AVarEq (av1, av2)]++ (MFresh (Fresh fr1), MFresh (Fresh fr2))+ | lidId fr1 == lidId fr2 -> newEqs [TIDEq (lidTID fr1, lidTID fr2)]+ | otherwise -> different "nonce" fr1 fr2++ (MHash m1, MHash m2 ) -> newEqs [MsgEq (m1, m2)]+ (MTup m11 m12, MTup m21 m22 ) -> newEqs [MsgEq (m11, m21), MsgEq (m12, m22)]+ (MEnc m11 m12, MEnc m21 m22 ) -> newEqs [MsgEq (m11, m21), MsgEq (m12, m22)]+ (MAsymPK m1, MAsymPK m2 ) -> newEqs [MsgEq (m1, m2)]+ (MAsymSK m1, MAsymSK m2 ) -> newEqs [MsgEq (m1, m2)]+ (MSymK m11 m12, MSymK m21 m22) -> newEqs [MsgEq (m11, m21), MsgEq (m12, m22)]++ (m1@(MShrK m11 m12), m2@(MShrK m21 m22))+ | m11 == m21 -> newEqs [MsgEq (m12, m22)]+ | m11 == m22 -> newEqs [MsgEq (m12, m21)]+ | m12 == m21 -> newEqs [MsgEq (m11, m22)]+ | m12 == m22 -> newEqs [MsgEq (m11, m21)]+ | m11 == m12 -> newEqs [MsgEq (m11, m21), MsgEq (m11, m22)]+ | m21 == m22 -> newEqs [MsgEq (m11, m21), MsgEq (m12, m21)]+ | (m1, m2) `U.equiv` posteqs -> skipEq+ | otherwise -> + return ([], eqs { postEqs = U.equate m1 m2 $ posteqs }, False)++ (MConst c1, MConst c2)+ | c1 == c2 -> skipEq+ | otherwise -> different "constant" c1 c2++ (m1, m2) -> different "message" m1 m2+ + where+ skipEq = return ([], eqs , False)+ newEqs ueqs = return (ueqs, eqs , False)+ updateSolution eqs' = return ([], eqs', True)+ noUnifier = fail . ("solve1: " ++)+ different ty x y = noUnifier $ ty ++ " '" ++ show x ++ "' /= '" ++ show y ++ "'"++ elimVarEqVar elim (vl, lhs) (vr, rhs) =+ case compare vl vr of+ EQ -> skipEq+ LT -> elim vr lhs+ GT -> elim vl rhs+++-- | Remove the thread identifier equalities. This is logically safe iff there is no fact+-- outside the equalities that still refers to the dropped thread identifiers.+trimTIDEqs :: Equalities -> ([TID], Equalities) -- ^ Dropped TIDs plus updated equalities+trimTIDEqs eqs = (M.keys . tidEqs $ eqs, eqs { tidEqs = M.empty })++-- | Remove the agent identifiers equalities. This is logically safe iff there is no fact+-- outside the equalities that still refers to the dropped agent identifiers.+trimAgentEqs :: Equalities -> ([AgentId], Equalities) -- ^ Dropped AgentIds plus updated equalities+trimAgentEqs eqs = (M.keys . agntEqs $ eqs, eqs { agntEqs = M.empty })++-- | The maximal mapped thread identifier.+maxMappedTID :: Equalities -> Maybe TID+maxMappedTID = fmap (fst . fst) . M.maxViewWithKey . tidEqs++-- | The maximal mapped agent identifier.+maxMappedAgentId :: Equalities -> Maybe AgentId+maxMappedAgentId = fmap (fst . fst) . M.maxViewWithKey . agntEqs+++-- | Retrieve the role of a thread.+threadRole :: TID -> Equalities -> Maybe Role+threadRole tid eqs = M.lookup (substTID eqs tid) $ roleEqs eqs+++-------------------------------------------------------------------------------+-- Abusing equalities to represent mappings of logical variables+-------------------------------------------------------------------------------++newtype Mapping = Mapping { getMappingEqs :: Equalities }+ deriving( Eq, Ord, Show, Data, Typeable )++-- | Map the equalities inside a mapping.+mapMapping :: (Equalities -> Equalities) -> Mapping -> Mapping+mapMapping f = Mapping . f . getMappingEqs++-- | An empty mapping.+emptyMapping :: Mapping+emptyMapping = Mapping empty++-- | A mapping of logical variables and the corresponding substitution can be+-- represented as an abstract Equalities value. However, it violates the+-- invariant that the domain of the equalities must be invariant under+-- substitution. This is OK, as domain and range of a mapping are from+-- different logical contexts.+mkMapping :: M.Map TID TID -> M.Map AgentId AgentId -> Mapping+mkMapping tideqs agnteqs = Mapping $+ empty {tidEqs = tideqs , agntEqs = M.map Left agnteqs}++-- | Add a mapping from one thread identifier to another one, possibly+-- overriding an existing mapping.+addTIDMapping :: TID -> TID -> Mapping -> Mapping+addTIDMapping from to = mapMapping $ \eqs ->+ eqs { tidEqs = M.insert from to $ tidEqs eqs }++-- | Add a mapping from one thread identifier to another one, possibly+-- overriding an existing mapping.+addAgentIdMapping :: AgentId -> AgentId -> Mapping -> Mapping+addAgentIdMapping from to = mapMapping $ \eqs -> + eqs { agntEqs = M.insert from (Left to) $ agntEqs eqs }++-- | Add a mapping from one thread identifier to an other role, possibly+-- overriding an existing mapping.+addTIDRoleMapping :: TID -> Role -> Mapping -> Mapping+addTIDRoleMapping tid role = mapMapping $ \eqs -> + let tid' = substTID eqs tid+ in eqs { roleEqs = M.insert tid' role $ roleEqs eqs }++-- | Delete the mapping of the given thread identifier.+deleteTIDMapping :: TID -> Mapping -> Mapping+deleteTIDMapping tid = mapMapping $ \eqs ->+ eqs { tidEqs = M.delete tid $ tidEqs eqs }++-- | Delete the mapping of the given agent identifier.+deleteAgentIdMapping :: AgentId -> Mapping -> Mapping+deleteAgentIdMapping aid = mapMapping $ \eqs ->+ eqs { agntEqs = M.delete aid $ agntEqs eqs }+++------------------------------------------------------------------------------+-- Pretty Printing+------------------------------------------------------------------------------++-- Helper functions for pretty printing+---------------------------------------++ppEq :: (a -> Doc) -> (b -> Doc) -> (a, b) -> Doc+ppEq pp1 pp2 (x1, x2) = pp1 x1 <-> char '=' <-> pp2 x2++ppEq' :: (a -> Doc) -> (a, a) -> Doc+ppEq' pp = ppEq pp pp++-- Isar+-------++instance Isar AnyEq where+ isar conf eq0 = case eq0 of+ TIDEq eq -> ppEq' ppIsar eq+ RoleEq eq -> ppEq' (text . roleName) eq+ TIDRoleEq (tid, role) -> + text "roleMap r" <-> ppIsar tid <-> text ("= Some " ++ roleName role)+ AgentEq eq -> ppEq ppIsar (either ppIsar ppIsar) eq+ AVarEq eq -> ppEq' ppIsar eq+ MVarEq eq -> ppEq ppIsar ppIsar eq+ MsgEq eq -> ppEq' ppIsar eq+ where+ ppIsar :: Isar a => a -> Doc+ ppIsar = isar conf++-- SP Theory+------------++sptAnyEq :: AnyEq -> Doc+sptAnyEq eq0 = case eq0 of+ TIDEq eq -> ppEq' sptTID eq+ RoleEq eq -> ppEq' (text . roleName) eq+ TIDRoleEq (tid, role) -> + text "role(" <-> sptTID tid <-> text (") = " ++ roleName role)+ AgentEq eq -> ppEq sptAgentId (either sptAgentId sptAVar) eq+ AVarEq eq -> ppEq' sptAVar eq+ MVarEq eq -> ppEq sptMVar sptMessage eq+ MsgEq eq -> ppEq' sptMessage eq+++{-+-- | Convert the equalities for pretty printing.+sptEqualities :: Equalities -> + ([Doc], [Doc], [Doc]) -- ^ quantified variables, representable+ -- equalities, non-representable equalities+sptEqualities (Equalities tideqs roleeqs aveqs mveqs agnteqs) =+ ( map sptTID (M.keys roleeqs) +++ [ sptAgentId aid | (aid, Nothing) <- M.toList agnteqs]+ , ppMapMaybe ppTIDRoleEq roleeqs ++ + ppVarEqs ppAVar ppAVar aveqs ++ + ppVarEqs ppMVar sptMessage mveqs +++ ppVarEqs ppAgent (maybe emptyDoc (either ppAgent ppAVar)) agnteqs+ , ppMap ppTIDEq tideqs +++ ppMapMaybe ppAgentEq agnteqs+ )+ where+ ppAVar = sptMessage . MAVar+ ppMVar = sptMessage . MMVar+ ppAgent = sptMessage . MAgent+ ppMap ppElem = map ppElem . M.toList+ ppMapMaybe ppElem m = map ppElem [(k,v) | (k, Just v) <- M.toList m]+ ppTIDEq (tid1,tid2) = sptTID tid1 <-> text "->" <-> sptTID tid2+ ppTIDRoleEq (tid, role) = text "role(" <> sptTID tid <> text ") =" <-> text (roleName role)+ ppAgentEq (aid, rhs) = sptAgentId aid <-> text "->" <-> either sptAgentId sptLocalId rhs+ ppVarEqs dom ran = ppMap ppVarEq . equalityChains+ where+ ppVarEq (r,ds) = fsep . intersperse (char '=') $ ran r : map dom (S.toList ds)++-- | Compute the equality classes given wrto a partial function.+equalityChains :: (Ord a, Ord b) => M.Map a b -> M.Map b (S.Set a)+equalityChains = foldl' insertEdge M.empty . M.toList+ where+ insertEdge m (from,to) = M.insertWith' S.union to (S.singleton from) m+-}
@@ -0,0 +1,190 @@+{-# LANGUAGE DeriveDataTypeable #-}+-- | Symbolic events that we are reasoning about+module Scyther.Event (+-- * Events+ Event(..)+ , substEv+ , substEvOrd+ , evTIDs+ , evOrdTIDs++ -- ** Event Order+ , EventOrder+ , cyclic+ , before++-- * Output+ , isaEvent+ , isaEventOrd+ , sptEvent+ , sptRawEvent+ , sptEventOrd+) where++import qualified Data.Set as S+import Data.Data++import Control.Arrow ( (***) )+import Control.Monad++import Text.Isar++import Scyther.Protocol+import Scyther.Message+import Scyther.Equalities++------------------------------------------------------------------------------+-- Events+------------------------------------------------------------------------------++-- | The logical denotation of an event of the execution of a security+-- protocol.+data Event =+ Step TID RoleStep -- ^ The thread executed the role step.+ | Learn Message -- ^ The message was learnt by the intruder.+ deriving( Eq, Ord, Show, Data, Typeable )++-- | The event order induced by the trace of the reachable state we are+-- reasoning about.+type EventOrder = S.Set (Event,Event)++-- | Is the event order cyclic?+cyclic :: EventOrder -> Bool+cyclic evord = + maybe True (const False) $ foldM visitForest S.empty (map fst evPairs)+ where + evPairs = S.toList evord+ visitForest visited x+ | x `S.member` visited = return visited+ | otherwise = findLoop S.empty visited x++ -- findLoop :: Ord n => S.Set n -> S.Set n -> n -> Maybe (S.Set n)+ findLoop parents visited x + | x `S.member` parents = mzero+ | x `S.member` visited = return visited+ | otherwise = + S.insert x `liftM` foldM (findLoop parents') visited next+ where+ next = [ e' | (e,e') <- evPairs, e == x ]+ parents' = S.insert x parents++-- | Must an event have happened before another one with respect to the given+-- event order.+--+-- /before evord from to/ holds iff the event order /evord/ implies that the+-- event /from/ must have happened before the event /to/ in the reachable state+-- we are reasoning about.+before :: EventOrder -> Event -> Event -> Bool+before evord from to = existsPath S.empty [from]+ where+ evPairs = S.toList evord+ existsPath _ [] = False+ existsPath visited (x:xs)+ | x == to = True+ | x `S.member` visited = existsPath visited xs+ | otherwise = + existsPath (S.insert x visited) (next ++ xs)+ where+ next = [ e' | (e,e') <- evPairs, e == x ]++-- | Substitute an event according to the equalities.+substEv :: Equalities -> Event -> Event+substEv eqs (Learn m) = Learn (substMsg eqs m)+substEv eqs (Step tid step) = Step (substTID eqs tid) step++-- | Substitute an event order according to the equalities.+substEvOrd :: Equalities -> (Event, Event) -> (Event, Event)+substEvOrd eqs = substEv eqs *** substEv eqs++-- | The threads associated to an event.+evTIDs :: Event -> [TID]+evTIDs (Step tid _) = return tid+evTIDs (Learn m) = msgTIDs m++-- | The threads associated to an event order.+evOrdTIDs :: (Event, Event) -> [TID]+evOrdTIDs (e1, e2) = evTIDs e1 `mplus` evTIDs e2+++------------------------------------------------------------------------------+-- Pretty Printing+------------------------------------------------------------------------------++-- Helper function+------------------++eventTag :: (Event -> Doc) -- ^ Raw pretty printing function+ -> (Doc -> Doc) -- ^ Modifier for learn events+ -> (Doc -> Doc) -- ^ Modifier for step events+ -> Event -> Doc +eventTag pp ln _ ev@(Learn _) = ln (pp ev)+eventTag pp _ st ev@(Step _ _) = st (pp ev)++-- Isar Output+--------------++-- | Pretty print the before order predicate.+esplBefore :: IsarConf -> Doc -> Doc -> Doc+esplBefore conf e1 e2+ | isPlainStyle conf = sep [text "predOrd t", nest 2 (parens e1), nest 2 (parens e2)]+ | otherwise = sep [e1 <-> symbol "\\<prec>", e2]++-- | Render an event in the Isar format.+isaRawEvent :: Bool -> IsarConf -> Mapping -> Event -> Doc+isaRawEvent addParens conf _ (Learn m) =+ (if addParens then parens else id) $ isar conf m+isaRawEvent _ conf mapping (Step tid step) = + nestShort 2 lparen rparen (fsep [isar conf tid <> comma, ppStep])+ where+ ppStep = isaRoleStep conf (threadRole tid (getMappingEqs mapping)) step++-- | Render an event in the Isar format.+isaEvent :: IsarConf + -> Mapping -- ^ A mapping of the logical variables. The thread id to+ -- role assigment is used for resolving steps to their+ -- abbreviated notation consisting of role name plus step+ -- label.+ -> Event -> Doc+isaEvent conf m = + eventTag (isaRawEvent False conf m) (inSet "knows t") (inSet "steps t")+ where + inSet set d = d <-> isaIn conf <-> text set++-- | Render an event order in the Isar format. See 'isaEvent' for an+-- explanation of the mapping.+isaEventOrd :: IsarConf -> Mapping -> (Event, Event) -> Doc+isaEventOrd conf m (e1, e2) = + esplBefore conf (ppEv e1) (ppEv e2)+ where + ppEv = eventTag (isaRawEvent True conf m) (text "Ln" <>) (text "St" <>)++instance Isar Event where+ isar conf = isaEvent conf (Mapping empty)+++-- SP Theory Output+-------------------++-- | Render an event in security protocol theory format without any added+-- tagging; i.e. learned messages are rendered as is, and executed steps are+-- rendered as a tuple of thread identifier and role step (abbreviated if+-- possible).+sptRawEvent :: Mapping -> Event -> Doc+sptRawEvent _ (Learn m) = sptMessage m+sptRawEvent mapping (Step tid step) = + parens $ fsep [sptTID tid <> comma, ppStep]+ where+ ppStep = sptRoleStep (threadRole tid (getMappingEqs mapping)) step++-- | Render a fact that an event happened in security protocol theory format.+sptEvent :: Mapping -> Event -> Doc+sptEvent m = eventTag (sptRawEvent m) ((text "knows" <>) . parens) (text "step" <>)++-- | Render an event order in security protocol theory format.+sptEventOrd :: Mapping -> [Event] -> Doc+sptEventOrd m = + fcat . punctuate (text " < ") . map ppEv+ where + ppEv = eventTag (sptRawEvent m) ((text "Ln" <>) . parens) (text "St" <>)++
@@ -0,0 +1,1195 @@+{-# LANGUAGE FlexibleContexts, DeriveDataTypeable #-}+-- | Conjunctions of the logical facts needed during a proof using decryption chain reasoning.+module Scyther.Facts (++ module Scyther.Protocol+ , module Scyther.Typing+ , module Scyther.Message+ , module Scyther.Event+ , module Scyther.Formula++-- * Facts+ , Facts+ , protocol+ + -- ** Construction+ , empty+ , freshTID+ , freshAgentId+ , quantifyTID+ , quantifyAgentId+ , conjoinAtoms+ , setTyping++ -- ** Queries+ , nullFacts+ , freeVariableMappings+ , proveFacts+ , proveFalse+ , proveAtom+ , proveFormula+ , toAtoms+ , nextTID+ , nextAgentId+ , quantifiedTIDs++ -- ** Substitution under the equalities of the facts+ , substEv+ , threadRole+ , eqsToMapping+ , applyMapping++ -- ** Rule applications+ , oldestOpenMessages+ , chainRuleFacts+ , saturateFacts+ , exploitTypingFacts+ , exploitLongTermKeySecrecy+ + , splittableEqs+ , splitEqFacts++-- * Output+ , isaFacts+ , sptFacts++) where++import Extension.Prelude++import Safe+import Data.List+import Data.Maybe+import Data.Monoid+import qualified Data.Set as S+import qualified Data.Map as M+import Data.Data++import Control.Arrow ( second, (***) )+import Control.Applicative hiding (empty)+import Control.Monad+import Control.Monad.State++import Text.Isar++import Scyther.Protocol+import Scyther.Typing+import Scyther.Message+import qualified Scyther.Equalities as E+import Scyther.Equalities hiding (solve, substTID, threadRole, substMVar, substAVar, substMsg, substAnyEq, empty)+import Scyther.Event hiding (substEv, substEvOrd)+import qualified Scyther.Event as E+import Scyther.Formula hiding (substAtom)+import qualified Scyther.Formula as F+++------------------------------------------------------------------------------+-- Facts+------------------------------------------------------------------------------++-- | A conjunction of logical facts.+-- +-- Invariants that hold for a value @facts = Facts _ evs evord co uc eqs@:+--+-- 1. All facts are invariant under their corresponding substitution. This+-- excludes the quantifiers, as they are no facts.+--+-- 2. All trivial learn events are removed (or split in case of a pair).+--+-- We assume that all thread identifiers that are assigned to a role are+-- locally quantified. The kind of quantification depends on the context. If+-- the set of facts models the premises of a proof state then this would be+-- universal quantification. If the set of facts models an authentication+-- conclusion this would be existential quantification.+--+data Facts = Facts {+ events :: S.Set Event -- ^ Statements about events that must have happened.+ , eventOrd :: EventOrder -- ^ Statements about the order of events that happened.+ -- FIXME: Compromising other values than agent variables should also be possible.+ , compromised :: S.Set Message -- ^ Statements about agents being compromised.+ , uncompromised :: S.Set Message -- ^ Statements about agents being uncompromised.+ , equalities :: E.Equalities -- ^ All equalities that must hold.+ , tidQuantifiers :: S.Set TID -- ^ All thread IDs occurring in the facts.+ , aidQuantifiers :: S.Set AgentId -- ^ All agent IDs ocurring in the facts.+ , optTyping :: Maybe Typing -- ^ The typing if there is any that the+ -- current state satisfies.+ -- NOTE: The outer Maybe is used for facts that don't have a typing. The + -- inner maybe is a cheap construction accomodating legacy weak-atomicity.++ , covered :: S.Set Message -- ^ The messages that have already been used in a + -- case distinction.+ , protocol :: Protocol -- ^ The protocol that the current state+ -- is a reachable state of.+ }+ deriving( Eq, Ord, Show, Data, Typeable )++------------------------------------------------------------------------------+-- Queries+------------------------------------------------------------------------------++-- | True if no premises apart from state reachability and the optional+-- well-typedness claim are present. Note that there may be quantifiers and+-- covered goals.+nullFacts :: Facts -> Bool+nullFacts facts = + S.null (events facts) &&+ S.null (eventOrd facts) &&+ S.null (compromised facts) &&+ S.null (uncompromised facts) &&+ E.null (equalities facts)++------------------------------------------------------------------------------+-- Construction+------------------------------------------------------------------------------++-- | Empty set of facts; logically equivalent to true.+empty :: Protocol -> Facts+empty = Facts S.empty S.empty S.empty S.empty E.empty S.empty S.empty Nothing S.empty++-- | Set the protocol.+--+-- PRE: Setting a protocol is the identity iff the new protocol agrees with the+-- existing one.+--+-- Uses 'fail' for error reporting.+setProtocol :: Monad m => Protocol -> Facts -> m Facts+setProtocol proto facts + | proto == protocol facts = return facts+ | otherwise = fail $ "setProtocol: '" ++ show proto ++ "' /= '" + ++ show (protocol facts) ++ "'" ++-- | Set the typing. +--+-- PRE: There mustn't be a different existing typing.+--+-- Uses 'fail' for error reporting.+setTyping :: Monad m => Typing -> Facts -> m Facts+setTyping typ facts = case optTyping facts of+ Just typ' | typ /= typ' -> fail $ "setTyping: '" ++ show typ ++ "' /= '" + ++ show typ' ++ "'"+ _ -> return $ facts { optTyping = Just typ }+++-- | Create a mapping from the equalities of the facts.+eqsToMapping :: Facts -> Mapping+eqsToMapping = Mapping . equalities++-- Quantifiers+--------------++-- | Tries to quantify the given thread identifier. If it is already quantified+-- `fail` is called in the given monad.+quantifyTID :: Monad m => TID -> Facts -> m Facts+quantifyTID tid facts+ | tidQuantified facts tid = fail $ "quantifyTID: " ++ show tid ++ " already quantified."+ | otherwise = + return $ facts { tidQuantifiers = S.insert tid $ tidQuantifiers facts }++-- | Tries to quantify the given agent identifier. If it is already quantified+-- `fail` is called in the given monad.+quantifyAgentId :: Monad m => AgentId -> Facts -> m Facts+quantifyAgentId aid facts+ | agentIdQuantified facts aid = + fail $ "quantifyAgentId: " ++ show aid ++ " already quantified."+ | otherwise = + return $ facts { aidQuantifiers = S.insert aid $ aidQuantifiers facts }++-- | Get a fresh TID and the updated set of facts.+freshTID :: Facts -> (TID, Facts)+freshTID facts = + (tid, facts { tidQuantifiers = S.insert tid $ tidQuantifiers facts })+ where tid = nextTID facts++-- | Get a fresh AgentId and the updated set of facts.+freshAgentId :: Facts -> (AgentId, Facts)+freshAgentId facts =+ (aid, facts { aidQuantifiers = S.insert aid $ aidQuantifiers facts })+ where aid = nextAgentId facts++-- | The list of thread ids that are quantified.+quantifiedTIDs :: Facts -> [TID]+quantifiedTIDs = S.toList . tidQuantifiers++-- Certification+----------------++-- | A value certified to be satisfy. This is a type level construct+-- helping the implementor to discern between values from the outside and+-- values with their invariants checked.+--+-- What is missing is the binding between the context and the checked value. It+-- is up to the user to not mix this up.+newtype Cert a = Cert { certified :: a }+ deriving( Eq, Ord, Show )++-- | Changed the certified value. Note that you have to guarantee that the+-- required invariants are not violated.+mapCertified :: (a -> b) -> Cert a -> Cert b+mapCertified f (Cert x) = Cert (f x)++-- | Check if a TID is quantified in these facts+tidQuantified :: Facts -> TID -> Bool+tidQuantified facts = (`S.member` tidQuantifiers facts)++-- | Check if a agent id is quantified in these facts+agentIdQuantified :: Facts -> AgentId -> Bool+agentIdQuantified facts = (`S.member` aidQuantifiers facts)++-- | Check if all logical variables in an local id are quantified.+lidQuantified :: Facts -> LocalId -> Bool+lidQuantified facts = tidQuantified facts . lidTID++-- | Check if all logical variables in an agent variable are quantified.+avarQuantified :: Facts -> AVar -> Bool+avarQuantified facts = lidQuantified facts . getAVar++-- | Check if all logical variables in an message variable are quantified.+mvarQuantified :: Facts -> MVar -> Bool+mvarQuantified facts = lidQuantified facts . getMVar++-- |Check if all logical variables in an agent eq RHS are quantified.+agentEqRHSQuantified :: Facts -> E.AgentEqRHS -> Bool+agentEqRHSQuantified facts = either (agentIdQuantified facts) (avarQuantified facts)++-- | Check if all logical variables in an message are quantified.+msgQuantified :: Facts -> Message -> Bool+msgQuantified facts m =+ all (tidQuantified facts) (msgTIDs m) && + all (agentIdQuantified facts) (msgAgentIds m)++-- | Check if all logical variables in an event are quantified.+evQuantified :: Facts -> Event -> Bool+evQuantified facts (Learn m) = msgQuantified facts m+evQuantified facts (Step tid _) = tidQuantified facts tid++-- | Check if all logical variables in an event order are quantified.+evOrdQuantified :: Facts -> (Event, Event) -> Bool+evOrdQuantified facts (e1, e2) = evQuantified facts e1 && evQuantified facts e2++-- | Check if an equality contains only quantified logical variables.+anyEqQuantified :: Facts -> E.AnyEq -> Bool+anyEqQuantified facts eq = case eq of+ E.TIDEq (tid1, tid2) -> tidQuantified facts tid1 && tidQuantified facts tid2+ E.TIDRoleEq (tid, _) -> tidQuantified facts tid+ E.RoleEq _ -> True+ E.AgentEq (aid, rhs) -> agentIdQuantified facts aid && agentEqRHSQuantified facts rhs+ E.AVarEq (av1, av2) -> avarQuantified facts av1 && avarQuantified facts av2+ E.MVarEq (mv, m) -> mvarQuantified facts mv && msgQuantified facts m+ E.MsgEq (m1, m2) -> msgQuantified facts m1 && msgQuantified facts m2+ +-- | Check if an atom contains only quantified logical variables.+atomQuantified :: Facts -> Atom -> Bool+atomQuantified facts atom = case atom of+ AFalse -> True+ AEq eq -> anyEqQuantified facts eq+ AEv ev -> evQuantified facts ev+ AEvOrd ord -> evOrdQuantified facts ord+ ACompr m -> msgQuantified facts m+ AUncompr m -> msgQuantified facts m+ AHasType mv _ -> mvarQuantified facts mv+ ATyping _ -> True+ AReachable _ -> True+++-- | Certification of a value with respect to a check and a morphism required+-- to establish the required invariants in the context of a set of facts.+certify :: Show a => (Facts -> a -> Bool) -> (Facts -> a -> b) -> Facts -> a -> Cert b+certify check conv facts x+ | check facts x = Cert $ conv facts x+ | otherwise = error $ "certify: check failed for '" ++ show x ++ "'"++-- | Certify a thread identifer.+-- certTID :: Facts -> TID -> Cert TID+-- certTID = certify tidQuantified substTID++-- | Certify an agent variable.+-- certAVar :: Facts -> AVar -> Cert AVar+-- certAVar = certify avarQuantified substAVar++-- | Certify a message.+certMsg :: Facts -> Message -> Cert Message+certMsg = certify msgQuantified substMsg++-- | Certify an event.+-- certEv :: Facts -> Event -> Cert Event+-- certEv = certify evQuantified substEv++-- | Certify an event order.+certEvOrd :: Facts -> (Event, Event) -> Cert (Event, Event)+certEvOrd = certify evOrdQuantified substEvOrd++-- | Certify an equality.+certAnyEq :: Facts -> E.AnyEq -> Cert E.AnyEq+certAnyEq = certify anyEqQuantified substAnyEq++-- | Certify an atom: All logical variables are quantified under the given+-- facts and all values are invariant under the equalities associated with the+-- facts.+certAtom :: Facts -> Atom -> Cert Atom+certAtom = certify atomQuantified substAtom+++-- Equalities+-------------++-- | Lift a substitutition.+liftSubst :: (E.Equalities -> a -> b) -> Facts -> a -> b+liftSubst subst facts = subst (equalities facts)++-- | Substitute a TID.+substTID :: Facts -> TID -> TID+substTID = liftSubst E.substTID++-- | Substitute an agent variale.+-- substAVar :: Facts -> AVar -> AVar+-- substAVar = liftSubst E.substAVar++-- | Substitute an message variale.+substMVar :: Facts -> MVar -> Message+substMVar = liftSubst E.substMVar++-- | Substitute an message variale.+-- substAgentId :: Facts -> AgentId -> E.AgentEqRHS+-- substAgentId = liftSubst E.substAgentId++-- | Substitute an message variale.+-- substAgentEqRHS :: Facts -> E.AgentEqRHS -> E.AgentEqRHS+-- substAgentEqRHS = liftSubst E.substAgentEqRHS++-- | Substitute a message.+substMsg :: Facts -> Message -> Message+substMsg = liftSubst E.substMsg++-- | Substitute an equality.+substAnyEq :: Facts -> E.AnyEq -> E.AnyEq+substAnyEq = liftSubst E.substAnyEq++-- | Substitute an atom.+substAtom :: Facts -> Atom -> Atom+substAtom = liftSubst F.substAtom++-- | Substitute an event.+substEv :: Facts -> Event -> Event+substEv = liftSubst E.substEv++-- | Substitute an event order.+substEvOrd :: Facts -> (Event, Event) -> (Event, Event)+substEvOrd = liftSubst E.substEvOrd++-- | The role assigned to a thread.+threadRole :: TID -> Facts -> Maybe Role+threadRole tid = E.threadRole tid . equalities++-- | Remove thread identifier and agent identifiers equalities and the+-- quantifiers that were mapped by them.+--+-- This operation is logically safe iff there are no references to the mapped+-- logical variables outside the facts.+trimQuantifiers :: Facts -> Facts+trimQuantifiers facts = facts { + equalities = eqs' + , tidQuantifiers = S.filter (`notElem` tids) $ tidQuantifiers facts+ , aidQuantifiers = S.filter (`notElem` aids) $ aidQuantifiers facts+ }+ where+ (tids, (aids, eqs')) = second E.trimAgentEqs . E.trimTIDEqs $ equalities facts++-- | Solve the equations in the context of the given facts and update all facts+-- accordingly.+solve :: Monad m => [Cert E.AnyEq] -> Facts -> m Facts+solve ueqs facts = do+ eqs <- E.solve (map certified ueqs) $ equalities facts+ return . removeTrivialFacts $ facts {+ events = S.map (E.substEv eqs) (events facts)+ , eventOrd = S.map (E.substEvOrd eqs) (eventOrd facts)+ , compromised = S.map (E.substMsg eqs) (compromised facts)+ , uncompromised = S.map (E.substMsg eqs) (uncompromised facts)+ , equalities = eqs+ , tidQuantifiers = tidQuantifiers facts+ , aidQuantifiers = aidQuantifiers facts+ , covered = S.map (E.substMsg eqs) (covered facts)+ }++ +-- Compromised agents+---------------------++-- | Mark an message as being a compromised agent name.+compromise :: Message -> Facts -> Facts+compromise m facts =+ facts { compromised = S.insert (certified m') (compromised facts) }+ where m' = certMsg facts m++-- | Mark an message as not being a compromised agent name.+uncompromise :: Message -> Facts -> Facts+uncompromise m facts =+ facts { uncompromised = S.insert (certified m') (uncompromised facts) }+ where m' = certMsg facts m+++-- Incremental construction+---------------------------++-- | Inserts an event fact.+insertEv :: Cert Event -> Facts -> Facts+insertEv ev prems = prems { events = S.insert (certified ev) (events prems) }++-- | Delete an event fact.+deleteEv :: Cert Event -> Facts -> Facts+deleteEv ev prems = prems { events = S.delete (certified ev) (events prems) }++-- | Insert a learn event fact.+insertLearn :: Cert Message -> Facts -> Facts+insertLearn m = insertEv (mapCertified Learn m)++-- | Inserts an event order fact.+insertEvOrd :: Cert (Event, Event) -> Facts -> Facts+insertEvOrd ord prems = + prems { eventOrd = S.insert (certified ord) (eventOrd prems) }++-- | Delete an event order fact.+deleteEvOrd :: Cert (Event, Event) -> Facts -> Facts+deleteEvOrd ord prems =+ prems { eventOrd = S.delete (certified ord) (eventOrd prems) }++-- | Insert a thread identifier to role assignment. This will fail with+-- an error iff this assignment conflicts with an existing assignment of+-- the same thread identifier to a different role.+insertRole :: TID -> Role -> Facts -> Facts+insertRole tid role facts = maybe err id $+ solve [certAnyEq facts $ E.TIDRoleEq (tid, role)] facts+ where+ err = error $ "insertRole: failed to insert role"+++-- | Build the conjunction of the atoms and the facts; a result of 'Nothing'+-- means that the conjunction is logically equivalent to False. This will occur+-- in case 'AFalse' is conjoined or an equality that cannot be unified.+--+-- PRE: The atom must pass certification under the given facts.+--+-- PRE: The atom must not be a 'AHasTyp' or a 'ATyping' atom, as they are not+-- representable by 'Facts'+conjoinAtoms :: Monad m => [Atom] -> Facts -> m (Maybe Facts)+conjoinAtoms atoms facts0 = foldM conjoinAtom (Just facts0) atoms+ where+ conjoinAtom Nothing _ = return Nothing+ conjoinAtom (Just facts) atom = case certified $ certAtom facts atom of+ AFalse -> return Nothing+ -- FIXME: repeated calls to solve may be a bit expensive due to duplicated+ -- work of 'removeTrivialFacts'.+ AEq eq -> return $ solve [Cert eq] facts+ AEv ev -> return . Just $ insertEvNonTrivial (Cert ev) facts+ AEvOrd ord -> return . Just $ insertEvOrdNonTrivial (Cert ord) facts+ ACompr m -> return . Just $ compromise m facts+ AUncompr m -> return . Just $ uncompromise m facts+ AReachable p -> Just `liftM` setProtocol p facts+ ATyping typ -> Just `liftM` setTyping typ facts+ _ -> error $ "conjoinAtoms: atom '" ++ show atom ++ "' not supported."+++++-- Combined construction and application of inference rules+-----------------------------------------------------------++-- | Inserts an event order fact and both event facts implied by the presence+-- of this event oder fact.+insertEvOrdAndEvs :: Cert (Event, Event) -> Facts -> Facts+insertEvOrdAndEvs ord = + insertEv (mapCertified fst ord) . + insertEv (mapCertified snd ord) . insertEvOrd ord++-- | Insert all non-trivial events implied by the given event.+insertEvNonTrivial :: Cert Event -> Facts -> Facts+insertEvNonTrivial ev prems = case certified ev of+ Learn m -> foldl' (flip (insertLearn . Cert)) prems (splitNonTrivial m)+ Step _ _ -> insertEv ev prems++-- | Insert all event orders which are non-trivial in their first argument+-- implied by the given event order.+insertEvOrdNonTrivial :: Cert (Event, Event) -> Facts -> Facts+insertEvOrdNonTrivial ord prems = case certified ord of+ (Learn m, to) -> foldl' (insertLearnBefore to) prems (splitNonTrivial m)+ _ -> insertEvOrdAndEvs ord prems+ where+ insertLearnBefore to p m = insertEvOrdAndEvs (Cert (Learn m, to)) p+ +-- | Insert an executed role step and all non-trivial facts implied by the+-- Input rule.+insertStepInputClosed :: Cert (TID, RoleStep) -> Facts -> Facts+insertStepInputClosed s prems = case certified s of+ (tid, step@(Recv _ pt)) ->+ let m = substMsg prems (inst tid pt) in+ insertEvOrdNonTrivial (Cert (Learn m, Step tid step)) prems+ (tid, step@(Send _ _)) -> insertEv (Cert (Step tid step)) prems++-- | Insert an executed role step and all non-trivial facts implied by the+-- Input and Role rules.+insertStepPrefixClosed :: Cert (TID, RoleStep) -> Facts -> Facts+insertStepPrefixClosed s = case certified s of+ (tid, step) -> execState $ do+ let err = error $ "insertStepPrefixClosed: no role assigned to thread " ++ show tid+ role <- gets (fromMaybe err . threadRole tid)+ let prefix = takeWhile (/= step) (roleSteps role) ++ [step]+ insertStepOrd = modify . insertEvOrdAndEvs . Cert . (Step tid *** Step tid)+ mapM_ (modify . insertStepInputClosed . (Cert . ((,) tid))) prefix+ mapM_ insertStepOrd $ zip prefix (tail prefix)++-- | Insert an event an all non-trivial facts implied by the Input and Role+-- rules.+insertEvSaturated :: Cert Event -> Facts -> Facts+insertEvSaturated ev = case certified ev of+ (Learn _ ) -> insertEvNonTrivial ev+ (Step tid step) -> insertStepPrefixClosed (Cert (tid, step))++-- | Derive all non-trivial facts implied by the splitting rules and remove+-- remove trivial facts.+removeTrivialFacts :: Facts -> Facts+removeTrivialFacts = execState $ do+ evs <- S.toList <$> gets events+ mapM_ checkEv evs+ evord <- S.toList <$> gets eventOrd+ mapM_ checkEvOrd evord+ where+ checkEv ev@(Learn m)+ | trivial m = modify (insertEvNonTrivial (Cert ev) . deleteEv (Cert ev))+ | otherwise = return ()+ checkEv _ = return ()+ checkEvOrd ord@(Learn m, _)+ | trivial m = modify (insertEvOrdNonTrivial (Cert ord) . deleteEvOrd (Cert ord))+ | otherwise = return ()+ checkEvOrd _ = return ()++-- | Saturate facts modulo removal of trivial facts; i.e. apply all rules+-- except the chain rule eagerly and remove trivial facts.+saturateFacts :: Facts -> Facts+saturateFacts = execState $ do+ modify removeTrivialFacts+ evs <- gets events+ evord <- gets eventOrd+ let evs' = (evs `S.union` S.map fst evord) `S.union` S.map snd evord+ mapM_ (modify . insertEvSaturated . Cert) (S.toList evs')++-- | Make use of the typing assumption by checking for instantiated message variables+-- if their instantiation does not agree with the structural type and hence they must+-- be known before the given step.+--+-- Is equal to 'mzero' in case the facts don't contain a typing.+exploitTypingFacts :: MonadPlus m => Facts -> m Facts+exploitTypingFacts facts0 = do+ typ <- getTyping facts0+ return $ case typ of+ WeaklyAtomic -> foldl' weaklyAtomic facts0 . E.getMVarEqs . equalities $ facts0+ Typing _ -> facts0 -- TODO: implement this check+ where+ weaklyAtomic :: Facts -> (MVar, Message) -> Facts+ weaklyAtomic facts (_, MMVar _ ) = facts+ weaklyAtomic facts (_, MFresh _) = facts+ weaklyAtomic facts (MVar (LocalId (i, tid)), m ) =+ case threadRole tid facts of+ Nothing -> error $ "exploitTypingFacts: no role assigned to '"++show tid++"'"+ Just role -> + case find (S.member i . stepFMV) (roleSteps role) of+ Nothing -> + error $ "exploitTypingFacts: variable '"++show i++"' does not occur in role."+ Just step -> + insertEvOrdNonTrivial (Cert (Learn m, Step tid step)) facts++------------------------------------------------------------------------------+-- Queries+------------------------------------------------------------------------------++-- | The next free thread identifier+nextTID :: Facts -> TID+nextTID = maybe 0 (succ . fst) . S.maxView . tidQuantifiers++-- | The next free agent identifier+nextAgentId :: Facts -> AgentId+nextAgentId = maybe 0 (succ . fst) . S.maxView . aidQuantifiers++-- | Try to retrieve the typing; equal to 'mzero' if there is none.+getTyping :: MonadPlus m => Facts -> m Typing+getTyping = maybe mzero return . optTyping++-- | Check if a set of facts is trivially contradictory.+--+-- NOTE: This is not the same as trying to prove the atom AFalse under these+-- premises. The checks are separated due to efficiency reasons.+proveFalse :: Facts -> Bool+proveFalse prems = + not (S.null (compromised prems `S.intersection` uncompromised prems)) ||+ any noAgent (S.toList (compromised prems)) ||+ cyclic (eventOrd prems)+ where+ noAgent (MMVar _) = False+ noAgent (MAVar _) = False+ noAgent (MAgent _) = False+ noAgent _ = True++-- | True iff the facts imply the validity of the given atom. Note that this check+-- is incomplete; i.e. there may be atoms that would be true under these facts,+-- but are not detected as such.+--+-- PRE: Trivial learn events must be split. You may achieve this using+-- 'removeTrivialFacts'.+proveAtom :: Facts -> Atom -> Bool+proveAtom facts = checkAtom . certified . certAtom facts+ where+ -- PRE: atom is fully substituted+ checkAtom atom = case atom of+ AFalse -> False+ AEq eq -> E.reflexive eq+ AEv (Learn m) -> all checkLearn (splitNonTrivial m)+ AEv ev -> ev `S.member` events facts+ AEvOrd (Learn m, e2) -> all (checkLearnBefore e2) (splitNonTrivial m)+ AEvOrd (e1, e2) -> before (eventOrd facts) e1 e2+ ACompr m -> m `S.member` compromised facts+ AUncompr m -> m `S.member` uncompromised facts+ AHasType mv Nothing -> weaklyAtomic mv (substMVar facts mv)+ AHasType mv (Just ty) -> checkType (substMVar facts mv) ty+ ATyping typ -> Just typ == optTyping facts+ AReachable proto -> proto == protocol facts++ checkLearn m = Learn m `S.member` events facts+ checkLearnBefore to m = before (eventOrd facts) (Learn m) to++ weaklyAtomic mv (MMVar mv') = mv /= mv' -- FIXME: This case is missing in checkType below.+ weaklyAtomic _ m = checkAtom (AEv (Learn m))++ checkType (MAVar _) (AgentT) = True+ checkType (MAgent _) (AgentT) = True+ checkType (MConst i) (ConstT i') = i == i'+ checkType (MFresh (Fresh (LocalId (i, tid)))) (NonceT role i') =+ i == i' && threadRole tid facts == Just role+ checkType (MHash m) (HashT ty) = checkType m ty+ checkType (MEnc m1 m2) (EncT ty1 ty2) = checkType m1 ty1 && checkType m2 ty2+ checkType (MTup m1 m2) (TupT ty1 ty2) = checkType m1 ty1 && checkType m2 ty2+ checkType (MSymK m1 m2) (SymKT ty1 ty2) = checkType m1 ty1 && checkType m2 ty2+ checkType (MAsymPK m) (AsymPKT ty) = checkType m ty+ checkType (MAsymSK m) (AsymSKT ty) = checkType m ty+ checkType m (KnownT step) = checkAtom (AEv (Learn m))+ -- FIXME: Really check that m was learned before step. Needs a change in the+ -- signature, because the conclusion of a type induction theorem features a+ -- trace extended by a receive step.+ --+ -- Here, we just assume that the correct step was specified; as our+ -- automatic inference will do.+ checkType m (SumT ty1 ty2) = checkType m ty1 || checkType m ty2+ checkType _ _ = False+++-- | Try to prove that the formula holds under these facts.+proveFormula :: Facts -> Formula -> Bool+proveFormula facts = prove (Mapping E.empty)+ where+ prove mapping (FAtom atom) = proveAtom facts (F.substAtom (getMappingEqs mapping) atom)+ prove mapping (FConj f1 f2) = prove mapping f1 && prove mapping f2+ prove mapping (FExists v f) = any (\mk -> prove (mk mapping) f) (mkMappings v)+ -- the mappings assign witnesses to the existentially quantified variables.+ mkMappings (Left tid) = map (E.addTIDMapping tid) (S.toList $ tidQuantifiers facts)+ mkMappings (Right aid) = map (E.addAgentIdMapping aid) (S.toList $ aidQuantifiers facts)++-- | Try to find a long-term-key that must be secret due to the+-- uncompromisedness assumptions, but is claimed to be known to the intruder;+-- i.e. if this method returns a message, then the premises are contradictory.+exploitLongTermKeySecrecy :: Facts -> Maybe Message+exploitLongTermKeySecrecy facts = msum . map check . S.toList $ events facts+ where+ check (Learn key@(MSymK m1 m2)) = do+ guard (all (`S.member` uncompromised facts) [m1, m2])+ return key+ check (Learn key@(MShrK m1 m2)) = do+ guard (all (`S.member` uncompromised facts) [m1, m2])+ return key+ check (Learn key@(MAsymSK m)) = do+ guard (m `S.member` uncompromised facts)+ return key+ check _ = mzero+++-- Deconstruction+-----------------++-- | Represent the facts as a set of atoms.+toAtoms :: Facts -> [Atom]+toAtoms facts = mconcat [+ AEq <$> E.toAnyEqs (equalities facts)+ , AUncompr <$> S.toList (uncompromised facts)+ , ACompr <$> S.toList (compromised facts)+ , AEv <$> S.toList (events facts)+ , AEvOrd <$> S.toList (eventOrd facts)+ ]++------------------------------------------------------------------------------+-- Chain Rule Application+------------------------------------------------------------------------------++-- | Compute the set of messages that have no given previous event.+--+-- PRE: Assumes all events in the event order are also part of the+-- set of events.+openMessages :: Facts -> [Message]+openMessages prems = nub $ filter okGoal $ catMaybes+ [ case e of Learn m -> Just m; _ -> Nothing + | e <- S.toList $ events prems `S.difference` S.map snd (eventOrd prems) ]+ where + okGoal (MMVar _) = False+ okGoal (MAgent _) = False+ okGoal (MAsymPK _) = False+ okGoal (MInvKey _) = False+ okGoal m = not (trivial m) && (m `S.notMember` covered prems)++-- | Sort open messages ascending with respect to the maximal thread id.+oldestOpenMessages :: Facts -> [Message]+oldestOpenMessages prems = + map fst . sortOn snd . mapMaybe score $ ms+ where+ ms = openMessages prems+ co = compromised prems+ ltkLocalIds (MAsymSK m@(MAVar a)) + | m `S.member` co = []+ | otherwise = [getAVar a]+ ltkLocalIds (MSymK ma@(MAVar a) mb@(MAVar b))+ | ma `S.member` co || mb `S.member` co = []+ | otherwise = [getAVar a, getAVar b]+ ltkLocalIds (MShrK ma@(MAVar a) mb@(MAVar b))+ | ma `S.member` co || mb `S.member` co = []+ | otherwise = [getAVar a, getAVar b]+ ltkLocalIds _ = []+ score m = fmap (\x->(m,x)) . maximumMay $+ [ tid | MVar (LocalId (_,tid)) <- msgFMV m ] +++ [ tid | Fresh (LocalId (_,tid)) <- msgFresh m ] +++ [ tid | LocalId (_,tid) <- ltkLocalIds m ]++-- | A data type to represent the state of the chain rule computation.+data ChainRuleState = ChainRuleState+ { crsCaseName :: [String]+ , crsNewVars :: [Either TID AgentId]+ , crsFacts :: Facts+ , crsFinalEq :: Maybe E.MsgEq+ }++type ChainRuleM = StateT ChainRuleState []++-- | Add a fragment of the case name. +addCaseFragment :: String -> ChainRuleM ()+addCaseFragment name = modify $ \crs -> crs { crsCaseName = crsCaseName crs ++ [name] }++-- | Add a newly quantified variable.+addNewVar :: Either TID AgentId -> ChainRuleM ()+addNewVar v = modify $ \crs -> crs { crsNewVars = crsNewVars crs ++ [v] }++-- | Change the facts of the chain rule computation state.+modifyFacts :: (Facts -> Facts) -> ChainRuleM ()+modifyFacts f = modify $ \crs -> crs { crsFacts = f $ crsFacts crs }++-- | Gets a component of the facts.+getsFacts :: (Facts -> a) -> ChainRuleM a+getsFacts f = gets (f . crsFacts)++-- | Set the equality that has to be solved for the case to be complete.+setFinalEq :: E.MsgEq -> ChainRuleM ()+setFinalEq eq = modify $ \crs -> crs { crsFinalEq = Just eq }++-- try to unify the two messages in the context of the current facts;+-- this function will always succeed, but the facts may be Nothing+unify :: Message -> Message -> ChainRuleM ()+unify m m' = do+ crs <- get+ maybe mzero (modifyFacts . const) $ + solve [certAnyEq (crsFacts crs) $ E.MsgEq (m', m)] (crsFacts crs)+ +-- get a fresh thread identifier and update the facts accordingly+getFreshTID :: ChainRuleM TID+getFreshTID = do+ (tid, facts) <- getsFacts freshTID+ modifyFacts (const facts)+ addNewVar (Left tid)+ return tid++-- | Expand the a type into a message with fresh logical variables for the+-- unknowns.+expandType :: Type -> ChainRuleM Message+expandType (AgentT) = do+ (aid, facts) <- getsFacts freshAgentId+ modifyFacts (const facts)+ addNewVar (Right aid)+ return $ MAgent aid+expandType (ConstT c) = return $ MConst c+expandType (NonceT role n) = do+ nTid <- getFreshTID+ modifyFacts (insertRole nTid role)+ return $ MFresh (Fresh (LocalId (n, nTid)))+expandType (HashT ty) = MHash <$> expandType ty+expandType (EncT ty1 ty2) = MEnc <$> expandType ty1 <*> expandType ty2+expandType (TupT ty1 ty2) = MTup <$> expandType ty1 <*> expandType ty2+expandType (SymKT ty1 ty2) = MSymK <$> expandType ty1 <*> expandType ty2+expandType (AsymPKT ty) = MAsymPK <$> expandType ty+expandType (AsymSKT ty) = MAsymSK <$> expandType ty+expandType (SumT (KnownT _) ty) = expandType ty+ -- ^ ASSUMPTION: The step referenced in KnownT happens earlier than the current step.+expandType (KnownT _) = mzero+ -- ^ ASSUMPTION: The step referenced in KnownT happens earlier than the current step.+expandType ty = error $ "expandType: '" ++ ppTy ++ "' not supported"+ where ppTy = show . render $ sptType Nothing ty ++-- number cases such that duplicates get numbered individually+numberCases :: [ChainRuleState] -> [ChainRuleState]+numberCases cases = (`evalState` M.empty) . forM cases $ \ crs -> do+ let name = concat . intersperse "_" . map head . group $ crsCaseName crs+ counter <- get+ let i = M.findWithDefault (0::Int) name counter+ put $ M.insert name (succ i) counter+ return $ crs {crsCaseName = return $ if i == 0 then name else name ++ "_" ++ show i}+ -- TODO: Remove this magic number (0) hack+++-- | Extract the actual cases that result in new facts the other cases were+-- just there to compute the name+extractCase :: [E.AnyEq] -> ChainRuleState -> Maybe ((String, [Either TID AgentId]), Facts)+extractCase delayedEqs0 crs = do+ let facts0 = crsFacts crs+ unmappedTID tid + | substTID facts0 tid == tid = return (Left tid)+ | otherwise = mzero+ newVars = concatMap (either unmappedTID (return . Right)) $ crsNewVars crs+ delayedEqs = maybe [] (return . E.MsgEq) (crsFinalEq crs) ++ delayedEqs0+ -- NOTE we are careful here to certify the equalities again. This should be a+ -- no-op, but we'll leave it in for debugging purposes.+ facts <- solve (map (certAnyEq facts0) delayedEqs) facts0+ -- NOTE that at this point the case name is stored in complete form in the+ -- head fragment. Trivial facts need to be removed as they could have been+ -- introduced due to unification.+ return ( (head $ crsCaseName crs, newVars)+ , removeTrivialFacts . trimQuantifiers $ facts)++-- | Cases stemming from the initial intruder knowledge+initialIntruderKnowledge :: Message -> ChainRuleM ()+initialIntruderKnowledge m = do+ facts <- getsFacts id+ case m of+ MSymK a b -> do+ addCaseFragment "ik0"+ ( (modifyFacts $ compromise a) `mplus` (modifyFacts $ compromise b) )+ MShrK a b -> do+ addCaseFragment "ik0"+ ( (modifyFacts $ compromise a) `mplus` (modifyFacts $ compromise b) )+ MAsymSK a -> do+ addCaseFragment "ik0"+ modifyFacts $ compromise a+ -- fake+ MHash m1 -> do+ addCaseFragment "fake"+ modifyFacts $ insertEvOrdNonTrivial (certEvOrd facts (Learn m1, Learn m))+ MEnc m1 m2 -> do+ addCaseFragment "fake"+ modifyFacts+ ( insertEvOrdNonTrivial (certEvOrd facts (Learn m1, Learn m))+ . insertEvOrdNonTrivial (certEvOrd facts (Learn m2, Learn m)))+ MTup m1 m2 -> do+ addCaseFragment "fake"+ modifyFacts+ ( insertEvOrdNonTrivial (certEvOrd facts (Learn m1, Learn m))+ . insertEvOrdNonTrivial (certEvOrd facts (Learn m2, Learn m)))+ MFresh _ -> mzero+ _ -> error $ "initialIntruderKnowledge: message not supported '" ++ show m ++ "'"+++-- | Apply the chain rule to a message in the context of a protocol and a set+-- of established facts. Returns the list of facts corresponding to the+-- disjunctions in the conclusion of the chain rule, which are not trivially+-- false due to syntactic inequality.+chainRuleFacts :: MonadPlus m => Message -> Facts -> m [((String, [Either TID AgentId]), Facts)]+chainRuleFacts (MAVar _ ) _ = error $ "chainRuleFacts: application to agent variables not supported."+chainRuleFacts (MConst _) _ = error $ "chainRuleFacts: application to global constants not supported."+chainRuleFacts (MInvKey _) _ = error $ "chainRuleFacts: application to symbolically inverted keys not supported."+chainRuleFacts (MAsymPK _) _ = error $ "chainRuleFacts: no support for public keys."+chainRuleFacts (MTup _ _) _ = error $ "chainRuleFacts: no support for tuples."+chainRuleFacts m facts0 + | proveAtom facts0 (F.AEv (Learn m)) = assembleCases `liftM` getTyping facts0+ | otherwise = error $ "chainRuleFacts: could not prove that '" ++ show m ++ "' is known to the intruder."+ where+ assembleCases typ = + mapMaybe (extractCase delayedEqs) . numberCases . + flip execStateT (ChainRuleState [] [] facts1 Nothing) $ (+ initialIntruderKnowledge m+ `mplus`+ -- send steps+ do tid <- getFreshTID+ proto <- getsFacts protocol+ msum $ map (roleChains typ tid) $ protoRoles proto+ -- don't output cases where the facts are already contradictory without+ -- the context. This caters for messages that are received and sent in+ -- exactly the same form.+ finalFacts <- gets crsFacts+ guard (not $ proveFalse finalFacts)+ )+ where+ facts1 = facts0 { equalities = E.empty+ , covered = S.insert m $ covered facts0 }+ delayedEqs = E.toAnyEqs $ equalities facts0++ -- insert a list of previous events+ insertPrevious :: [Event] -> Event -> ChainRuleM ()+ insertPrevious prev ev = modifyFacts $+ \facts -> foldl' insertSingle facts prev+ where+ insertSingle p prevEv = insertEvOrdNonTrivial (certEvOrd p (prevEv, ev)) p+ + -- enumerate chainRuleFacts starting from the given role+ roleChains :: Typing -> TID -> Role -> ChainRuleM ()+ roleChains genTyp tid role = do + modifyFacts $ insertRole tid role+ addCaseFragment $ roleName role+ msum . map stepChains $ roleSteps role+ where+ stepChains :: RoleStep -> ChainRuleM ()+ stepChains (Recv _ _) = mzero+ stepChains step@(Send _ pt) = do+ -- trace ("stepChains: " ++ roleName role ++"_"++getLabel l) (return ())+ modifyFacts $ insertStepPrefixClosed (Cert (tid, step))+ addCaseFragment $ stepLabel step+ msgChains [(Step tid step)] (inst tid pt)+ where+ -- case naming+ msgName (MConst i) = getId i+ msgName (MFresh fr) = lidName . getFresh $ fr+ msgName (MAVar av) = lidName . getAVar $ av+ msgName (MMVar mv) = lidName . getMVar $ mv+ msgName (MHash _) = "hash"+ msgName (MEnc _ _) = "enc"+ msgName (MTup _ _) = "tup"+ msgName (MSymK _ _) = "K_ud"+ msgName (MShrK _ _) = "K_bd"+ msgName (MAsymPK _) = "pk"+ msgName (MAsymSK _) = "sk"+ msgName (MAgent _) = "someAgent"+ msgName (MInvKey _) = "invKey"++ lidName = getId . fst . getLocalId++ -- chain enumeration+ msgChains :: [Event] -> Message -> ChainRuleM ()+ msgChains _ (MAVar _) = mzero+ msgChains _ (MAgent _) = mzero+ msgChains _ (MConst _) = mzero+ msgChains prev v@(MMVar mv) = do+ -- trace ("msgChains: " ++ show m') (return ())+ addCaseFragment $ msgName v+ case genTyp of+ WeaklyAtomic -> do -- weak atomicity typing+ -- apply rule ATOMIC and discarge composite case immediatly+ -- m must be a message variable or a fresh message in order to unify+ case m of MMVar _ -> return (); MFresh _ -> return (); _ -> mzero+ insertPrevious prev (Learn v)+ setFinalEq (v, m)+ Typing typ -> -- type invariant+ case M.lookup (lidId $ getMVar mv, role) typ of+ Nothing -> error $ "msgChains: no type provided for '"++show mv++"'"+ Just vty -> do+ vm <- expandType vty+ unify v vm+ msgChains prev vm+ + msgChains prev m'@(MEnc m1 m2) = + do insertPrevious prev (Learn m')+ ( do -- trace ("msgChains: unify " ++ show m' ++ " =?= " ++ show m) (return ())+ addCaseFragment $ msgName m'+ setFinalEq (m', m)+ `mplus`+ msgChains [Learn m', Learn (MInvKey m2)] m1 )+ msgChains prev (MTup m1 m2) = msgChains prev m1 `mplus` msgChains prev m2+ msgChains prev m'@(MFresh _) = do+ insertPrevious prev (Learn m')+ addCaseFragment $ msgName m'+ unify m' m -- here we have to unify, as Isabelle is also doing it early+ msgChains prev m' = do+ insertPrevious prev (Learn m')+ addCaseFragment $ msgName m'+ setFinalEq (m', m)++------------------------------------------------------------------------------+-- Message Equality Splitting to deal with 'MShrK a b = MShrK x y' eqs+------------------------------------------------------------------------------++{-+data Goal = MsgGoal Message -- ^ A message that the intruder must know.+ | SplitGoal MsgEq -- ^ Case splitting from an equality over+ -- bi-directional keys.+ deriving( Eq, Ord, Show, Data, Typeable )+ +-- | Goals that could be solved in the given sequent.+openGoals :: Facts -> [Goal]+openGoals facts = + do eq@(MShrK _ _, MShrK _ _) <- getPostEqs $ equalities facts+ guard (not $ uncurry (==) eq)+ return $ SplitGoal eq+ ++ + map MsgGoal (oldestOpenMessages facts)++-- | Solve a goal.+-- solveGoal :: +-}++-- | Equalities that can be splitted.+splittableEqs :: Facts -> [MsgEq]+splittableEqs facts = + do eq@(MShrK _ _, MShrK _ _) <- getPostEqs $ equalities facts+ guard (not $ uncurry (==) eq)+ return eq++-- | Split an equality between bi-directional symmetric shared keys.+splitEqFacts :: MsgEq -> Facts -> [Maybe Facts]+splitEqFacts (MShrK a b, MShrK x y) facts =+ [ addEqs [MsgEq (a,x), MsgEq (b,y)]+ , addEqs [MsgEq (b,x), MsgEq (a,y)]+ ]+ where+ addEqs eqs = solve (map (certAnyEq facts) eqs) facts++splitEqFacts eq _ = + error $ "splitEqFacts: cannot split equality '" ++ show eq ++ "'"+++------------------------------------------------------------------------------+-- Resolution+------------------------------------------------------------------------------++proveFacts :: Facts -- ^ From these premises+ -> Facts -- ^ Show the these conclusion+ -> Mapping -- ^ Mapping the free variables of the conclusion to the premises.+ -> Bool+proveFacts prems concl mapping =+ all (proveAtom prems . F.substAtom (getMappingEqs mapping)) (toAtoms concl)++-- | Possible unifiers making the first set of facts provable under the second+-- set of facts. resulting equalities describe the mapping from all logical+-- variables of the first set of facts logical variables of the second set of+-- facts.+--+-- NOTE: You may want to use 'trimQuantifiers' before using this function to+-- avoid getting superfluous unifiers.+freeVariableMappings :: Facts -> Facts -> [Mapping]+freeVariableMappings from to = do+ mapping <- quantifierMappings+ return mapping+ where+ quantifierMappings = do+ tideqs <- foldM mkTIDMapping M.empty . S.toList $ tidQuantifiers from+ agnteqs <- foldM mkAgentIdMapping M.empty . S.toList $ aidQuantifiers from+ return $ E.mkMapping tideqs agnteqs++ mkTIDMapping eqs tidF = do+ tidT <- msum . map return . S.toList $ tidQuantifiers to+ return $ M.insert tidF tidT eqs++ mkAgentIdMapping eqs aidF = do+ aidT <- msum . map return . S.toList $ aidQuantifiers to+ return $ M.insert aidF aidT eqs+++-- | Apply the mapping of agent and thread equalities to the facts.+--+-- TODO: Improve error handling. Currently, 'error' is called if the facts +-- are contradictory after the substitution.+applyMapping :: Mapping -> Facts -> Facts+applyMapping mapping facts0 = case newFacts of+ Just (Just facts) -> facts+ _ -> error "applyMapping: failed to reconstruct facts after mapping"+ where+ p = protocol facts0++ newFacts = addAtoms =<< quantifyAIDs =<< quantifyTIDs (empty p)++ eqs = getMappingEqs mapping+ qTID = flip (quantifyTID . E.substTID eqs)+ qAID = flip (quantifyAgentId . either id err . E.substAgentId eqs)+ err = error "applyMapping: mapping does not map agent ids to agent ids"+ quantifyTIDs facts = foldM qTID facts $ S.toList $ tidQuantifiers facts0+ quantifyAIDs facts = foldM qAID facts $ S.toList $ aidQuantifiers facts0++ addAtoms = conjoinAtoms atoms + atoms = map (F.substAtom (getMappingEqs mapping)) . toAtoms $ facts0+++------------------------------------------------------------------------------+-- Pretty Printing+------------------------------------------------------------------------------++-- Helper functions+-------------------++isReprEq :: E.AnyEq -> Bool+isReprEq (TIDEq _) = False+isReprEq (AgentEq _) = False+isReprEq _ = True++ppSet :: (a -> b) -> S.Set a -> [b]+ppSet ppElem = map ppElem . S.toList+++-- To Isar+----------++-- | Pretty print the facts in Isar format.+isaFacts :: IsarConf -> Facts + -> ([Doc],[Doc],[Doc]) -- ^ Quantified variables, representable facts, and non-representable facts+isaFacts conf facts =+ ( ppSet (isar conf) (tidQuantifiers facts) +++ ppSet (isar conf) (aidQuantifiers facts)+ , map (isar conf) reprEqs +++ ppSet (isaUncompr conf) (uncompromised facts) +++ ppSet (isaCompr conf) (compromised facts) +++ ppSet (isaEventOrd conf (Mapping eqs)) (eventOrd facts) +++ ppSet (isaEvent conf (Mapping eqs)) (events facts)+ , map (isar conf) nonReprEqs+ ) + where+ eqs = equalities facts+ (reprEqs, nonReprEqs) = partition isReprEq $ E.toAnyEqs eqs+++-- To a security protocol theory+--------------------------------+++-- | Pretty print the facts in security protocol theory format.+sptFacts :: Facts+ -> ([Doc],[Doc],[Doc]) -- ^ Quantified variables, representable facts, and non-representable facts+sptFacts facts =+ ( ppSet sptTID (tidQuantifiers facts) +++ ppSet sptAgentId (aidQuantifiers facts)+ , map sptAnyEq reprEqs +++ ppComprInfo "uncompromised" (uncompromised facts) +++ ppComprInfo "compromised" (compromised facts) +++ (map (sptEventOrd (Mapping eqs)) $ transitiveChains $ S.toList $ eventOrd facts) +++ ppSet (sptEvent (Mapping eqs)) (events facts)+ , map sptAnyEq nonReprEqs +++ (map ppCovered $ S.toList $ covered facts)+ ) + where+ eqs = equalities facts+ (reprEqs, nonReprEqs) = partition isReprEq $ E.toAnyEqs eqs++ ppCovered m = text "covered" <> parens (sptMessage m)+ ppComprInfo setName set + | S.null set = mzero+ | otherwise = return . fsep $+ (text setName <> lparen : (map (nest 2) . punctuate comma) + (ppSet sptMessage set)) ++ [rparen]+++-- | Compute a list of transitive chains representing an abbreviated version of+-- the given binary relation.+transitiveChains :: Ord a => [(a,a)] -> [[a]]+transitiveChains = sortOn head . foldl' insertEdge []+ where+ findChain sel x cs = case break ((x ==) . sel) cs of+ (_,[]) -> (cs, [x])+ (cs1, c:cs2) -> (cs1 ++ cs2, c)+ insertEdge chains0 (from,to) = + let (chains1, prefix) = findChain last from chains0+ (chains2, suffix) = findChain head to chains1+ in (prefix ++ suffix) : chains2+
@@ -0,0 +1,267 @@+{-# LANGUAGE DeriveDataTypeable #-}+module Scyther.Formula (+-- * Data Types+ Atom(..)+ , Formula(..)++-- ** Construction+ , substAtom+ , relabelTIDs++-- ** Queries+ , hasQuantifiers+ , conjuncts+ , conjunctionToAtoms+ , isTypingFormula+ , destTypingFormula+ , atomTIDs+ , findRole++-- * Pretty Printing+ , isaCompr+ , isaUncompr+ , sptAtom+ , isaAtom+ , isaFormula+ , sptFormula+) where++import Data.Maybe+import Data.Data++import Control.Applicative as App+import Control.Monad+import Control.Monad.State+import Control.Monad.Reader++import Text.Isar++import Scyther.Protocol+import Scyther.Message+import Scyther.Equalities as E+import Scyther.Event+import Scyther.Typing++------------------------------------------------------------------------------+-- Data Types+------------------------------------------------------------------------------++-- | A representable logical atom.+data Atom =+ AFalse -- ^ 'False' in Isabelle.+ | AEq AnyEq -- ^ An equality+ | AEv Event -- ^ An event must have happened.+ | AEvOrd (Event, Event) -- ^ An event order.+ | ACompr Message -- ^ A compromised agent variable.+ | AUncompr Message -- ^ An uncompromised agent variable.+ | AHasType MVar (Maybe Type) + -- ^ A claim that a variable is of the given type;+ -- Nothing stands for weakly-atomic.+ | ATyping Typing -- ^ A claim that the current state of a protocol is+ -- approximated by the given typing.+ | AReachable Protocol -- ^ A claim that the current state is reachable.+ deriving( Eq, Show, Ord, Data, Typeable )++-- | A representable logical formula. Currently these are monotonic formula.+data Formula = + FAtom Atom+ | FConj Formula Formula+ | FExists (Either TID AgentId) Formula+ deriving( Eq, Show, Ord, Data, Typeable )++-- Queries on the structure of the formula+------------------------------------------++-- | A formula is a single atom claiming well-typedness.+isTypingFormula :: Formula -> Bool+isTypingFormula = isJust . destTypingFormula++-- | Extract the typing from a singleton well-typedness formula.+destTypingFormula :: Formula -> Maybe Typing+destTypingFormula (FAtom (ATyping typ)) = return typ+destTypingFormula _ = mzero++-- | Relabel quantified TIDs according to the given list of labels.+relabelTIDs :: [TID] -> Formula -> Formula+relabelTIDs tids0 formula = + runReader (evalStateT (go formula) tids0) (Mapping E.empty)+ where+ go (FAtom atom) = FAtom <$> ((substAtom . getMappingEqs) <$> ask <*> pure atom)+ go (FConj l r) = FConj <$> go l <*> go r+ go (FExists (Left tid) inner) = do+ tids <- get+ case tids of+ [] -> error "relabelTIDs: out of labels"+ tid':tids' -> do + put tids'+ FExists (Left tid') <$> local (addTIDMapping tid tid') (go inner)+ go (FExists q@(Right _) inner) = FExists q <$> go inner+++-- | Compute the threads associated to the given atom.+atomTIDs :: Atom -> [TID]+atomTIDs AFalse = mzero+atomTIDs (ATyping _) = mzero+atomTIDs (AReachable _) = mzero+atomTIDs (AEv e) = evTIDs e+atomTIDs (AEvOrd ord) = evOrdTIDs ord+atomTIDs (ACompr m) = msgTIDs m+atomTIDs (AUncompr m) = msgTIDs m+atomTIDs (AHasType v _) = return $ mvarTID v+atomTIDs (AEq eq) = anyEqTIDs eq+ ++-- Substitution+---------------++-- | Substitute all variables in an atom.+-- +-- NOTE: A 'HasType' atom will only have its thread identifier substituted, but+-- not the whole message variable.+substAtom :: Equalities -> Atom -> Atom+substAtom eqs atom = case atom of+ AFalse -> atom+ AEq eq -> AEq $ substAnyEq eqs eq+ AEv ev -> AEv $ substEv eqs ev+ AEvOrd ord -> AEvOrd $ substEvOrd eqs ord+ ACompr m -> ACompr $ substMsg eqs m+ AUncompr m -> AUncompr $ substMsg eqs m+ AHasType mv ty -> AHasType (mapMVar (substLocalId eqs) mv) ty+ ATyping _ -> atom+ AReachable _ -> atom+++-- Queries+----------++{-+-- | True iff the atom is a well-typedness atom.+isTypeInvariant :: Atom -> Bool+isTypeInvariant (ATyping _) = True+isTypeInvariant _ = False+-}++-- | True iff the formula does contain an existential quantifier.+hasQuantifiers :: Formula -> Bool+hasQuantifiers = isNothing . conjunctionToAtoms++-- | Convert a formula consisting of conjunctions only to a list of atoms. Uses+-- 'fail' for error reporting.+conjunctionToAtoms :: MonadPlus m => Formula -> m [Atom]+conjunctionToAtoms (FAtom a) = return [a]+conjunctionToAtoms (FConj f1 f2) = + (++) `liftM` conjunctionToAtoms f1 `ap` conjunctionToAtoms f2+conjunctionToAtoms _ = + fail "conjunctionToAtoms: existential quantifier encountered."++-- | Split all toplevel conjunctions.+conjuncts :: Formula -> [Formula]+conjuncts (FConj f1 f2) = conjuncts f1 ++ conjuncts f2+conjuncts f = pure f++-- | Find the first conjoined thread to role equality for this thread, if there+-- is any.+findRole :: TID -> Formula -> Maybe Role+findRole tid = go+ where+ go (FAtom (AEq (TIDRoleEq (tid', role))))+ | tid == tid' = return role+ | otherwise = mzero+ go (FAtom _) = mzero+ go (FConj f1 f2) = go f1 `mplus` go f2+ go (FExists v f)+ | Left tid == v = mzero+ | otherwise = go f+++------------------------------------------------------------------------------+-- Pretty Printing+------------------------------------------------------------------------------++-- | A compromised agent variable in Isar format.+isaCompr :: IsarConf -> Message -> Doc+isaCompr conf m = text "RLKR" <> parens (isar conf m) <-> isaIn conf <-> text "reveals t"++-- | An uncompromised agent variable in Isar format.+isaUncompr :: IsarConf -> Message -> Doc+isaUncompr conf m = text "RLKR" <> parens (isar conf m) <-> isaNotIn conf <-> text "reveals t"++-- | A compromised agent variable in security protocol theory format.+sptCompr :: Message -> Doc+sptCompr m = text "compromised" <> parens (sptMessage m)++-- | An uncompromised agent variable in security protocol theory format.+sptUncompr :: Message -> Doc+sptUncompr m = text "uncompromised" <> parens (sptMessage m)++-- | Pretty print an atom in Isar format.+isaAtom :: IsarConf -> Mapping -> Atom -> Doc+isaAtom conf mapping atom = case atom of+ AFalse -> text "False"+ AEq eq -> ppIsar eq+ AEv ev -> isaEvent conf mapping ev+ AEvOrd ord -> isaEventOrd conf mapping ord+ ACompr av -> isaCompr conf av+ AUncompr av -> isaUncompr conf av+ AHasType mv ty -> let tid = mvarTID mv+ optRole = threadRole tid (getMappingEqs mapping)+ in ppIsar mv <-> isaIn conf <-> + isaOptType conf optRole ty <-> ppIsar (mvarTID mv) <-> + isaExecutionSystemState conf+ ATyping _ -> text "well-typed"+ AReachable p -> + text "(t,r,s)" <-> isaIn conf <-> text "reachable" <-> text (protoName p)+ where+ ppIsar :: Isar a => a -> Doc+ ppIsar = isar conf+++-- | Pretty print an atom in security protocol theory format.+sptAtom :: Mapping -> Atom -> Doc+sptAtom mapping atom = case atom of+ AFalse -> text "False"+ AEq eq -> sptAnyEq eq+ AEv ev -> sptEvent mapping ev+ AEvOrd (e1,e2) -> sptEventOrd mapping [e1,e2]+ ACompr av -> sptCompr av+ AUncompr av -> sptUncompr av+ AHasType mv ty -> let optRole = threadRole (mvarTID mv) (getMappingEqs mapping)+ in sptMVar mv <-> text "::" <-> sptOptType optRole ty+ ATyping WeaklyAtomic -> text "weakly-atomic"+ ATyping typ -> sptTyping typ+ AReachable p -> text "reachable" <-> text (protoName p)+++-- | A formula in Isar format.+isaFormula :: IsarConf -> Mapping -> Formula -> Doc+isaFormula conf = pp+ where+ ppIsar :: Isar a => a -> Doc+ ppIsar = isar conf+ + pp m (FAtom atom) = isaAtom conf m atom+ pp m (FConj f1 f2) = sep [pp m f1 <-> isaAnd conf, pp m f2]+ pp m (FExists v f) = parens $+ sep [ isaExists conf <-> (either ppIsar ppIsar v) <> char '.'+ , nest 2 $ pp m' f+ ]+ where+ m' = case v of+ Left tid -> maybe id (addTIDRoleMapping tid) (findRole tid f) m+ Right _ -> m++-- | A formula in security protocol theory format.+sptFormula :: Mapping -> Formula -> Doc+sptFormula = pp+ where+ pp m (FAtom atom) = sptAtom m atom+ pp m (FConj f1 f2) = sep [pp m f1 <-> char '&', pp m f2]+ pp m (FExists v f) = parens $+ sep [ char '?' <-> (either sptTID sptAgentId v) <> char '.'+ , nest 2 $ pp m' f+ ]+ where+ m' = case v of+ Left tid -> maybe id (addTIDRoleMapping tid) (findRole tid f) m+ Right _ -> m+
@@ -0,0 +1,206 @@+-- | Dependency analysis of goals occurring during security proofs.+module Scyther.GoalFlow where++import Control.Monad++import Data.DAG.Simple+import Data.Maybe+import Data.List+import qualified Data.Set as S++import Text.Isar++import Scyther.Protocol+import Scyther.Message+import Scyther.Equalities+import Scyther.Theory++unifiable :: Message -> Message -> Bool+unifiable m1 m2 = isJust $ solve [MsgEq (m1, m2)] empty++-- | All flows from a sent pattern to a received pattern.+patternFlows :: Pattern -> Pattern -> [(Message, Message, Equalities)]+patternFlows ptSend ptRecv = do+ m1 <- S.toList $ messageparts mSend+ m2 <- S.toList $ submessages mRecv+ guard (isEncOrHash m1 && isEncOrHash m2)+ eqs <- solve [MsgEq (m1, m2)] empty+ return (m1, m2, eqs)+ where+ mSend = inst 0 ptSend+ mRecv = inst 1 ptRecv+ isEncOrHash (MEnc _ _) = True+ isEncOrHash (MHash _) = True+ isEncOrHash _ = False+ +-- | All flows between different protocols+protoFlows :: Protocol -> [(((Role,RoleStep),Message),((Role,RoleStep),Message),Equalities)]+protoFlows proto = do+ send@(_, Send _ ptSend) <- steps+ recv@(_, Recv _ ptRecv) <- steps+ (mSend, mRecv, eqs) <- patternFlows ptSend ptRecv+ return ((send, mSend), (recv, mRecv), eqs)+ where+ steps = concat [ zip (repeat role) (roleSteps role) | role <- protoRoles proto ]++sptProtoFlows :: Protocol -> Doc+sptProtoFlows = vcat . map ppFlow . protoFlows+ where+ ppFlow ((send, mSend), (recv, mRecv), eqs) =+ ppLoc send <-> char '<' <-> ppLoc recv <> char ':' $-$+ nest 4 (sep [sptMessage mSend, char '=' <-> sptMessage mRecv]) $-$+ nest 2 (text "==>") $-$+ nest 4 (fsep . punctuate comma . map sptAnyEq $ toAnyEqs eqs)+ ppLoc (role, step) = sptRoleStep (Just role) step++type MsgVarNonces = S.Set ((Role, Id), (Role, Id))++roleRel :: Protocol -> [((Role,RoleStep),(Role,RoleStep))]+roleRel = concatMap rel . protoRoles+ where+ rel role = zip steps (tail steps)+ where+ steps = zip (repeat role) (roleSteps role)++-- computing the msg-variable-nonces+--+-- 1. determine combined relation: roleOrd + msgFlow+-- 2. toposort +-- 3. in order of toposort, for every receive determine+-- first received msg. vars+-- 4. for every first received msg. var, for every flow+-- equating it, transfer assignments+--+sptMsgVarAnn :: Protocol -> Doc+sptMsgVarAnn proto = + (if acyclic then emptyDoc else text "WARNING: full relation is cyclic") $-$+ (fsep . punctuate (text " <") $ map ppStep steps)+ where+ fullRel = roleRel proto ++ flowRel proto+ steps = toposort fullRel+ ppStep (role, step) = sptRoleStep (Just role) step+ acyclic = True -- TODO: Implement check++{-+ findTargets :: Message -> [AnyEq] -> [Either Fresh MsgVar]+ findTargets v eqs = do+ MsgEq (m1, m2) <- eqs+ (do guard (m1 == v)+ extractTarget m2+ `mplus`+ do guard (m2 == v)+ extractTarget m1)+ where+ extractTarget m = case m of + Fresh _ -> return . Left $ m2+ MsgVar _ -> return . Right $ m2+ _ -> mzero -- TODO: Make this more precise; i.e. its not+ -- always safe to ignore.++ updateAnn :: (Role,RoleStep) -> MsgVarNonces -> MsgVarNonces+ updateAnn (role, step) ann = do+ v <- firstRecvs role step+ (send, (mSend, sendTid), (mRecv, recvTid), eqs) <- inFlows proto (stepPat step)+ x <- findTargets (MsgVar (LocalId (v, recvTid))) $ toAnyEqs eqs+ case x of+ --- ... seems like the wrong approach.+ -- simulate algorithm more precisely, over-approximating some structures+ -- and use fixpoint+ ann `S.union`+ S.fromList [+ where+ +inFlows :: Protocol -> Pattern -> + [(((Role,RoleStep),(Message,TID),(Message,TID),Equalities)]+inFlows proto ptRecv = do+ send@(_, Send _ ptSend) <- protoSteps proto+ mSend <- S.toList $ messageparts $ inst sendTID ptSend+ mRecv <- S.toList $ submessages $ inst recvTID ptRecv+ guard (isEnc mSend && isEnc mRecv)+ eqs <- solve [MsgEq (mSend, mRecv)] empty+ return ((send, (mSend,sendTid), (mRecv,recvTid), eqs)+ where+ sendTid = 0+ recvTid = 1+ steps = protoSteps proto+ isEnc (MEnc _ _) = True+ isEnc _ = False++-}++firstRecvs :: Role -> RoleStep -> S.Set Id+firstRecvs _ (Send _ _) = S.empty+firstRecvs role recv@(Recv _ pt) = + patFMV pt `S.difference`+ (S.unions . map (patFMV . stepPat) $ takeWhile (/= recv) (roleSteps role))++-- | The role steps of a protocol.+protoSteps :: Protocol -> [(Role, RoleStep)]+protoSteps proto =+ concat [ zip (repeat role) (roleSteps role) | role <- protoRoles proto ]++sptFirstRecvs :: Protocol -> Doc+sptFirstRecvs proto = vcat $ map ppStep steps+ where+ steps = concat [ zip (repeat role) (roleSteps role) | role <- protoRoles proto ]+ ppStep (role, step) =+ sptRoleStep (Just role) step <> char ':' <->+ (fsep . punctuate comma . map sptId . S.toList $ firstRecvs role step)++existsFlow :: Pattern -> Pattern -> Bool+existsFlow ptSend ptRecv = or+ [ unifiable m1 m2 + | m1 <- S.toList $ messageparts mSend, + m2 <- S.toList $ submessages mRecv,+ isEncOrHash m1, + isEncOrHash m2+ ]+ where+ mSend = inst 0 ptSend+ mRecv = inst 1 ptRecv+ isEncOrHash (MEnc _ _) = True+ isEncOrHash (MHash _) = True+ isEncOrHash _ = False+++-- | Compute the message flow relation.+--+-- TLS has a backwards flow but only in the same thread, it depends on the+-- precise nature of such flow a if it is a problem or not; i.e. if it can be+-- used to introduce a cyclic new thread dependency.+--+-- The argument to use here is to incorporate the intra-thread flow into the+-- flow-induced-role-step-dependency computation+flowRel :: Protocol -> [((Role,RoleStep), (Role,RoleStep))]+flowRel proto = do+ [ (send, recv) | send@(_, Send _ ptSend) <- steps,+ recv@(_, Recv _ ptRecv) <- steps, existsFlow ptSend ptRecv ]+ where+ steps = protoSteps proto++sptProtoOrders :: Protocol -> Doc+sptProtoOrders proto = + text "role ord:" $-$+ nest 2 (ppRel $ roleRel proto) $-$+ text "flow rel:" $-$+ nest 2 (ppRel $ flowRel proto) $-$+ text "annotated flows:" $-$+ nest 2 (sptProtoFlows proto) $-$+ text "first receives:" $-$+ nest 2 (sptFirstRecvs proto) $-$+ text "topological sort according to flow:" $-$+ nest 2 (sptMsgVarAnn proto)+ where+ ppRel = fsep . punctuate comma . map ppPair+ ppPair (x,y) = ppStep x <-> char '<' <-> ppStep y+ ppStep (role, step) = sptRoleStep (Just role) step+++goalFlowAnalysis :: Theory -> Doc+goalFlowAnalysis (Theory _ items) = + vcat . intersperse (text "") $ [ analyzeProto p | ThyProtocol p <- items ]+ where+ analyzeProto proto = + sptProtocol proto $-$+ text "" $-$+ sptProtoOrders proto
@@ -0,0 +1,401 @@+{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable #-}+-- | The actual messages being sent and received over the network are always+-- ground. Here we develop a representation of the denotations of actual+-- messages that may occur during a security proof. This involves symbolically+-- instantiated variables and symbolically inverted keys.+module Scyther.Message (+-- * Messages+ TID(..)+ , LocalId(..)+ , Fresh(..)+ , AVar(..)+ , MVar(..)+ , AgentId(..)+ , Message(..)+ -- ** Queries+ , lidId+ , lidTID+ , avarTID+ , mvarTID+ , msgFMV+ , msgFresh+ , msgAgentIds+ , msgTIDs+ , trivial+ , submessages+ , messageparts+ -- ** Construction/Transformation+ , mapFresh+ , mapAVar+ , mapMVar+ , inst+ , normMsg+ , splitNonTrivial++-- * Output+ , sptTID+ , sptAgentId+ , sptFresh+ , sptAVar+ , sptMVar+ , sptMessage+) where++import Control.Monad+import Control.Applicative++import Data.Data+import Data.Monoid+import qualified Data.Set as S++import Text.Isar++import Scyther.Protocol++------------------------------------------------------------------------------+-- Messages+------------------------------------------------------------------------------++-- | A logical variable for a thread identifier. Note that these are the only+-- free logical variables being used during proofs. Depending on their context+-- they are either universally or existentially quantified.+newtype TID = TID { getTID :: Int }+ deriving( Eq, Ord, Enum, Num, Data, Typeable {-! NFData !-})++instance Show TID where+ show (TID tid) = '#':show tid++-- | An agent name identifier+newtype AgentId = AgentId { agentId :: Int }+ deriving( Eq, Ord, Enum, Num, Data, Typeable )++instance Show AgentId where+ show (AgentId aid) = 'a':show aid+++-- | A local identifier.+newtype LocalId = LocalId { getLocalId :: (Id, TID) }+ deriving( Eq, Ord, Data, Typeable )++instance Show LocalId where+ show (LocalId (i, tid)) = show i ++ show tid++-- | An agent variable.+newtype AVar = AVar { getAVar :: LocalId }+ deriving( Eq, Ord, Show, Data, Typeable )++-- | A message variable.+newtype MVar = MVar { getMVar :: LocalId }+ deriving( Eq, Ord, Show, Data, Typeable )++-- | A fresh message.+newtype Fresh = Fresh { getFresh :: LocalId }+ deriving( Eq, Ord, Show, Data, Typeable )+ ++-- | Denotations of messages as they occurr during reasoning. Note that we do+-- not model agents, as in the proofs that we want to do no actual agent+-- reference will be needed.+--+-- Note: This is /no free algebra/ due to the nested equalities on thread+-- identifiers and the key-inversion function. However, there is still a most+-- general unifier. The easiest way to understand these messages is to map +-- them to the corresponding Isabelle proof states.+data Message = + MConst Id -- ^ A global constant.+ | MFresh Fresh -- ^ A freshly generated message.+ | MAVar AVar -- ^ A symbolically instantiated agent variable.+ | MMVar MVar -- ^ A symbolically instantiated message variable; + | MAgent AgentId -- ^ Some agent name+ -- @MVar (LocalId (Id \"v\", TID 1))@ corresponds to @s(|MV ''v'' tid1|)@.+ | MHash Message -- ^ Hashing+ | MTup Message Message -- ^ Pairing+ | MEnc Message Message -- ^ Encryption or signing depending on the key (the second argument)+ | MSymK Message Message -- ^ A long-term uni-directional symmetric key+ | MShrK Message Message -- ^ A long-term bi-directional symmetric key.+ | MAsymPK Message -- ^ A long-term asymmetric public key.+ | MAsymSK Message -- ^ A long-term asymmetric private key.+ | MInvKey Message -- ^ An application of the key inversion function.+ deriving( Eq, Ord, Show, Data, Typeable {-! NFData !-} )++-- Queries+----------++-- | Identifier of a local id.+lidId :: LocalId -> Id+lidId = fst . getLocalId++-- | Thread identifier of a local id.+lidTID :: LocalId -> TID+lidTID = snd . getLocalId++-- | The thread corresponding to an agent variable+avarTID :: AVar -> TID+avarTID = snd . getLocalId . getAVar ++-- | The thread corresponding to an message variable+mvarTID :: MVar -> TID+mvarTID = snd . getLocalId . getMVar ++-- | Thread identifiers of a message.+msgTIDs :: Message -> [TID]+msgTIDs (MConst _) = empty+msgTIDs (MFresh f) = pure . lidTID . getFresh $ f+msgTIDs (MAVar v) = pure . avarTID $ v+msgTIDs (MMVar v) = pure . mvarTID $ v+msgTIDs (MAgent _) = empty+msgTIDs (MHash m) = msgTIDs m+msgTIDs (MTup m1 m2) = msgTIDs m1 `mappend` msgTIDs m2+msgTIDs (MEnc m1 m2) = msgTIDs m1 `mappend` msgTIDs m2+msgTIDs (MSymK m1 m2) = msgTIDs m1 `mappend` msgTIDs m2+msgTIDs (MShrK m1 m2) = msgTIDs m1 `mappend` msgTIDs m2+msgTIDs (MAsymPK m) = msgTIDs m+msgTIDs (MAsymSK m) = msgTIDs m+msgTIDs (MInvKey m) = msgTIDs m++-- | Agent identifiers of a message.+msgAgentIds :: Message -> [AgentId]+msgAgentIds (MConst _) = empty+msgAgentIds (MFresh _) = empty+msgAgentIds (MAVar _) = empty+msgAgentIds (MMVar _) = empty+msgAgentIds (MAgent a) = pure a+msgAgentIds (MHash m) = msgAgentIds m+msgAgentIds (MTup m1 m2) = msgAgentIds m1 `mappend` msgAgentIds m2+msgAgentIds (MEnc m1 m2) = msgAgentIds m1 `mappend` msgAgentIds m2+msgAgentIds (MSymK m1 m2) = msgAgentIds m1 `mappend` msgAgentIds m2+msgAgentIds (MShrK m1 m2) = msgAgentIds m1 `mappend` msgAgentIds m2+msgAgentIds (MAsymPK m) = msgAgentIds m+msgAgentIds (MAsymSK m) = msgAgentIds m+msgAgentIds (MInvKey m) = msgAgentIds m++-- | Free message variables of a message.+msgFMV :: Message -> [MVar]+msgFMV (MMVar v) = pure v+msgFMV (MHash m) = msgFMV m+msgFMV (MTup m1 m2) = msgFMV m1 <|> msgFMV m2+msgFMV (MEnc m1 m2) = msgFMV m1 <|> msgFMV m2+msgFMV (MSymK m1 m2) = msgFMV m1 <|> msgFMV m2+msgFMV (MAsymPK m) = msgFMV m+msgFMV (MAsymSK m) = msgFMV m+msgFMV (MInvKey m) = msgFMV m+msgFMV _ = empty++-- | Fresh messages of a message.+msgFresh :: Message -> [Fresh]+msgFresh (MFresh lid) = pure lid+msgFresh (MHash m) = msgFresh m+msgFresh (MTup m1 m2) = msgFresh m1 <|> msgFresh m2+msgFresh (MEnc m1 m2) = msgFresh m1 <|> msgFresh m2+msgFresh (MSymK m1 m2) = msgFresh m1 <|> msgFresh m2+msgFresh (MAsymPK m) = msgFresh m+msgFresh (MAsymSK m) = msgFresh m+msgFresh (MInvKey m) = msgFresh m+msgFresh _ = empty++-- | A message is trivial iff it is a tuple or it is guaranteed to be in the+-- initial intruder knowledge (i.e., global constants and agent variables).+--+-- PRE: Message must be normalized.+trivial :: Message -> Bool+trivial (MConst _) = True+trivial (MAVar _) = True+trivial (MTup _ _) = True+trivial (MAgent _) = True+trivial _ = False++-- | The submessages of message.+submessages :: Message -> S.Set Message+submessages m@(MHash m1) = S.insert m $ submessages m1+submessages m@(MTup m1 m2) = S.insert m $ submessages m1 `S.union` submessages m2+submessages m@(MEnc m1 m2) = S.insert m $ submessages m1 `S.union` submessages m2+submessages m@(MSymK m1 m2) = S.insert m $ submessages m1 `S.union` submessages m2+submessages m@(MAsymPK m1) = S.insert m $ submessages m1+submessages m@(MAsymSK m1) = S.insert m $ submessages m1+submessages (MInvKey _) = error "submessages: undefined for key inversion"+submessages m = S.singleton m++-- | The accessible submessages of message.+messageparts :: Message -> S.Set Message+messageparts m@(MTup m1 m2) = S.insert m $ messageparts m1 `S.union` messageparts m2+messageparts m@(MEnc m1 m2) = S.insert m $ messageparts m1 `S.union` messageparts m2+messageparts m = S.singleton m+++-- Construction/Transformaiton+------------------------------++mapFresh :: (LocalId -> LocalId) -> Fresh -> Fresh+mapFresh f = Fresh . f . getFresh++mapAVar :: (LocalId -> LocalId) -> AVar -> AVar+mapAVar f = AVar . f . getAVar++mapMVar :: (LocalId -> LocalId) -> MVar -> MVar+mapMVar f = MVar . f . getMVar++-- | Instantiate a pattern to a message. Variables are instantiated+-- symbolically. The resulting message is guaranteed to be normalized w.r.t+-- `normMsg`.+inst :: TID -> Pattern -> Message+inst _ (PConst i) = MConst i+inst tid (PFresh i) = MFresh (Fresh (LocalId (i, tid)))+inst tid (PAVar i) = MAVar (AVar (LocalId (i, tid)))+inst tid (PMVar i) = MMVar (MVar (LocalId (i, tid)))+inst tid (PHash pt) = MHash (inst tid pt)+inst tid (PTup pt1 pt2) = MTup (inst tid pt1) (inst tid pt2)+inst tid (PEnc pt1 pt2) = MEnc (inst tid pt1) (inst tid pt2)+inst tid (PSign pt1 pt2) = MTup m1 (MEnc m1 (normMsg $ MInvKey (inst tid pt2)))+ where m1 = inst tid pt1+inst tid (PSymK pt1 pt2) = MSymK (inst tid pt1) (inst tid pt2)+inst tid (PShrK pt1 pt2) = MShrK (inst tid pt1) (inst tid pt2)+inst tid (PAsymPK pt) = MAsymPK (inst tid pt)+inst tid (PAsymSK pt) = MAsymSK (inst tid pt)++-- | Normalize a message; i.e., apply key-inversion if possible and swap shared+-- key arguments, if required.+normMsg :: Message -> Message+normMsg m@(MConst _) = m+normMsg m@(MFresh _) = m+normMsg m@(MAVar _) = m+normMsg m@(MMVar _) = m+normMsg m@(MAgent _) = m+normMsg (MInvKey (MInvKey m)) = normMsg m+normMsg (MInvKey (MAsymPK m)) = MAsymSK (normMsg m)+normMsg (MInvKey (MAsymSK m)) = MAsymPK (normMsg m)+normMsg m@(MInvKey (MMVar _)) = m+normMsg (MInvKey m) = normMsg m+normMsg (MHash m) = MHash (normMsg m)+normMsg (MTup m1 m2) = MTup (normMsg m1) (normMsg m2)+normMsg (MEnc m1 m2) = MEnc (normMsg m1) (normMsg m2)+normMsg (MSymK m1 m2) = MSymK (normMsg m1) (normMsg m2)+normMsg (MShrK m1 m2) + | m1' < m2' = MShrK m1' m2'+ | otherwise = MShrK m2' m1'+ where+ m1' = normMsg m1+ m2' = normMsg m2+normMsg (MAsymPK m) = MAsymPK (normMsg m)+normMsg (MAsymSK m) = MAsymSK (normMsg m)+++-- | Splits a message into the list of non-'trivial' messages accessible using+-- projection only.+--+-- Postcondition: All messages in the list are non-'trivial'.+splitNonTrivial :: Message -> [Message]+splitNonTrivial (MTup m1 m2) = splitNonTrivial m1 `mplus` splitNonTrivial m2+splitNonTrivial m = do+ guard (not $ trivial m) + return m++++------------------------------------------------------------------------------+-- ISAR Output+------------------------------------------------------------------------------++-- | Textual symbolic application of the substitution.+-- TODO: Remove hack about thread identifier to state assignment.+esplSubst :: LocalId -> IsarConf -> Doc -> Doc+esplSubst (LocalId (_,tid)) conf var + | tid == 0 = isarSubst conf <> parens var+ | otherwise = text "s" <> parens var++instance Isar TID where+ isar _ tid = text "tid" <> int (getTID tid)+ -- | isPlainStyle conf = text "tid" <> int (getTID tid)+ -- | otherwise = text "tid" <> zeroWidthText "\\<^isub>" <> int (getTID tid)++instance Isar AgentId where+ isar _ aid = text "a" <> int (agentId aid)+ -- | isPlainStyle conf = text "a" <> int (agentId aid)+ -- | otherwise = text "a" <> zeroWidthText "\\<^isub>" <> int (agentId aid)++instance Isar LocalId where+ isar conf (LocalId (i, tid)) = isar conf i <-> isar conf tid++instance Isar Fresh where+ isar conf (Fresh i) = text "LN" <-> isar conf i++instance Isar AVar where+ isar conf (AVar i) = esplSubst i conf (text "AV" <-> isar conf i)++instance Isar MVar where+ isar conf (MVar i) = esplSubst i conf (text "MV" <-> isar conf i)++instance Isar Message where+ isar conf x = case x of+ (MConst i) -> text "LC" <-> isar conf i+ (MFresh i) -> isar conf i + (MAVar i) -> isar conf i+ (MMVar i) -> isar conf i+ (MAgent i) -> isar conf i+ (MHash m) -> text "Hash" <-> ppTup m+ pt@(MTup _ _) -> ppTup pt+ (MEnc m k) -> text "Enc" <-> sep [ppTup m, ppTup k]+ (MSymK a b) -> text "K" <-> sep [ppTup a, ppTup b]+ (MShrK a b) -> text "Kbd" <-> sep [ppTup a, ppTup b]+ (MAsymPK a) -> text "PK" <-> ppTup a+ (MAsymSK a) -> text "SK" <-> ppTup a+ (MInvKey m) -> text "inv" <> parens (isar conf m)+ where+ -- pretty print a tuple as right associate list+ ppTup m@(MTup _ _) = nestShort n ldelim rdelim (fsep $ punctuate comma $ map (isar conf) $ split m)+ ppTup m = nestShort' "(" ")" (isar conf m)+ -- split right associate nested tuples+ split (MTup m1 m2) = m1 : split m2+ split m = [m]+ -- determine output parameters+ (n,ldelim,rdelim) + | isPlainStyle conf = (3, text "{|", text "|}")+ | otherwise = (2, symbol "\\<lbrace>", symbol "\\<rbrace>") +++------------------------------------------------------------------------------+-- SP Theory Output+------------------------------------------------------------------------------++sptTID :: TID -> Doc+sptTID = text . show++sptAgentId :: AgentId -> Doc+sptAgentId = (char 'a' <>) . int . agentId++sptLocalId :: LocalId -> Doc+sptLocalId (LocalId (i, tid)) = sptId i <> sptTID tid++sptFresh :: Fresh -> Doc+sptFresh = (char '~' <>) . sptLocalId . getFresh++sptAVar :: AVar -> Doc+sptAVar = sptLocalId . getAVar++sptMVar :: MVar -> Doc+sptMVar = (char '?' <>) . sptLocalId . getMVar+++sptMessage :: Message -> Doc+sptMessage x = case x of+ (MConst i) -> char '\'' <> sptId i <> char '\''+ (MFresh i) -> sptFresh i+ (MAVar i) -> sptAVar i+ (MAgent i) -> sptAgentId i+ (MMVar i) -> sptMVar i+ (MHash m) -> text "h" <> ppBetween 1 "(" ")" m+ pt@(MTup _ _) -> ppBetween 1 "(" ")" pt+ (MEnc m k) -> fcat [ppBetween 1 "{" "}" m, sptMessage k]+ (MSymK a b) -> fcat [text "k(", sptMessage a, comma, sptMessage b, text ")"]+ (MShrK a b) -> fcat [text "k[", sptMessage a, comma, sptMessage b, text "]"]+ (MAsymPK a) -> text "pk" <> ppBetween 1 "(" ")" a+ (MAsymSK a) -> text "sk" <> ppBetween 1 "(" ")" a+ (MInvKey m) -> text "inv" <> ppBetween 1 "(" ")" m+ where+ -- pretty print a tuple as right associate list+ ppBetween n lead finish m@(MTup _ _) = + fcat . (text lead :) . (++[text finish]) . map (nest n) . punctuate (text ", ") . map sptMessage $ split m+ ppBetween _ lead finish m = text lead <> sptMessage m <> text finish+ -- split right associate nested tuples+ split (MTup m1 m2) = m1 : split m2+ split m = [m]+
@@ -0,0 +1,438 @@+{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable #-}+-- | A representation for proofs constructed using our security protocol+-- verification theory.+module Scyther.Proof (+ -- * Datatypes+ Proof(..)+ , TrivReason(..)+ , Rule(..)++ -- ** Proof construction+ , dfsProof+ , shortestProof+ , minimizeProof+ , mapProofSequents++ -- ** Queries+ , prfSequent+ , prfProto+ , isAxiomProof+ , isTrivialProof+ , complete+ , sound+ , depends+ , extractTypeInvariant++ -- *** Proof sizes+ , ProofSize+ , getProofSize+ , missingProofSize+ , proofSize++ -- * Special "Proofs"+ , existsPossibleAttack+ , displayChainRule++) where++import Data.Function+import Data.Maybe+import Data.List+import Data.Monoid+import qualified Data.Set as S+import Data.Data++import Control.Applicative+import Control.Monad+import Control.Monad.State+import Control.Monad.BoundedDFS++import Extension.Prelude++import Scyther.Facts +import qualified Scyther.Equalities as E +import Scyther.Sequent++------------------------------------------------------------------------------+-- Data Types+------------------------------------------------------------------------------++-- | A proof of a sequent.+data Proof =+ Axiom Sequent -- ^ Assumed as an axiom.+ | PossibleAttack Sequent Sequent -- ^ A possible attack on the given sequent.+ | Missing Sequent String Bool -- ^ A missing proof and the reason why it is+ -- missing plus a flag for displaying the sequent.+ | Trivial Sequent TrivReason -- ^ A trivial proof for the sequent and the+ -- reason why it is trivial.+ | RuleApp Sequent Rule [Proof] -- ^ An application of a rule/theorem and the+ -- proofs for all the resulting sequents.+ deriving( Eq, Show, Data, Typeable {-! NFData !-} )++-- | Triviality reasons.+data TrivReason =+ TrivContradictoryPremises+ | TrivPremisesImplyConclusion+ | TrivLongTermKeySecrecy Message+ deriving( Eq, Show, Data, Typeable {-! NFData !-} )++-- | Supported rules.+data Rule =+ Saturate+ | ForwardResolution (Named Sequent) E.Mapping+ | ChainRule Message [(String, [Either TID AgentId])]+ | SplitEq E.MsgEq [Bool] -- True, if sub-proof for this case is present.+ | TypingCases [String]+ deriving( Eq, Show, Data, Typeable {-! NFData !-} )++------------------------------------------------------------------------------+-- Simple Queries+------------------------------------------------------------------------------++-- | True iff the proof is trivial.+isTrivialProof :: Proof -> Bool+isTrivialProof (Trivial _ _) = True+isTrivialProof _ = False++-- | True iff the proof is an axiom definition.+--+-- NOTE: This checks only if the proof is directly by axiom.+isAxiomProof :: Proof -> Bool+isAxiomProof (Axiom _) = True+isAxiomProof _ = False++-- | Extract the proven sequent from a proof.+prfSequent :: Proof -> Sequent+prfSequent (Axiom se) = se+prfSequent (PossibleAttack se _) = se+prfSequent (Missing se _ _) = se+prfSequent (Trivial se _) = se+prfSequent (RuleApp se _ _) = se++-- | Extract the protocol concerned by a proof.+prfProto :: Proof -> Protocol+prfProto = seProto . prfSequent+++------------------------------------------------------------------------------+-- Proof Construction+------------------------------------------------------------------------------++-- | Try proving a sequent by assumption; i.e. by showing that the premises+-- directly imply the conclusion.+byAssumption :: Monad m => Sequent -> m Proof+byAssumption se@(Sequent prem concl)+ | proveFalse prem = return $ Trivial se TrivContradictoryPremises+ | proveFormula prem concl = return $ Trivial se TrivPremisesImplyConclusion+ | otherwise = case exploitLongTermKeySecrecy prem of+ Just key -> return $ Trivial se (TrivLongTermKeySecrecy key)+ Nothing -> fail $ "byAssumption: cannot prove conclusion from premises"+++-- | An order preferring typing conclusions and then false conclusions.+reuseOrder :: Formula -> Formula -> Ordering+reuseOrder (FAtom (ATyping typ1)) (FAtom (ATyping typ2)) = compare typ1 typ2+reuseOrder (FAtom (ATyping _)) _ = LT+reuseOrder _ (FAtom (ATyping _)) = GT+reuseOrder (FAtom AFalse) (FAtom AFalse) = EQ+reuseOrder (FAtom AFalse) _ = LT+reuseOrder _ (FAtom AFalse) = GT+reuseOrder f1 f2 = compare f1 f2+++-- | A generic proof strategy for proving sequents. Eagerly reuses lemmas in+-- the order they were given using forward resolution.+genericProof :: MonadPlus m + => m () -- ^ A marker for usages of the chain rule.+ -> (Facts -> [Message]) -- ^ A heuristic for the order of+ -- messages to be tried using the chain rule.+ -> [Named Sequent] -- ^ Rules that should be reused in this proof.+ -> Sequent -- ^ The sequent to be proven+ -> m Proof+genericProof chainRuleMarker goals rawRules se0 = + case saturate se0 of+ Just se1 -> (RuleApp se0 Saturate . return) `liftM` prove se1+ Nothing -> prove se0+ where+ -- the theorems for reuse: prefer false conclusions over arbitrary conclusions+ reusableRules :: [Named Sequent]+ reusableRules = sortBy (reuseOrder `on` (seConcl . snd)) rawRules++ -- build a proof step corresponding to the reuse of a rule.+ reuseRule se rule = do+ (mapping, optSequent) <- frule (snd rule) se+ let mkProof = RuleApp se (ForwardResolution rule mapping)+ case optSequent of + Nothing -> return $ return $ mkProof []+ Just sequent -> return $ (mkProof . return) `liftM` prove sequent++ -- use the chain rule+ useChainRule se m = do+ chainRuleMarker+ case chainRule se m of+ Just cases -> do+ let (info, sequents) = unzip cases+ (RuleApp se (ChainRule m info)) `liftM` mapM prove sequents+ Nothing -> return $ Missing se "prover stuck => no type invariant available" True++ -- prove a sequent+ prove se = + case byAssumption se of+ Just prf -> return prf -- proven by assumption+ Nothing ->+ case wellTypedCases se of+ Just cases -> do -- try to prove well-typedness cases+ let (names, sequents) = unzip cases+ RuleApp se (TypingCases names) `liftM` mapM prove sequents+ Nothing ->+ case msum (map (reuseRule se) reusableRules) of+ Just mkPrf -> mkPrf -- could reuse a proven sequent+ Nothing -> -- try to use the chain rule+ case splittableEqs (sePrem se) of+ -- split the first available equality+ eq:_ -> do+ let sequents = splitEq eq se+ RuleApp se (SplitEq eq (map isJust sequents)) `liftM`+ mapM prove (catMaybes sequents)+ + -- there is none => chain rule is our last resort+ [] ->+ case goals (sePrem se) of+ [] -> return $ PossibleAttack se se+ ms -> msum $ map (useChainRule se) ms++++-- | Use a (possibly bounded) depth-first search for finding the proof.+-- TODO: Make error handling explicit.+dfsProof :: Maybe Int -> (Facts -> [Message]) -> [Named Sequent] -> Sequent -> Maybe Proof+dfsProof Nothing heuristic rules se = + runUnboundedDFS $ genericProof (return ()) heuristic rules se+dfsProof (Just bound) heuristic rules se = + evalBoundedDFS (genericProof (updateCost succ) heuristic rules se) (<= bound) 0+ +-- | Use branch-and-bound search to find the shortest proof.+-- TODO: Make error handling explicit.+shortestProof :: Maybe Int -> (Facts -> [Message]) -> [Named Sequent] -> Sequent -> Maybe Proof+shortestProof optBound heuristic rules se = + evalBranchAndBound+ (genericProof (updateCost (fmap succ)) heuristic rules se)+ optBound ++-- | Check if there exists a case where the prover gets stuck using unbounded DFS+-- and the given heuristic and theorems to reuse.+existsPossibleAttack :: (Facts -> [Message]) -> [Named Sequent] -> Sequent -> Maybe Proof+existsPossibleAttack heuristic rules se = + findAttack =<< (runUnboundedDFS $ genericProof (return ()) heuristic rules se)++------------------------------------------------------------------------------+-- Proof Checking and Minimization+------------------------------------------------------------------------------++-- | A proof is locally sound iff each rule application is sound.+checkProof :: Sequent -> Proof -> Maybe Proof+checkProof se0 prf0 = evalStateT (go prf0) se0+ where+ mkSubproof se prf = put se >> go prf++ go :: Proof -> StateT Sequent Maybe Proof+ go (Missing _ reason showSequent) = + Missing <$> get <*> pure reason <*> pure showSequent+ go prf@(Axiom seAxiom) = do+ se <- get+ guard (se == seAxiom)+ return prf+ go prf@(PossibleAttack seAttacked _) = do+ se <- get+ guard (se == seAttacked)+ return prf+ go (Trivial _ reason@TrivContradictoryPremises) = do+ prem <- gets sePrem+ guard (proveFalse prem)+ Trivial <$> get <*> pure reason+ go (Trivial _ reason@TrivPremisesImplyConclusion) = do+ se <- get+ guard (proveFormula (sePrem se) (seConcl se))+ Trivial <$> get <*> pure reason+ go (Trivial _ reason@(TrivLongTermKeySecrecy key)) = do+ se <- get+ case exploitLongTermKeySecrecy (sePrem se) of+ Just key' -> do guard (key == key')+ Trivial <$> get <*> pure reason+ Nothing -> mzero+ go (RuleApp _ Saturate [prf]) = do+ se <- get+ case saturate se of+ Just se' -> (RuleApp se Saturate . return) <$> (put se' >> go prf)+ Nothing -> go prf+ go (RuleApp _ rule@(ForwardResolution thm mapping) prfs) = do+ se <- get+ let statePrem = sePrem se+ guard (proveFacts statePrem (sePrem $ snd thm) mapping)+ optSequent <- fruleInst (snd thm) mapping se+ case optSequent of + Nothing -> do guard (null prfs)+ return $ RuleApp se rule prfs+ Just sequent -> case prfs of+ [prf] -> (RuleApp se rule . return) `liftM` mkSubproof sequent prf+ _ -> mzero+ go (RuleApp _ rule@(ChainRule m info) prfs) = do+ se <- get+ -- FIXME: Here we could get a problem if the atom can no longer be+ -- certified. This will probably not occur in our current setting, as+ -- proof minimization does not change the quantifiers because only+ -- non-existentially quantified conclusions are reused.+ guard (proveAtom (sePrem se) (AEv (Learn m)))+ (info', sequents') <- unzip `liftM` chainRule se m+ guard (info == info')+ RuleApp <$> get <*> pure rule <*> zipWithM mkSubproof sequents' prfs++ go (RuleApp _ rule@(SplitEq eq info) prfs) = do+ se <- get+ guard (eq `elem` splittableEqs (sePrem se))+ let optSequents' = splitEq eq se+ info' = map isJust optSequents'+ sequents' = catMaybes optSequents'+ guard (info == info')+ RuleApp <$> get <*> pure rule <*> zipWithM mkSubproof sequents' prfs++ go (RuleApp _ rule@(TypingCases info) prfs) = do+ se <- get+ (info', sequents') <- unzip `liftM` wellTypedCases se+ guard (info == info')+ RuleApp <$> get <*> pure rule <*> zipWithM mkSubproof sequents' prfs+ go _ = mzero++-- | Find the first 'PossibleAttack' proof state and replace all other proof+-- steps on the way to this state by missing steps.+findAttack :: Proof -> Maybe Proof+findAttack = fmap head . go . return+ where+ unvisited prf = Missing (prfSequent prf) "not yet investigated" False+ + go :: [Proof] -> Maybe [Proof]+ go [] = Nothing+ go (prf : prfs) = case prf of+ RuleApp se rule subprfs -> + -- look for an attack in the subproofs of the given rule+ (do subprfs' <- go subprfs+ return $ RuleApp se rule subprfs' : map unvisited prfs+ ) `mplus`+ -- look for an attack in the remaining proofs+ ((unvisited prf :) `liftM` go prfs) + -- attack found: return it together with the unvisited siblings+ PossibleAttack _ _ -> return $ prf : map unvisited prfs + -- look for an attack in the siblings and prepend ourselves unvisited+ _ -> (unvisited prf :) `liftM` go prfs++-- | A proof is complete iff no 'Missing' proof or 'PossibleAttack' is part of it.+complete :: Proof -> Bool+complete (Missing _ _ _) = False+complete (PossibleAttack _ _) = False+complete (RuleApp _ _ prfs) = all complete prfs+complete _ = True++-- | A proof is sound iff it is complete and each inference step is sound.+sound :: Proof -> Bool+sound prf = complete prf && isJust (checkProof (prfSequent prf) prf)++-- | Minimize a proof by removing all unnecesary forward resolutions.+minimizeProof :: Proof -> Proof+minimizeProof prf0 = fromMaybe prf0 $ do+ prf <- go prf0 + checkProof (prfSequent prf) prf+ where+ go (RuleApp se rule@(ForwardResolution _ _) [prf]) = do + prf' <- go prf+ (checkProof se prf' <|> pure (RuleApp se rule [prf']))+ go (RuleApp se rule prfs) =+ RuleApp se rule <$> mapM go prfs+ go prf = return prf++-- | Output the set of theorems a proof depends on.+depends :: Proof -> S.Set (String, Protocol)+depends (RuleApp _ (ForwardResolution (name, se) _) prfs) =+ S.insert (name, seProto se) $ S.unions $ map depends prfs+depends (RuleApp _ _ prfs) = S.unions $ map depends prfs+depends _ = S.empty++-- | Extracts the first type invariant occurring in a forward resolution. This+-- is required because in Isabelle type invariants are handled using locales,+-- while we are handling them using forward resolution. +--+-- Note that our system here is more general, but for the current setup, we do+-- not see this generality.+extractTypeInvariant :: Proof -> Maybe (Named Typing)+extractTypeInvariant (RuleApp _ (ForwardResolution (name, se) _) prfs) =+ case destTypingFormula (seConcl se) of+ Just typ -> return (name, typ)+ Nothing -> msum $ map extractTypeInvariant prfs+extractTypeInvariant (RuleApp _ _ prfs) = msum $ map extractTypeInvariant prfs+extractTypeInvariant _ = mzero++------------------------------------------------------------------------------+-- Proof Sizes+------------------------------------------------------------------------------++-- | Proof size datatype counting number of chain rule applications and the+-- number of forward resolutions. The 'Monoid' instance corresponds to adding+-- proof sizes.+newtype ProofSize = ProofSize (Sum Int, Sum Int, Sum Int)+ deriving( Eq, Ord, Monoid )++instance Show ProofSize where+ show s = + concat ["C:", show nChain, " F:", show nForward, " M:", show nMissing]+ where+ (nChain, nForward, nMissing) = getProofSize s++-- | Extract the raw proof size information.+getProofSize :: ProofSize -> (Int, Int, Int)+getProofSize (ProofSize (nChain, nForward, nMissing)) = + (getSum nChain, getSum nForward, getSum nMissing)++-- | The size of a missing proof.+missingProofSize :: ProofSize+missingProofSize = ProofSize (mempty, mempty, Sum 1)++-- | Compute the size of a proof.+proofSize :: Proof -> ProofSize+proofSize (Axiom _) = mempty+proofSize (PossibleAttack _ _) = mempty+proofSize (Trivial _ _) = mempty+proofSize (Missing _ _ _) = missingProofSize+proofSize (RuleApp _ rule prfs) = mconcat $+ (case rule of+ ChainRule _ _ -> pure $ ProofSize (Sum 1, mempty, mempty)+ ForwardResolution _ _ -> pure $ ProofSize (mempty, Sum 1, mempty)+ _ -> mempty+ ) ++ map proofSize prfs++-- | Map the sequents of the proof.+mapProofSequents :: (Sequent -> Sequent) -> Proof -> Proof+mapProofSequents f = go+ where+ go (Axiom se) = Axiom (f se)+ go (PossibleAttack se se') = PossibleAttack (f se) (f se')+ go (Trivial se reason) = Trivial (f se) reason+ go (Missing se reason hide) = Missing (f se) reason hide+ go (RuleApp se rule prfs) = RuleApp (f se) rule (map go prfs)+++-- Chain Rule Display+------------------------------------------------------------------------------++displayChainRule :: Protocol -> Maybe Typing -> Proof+displayChainRule _ _ = error "displayChainRule: not yet upgraded"+{-+displayChainRule proto optTyp = + RuleApp se (ChainRule optTyp m (map fst cases)) (map mkPrf cases)+ where+ tid = 0 + m = (MMVar (LocalId (Id "m", tid)))+ prem = insertEv (Learn m) $ insertThread tid $ emptyFacts+ se = Sequent proto (FFacts prem) FFalse+ cases = chainRule proto optTyp m prem+ mkPrf c = Missing (Sequent proto (FFacts (snd c)) FFalse) "chain rule case:"++-}
@@ -0,0 +1,458 @@+{-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable #-}+-- | Security protocol represented as a set of roles which are sequences of+-- send and receive steps.+module Scyther.Protocol (++-- * Types+ Id(..)+ , Pattern(..)+ , Label(..)+ , RoleStep(..)+ , Role(..)+ , Protocol(..)+ , RoleStepOrder++-- * Queries++ -- ** Patterns+ , patFMV+ , patFAV+ , subpatterns+ , patternparts+ , splitpatterns++ -- ** Role Steps+ , stepPat+ , stepLabel+ , stepFMV+ , stepFAV++ -- ** Roles+ , roleFMV+ , roleFAV+ , lookupRoleStep+ , wfRole+ , roleOrd++ -- ** Protocols+ , lookupRole+ , stateLocale+ , restrictedStateLocale+ , weakAtomicityLocale+ , weakAtomicityInvariant+ , labelOrd+ , protoOrd++ -- ** Wellformedness+ , ProtoIllformedness+ , wfProto+ , sptProtoIllformedness++-- * Output+ , isaRoleStep+ , sptId + , sptLabel+ , sptPattern+ , sptRoleStep+ , sptRole+ , sptProtocol+) where++import Safe+import Data.List+import qualified Data.Set as S+import Data.Data++import Control.Monad++import Extension.Prelude+import Text.Isar++-- Datatypes+------------++-- | An identifier.+newtype Id = Id { getId :: String }+ deriving( Eq, Ord, Data, Typeable {-! NFData !-} )++instance Show Id where+ show (Id i) = i++-- | A message pattern.+data Pattern = + PConst Id -- ^ A global constant.+ | PFresh Id -- ^ A message to be freshly generated.+ | PAVar Id -- ^ An agent variable.+ | PMVar Id -- ^ A message variable.+ | PHash Pattern -- ^ Hashing+ | PTup Pattern Pattern -- ^ Pairing+ | PEnc Pattern Pattern -- ^ Symmetric or asymmetric encryption (depent on the key).+ | PSign Pattern Pattern -- ^ A signature to be verified with the given key.+ | PSymK Pattern Pattern -- ^ A long-term unidirectional symmetric key.+ | PShrK Pattern Pattern -- ^ A long-term bi-directional symmetric key.+ | PAsymPK Pattern -- ^ A long-term public key.+ | PAsymSK Pattern -- ^ A long-term private key+ deriving( Eq, Ord, Show, Data, Typeable {-! NFData !-} )++-- | A label of a role step.+newtype Label = Label { getLabel :: String }+ deriving( Eq, Ord, Show, Data, Typeable {-! NFData !-} )++-- | A role step.+data RoleStep = + Send Label Pattern -- ^ A send step.+ | Recv Label Pattern -- ^ A receive step.+ deriving( Eq, Ord, Show, Data, Typeable {-! NFData !-} )++-- | A role of a protocol. Its name has no operational meaning, but is carried+-- along to allow for human readable printing.+data Role = Role { + roleName :: String+ , roleSteps :: [RoleStep] + }+ deriving( Eq, Ord, Show, Data, Typeable {-! NFData !-} )++-- | A protocol. As for roles, its name has no operational meaning, but is+-- carried along to allow for human readable printing.+data Protocol = Protocol { + protoName :: String+ , protoRoles :: [Role]+ }+ deriving( Eq, Ord, Show, Data, Typeable {-! NFData !-} )+++-- Queries+----------+++-- | Find a role in a protocol according to its name.+lookupRole :: String -> Protocol -> Maybe Role+lookupRole name = find ((== name) . roleName) . protoRoles++-- | Find a role step in a role according to its label.+lookupRoleStep :: String -> Role -> Maybe RoleStep+lookupRoleStep lbl = find ((== lbl) . stepLabel) . roleSteps++-- | Pattern of of a role step+stepPat :: RoleStep -> Pattern+stepPat (Send _ pt) = pt+stepPat (Recv _ pt) = pt++-- | The string label of a role step.+stepLabel :: RoleStep -> String+stepLabel (Send l _) = getLabel l+stepLabel (Recv l _) = getLabel l++-- | Pattern subterms.+subpatterns :: Pattern -> S.Set Pattern+subpatterns pt@(PHash pt1) = S.insert pt $ subpatterns pt1+subpatterns pt@(PTup pt1 pt2) = S.insert pt $ subpatterns pt1 `S.union` subpatterns pt2+subpatterns pt@(PEnc pt1 pt2) = S.insert pt $ subpatterns pt1 `S.union` subpatterns pt2+subpatterns pt@(PSign pt1 pt2) = S.insert pt $ subpatterns pt1 `S.union` subpatterns pt2+subpatterns pt@(PSymK pt1 pt2) = S.insert pt $ subpatterns pt1 `S.union` subpatterns pt2+subpatterns pt@(PShrK pt1 pt2) = S.insert pt $ subpatterns pt1 `S.union` subpatterns pt2+subpatterns pt@(PAsymPK pt1) = S.insert pt $ subpatterns pt1+subpatterns pt@(PAsymSK pt1) = S.insert pt $ subpatterns pt1+subpatterns pt = S.singleton pt++-- | Accessible pattern subterms.+patternparts :: Pattern -> S.Set Pattern+patternparts pt@(PTup pt1 pt2) = S.insert pt $ patternparts pt1 `S.union` patternparts pt2+patternparts pt@(PEnc pt1 _) = S.insert pt $ patternparts pt1+patternparts pt@(PSign pt1 _) = S.insert pt $ patternparts pt1+patternparts pt = S.singleton pt++-- | Splitting top-level pairs.+splitpatterns :: Pattern -> S.Set Pattern+splitpatterns (PTup pt1 pt2) = splitpatterns pt1 `S.union` splitpatterns pt2+splitpatterns (PSign pt _ ) = splitpatterns pt+splitpatterns pt = S.singleton pt++-- | Free message variables of a pattern.+patFMV :: Pattern -> S.Set Id+patFMV (PMVar v) = S.singleton v+patFMV (PHash pt) = patFMV pt+patFMV (PTup pt1 pt2) = patFMV pt1 `S.union` patFMV pt2+patFMV (PEnc pt1 pt2) = patFMV pt1 `S.union` patFMV pt2+patFMV (PSign pt1 pt2) = patFMV pt1 `S.union` patFMV pt2+patFMV (PSymK pt1 pt2) = patFMV pt1 `S.union` patFMV pt2+patFMV (PShrK pt1 pt2) = patFMV pt1 `S.union` patFMV pt2+patFMV (PAsymPK pt) = patFMV pt+patFMV (PAsymSK pt) = patFMV pt+patFMV _ = S.empty++-- | Frees message variables of a role step.+stepFMV :: RoleStep -> S.Set Id+stepFMV = patFMV . stepPat++-- | Free message variables of a role.+roleFMV :: Role -> S.Set Id+roleFMV = S.unions . map (patFMV . stepPat) . roleSteps++-- | Free agent variables of a pattern.+patFAV :: Pattern -> S.Set Id+patFAV (PAVar v) = S.singleton v+patFAV (PHash pt) = patFAV pt+patFAV (PTup pt1 pt2) = patFAV pt1 `S.union` patFAV pt2+patFAV (PEnc pt1 pt2) = patFAV pt1 `S.union` patFAV pt2+patFAV (PSign pt1 pt2) = patFAV pt1 `S.union` patFAV pt2+patFAV (PSymK pt1 pt2) = patFAV pt1 `S.union` patFAV pt2+patFAV (PShrK pt1 pt2) = patFAV pt1 `S.union` patFAV pt2+patFAV (PAsymPK pt) = patFAV pt+patFAV (PAsymSK pt) = patFAV pt+patFAV _ = S.empty+++-- | Frees agent variables of a role step.+stepFAV :: RoleStep -> S.Set Id+stepFAV = patFAV . stepPat++-- | Free agent variables of a role.+roleFAV :: Role -> S.Set Id+roleFAV = S.unions . map (patFAV . stepPat) . roleSteps++-- Well-formedness of protocols and roles+-----------------------------------------++data ProtoIllformedness =+ NonUnique Role+ | SendBeforeReceive Role RoleStep Id+ | AccessibleLongTermKey Role RoleStep Pattern+ deriving( Eq, Ord, Show )++-- | Check if a role is well-formed; i.e., all steps are distinct, no+-- message variable is sent before it is received, and patterns do not+-- contain long-term-keys in accessible positions.+wfRole :: Role -> [ProtoIllformedness]+wfRole role = msum+ [ do guard (unique $ roleSteps role)+ return $ NonUnique role+ , recv_before_send S.empty (roleSteps role)+ , msum . map accessibleLongTermKeys $ roleSteps role+ ]+ where+ recv_before_send _ [] = mzero+ recv_before_send received (step@(Send _ pt) : rs) = + do v <- S.toList $ patFMV pt+ guard (v `S.member` received)+ return $ SendBeforeReceive role step v+ `mplus`+ recv_before_send received rs+ recv_before_send received (Recv _ pt : rs) = + recv_before_send (patFMV pt `S.union` received) rs++ accessibleLongTermKeys step = do+ m <- S.toList . patternparts $ stepPat step+ key <- case m of+ PSymK _ _ -> return m+ PAsymSK _ -> return m+ _ -> mzero+ return $ AccessibleLongTermKey role step key++-- | Check if a protocol is well-formed; i.e., all roles are well-formed.+wfProto :: Protocol -> [ProtoIllformedness]+wfProto = concatMap wfRole . protoRoles++-- | Pretty print a protocol ill-formedness.+sptProtoIllformedness :: ProtoIllformedness -> Doc+sptProtoIllformedness pif = case pif of+ NonUnique role -> + text $ "role '" ++ roleName role ++ "' contains duplicate steps."+ SendBeforeReceive role step v ->+ text (roleName role) <> colon <-> + sptRoleStep Nothing step <> colon <->+ text "message variable" <-> quotes (sptId v) <-> text "sent before received."+ AccessibleLongTermKey role step _ ->+ text (roleName role) <> colon <-> + sptRoleStep Nothing step <> colon <->+ text "long-term keys must not be accessible."+++-- Various orders on role steps+-------------------------------++-- | An order relation on role steps of a role.+type RoleStepOrder = [((RoleStep,Role),(RoleStep,Role))]++-- | The order of role steps as they are given in the role.+roleOrd :: Role -> RoleStepOrder+roleOrd role = zip steps (tailDef [] steps)+ where+ steps = zip (roleSteps role) (repeat role) ++-- | The order of role steps in the protocol such that every send step is+-- occurs before every receive step having the same label.+labelOrd :: Protocol -> RoleStepOrder+labelOrd proto = + [ (send, recv) | send@(Send l _, _) <- steps, + recv@(Recv l' _, _) <- steps, l == l' ]+ where+ steps = concat [ zip (roleSteps role) (repeat role) | role <- protoRoles proto ]+ +-- | The combination of all role orders and the label order of the protocol.+protoOrd :: Protocol -> RoleStepOrder+protoOrd proto = labelOrd proto ++ concatMap roleOrd (protoRoles proto)+++------------------------------------------------------------------------------+-- ISAR Output+------------------------------------------------------------------------------++-- | The name of the locale assuming a reachable state of the given protocol.+stateLocale :: Protocol -> String+stateLocale proto = protoName proto ++ "_state"++-- | The name of the locale assuming a reachable state satisfying the axioms of+-- the theory.+restrictedStateLocale :: Protocol -> String+restrictedStateLocale proto = "restricted_" ++ protoName proto ++ "_state"++-- | The name of the weak atomicity type invariant of the given protocol.+weakAtomicityInvariant :: Protocol -> String+weakAtomicityInvariant proto = "atomic_" ++ protoName proto++-- | The name of the locale assuming weak atomicity of the given protocol.+weakAtomicityLocale :: Protocol -> String+weakAtomicityLocale proto = "atomic_" ++ stateLocale proto++-- | Pretty print a rolestep in ISAR format. If a role is given, then the label+-- of the role step in this role is used to abbreviate the step name.+isaRoleStep :: IsarConf -> Maybe Role -> RoleStep -> Doc+isaRoleStep conf optRole step = + case optRole of+ Just role | step `elem` roleSteps role -> -- abbreviate+ text $ roleName role ++ "_" ++ stepLabel step+ _ ->+ text name <-> isar conf (Label $ stepLabel step) <-> ppPat (stepPat step) + where+ name = case step of Send _ _ -> "Send"; Recv _ _ -> "Recv"+ ppPat pt@(PTup _ _) = isar conf pt+ ppPat pt = nestShort' "(" ")" (isar conf pt)++instance Isar Id where+ isar _ (Id i) = text $ "''"++i++"''"++instance Isar Label where+ isar _ (Label l) = text $ "''"++l++"''"++instance Isar Pattern where+ isar conf x = case x of+ (PConst i) -> text "sC" <-> isar conf i+ (PFresh i) -> text "sN" <-> isar conf i+ (PAVar i) -> text "sAV" <-> isar conf i+ (PMVar i) -> text "sMV" <-> isar conf i+ (PHash pt) -> text "PHash" <-> ppTup pt+ pt@(PTup _ _) -> ppTup pt+ (PEnc m k) -> text "PEnc" <-> sep [ppTup m, ppTup k]+ (PSign m k) -> text "PSign" <-> sep [ppTup m, ppTup k]+ (PSymK (PAVar a) (PAVar b)) -> text "sK" <-> isar conf a <-> isar conf b+ (PSymK a b) -> text "PSymK" <-> sep [ppTup a, ppTup b]+ (PShrK a b) -> text "sKbd" <-> keyVar a <-> keyVar b+ (PAsymPK (PAVar a)) -> text "sPK" <-> isar conf a+ (PAsymPK a) -> text "PAsymPK" <-> ppTup a+ (PAsymSK (PAVar a)) -> text "sSK" <-> isar conf a+ (PAsymSK a) -> text "PAsymSK" <-> ppTup a+ where+ -- pretty print a tuple as right associate list+ ppTup pt@(PTup _ _) = nestShort n left right (fsep $ punctuate comma $ map (isar conf) $ split pt)+ ppTup pt = nestShort' "(" ")" (isar conf pt)+ -- split right associate nested tuples+ split (PTup pt1 pt2) = pt1 : split pt2+ split pt = [pt]+ -- determine output parameters+ (n,left,right)+ | isPlainStyle conf = (3, text "<|", text "|>")+ | otherwise = (2, symbol "\\<langle>", symbol "\\<rangle>") + -- extract a variable of a bi-directional key+ keyVar (PAVar v) = parens $ text "AVar" <-> isar conf v+ keyVar (PMVar v) = parens $ text "MVar" <-> isar conf v+ keyVar _ = error $ "bi-directional key '" ++ show x ++ "' not supported."+++instance Isar RoleStep where+ isar conf = isaRoleStep conf Nothing++instance Isar Role where+ isar conf (Role name steps) = + text "role" <-> text name $-$+ text "where" <-> text "\"" <> text name <-> text "=" $-$+ nest 2 (+ (vcat $ zipWith (<->) separators (map (isar conf) steps)) $-$+ text "]\""+ )+ where+ separators = map text ("[" : replicate (length steps - 1) ",")++instance Isar Protocol where+ isar conf (Protocol name roles) =+ vcat (map (($-$ text "") . isar conf) roles) $-$+ text "protocol" <-> text name $-$+ sep [text "where" <-> text "\"" <> text name <-> text "=", roleSet]+ where+ roleSet = nestShort' "{" "}\"" + (fsep $ punctuate comma $ map (text . roleName) roles)+++------------------------------------------------------------------------------+-- SP Theory Output+------------------------------------------------------------------------------++sptId :: Id -> Doc+sptId = text . getId++sptLabel :: Label -> Doc+sptLabel = text . getLabel++sptPattern :: Pattern -> Doc+sptPattern x = case x of+ (PConst i) -> char '\'' <> sptId i <> char '\''+ (PFresh i) -> char '~' <> sptId i+ (PAVar i) -> sptId i+ (PMVar i) -> char '?' <> sptId i+ (PHash m) -> text "h" <> ppBetween 3 "(" ")" m+ pt@(PTup _ _) -> ppBetween 1 "(" ")" pt+ (PEnc m k) -> fcat [ppBetween 1 "{" "}" m, sptPattern k]+ (PSign m k) -> fcat [ppBetween 1 "sign{" "}" m, sptPattern k]+ (PSymK a b) -> fcat [text "k(", sptPattern a, comma, sptPattern b, text ")"]+ (PShrK a b) -> fcat [text "k[", sptPattern a, comma, sptPattern b, text "]"]+ (PAsymPK a) -> text "pk" <> ppBetween 1 "(" ")" a+ (PAsymSK a) -> text "sk" <> ppBetween 1 "(" ")" a+ where+ -- pretty print a tuple as right associate list+ ppBetween n lead finish pt@(PTup _ _) = + fcat . (text lead :) . (++[text finish]) . map (nest n) . punctuate (text ", ") . map sptPattern $ split pt+ ppBetween _ lead finish pt = text lead <> sptPattern pt <> text finish+ -- split right associate nested tuples+ split (PTup pt1 pt2) = pt1 : split pt2+ split pt = [pt]++-- | Pretty print a rolestep. If a role is given, then the label of the role+-- step in this role is used to abbreviate the step name.+sptRoleStep :: Maybe Role -> RoleStep -> Doc+sptRoleStep optRole step = + case optRole of+ Just role | step `elem` roleSteps role -> -- abbreviate+ text $ roleName role ++ "_" ++ stepLabel step+ _ ->+ (text $ name ++ "_" ++ stepLabel step) <> ppPat (stepPat step) + where+ name = case step of Send _ _ -> "Send"; Recv _ _ -> "Recv"+ ppPat pt@(PTup _ _) = sptPattern pt+ ppPat pt = nestShort' "(" ")" (sptPattern pt)++-- | Pretty print a role in SP theory format.+sptRole :: Role -> Doc+sptRole(Role name steps) = + text "role" <-> text name $-$+ nestBetween 2 lbrace rbrace (+ (vcat $ map (sptRoleStep Nothing) steps)+ )++-- | Pretty print a protocol in SP theory format.+sptProtocol :: Protocol -> Doc+sptProtocol (Protocol name roles) =+ text "protocol" <-> text name $-$+ nestBetween 2 lbrace rbrace (+ vcat (intersperse (text "") $ map sptRole roles)+ )+
@@ -0,0 +1,219 @@+{-# LANGUAGE DeriveDataTypeable #-}+module Scyther.Sequent (++ -- * Datatype+ Sequent(..)+ , seProto++ -- ** Logically safe construction+ , wellTypedCases+ , saturate+ , frule+ , fruleInst+ , chainRule+ , splitEq+ , exploitTyping+ , uniqueTIDQuantifiers+) where++import Data.Maybe+import qualified Data.Map as M+import qualified Data.Set as S+import Data.Data++import Control.Arrow+import Control.Monad++import qualified Scyther.Equalities as E+import Scyther.Facts+import Scyther.Formula+++------------------------------------------------------------------------------+-- Sequents+------------------------------------------------------------------------------++-- | A sequent with a conjunction of a set of facts as the premise and a single+-- formula as the conclusion denoting a statement about a reachable state of+-- a protocol.+data Sequent = Sequent {+ sePrem :: Facts+ , seConcl :: Formula+ }+ deriving( Eq, Show, Ord, Data, Typeable )++-- | The protocol of a sequent.+seProto :: Sequent -> Protocol+seProto = protocol . sePrem+++-- Construction+---------------++-- | Make all thread identifiers occurring in the sequent unique by+-- consistently relabeling the thread identifiers in the conclusion.+uniqueTIDQuantifiers :: Sequent -> Sequent+uniqueTIDQuantifiers (Sequent prem concl) = + Sequent prem (relabelTIDs [nextTID prem..] concl)++-- | Apply a function to the premise, but return only the updated sequent if+-- the premise was changed.+changePrem :: MonadPlus m => (Facts -> m Facts) -> Sequent -> m Sequent+changePrem f se = do+ let prem0 = sePrem se+ prem1 <- f prem0+ guard (prem0 /= prem1)+ return $ se { sePrem = prem1 }+++-- | The named list of sequents which need to be proven in order to prove that+-- the given protocol is well typed or weakly-atomic+--+-- PRE: The conclusion of the sequent must be typing atom.+--+-- Uses 'fail' for error reporting.+wellTypedCases :: MonadPlus m => Sequent -> m [(String, Sequent)]+wellTypedCases se = case seConcl se of+ FAtom (ATyping someTyp) -> + return $ protoRoles (seProto se) >>= roleProofs someTyp+ _ -> mzero+ where+ roleProofs someTyp role = proveRecvs S.empty (roleSteps role)+ where+ proveRecvs _ [] = []+ proveRecvs recv ( Send _ _ : steps) = proveRecvs recv steps+ proveRecvs recv ((Recv _ (PMVar lid)) : steps) = + -- don't prove single reiceves as they are handled directly by the tactic+ -- on the Isabelle side.+ proveRecvs (S.insert lid recv) steps+ proveRecvs recv (step@(Recv _ pt) : steps) = + let mvars = patFMV pt+ in (S.toList mvars >>= proveVar) `mplus` + (proveRecvs (recv `S.union` mvars) steps)+ where+ proveVar v+ | v `S.member` recv = fail "proveVar: not first receive"+ | otherwise = do+ return (name, Sequent prem concl)+ where+ name = roleName role ++ "_" ++ stepLabel step ++ "_" ++ getId v+ (tid, prem0) = freshTID (sePrem se)+ mv = MVar (LocalId (v, tid))+ premErr = error $ "wellTypedCases: could not add thread " ++ show tid ++ ". This should not happen."+ prem1 = maybe premErr saturateFacts . join $ + conjoinAtoms [AEv (Step tid step), AEq (E.TIDRoleEq (tid, role))] prem0+ prem = fromMaybe (error "failed to set typing") $ setTyping someTyp prem1+ concl = FAtom $ + case someTyp of+ WeaklyAtomic -> AHasType mv Nothing+ Typing typ -> case M.lookup (v, role) typ of+ Just ty -> AHasType mv (Just ty)+ Nothing -> error $ + "wellTypedCases: no type given for '"++show v++"' in role '"++roleName role++"'"+++-- | Emulate a variant Isabelle's 'frule' tactic. It works only if the given+-- maping of free variables of the rule makes the premise of the rule provable+-- under the given proof state. Then, the conclusion of the rule with free+-- variables mapped accordingly is added to premises of the proof state. The+-- last step works currently only for conclusions being false of pure+-- conclusions.+--+-- NOTE that 'frule' works only for rules that contain no existential+-- quantifiers in the conclusion.+fruleInst :: MonadPlus m+ => Sequent -- ^ rule + -> E.Mapping -- ^ mapping of free variables of rule to proof state+ -> Sequent -- ^ proof state+ -> m (Maybe Sequent) -- ^ some result if resolution worked. Nothing+ -- denotes that False was derived. Just means that+ -- premises of proof state were extended.+ --+ -- mzero if rule could not be applied+fruleInst rule mapping state = do+ atoms <- conjunctionToAtoms $ seConcl rule+ let statePrem = sePrem state+ guard (proveFacts statePrem (sePrem rule) mapping)+ optStatePrem' <- conjoinAtoms (map (substAtom (E.getMappingEqs mapping)) atoms) statePrem+ case optStatePrem' of+ Nothing -> do return Nothing+ Just statePrem' -> do guard (statePrem /= statePrem')+ return . Just $ Sequent statePrem' (seConcl state)++-- | Like 'fruleInst' but tries all mappings.+frule :: MonadPlus m+ => Sequent -- ^ rule + -> Sequent -- ^ proof state+ -> m (E.Mapping, Maybe Sequent) + -- ^ some result if resolution worked. Nothing denotes that False was+ -- derived. Just means that premises of proof state were extended.+ --+ -- mzero if rule could not be applied+frule rule state = case resolutions of+ [] -> mzero+ res : _ -> return res+ where+ resolutions = do+ mapping <- freeVariableMappings (sePrem rule) (sePrem state)+ ((,) mapping) `liftM` fruleInst rule mapping state+++{-+-- | Emulate Isabelle's 'frule' tactic; i.e. the first sequent is the rule that+-- is used for resolution.+--+-- NOTE that 'frule' works only for rules that contain no existential+-- quantifiers in the conclusion.+frule :: Sequent -- ^ Rule to use for resolution.+ -> Sequent -- ^ Proof state that this rule is resolved against.+ -> [(Mapping, Maybe Sequent)]+ -- ^ The mapping and no resulting proof state+ -- if the resolution solved this subgoal;+ -- otherwise the new subgoal provided it is+ -- differnt from the old one.+frule rule state = do+ atoms <- conjunctionToAtoms $ seConcl rule+ let prem0 = sePrem state+ mapping <- resolve (sePrem rule) prem0+ optPrem1 <- conjoinAtoms (map (substAtom (getMappingEqs mapping)) atoms) prem0+ case optPrem1 of+ Nothing -> do return (mapping, Nothing)+ Just prem1 -> do guard (prem1 /= prem0)+ return (mapping, Just $ Sequent prem1 (seConcl state))+-}++-- | Try to saturate a sequent, if possible and leading to new facts.+saturate :: MonadPlus m => Sequent -> m Sequent+saturate = changePrem (return . saturateFacts)++-- | Try to use the chain rule. +--+-- MonadPlus is used to report a failure to apply the rule.+--+chainRule :: MonadPlus m + => Sequent -> Message + -> m [((String, [Either TID AgentId]), Sequent)]+chainRule se m = + map (second mkSequent) `liftM` chainRuleFacts m (sePrem se)+ where + mkSequent prem = Sequent prem (seConcl se)++-- | Try to exploit the typing. Fails if no new facts could be derived.+exploitTyping :: MonadPlus m => Sequent -> m Sequent+exploitTyping = changePrem exploitTypingFacts++-- | Split a splittable equality.+-- splitting can be done.+splitEq :: E.MsgEq -> Sequent -> [Maybe Sequent]+splitEq eq se + | eq `elem` splittableEqs prems = map (fmap updPrem) $ splitEqFacts eq prems+ | otherwise = error $ "splitEq: equality not present"+ where+ prems = sePrem se+ updPrem prem' = se {sePrem = prem'}++ ++++
@@ -0,0 +1,373 @@+{-# LANGUAGE DeriveDataTypeable #-}+module Scyther.Theory (++ -- * Theorems+ Theorem+ , thmProto+ , thmName+ , thmSequent+ , thmProof+ , isAxiom++ -- * Theory items+ , ThyItem(..)++ -- * Theory Datatypes+ , Theory(..)++ -- ** Construction+ , adaptTheoryName+ , insertItem+ , shrinkTheory+ , proveSequents+ , mapTheorySequents+ , addMissingTypingInvariants+ , ensureUniqueRoleNames+ , composeParallel++ -- ** Queries+ , lookupProtocol+ , unsoundTheorems+ , theoryProofSize+ , theoryOverview+ , classifyProperties+ -- , wfTheory++) where++import Safe+import Data.Either (partitionEithers)+import Data.Monoid+import Data.List (isPrefixOf)+import qualified Data.Set as S+import qualified Data.Map as M+import Data.DAG.Simple+import Data.Data+import Data.Generics.Uniplate.Data++import Control.Monad+import Control.Monad.State++import System.FilePath++import Extension.Prelude++import Scyther.Facts+import Scyther.Sequent+import Scyther.Proof++------------------------------------------------------------------------------+-- Theorems+------------------------------------------------------------------------------++-- | A theorem is just a named proof.+type Theorem = Named Proof++-- | The name of a theorem.+thmName :: Theorem -> String+thmName = fst++-- | The proof of a theorem.+thmProof :: Theorem -> Proof+thmProof = snd++-- | The sequent of a theorem.+thmSequent :: Theorem -> Sequent+thmSequent = prfSequent . thmProof++-- | The protocol of a theorem.+thmProto :: Theorem -> Protocol+thmProto = prfProto . thmProof++-- | Check if a theorem is an axiom.+isAxiom :: Theorem -> Bool+isAxiom = isAxiomProof . snd+++------------------------------------------------------------------------------+-- Theory Items+------------------------------------------------------------------------------+++-- | A theory item is a (meta-)logical fact representable by our security+-- protocol theory.+data ThyItem =+ ThyProtocol Protocol+ | ThySequent (Named Sequent)+ | ThyTheorem (Named Proof)+ | ThyText String+ deriving( Eq, Show, Data, Typeable {-! NFData !-} )+++------------------------------------------------------------------------------+-- Theories+------------------------------------------------------------------------------++data Theory = Theory {+ thyName :: String+ , thyItems :: [ThyItem]+ }+ deriving( Eq, Show, Data, Typeable {-! NFData !-} )+++-- Construction+---------------++-- | Map the items of a theory.+mapTheoryItems :: ([ThyItem] -> [ThyItem]) -> Theory -> Theory+mapTheoryItems f (Theory name items) = Theory name (f items)++-- | Map the sequents of a theory.+mapTheorySequents :: (Sequent -> Sequent) -> Theory -> Theory+mapTheorySequents f = mapTheoryItems (map mapThyItemSequents)+ where+ mapThyItemSequents item = case item of+ ThySequent (name, se) -> ThySequent (name, f se)+ ThyTheorem (name, prf) -> ThyTheorem (name, mapProofSequents f prf)+ ThyProtocol _ -> item+ ThyText _ -> item++-- | Insert a theory item into a theory.+insertItem :: ThyItem -> Theory -> Theory+insertItem item thy = thy { thyItems = thyItems thy ++ [item] }++-- | Most proofs require a typing invariant to be present for the protocol+-- under investigation. We try to derive one from the protcol specification+-- for every protocol that has none.+addMissingTypingInvariants :: Theory -> Theory+addMissingTypingInvariants thy =+ Theory (thyName thy) (concatMap add $ thyItems thy)+ where+ mkTypingSequent p = case mscTyping p of+ Just typ -> return $ ThySequent ( protoName p ++ "_msc_typing"+ , Sequent (empty p) (FAtom (ATyping typ)))+ Nothing -> mzero++ add item = case item of+ ThyProtocol p + | noTypingInvariant p -> [item] ++ mkTypingSequent p+ _ -> [item]++ noTypingInvariant p = and $ do+ item <- thyItems thy+ se <- case item of+ ThySequent (_, se) -> return se+ ThyTheorem (_, prf) -> return (prfSequent prf)+ _ -> mzero+ guard (isTypingFormula $ seConcl se)+ return (p /= seProto se)++-- | Prove all claims with the given heuristic optionally using the given+-- bound.+proveSequents :: (Sequent -> Theorem -> Bool) + -- ^ Predicate determining theorems for reuse for proving the+ -- given sequent.+ -> ([Named Sequent] -> Sequent -> Maybe Proof) + -- ^ Proof construction function.+ -> Theory -> Theory+proveSequents reuse prover thy =+ Theory (thyName thy) (flip execState [] . mapM_ prove $ thyItems thy)+ where+ prove (item@(ThySequent (name, se))) = do+ prevItems <- get+ let reusableThms = [ (thmName th, thmSequent th) + | ThyTheorem th <- prevItems, reuse se th, thmProto th == seProto se]++ case prover reusableThms se of+ Just prf -> modify (++[ThyTheorem (name, prf)])+ Nothing -> modify (++[item])++ prove item = modify (++[item])++-- | Only keep theorems for which the given predicate is true or which are+-- referenced by some kept theorem.+shrinkTheory :: (String -> Bool) -> Theory -> Theory+shrinkTheory mustKeep (Theory name items) =+ Theory name (filter keep items)+ where+ thmInfo thm = (thmName thm, thmProto thm)+ kept = [ thmInfo thm | ThyTheorem thm <- items, mustKeep $ thmName thm ]+ dependencies =+ [ (thmInfo thm, dep) + | ThyTheorem thm <- items, dep <- S.toList . depends $ thmProof thm ]+ toKeep = reachableSet kept dependencies+ keep :: ThyItem -> Bool+ keep (ThyTheorem thm) = (thmInfo thm `S.member` toKeep)+ keep (ThySequent se) = mustKeep $ fst se+ keep _ = True++-- | Adapt the theory name to the base name of the given file.+adaptTheoryName :: FilePath -> Theory -> Theory+adaptTheoryName file thy = thy { thyName = takeBaseName file }++-- | Ensures that all roles are globally uniquely named by prefixing all role+-- names with their corresponding protocol name, if two roles have equal names.+ensureUniqueRoleNames :: Theory -> Theory+ensureUniqueRoleNames thy+ | unique rs = thy+ | otherwise = mapTheoryItems (map addPrefix) thy+ where+ rs = [roleName r | ThyProtocol p <- thyItems thy, r <- protoRoles p]++ prefixRoleName p r = r {roleName = protoName p ++ "_" ++ roleName r}++ getProtocol (ThyProtocol p) = return p+ getProtocol (ThySequent s) = return (seProto $ snd s)+ getProtocol (ThyTheorem p) = return (thmProto p)+ getProtocol (ThyText _) = mzero++ addPrefix item = case getProtocol item of+ Just p -> transformBi (prefixRoleName p) item+ Nothing -> item++-- | Compose all protocol in the theory in parallel. Assumes that both protocol+-- names as well as role names are /globally/ unique.+composeParallel :: Theory -> Theory+composeParallel thy + | length ps <= 1 = thy+ | otherwise = thy { thyItems = [ThyProtocol pc, ThySequent sec] ++ items3 }+ where+ (ps, items1) = partitionEithers $ do+ item <- thyItems thy+ case item of + ThyProtocol p -> return $ Left p+ _ -> return $ Right item++ (typs, items2) = partitionEithers $ do+ item <- items1 + case item of+ ThySequent (_, Sequent _ (FAtom (ATyping (Typing typ))))+ -> return $ Left typ+ ThySequent x -> return $ Right $ ThySequent $ prefixProtoName (seProto $ snd x) x+ ThyTheorem x -> return $ Right $ ThyTheorem $ prefixProtoName (thmProto x) x+ _ -> return $ Right item+++ prefixProtoName :: Protocol -> (String, a) -> (String, a)+ prefixProtoName p x@(n, v)+ | protoName p `isPrefixOf` n = x+ | otherwise = (protoName p ++ "_" ++ n, v)+ + namec = thyName thy+ pc = Protocol namec (concatMap protoRoles ps)+ sec = ( namec ++ "_composed_typing"+ , Sequent (empty pc) (FAtom (ATyping (Typing (M.unions typs))))+ )++ replaceProtocol :: Protocol -> Protocol+ replaceProtocol = const pc++ items3 = transformBi replaceProtocol items2+++-- Queries+----------++-- | Find a protocol in the theory according to its name.+lookupProtocol :: String -> Theory -> Maybe Protocol+lookupProtocol name thy = + headMay [proto | ThyProtocol proto <- thyItems thy, protoName proto == name]++-- | Find all unsound theorems of the theory.+unsoundTheorems :: Theory -> [(Protocol, String)]+unsoundTheorems (Theory _ items) = + [ (prfProto prf, name) + | ThyTheorem (name, prf) <- items, not (sound prf) + ] +++ [ (seProto se, name) + | ThySequent (name, se) <- items+ ]++-- | Total proof size.+theoryProofSize :: Theory -> ProofSize+theoryProofSize (Theory _ items) = mconcat $+ [ proofSize (thmProof th) | ThyTheorem th <- items ] +++ [ missingProofSize | ThySequent _ <- items ]++-- | Count and classify the properties selected by the given predicate into+-- secrecy properties, authentication properties, and other properties.+classifyProperties :: (String -> Bool) -> Theory -> (Int, Int, Int)+classifyProperties toClassify = foldl classify (0,0,0) . thyItems+ where+ getSequent (ThyTheorem thm) = do+ guard (toClassify $ thmName thm) + return $ thmSequent thm+ getSequent (ThySequent se) = do+ guard (toClassify (fst se))+ return (snd se)+ getSequent _ = mzero++ classify counts@(nSec, nAuth, nOther) item = case getSequent item of+ Just se | isContradictionProp se -> (succ nSec, nAuth, nOther)+ Just se | isExistsStructureProp se -> ( nSec, succ nAuth, nOther)+ Just _ -> ( nSec, nAuth, succ nOther)+ Nothing -> counts++ -- | True, if the sequent implies 'FFalse'.+ isContradictionProp :: Sequent -> Bool+ isContradictionProp = (FAtom AFalse ==) . seConcl++ -- | True, if the sequents conclusion contains an existentially quantified+ -- thread.+ isExistsStructureProp :: Sequent -> Bool+ isExistsStructureProp = hasQuantifiers . seConcl++-------------------------------------------------------------------------------+-- Overview generation+-------------------------------------------------------------------------------++theoryOverview :: Theory -> Theory+theoryOverview = error "theoryOverview: upgrade to new infrastructure"++{-+lookupTypeInvariants :: Protocol -> Theory -> [(ThyItem, Maybe Typing)]+lookupTypeInvariants proto thy = do+ item <- thyItems thy+ se <- case item of+ ThySequent _ se -> return se+ ThyTheorem th -> return $ thmSequent th+ _ -> mzero+ guard (seProto se == proto)+ case seConcl se of+ FTyping typ -> return (item, typ)+ _ -> mzero++-- | The overview of a theory lists for each protocol its associated typings+-- together with the corresponding chain rule. If no typing is given, then it+-- tries to infer it from the message sequence chart.+theoryOverview :: Theory -> Theory+theoryOverview thy@(Theory name items) = + Theory name $ concat [ protoOverview proto | ThyProtocol proto <- items]+ where+ protoOverview proto = + (ThyText $ "Overview of protocol '"++protoName proto++"'") : + ThyProtocol proto : typInvs+ where+ typInvs = case lookupTypeInvariants proto thy of+ [] -> case mscTyping proto of+ Just typing -> addChainRule+ ( ThySequent "auto_msc_typing" $+ Sequent proto (FFacts emptyFacts) (FTyping (Just typing))+ , Just typing )+ Nothing -> return $+ ThyText "failed to infer typing from protocol specification\n\+ \(maybe some message patterns are not unifiable)"+ xs -> concatMap addChainRule xs++ addChainRule (item, typ) = + [ item+ , ThyText $ unlines+ [ "Note that the chain rule below is only an informal representation of the"+ , "actual chain rule, which you can find in the Isabelle theories. In particular,"+ , "it is missing the cases for the initial intruder knowledge and uses a dummy"+ , "conclusion 'False'." ]+ , ThyTheorem $ Theorem ("chain_rule_OF_" ++ name) (displayChainRule proto typ)+ ]+ where+ name = case item of+ ThySequent n _ -> n+ ThyTheorem th -> thmName th+ _ -> error $ "theoryOverview: expected sequent or theorem item"+++-}
@@ -0,0 +1,437 @@+-- | .dot file generation for elements of a security protocol theory.+module Scyther.Theory.Dot (+ dotSequentMarked+ , dotProtocol+ , graphvizDotToPng+) where++import Safe+import Data.Maybe+import Data.List (find)+import qualified Data.Set as S+import qualified Data.Map as M+import Data.Color++import Control.Basics+import Control.Monad.State+import Control.Monad.Reader+import Control.Concurrent.Chan++import Text.Dot as Dot+import Text.Isar hiding (hcat)++import System.Process (waitForProcess, runCommand)++import qualified Scyther.Equalities as E+import Scyther.Facts+import Scyther.Sequent++-----------------------------------------------------------------------------+-- Utility Functions+-----------------------------------------------------------------------------++-- | Find a value in a map and display an error if it cannot be found.+findWithError :: Ord k => String -> k -> M.Map k v -> v+findWithError msg k = fromMaybe (error msg) . M.lookup k++-- | Find a value and display the key in case it cannot be found.+findShowError :: (Ord k, Show k) => k -> M.Map k v -> v+findShowError k = + findWithError ("findShowError: key '"++show k++"' not in map.") k++-- | The style of an edge between two nodes of the same thread.+threadEdgeStyle :: [(String, String)]+threadEdgeStyle = [("style","bold"),("weight","10.0")]++-- | Set default attributes for nodes and edges.+setDefaultAttributes :: Dot ()+setDefaultAttributes = do+ attribute ("nodesep","0.3")+ attribute ("ranksep","0.3")+ nodeAttributes [("fontsize","10"),("fontname","Helvetica"),("width","0.3"),("height","0.2")]+ edgeAttributes [("fontsize","10"),("fontname","Helvetica")]++-- | Find the color; default to the color for Nothing, if no color can be+-- found.+getColorWithDefault :: TID -> M.Map (Maybe TID) v -> v+getColorWithDefault tid m = M.findWithDefault (m M.! Nothing) (Just tid) m++-----------------------------------------------------------------------------+-- DOT Graph Generation+-----------------------------------------------------------------------------++-- Grouping different thread identifiers according to their role+----------------------------------------------------------------++type TIDMap = M.Map TID (Maybe Role)++extractTIDMap :: Sequent -> TIDMap+extractTIDMap se = formulaMap (seConcl se) (M.fromList fromPrem)+ where+ prem = sePrem se+ fromPrem = [ (tid, threadRole tid prem) | tid <- quantifiedTIDs prem ]++ formulaMap :: Formula -> TIDMap -> TIDMap+ formulaMap formula = case formula of+ (FExists (Left tid) prop) -> formulaMap prop . M.insert tid Nothing+ (FExists (Right _ ) prop) -> formulaMap prop+ (FConj lprop rprop) -> formulaMap lprop . formulaMap rprop+ (FAtom (AEq (E.TIDRoleEq (tid, role)))) -> M.insert tid (Just role)+ _ -> id+++-- Color map+------------++type ColorMap = M.Map (Maybe TID) String++-- | A map from thread identifiers to strings identifying their color.+-- type ColorMap = M.Map SequentTID String++-- | A reserved thread identifier for the intruder+intruderTID :: TID+intruderTID = -1++-- | The hue of the intruder events+intruderHue :: Double+intruderHue = 18 / 360++-- | Generate a color map mapping every thread to it's specific color. The+-- intruder gets one color accessible under the thread identifier @intrSID@+threadColors :: Sequent -> ColorMap+threadColors se = M.fromList $ assocs+ where+ optRoles = (1, Nothing) : (zip [2..] . map Just . protoRoles $ seProto se)++ roleeqs = M.toList $ extractTIDMap se+ threadsOfRole optRole = [ tid | (tid, optRole') <- roleeqs, optRole == optRole' ]++ tidGroupEqs :: [[(TID, (Int, Int))]]+ tidGroupEqs = + [(intruderTID, (0,0))] : + [ [ (tid, (roleIdx, tidIdx)) + | (tidIdx, tid) <- zip [0..] $ threadsOfRole optRole ]+ | (roleIdx, optRole) <- optRoles ]++ getColor idx = + maybe (error $ "color of " ++ show idx ++ " not found") snd $+ find ((idx ==) . fst) $ colors++ colors = colorGroups intruderHue (map length tidGroupEqs)++ assocs = (Nothing, "#eeeeee") :+ [ (Just tid, hsvToHex $ getColor idx) | (tid, idx) <- concat tidGroupEqs ]+++-- Custom Monad for transporting the relevant information+---------------------------------------------------------++type NodeMap = M.Map Event NodeId++data DotEnv = DotEnv {+ colorMap :: ColorMap -- ^ Assigns colors to threads+ , threadMapping :: E.Mapping -- ^ Assigns threads to roles+ , marked :: S.Set Event -- ^ Events to be marked+ }++data DotState = DotState {+ nodeMap :: M.Map Event NodeId+ -- ^ Mapping events to Dot node-ids.+ , threadAtoms :: M.Map (Maybe TID) [Atom]+ -- ^ Gather the atoms that do not have their own graphical representation+ -- according to the thread they belong to.+ }++-- | Modify the node map of a state.+mapNodeMap :: (NodeMap -> NodeMap) -> DotState -> DotState+mapNodeMap f s = s { nodeMap = f (nodeMap s) }++-- | A custom dot monad.+type MyDot = ReaderT DotEnv (StateT DotState Dot)++runMyDot :: ColorMap -> E.Mapping -> S.Set Event -> MyDot a -> Dot a+runMyDot cm tm ma m = evalStateT (runReaderT m env0) s0+ where+ env0 = DotEnv { colorMap = cm, threadMapping = tm, marked = ma }+ s0 = DotState { nodeMap = M.empty, threadAtoms = M.empty }++-- | Lift a nullary operation to our custom dot monad.+liftDot :: Dot a -> MyDot a+liftDot = lift . lift++-- | Lift a unary operation to our custom dot monad.+liftDot1 :: (Dot (a, DotState) -> Dot (b, DotState)) -> (MyDot a -> MyDot b)+liftDot1 f m = ReaderT $ \env -> StateT $ \s -> + f (runStateT (runReaderT m env) s)++-- | A lifted version of the @cluster@ method for constructing a graph cluster.+myCluster :: MyDot a -> MyDot (NodeId, a)+myCluster = liftDot1 (liftM adapt . cluster)+ where adapt (nid, (x, s)) = ((nid, x), s)++-- | Ensure that the given event is dotted and return its node id.+dotEvent :: Event -> MyDot NodeId+dotEvent ev = do+ optId <- gets $ M.lookup ev . nodeMap+ case optId of+ Just nid -> return nid+ Nothing -> do+ mapping <- asks threadMapping+ mark <- asks $ S.member ev . marked+ let peripheries | mark = "2"+ | otherwise = "1"+ label = render $ sptRawEvent mapping ev+ shape = case ev of+ Learn _ -> "ellipse"+ Step _ _ -> "box"+ color <- case ev of+ Learn _ -> asks $ getColorWithDefault intruderTID . colorMap+ Step tid _ -> asks $ getColorWithDefault tid . colorMap+ nid <- liftDot $ node + [ ("label", label)+ , ("shape", shape)+ , ("style", "filled")+ , ("fillcolor", color)+ , ("peripheries", peripheries)+ ]+ modify . mapNodeMap $ M.insert ev nid+ return nid++-- | Produce the Dot code and the updated dot state for a single atom.+dotAtom :: Atom -> MyDot ()+dotAtom (AEv ev) = dotEvent ev >> return ()+dotAtom (AEvOrd evord@(from, to)) = do+ fromId <- dotEvent from+ toId <- dotEvent to+ liftDot $ edge fromId toId edgestyle+ where+ edgestyle = case evord of+ (Step tid1 _, Step tid2 _) | tid1 == tid2 -> threadEdgeStyle+ _ -> []+dotAtom atom = addThreadAtom atom++-- | Reset the thread atoms to the given default thread/role information.+resetThreadAtoms :: [(Maybe TID, Maybe Role)] -> MyDot ()+resetThreadAtoms info = do+ s <- get+ put $ s { threadAtoms = M.fromList $ mapMaybe prepare info }+ where+ prepare (optTid, optRole) = do + role <- optRole+ tid <- optTid+ return (optTid, [AEq (E.TIDRoleEq (tid, role))])++-- | Add to given atom to its associated thread.+addThreadAtom :: Atom -> MyDot ()+addThreadAtom atom = do+ s <- get+ let ins = M.insertWith (++) (headMay $ atomTIDs atom) [atom]+ put $ s { threadAtoms = ins $ threadAtoms s }++-- | Produce the graphical information describing the atoms that have been+-- added to some thread using @addThreadAtom@.+dotThreads :: Bool -- ^ True iff the threads are quantified here.+ -> MyDot ()+dotThreads quantified = do+ threadInfo <- gets $ M.toList . threadAtoms+ mapM_ (uncurry (dotThread quantified)) threadInfo+ +-- | Produce the dot code to for a single thread described by the list of+-- atoms.+dotThread :: Bool -- ^ True iff the thread is quantified+ -> Maybe TID -> [Atom] -> MyDot ()+dotThread quantified optTid atoms = do+ mapping <- asks $ threadMapping+ let -- combine the thread info+ infoContent = filter (not.null)+ [ threadinfo+ , ppLidList "compromised: " compr+ , ppLidList "uncompromised: " uncompr+ , ppAtomList avareqs+ , ppAtomList other+ ]+ optRole = headMay [ role | AEq (E.TIDRoleEq (_, role)) <- atoms ]+ `mplus` (do tid <- optTid+ E.threadRole tid (E.getMappingEqs mapping))+ quantifier | quantified = "some"+ | otherwise = "thread"+ threadinfo = case (fmap show optTid, fmap roleName optRole) of+ (Nothing, Nothing) -> ""+ (Nothing, Just role) -> "running " ++ role+ (Just tid, Nothing) -> quantifier ++ " " ++ tid+ (Just tid, Just role) -> quantifier ++ " " ++ tid ++ " running " ++ role++ compr = [ a | ACompr a <- atoms ]+ uncompr = [ a | AUncompr a <- atoms ]+ avareqs = [ atom | atom@(AEq (E.AVarEq _)) <- atoms ]+ other = do+ atom <- atoms+ guard $ case atom of+ AEq eq -> case eq of+ E.TIDRoleEq _ -> False+ E.RoleEq _ -> False+ E.TIDEq _ -> False+ E.AVarEq _ -> False+ _ -> True+ AEv _ -> False+ AEvOrd _ -> False+ ACompr _ -> False+ AUncompr _ -> False+ _ -> True+ return atom++ ppAtomList [] = mzero+ ppAtomList as = unlines $ map (render . sptAtom mapping) as++ ppLidList _ [] = mzero+ ppLidList prefix lids =+ render . (text prefix <->) . fsep . punctuate comma $ map sptMessage lids+ unless (null infoContent) $ do+ color <- asks $ maybe (M.! Nothing) getColorWithDefault optTid . colorMap+ -- create the record node+ info <- liftDot $ record_+ (Dot.vcat' infoContent)+ [ ("style", "filled")+ , ("fillcolor", color )+ ]+ -- add an edge between the thread info node and the first node of+ -- this role that is present in the graph+ evMap <- gets nodeMap+ fromMaybe (return ()) $ do+ tid <- optTid+ role <- optRole+ let findStep step = M.lookup (Step tid step) evMap+ stepId <- msum . map findStep $ roleSteps role+ return $ liftDot $ edge info stepId threadEdgeStyle+++-- | Produce the dot code of the facts.+dotFacts :: Facts -> MyDot ()+dotFacts facts = do+ resetThreadAtoms $ + map (\tid -> (Just tid, threadRole tid facts)) (quantifiedTIDs facts) + mapM_ dotAtom $ toAtoms facts+ dotThreads True++-- | Hide all information belonging to the given thread id during the execution+-- of the local action.+localThreadInfo :: TID -> Maybe Role -> MyDot a -> MyDot a+localThreadInfo tid optRole m = do+ s <- get+ -- execute local action with the new role assignment noted+ x <- local (tryNoteRole tid optRole) $ m+ -- restore thread atoms+ let optTid = Just tid+ restoreAtoms = maybe (M.delete optTid) (M.insert optTid) + (M.lookup optTid (threadAtoms s))+ modify $ \s' -> s' { threadAtoms = restoreAtoms $ threadAtoms s' }+ -- return the result+ return x++-- | Modify the thread to role assignment.+tryNoteRole :: TID -> Maybe Role -> DotEnv -> DotEnv+tryNoteRole _ Nothing env = env+tryNoteRole tid (Just role) env = + env { threadMapping = E.addTIDRoleMapping tid role (threadMapping env) }++-- | Produce the dot code of the formula.+dotFormula :: Formula -> MyDot ()+dotFormula (FAtom atom) = dotAtom atom+dotFormula (FConj f1 f2) = dotFormula f1 >> dotFormula f2+dotFormula (FExists (Left tid) inner) = do+ localThreadInfo tid (findRole tid inner) $ do+ dotFormula inner+ optAtoms <- gets $ M.lookup (Just tid) . threadAtoms + maybe (return ()) (dotThread True (Just tid)) optAtoms +dotFormula (FExists (Right aid) inner) = do+ _ <- liftDot $ node [("label", "some agent " ++ show aid)]+ dotFormula inner++-- | Produce the dot code for a formula that is a conclusion of a sequent. This+-- takes care of handling the quantifiers stemming from the premises.+dotConclusion :: Formula -> MyDot ()+dotConclusion formula = do+ resetThreadAtoms []+ dotFormula formula+ dotThreads False++-- | Dot a sequent with two separate clusters for premise and conclusion.+dotSequent :: Sequent -> MyDot ()+dotSequent se = do+ s <- get+ liftDot setDefaultAttributes+ _ <- myCluster $ do+ liftDot $ attribute ("label","premise")+ dotFacts $ sePrem se+ -- restore state before premise dotting because premise and conclusion should+ -- not share nodes+ put s + _ <- myCluster $ do+ liftDot $ attribute ("label","conclusion")+ dotConclusion $ seConcl se+ return ()++-- | Dot a sequent with some marked events.+dotSequentMarked :: S.Set Event -> Sequent -> Dot ()+dotSequentMarked markedEvs se = + runMyDot (threadColors se) (eqsToMapping $ sePrem se) markedEvs $ dotSequent se++-- | Convert a protocol to a dot graph.+dotProtocol :: Protocol -> Dot ()+dotProtocol proto = do+ return ()+ setDefaultAttributes+ ids <- mapM dotStep steps+ let stepMap = M.fromList $ zip steps ids+ mapM_ (dotSend stepMap) steps+ mapM_ (dotRole stepMap) roles+ where+ roles = protoRoles proto+ steps = concatMap extractSteps roles+ extractSteps role = zip (repeat $ roleName role) (roleSteps role)++ rMap = M.fromList $ zip (map roleName roles) [2..]+ cMap = colorGroups intruderHue (replicate (length roles + 2) 1)+ getColor gIdx eIdx = + maybe (error "color not found") snd $ find (((gIdx, eIdx) == ) . fst) cMap+ getRoleColor role = hsvToHex $ getColor (findShowError role rMap) 0++ mkNode label color attrs = node $ [+ ("label",label)+ , ("shape","box")+ , ("style","filled")+ , ("fillcolor",color)+ ] ++ attrs++ dotStep (role, step) = + mkNode (render $ sptRoleStep Nothing step) (getRoleColor role) []++ dotSend _ (_, Recv _ _) = return ()+ dotSend stepMap send@(_, Send l _) = sequence_+ [ edge (findShowError send stepMap) (findShowError recv stepMap) []+ | recv@(_, Recv l' _) <- steps, l == l' ]++ dotRole stepMap role = do+ roleId <- mkNode ("role "++roleName role) (getRoleColor $ roleName role) [("peripheries","2")]+ let getStepId = (`findShowError` stepMap) . ((,) (roleName role))+ ids = roleId : map getStepId (roleSteps role)+ mkEdge (from, to) = edge from to threadEdgeStyle+ mapM_ mkEdge (zip ids (tail ids))+ ++------------------------------------------------------------------------------+-- Calling Graphviz' dot tool+------------------------------------------------------------------------------++-- | Convert a .dot file to a .png file using the dot tool.+graphvizDotToPng :: FilePath -- ^ Path to dot tool.+ -> FilePath -- ^ Dot file to convert+ -> FilePath -- ^ Png file to output+ -> Chan String -- ^ Message channel+ -> IO ()+graphvizDotToPng dotTool dotFile pngFile msgChan = do+ let cmd = dotTool ++ " -Tpng -o " ++ pngFile ++ " " ++ dotFile+ writeChan msgChan cmd+ hProc <- runCommand cmd + _ <- waitForProcess hProc+ return ()
@@ -0,0 +1,393 @@+{-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses #-}++-- remove the two warnings from tagsoup+{-# OPTIONS_GHC -fno-warn-warnings-deprecations #-}++-- | Converting security protocol theories to a bunch of HTML files and images.+module Scyther.Theory.Html (+ GenerationInput(..)+ , theoryToHtml+ , evalHtmlMarkup+) where++import Data.Char+import Data.Maybe+import qualified Data.Set as S+import qualified Data.Map as M+import Data.Time.Clock+import Data.Time.Format ()+import Data.Traversable (sequenceA)++import Control.Basics+import Control.Monad.Identity+import Control.Monad.State+import Control.Monad.Label+import Control.Concurrent.ManagedThreads++import Text.Isar+import Text.Dot+import Text.HTML.TagSoup+import Text.JSON++import System.IO+import System.Directory+import System.FilePath+import System.Timing++import Extension.Prelude++import Scyther.Protocol+import Scyther.Sequent+import Scyther.Theory+import Scyther.Theory.Dot+import Scyther.Theory.Pretty+++-- | Converts an indented string to the corresponding Html element.+indentedToHtmlString :: String -> String+indentedToHtmlString = unlines . map (addBreak . indent) . lines+ where+ addBreak = (++"<br />")+ indent = uncurry (++) . (concatMap (const " ") *** escapeText) . span isSpace+ escapeText = renderTags . parseTags++------------------------------------------------------------------------------+-- Html file generation+------------------------------------------------------------------------------++-- | Input for generation process that needs to be supplied from a caller of+-- @theoryToHtml@.+data GenerationInput = GenerationInput {+ giHeader :: String -- ^ Arbitrary html for the header+ , giTime :: UTCTime -- ^ Generation time.+ , giSystem :: String -- ^ Description of the system we run on.+ , giInputFile :: FilePath -- ^ Path to input file.+ , giTemplate :: FilePath -- ^ Path to template index.+ , giOutDir :: FilePath -- ^ Path to the output directory.+ , giMarkup :: HtmlMarkup Doc -- ^ Document representing theory to output.+ , giProofScript :: FilePath -> String + -- ^ A function mapping the output file name to a+ -- string representation of Isabelle/HOL+ -- certificate. The generation time will be+ -- measured as the time it takes to write+ -- this string to the output file.+ , giDotTool :: String -- ^ 'dot' tool to use.+ , giCmdLine :: String -- ^ The command line that was used in this call to+ -- scyther-proof.+ , giIsabelle :: Maybe (FilePath -> IO (IO String, Maybe String))+ -- ^ A checking function calling isabelle with+ -- the right parameters and returning an IO function+ -- for retrieving the logfile contents and an error+ -- message in case the check didn't succeed.+ }++-- | Information about various paths relevant for generating the HTML output.+data PathInfo = PathInfo {+ inputFileCopy :: FilePath -- ^ Path of input file copy.+ , proofScriptFile :: FilePath -- ^ Path of generated Isabelle proof script.+ , logFileCopy :: FilePath -- ^ Path of the copy of the logFile+ , outDir :: FilePath -- ^ Output directory.+ , imageDir :: FilePath -- ^ Relative directory for graphs.+ , filesDir :: FilePath -- ^ Relative directory for input and output files.+ }++-- | Compute the path info from the generation input.+pathInfo :: GenerationInput -> PathInfo+pathInfo input = info+ where+ info = PathInfo+ { inputFileCopy = filesDir info </> takeFileName (giInputFile input)+ , proofScriptFile = filesDir info </> + addExtension (takeBaseName (giInputFile input) ++ "_cert_auto") "thy"+ , logFileCopy = filesDir info </> "logfile"+ , outDir = giOutDir input+ , imageDir = "img"+ , filesDir = "files"+ }+++-- | Make a path that is specified relative to the output directory absolute.+mkAbsolute :: PathInfo -> FilePath -> FilePath+mkAbsolute info = (outDir info </>)++-- | Compute the list of absolute paths to directories required for generating+-- this HTML output.+requiredDirs :: PathInfo -> [FilePath]+requiredDirs info = map (mkAbsolute info) [".", imageDir info, filesDir info]++-- | Prepare information gathered during the generation of the resulting+-- theories for exporting as JSON.+jsGenerationInfo :: GenerationInput+ -> NominalDiffTime -- ^ Proof script generation time.+ -> Maybe (Bool, NominalDiffTime, FilePath) + -- ^ Proof checking time and relative logfile path.+ -> JSObject JSValue+jsGenerationInfo input genTime optCheckInfo = toJSObject $+ [ ("header", showJSON . toJSString $ giHeader input)+ , ("time", showJSON . toJSString . show $ giTime input)+ , ("system", showJSON . toJSString $ giSystem input)+ , ("inputFile", showJSON . fileLink $ inputFileCopy paths)+ , ("proofScript", showJSON . fileLink $ proofScriptFile paths)+ , ("commandLine", showJSON . toJSString $ giCmdLine input)+ ] +++ checkInfo optCheckInfo+ where+ paths = pathInfo input+ fileLink file = (toJSString (takeFileName file), toJSString file)+ genTimeString = "generated in " ++ show genTime++ checkInfo Nothing = + [ ("certificateStatus", showJSON . toJSString $ genTimeString) ]+ checkInfo (Just (success, checkTime, logFile)) =+ [ ( "certificateStatus", showJSON . toJSString $ genTimeString ++ status)+ , ( "logFile", showJSON (toJSString "logfile", toJSString logFile))+ ]+ where+ status | success = ", successfully checked in " ++ show checkTime+ | otherwise = ", CHECK FAILED after " ++ show checkTime++-- | Convert a security protocol theory to a HTML file visualizing it.+theoryToHtml :: GenerationInput -> IO ()+theoryToHtml input = do+ putStrLn ""+ putStrLn $ " copying template to output directory: " ++ outDir paths+ mapM_ (createDirectoryIfMissing True) $ requiredDirs paths+ copyTemplate (giTemplate input) $ outDir paths+ copyFile (giInputFile input) (mkAbsolute paths $ inputFileCopy paths)+ -- timed proof script generation+ putStr " generating proof script: " >> hFlush stdout+ genTime <- timed_ $ writeAbsolute (proofScriptFile paths) + (giProofScript input $ proofScriptFile paths)+ putStrLn $ show genTime+ -- timed isabelle check+ optCheckInfo <- case giIsabelle input of+ Nothing -> return Nothing+ Just machineCheck -> do+ putStr " checking proof script: " >> hFlush stdout+ ((logFileContents, optErrMsg), checkTime) <- timed $ + machineCheck (mkAbsolute paths $ proofScriptFile paths)+ putStrLn $ show checkTime+ -- write log file copy+ contents <- logFileContents+ writeAbsolute (logFileCopy paths) contents+ return $ Just (isNothing optErrMsg, checkTime, logFileCopy paths)+ -- json output+ let thyJSON = mkThyJSON (jsGenerationInfo input genTime optCheckInfo)+ writeAbsolute "theory.js"+ (("scytherP_theory_JSON = "++) . show $ showJSObject thyJSON "")+ -- graph generation+ putStrLn " generating visualizations using GraphViz:"+ parMkGraphs . sortOn snd $ M.toList graphs+ where+ paths = pathInfo input+ writeAbsolute = writeFile . mkAbsolute paths++ (ppThy, (st, graphs)) = runHtmlMarkup $ giMarkup input+ thyStr = indentedToHtmlString (render ppThy)+ mkThyJSON :: JSObject JSValue -> JSObject JSValue+ mkThyJSON genInfo = toJSObject+ [ ("theory", showJSON $ toJSString thyStr)+ , ("generationInfo", showJSON $ genInfo )+ , ("theoremDefs", showJSON $ htmlThmDefs st )+ , ("theoremRefs", showJSON $ htmlThmRefs st )+ , ("cases", showJSON $ htmlCases st )+ , ("proofstates", showJSON $ htmlGraphRefs st )+ , ("explanations", showJSON $ swapKeyValue $ htmlExpls st)+ ]+ swapKeyValue m = M.fromList [(y, x) | (x, y) <- M.toList m]++ -- create the graph corresponding to the given formula+ mkGraph (dotStr,idx) msgChan = do+ let outFile = mkAbsolute paths (imageDir paths </> ("graph_" ++ show idx))+ dotFile = addExtension outFile "dot"+ pngFile = addExtension outFile "png"+ writeFile dotFile dotStr+ graphvizDotToPng (giDotTool input) dotFile pngFile msgChan+ removeFile dotFile++ -- | Convert a list of dot strings in parallel to png files, using the number of+ -- cores+1 parallel executions of the dot tool.+ parMkGraphs = parCmd_ display . map mkGraph+ where+ display n i msg = hPutStrLn stdout $ " ["++showPadded i++" of "++show n++"] "++msg+ where showPadded x = flushRight (length (show n)) (show x)++-- | Copy all the files referenced in the template index file to the output+-- directory.+copyTemplate :: FilePath -- ^ Path of template index file.+ -> FilePath -- ^ Output directory.+ -> IO ()+copyTemplate templateFile targetDir = do+ let templateDir = takeDirectory templateFile+ template <- readFile templateFile+ let files = filter (not.null) $ lines template+ copy file = do+ let outPath = targetDir </> file+ createDirectoryIfMissing True (takeDirectory outPath)+ copyFile (templateDir </> file) outPath+ mapM_ copy files++------------------------------------------------------------------------------+-- Html Markup Output+------------------------------------------------------------------------------++-- Helper functions+-------------------++-- | Name value pairs for attributes.+type Attributes = [(String,String)]++-- | Output a document surrounded by a tag.+withTag :: Document d => + String -- ^ Tag name+ -> Attributes -- ^ Name, value pairs for attributes (no escaping done!)+ -> d -- ^ Inner document+ -> d+withTag tag atts d = + zeroWidthText ("<" ++ tag ++ attsStr ++ ">") <> d <> zeroWidthText ("</" ++ tag ++ ">")+ where+ attsStr | null atts = ""+ | otherwise = concat [ " "++a++"=\""++v++"\"" | (a,v) <- atts ]++-- | Output a document surrounded by a span tag.+withSpan :: Document d => Attributes -> d -> d+withSpan = withTag "span"+++-- Html Markup Monad+--------------------++newtype GraphIdx = GraphIdx { getGraphIdx :: Int }+ deriving( Eq, Ord, Num, Enum, JSON )++instance Show GraphIdx where+ show = show . getGraphIdx++type HtmlCase = (GraphIdx, [((String, Bool), GraphIdx)])+type HtmlSequent = GraphIdx+-- type HtmlSequent = (GraphIdx, GraphIdx)++data HtmlMarkupState = HtmlMarkupState {+ htmlCases :: M.Map Int HtmlCase+ , htmlThmDefs :: M.Map (String, String) HtmlSequent+ , htmlThmRefs :: M.Map Int HtmlSequent+ , htmlGraphRefs :: M.Map Int HtmlSequent+ , htmlExpls :: M.Map String Int + , htmlNextExplRef :: Int+ }++type GraphDesc = String++newtype HtmlMarkup a = HtmlMarkup {+ unHtmlMarkup :: StateT HtmlMarkupState + (ConsistentLabelsT GraphDesc GraphIdx Identity) a+ }+ deriving( Functor, Applicative, Monad )++instance MonadState HtmlMarkupState HtmlMarkup where+ get = HtmlMarkup get+ put = HtmlMarkup . put++-- | Get a uniquely numbered reference to a graph given as a 'Dot' action.+referenceGraph :: Dot a -> HtmlMarkup GraphIdx+referenceGraph = HtmlMarkup . lift . label . showDot++-- | Compute the next free index of a map of keys: 0 for the empty map and the+-- maximal index plus 1 otherwise.+nextIndex :: (Num k, Enum k) => M.Map k v -> k+nextIndex = maybe 0 (succ.fst.fst) . M.maxViewWithKey++-- | Insert the value at the 'nextIndex' of one of the maps underlying the+-- 'HtmlMarkupState'.+insertAtNextIndex :: (Ord k, Enum k, Num k) =>+ (HtmlMarkupState -> M.Map k v) -- ^ Get the map.+ -> (M.Map k v -> HtmlMarkupState -> HtmlMarkupState) -- ^ Set the map.+ -> v -> HtmlMarkup k+insertAtNextIndex getter setter c = HtmlMarkup $ do+ s <- get+ let cases = getter s+ next = nextIndex cases+ put (setter (M.insert next c cases) s)+ return next++insertHtmlCase :: HtmlCase -> HtmlMarkup Int+insertHtmlCase = insertAtNextIndex htmlCases (\x s->s {htmlCases = x})++insertGraphRef :: GraphIdx -> HtmlMarkup Int+insertGraphRef = insertAtNextIndex htmlGraphRefs (\x s->s {htmlGraphRefs = x})++insertThmRef :: HtmlSequent -> HtmlMarkup Int+insertThmRef = insertAtNextIndex htmlThmRefs (\x s->s {htmlThmRefs = x})++insertThmDef :: Theorem -> HtmlSequent -> HtmlMarkup (String, String)+insertThmDef thm se = do+ let name = (protoName . seProto $ thmSequent thm, thmName thm)+ modify (\s -> s { htmlThmDefs = M.insert name se (htmlThmDefs s) })+ return name++insertExplanation :: String -> HtmlMarkup Int+insertExplanation e = do+ expls <- gets htmlExpls+ case M.lookup e expls of+ Just ref -> return ref+ Nothing -> do+ st <- get+ let ref = htmlNextExplRef st+ put $ st { htmlNextExplRef = succ ref, htmlExpls = M.insert e ref expls }+ return ref++htmlSequent :: Sequent -> HtmlMarkup HtmlSequent+htmlSequent = referenceGraph . dotSequentMarked S.empty+ -- (,) <$> referenceGraph (dotPremise se) <*> referenceGraph (dotConclusion se)++htmlCase :: Dot a -> [((String,Bool),Dot b)] -> HtmlMarkup HtmlCase+htmlCase c scs =+ (,) <$> referenceGraph c <*>+ sequenceA [ (,) info <$> referenceGraph dot | (info, dot) <- scs ]++emptyHtmlMarkupState :: HtmlMarkupState+emptyHtmlMarkupState = HtmlMarkupState M.empty M.empty M.empty M.empty M.empty 0++runHtmlMarkup :: HtmlMarkup a -> (a, (HtmlMarkupState, M.Map GraphDesc GraphIdx))+runHtmlMarkup m = + case runIdentity . flip runConsistentLabelsT [1..] .+ flip runStateT emptyHtmlMarkupState . unHtmlMarkup $ m of+ ((res, st), (_, sequentIdxs)) -> (res, (st, sequentIdxs))++evalHtmlMarkup :: HtmlMarkup a -> a+evalHtmlMarkup = fst . runHtmlMarkup++instance MarkupMonad HtmlMarkup where+ withGraph dot d = do+ ref <- insertGraphRef =<< referenceGraph dot+ withSpan [("id", "graphRef_"++show ref)] d++ withExplanation expl d = do+ ref <- insertExplanation expl+ withSpan [("name", "explRef_"++show ref)] d++ noteCases c ntcs tcs d = do+ let addTag isTrivial (name, dot) = ((name, isTrivial), dot)+ cases = map (addTag False) ntcs ++ map (addTag True) tcs+ ref <- insertHtmlCase =<< htmlCase c cases+ withSpan [("id", "caseRef_"++show ref)] d++ theoremRef proto thmname = do+ let pname = protoName proto+ defs <- gets htmlThmDefs+ case M.lookup (pname, thmname) defs of+ Just se -> do+ ref <- insertThmRef se+ withSpan [("id","thmRef_"++show ref)] (text thmname)+ Nothing ->+ text thmname++ theoremDef thm d = do+ (pname, thname) <- insertThmDef thm =<< htmlSequent (thmSequent thm)+ let anchor = pname ++ "_" ++ thname+ withTag "a" [("name",anchor)] d++ keyword tag d = withSpan [("class","kw-"++tag)] d++ +
@@ -0,0 +1,372 @@+{+{-# OPTIONS_GHC -fno-warn-name-shadowing -fno-warn-unused-matches -fno-warn-unused-binds -fno-warn-missing-signatures #-}+module Scyther.Theory.Lexer where++}++$digit = [0-9]+$letter = [a-zA-Z]+$others = [\192-\214\216-\246\248-\255]++@integer = $digit++@identifierFirst = ($letter | $digit | $others)+@identifierAfter = ($letter | $digit | "_" | $others)+@identifier = @identifierFirst @identifierAfter*+@comment = $printable | $white+@lineComment = "//".*++tokens :-+ <0> $white+ ;++ <0> @lineComment ;+ <0> "(*" { beginComment "(*" comment }+ <comment> "(*" { beginComment "(*" comment }+ <comment> "*)" { endComment "(*" } + <0> "/*" { beginComment "/*" comment }+ <comment> "/*" { beginComment "/*" comment }+ <comment> "*/" { endComment "/*" } + <comment> @comment { skip }++ <0> "text{*" { beginComment "{*" comment }+ <0> "section{*" { beginComment "{*" comment }+ <0> "subsection{*" { beginComment "{*" comment }+ <comment> "{*" { beginComment "{*" comment }+ <comment> "*}" { endComment "{*" } ++ <0> "∀" { keyword FORALL }+ <0> "∃" { keyword EXISTS }+ <0> "∧" { keyword LAND }+ <0> "∨" { keyword LOR }+ <0> "¬" { keyword LNOT }+ <0> "≈" { keyword APPROX }++ <0> "," { keyword COMMA }+ <0> "(" { keyword LPAREN }+ <0> ")" { keyword RPAREN }+ <0> "[" { keyword LBRACKET }+ <0> "]" { keyword RBRACKET }+ <0> "{" { keyword LBRACE }+ <0> "}" { keyword RBRACE }+ <0> "'" { keyword SQUOTE }+ <0> \" { keyword DQUOTE }+ <0> "~" { keyword TILDE }+ <0> "^" { keyword HAT }+ <0> "=" { keyword EQUAL }+ <0> ":" { keyword COLON }+ <0> "$" { keyword DOLLAR }+ <0> "#" { keyword SHARP }+ <0> "*" { keyword STAR }+ <0> "<" { keyword LESS } + <0> ">" { keyword GREATER } + <0> "?" { keyword QUESTIONMARK } + <0> "&" { keyword AND } + <0> "|" { keyword MID } + <0> "." { keyword DOT } + <0> "_" { keyword UNDERSCORE } + <0> "-" { keyword MINUS } + <0> "+" { keyword PLUS } + <0> "->" { keyword RIGHTARROW } + <0> "<-" { keyword LEFTARROW } + <0> "-->" { keyword LONGRIGHTARROW } + <0> "<--" { keyword LONGLEFTARROW } + <0> @identifier { scanIdent }+++{++-- | Lex a keyword+keyword :: Keyword -> AlexAction Keyword+keyword kw input len = return kw++-- | Lex an identifier+scanIdent :: AlexAction Keyword+scanIdent (_,_,input) len = return $ IDENT (take len input)++{-+-- | Scan a string until EOF is encountered.+alexScanTokens :: String -> Either String [Keyword]+alexScanTokens inp = runAlex inp gather+ where+ gather = do+ t <- alexMonadScan+ case trace (show t) t of+ EOF -> return [EOF]+ _ -> (t:) `liftM` gather++-- | Scan a file.+scanFile f = do+ inp <- readFile f+ return $ alexScanTokens inp+-}++-- | Lexable Keywords+data Keyword =+ IDENT String+ | SQUOTE+ | DQUOTE+ | RIGHTARROW+ | LEFTARROW+ | LONGRIGHTARROW+ | LONGLEFTARROW+ | COMMA+ | DOT+ | COLON+ | QUESTIONMARK+ | AND+ | MID+ | DOLLAR+ | SHARP+ | LPAREN+ | RPAREN+ | LBRACKET+ | RBRACKET+ | LBRACE + | RBRACE+ | TILDE+ | HAT+ | STAR+ | UNDERSCORE+ | MINUS+ | PLUS+ | EQUAL+ | LESS+ | GREATER+ | EOF+ | FORALL+ | EXISTS+ | LAND+ | LOR+ | LNOT+ | APPROX+ -- dummy keyword to get rid of overlapping pattern matches+ | DUMMY_KEYWORD+ deriving( Eq )++instance Show Keyword where+ show kw = case kw of + IDENT i -> identifier i+ SQUOTE -> symbol "'"+ DQUOTE -> symbol "\""+ RIGHTARROW -> symbol "->"+ LEFTARROW -> symbol "<-"+ LONGRIGHTARROW -> symbol "-->"+ LONGLEFTARROW -> symbol "<--"+ COMMA -> symbol ","+ DOT -> symbol "."+ COLON -> symbol ":"+ QUESTIONMARK -> symbol "?"+ AND -> symbol "&"+ MID -> symbol "|"+ DOLLAR -> symbol "$"+ SHARP -> symbol "#"+ LPAREN -> symbol "("+ RPAREN -> symbol ")"+ LBRACKET -> symbol "["+ RBRACKET -> symbol "]"+ LBRACE -> symbol "{"+ RBRACE -> symbol "}"+ TILDE -> symbol "~"+ HAT -> symbol "^"+ STAR -> symbol "*"+ UNDERSCORE -> symbol "_"+ MINUS -> symbol "-"+ PLUS -> symbol "+"+ EQUAL -> symbol "="+ LESS -> symbol "<"+ GREATER -> symbol ">"+ EOF -> "end of file"+ FORALL -> symbol "∀" + EXISTS -> symbol "∃" + LAND -> symbol "∧" + LOR -> symbol "∨" + LNOT -> symbol "¬" + APPROX -> symbol "≈" + DUMMY_KEYWORD -> "DUMMY_KEYWORD (this should not occur!)"+ where+ identifier i = "identifier `" ++ i ++ "'"+ symbol s = "symbol `" ++ s ++ "'"+ keyword s = "keyword `" ++ s ++ "'"++-- -----------------------------------------------------------------------------+-- Alex wrapper code.+--+-- This code is in the PUBLIC DOMAIN; you may copy it freely and use+-- it for any purpose whatsoever.++-- -----------------------------------------------------------------------------+-- The input type+++type AlexInput = (AlexPosn, -- current position,+ Char, -- previous char+ String) -- current input string++alexInputPrevChar :: AlexInput -> Char+alexInputPrevChar (p,c,s) = c++alexGetChar :: AlexInput -> Maybe (Char,AlexInput)+alexGetChar (p,c,[]) = Nothing+alexGetChar (p,_,(c:s)) = let p' = alexMove p c in p' `seq`+ Just (c, (p', c, s))+++-- -----------------------------------------------------------------------------+-- Token positions++-- `Posn' records the location of a token in the input text. It has three+-- fields: the address (number of chacaters preceding the token), line number+-- and column of a token within the file. `start_pos' gives the position of the+-- start of the file and `eof_pos' a standard encoding for the end of file.+-- `move_pos' calculates the new position after traversing a given character,+-- assuming the usual eight character tab stops.++data AlexPosn = AlexPn !Int !Int !Int+ deriving (Eq)++instance Show AlexPosn where+ show (AlexPn _ l c) = "line "++show l++" column "++show c++alexStartPos :: AlexPosn+alexStartPos = AlexPn 0 1 1++alexMove :: AlexPosn -> Char -> AlexPosn+alexMove (AlexPn a l c) '\t' = AlexPn (a+1) l (((c+7) `div` 8)*8+1)+alexMove (AlexPn a l c) '\n' = AlexPn (a+1) (l+1) 1+alexMove (AlexPn a l c) _ = AlexPn (a+1) l (c+1)+++-- -----------------------------------------------------------------------------+-- Default monad+++data AlexState = AlexState {+ alex_pos :: !AlexPosn, -- position at current input location+ alex_inp :: String, -- the current input+ alex_chr :: !Char, -- the character before the input+ alex_scd :: !Int, -- the current startcode+ alex_ocd :: !Int, -- the old startcode before the comment started+ alex_cmt :: [String] -- stack of begin comment identifiers+ }++-- Compile with -funbox-strict-fields for best results!++runAlex :: String -> Alex a -> Either String a+runAlex input (Alex f) + = case f (AlexState {alex_pos = alexStartPos,+ alex_inp = input, + alex_chr = '\n',+ alex_scd = 0,+ alex_ocd = 0,+ alex_cmt = []+ }) of + Left msg -> Left msg+ Right ( _, a ) -> Right a++newtype Alex a = Alex { unAlex :: AlexState -> Either String (AlexState, a) }++instance Monad Alex where+ m >>= k = Alex $ \s -> case unAlex m s of + Left msg -> Left msg+ Right (s',a) -> unAlex (k a) s'+ return a = Alex $ \s -> Right (s,a)++alexGetPos :: Alex AlexPosn+alexGetPos = Alex $ \s@AlexState{alex_pos=pos} -> Right (s, pos)++alexGetInput :: Alex AlexInput+alexGetInput+ = Alex $ \s@AlexState{alex_pos=pos,alex_chr=c,alex_inp=inp} -> + Right (s, (pos,c,inp))++alexSetInput :: AlexInput -> Alex ()+alexSetInput (pos,c,inp)+ = Alex $ \s -> case s{alex_pos=pos,alex_chr=c,alex_inp=inp} of+ s@(AlexState{}) -> Right (s, ())++alexError :: String -> Alex a+alexError message = Alex $ \s -> Left $ message ++ " in " ++ show (alex_pos s)++alexGetStartCode :: Alex Int+alexGetStartCode = Alex $ \s@AlexState{alex_scd=sc} -> Right (s, sc)++alexSetStartCode :: Int -> Alex ()+alexSetStartCode sc = Alex $ \s -> Right (s{alex_scd=sc}, ())++alexGetOldStartCode :: Alex Int+alexGetOldStartCode = Alex $ \s@AlexState{alex_ocd=sc} -> Right (s, sc)++alexSetOldStartCode :: Int -> Alex ()+alexSetOldStartCode sc = Alex $ \s -> Right (s{alex_ocd=sc}, ())++alexGetComments :: Alex [String]+alexGetComments = Alex $ \s -> Right (s, alex_cmt s)++alexSetComments :: [String] -> Alex ()+alexSetComments cmt = Alex $ \s -> Right (s{alex_cmt=cmt}, ())++alexMonadScan = do+ inp <- alexGetInput+ sc <- alexGetStartCode+ case alexScan inp sc of+ AlexEOF -> alexEOF+ AlexError inp' -> alexError "lexical error"+ AlexSkip inp' len -> do+ alexSetInput inp'+ alexMonadScan+ AlexToken inp' len action -> do+ alexSetInput inp'+ action inp len++-- -----------------------------------------------------------------------------+-- Useful token actions++type AlexAction result = AlexInput -> Int -> Alex result++-- just ignore this token and scan another one+skip :: AlexAction Keyword+skip input len = alexMonadScan++-- ignore this token, but set the start code to a new value+begin :: Int -> AlexAction Keyword+begin code input len = do alexSetStartCode code; alexMonadScan++-- | Begin a comment starting with the given sign.+beginComment :: String -> Int -> AlexAction Keyword+beginComment cmtBegin code input len = do+ cmts <- alexGetComments+ alexSetComments $ cmtBegin : cmts+ if null cmts+ then alexGetStartCode >>= alexSetOldStartCode+ else return ()+ alexSetStartCode code+ alexMonadScan++-- | End a comment that started with the given begin comment sign.+endComment :: String -> AlexAction Keyword+endComment cmtBegin input len = do+ cmts <- alexGetComments+ case cmts of+ [] -> alexError $ "comment ended but no beginning '"++cmtBegin++"' marked."+ (cmt:cmts') -> do+ if cmt == cmtBegin + then do+ alexSetComments cmts'+ if null cmts' + then alexGetOldStartCode >>= alexSetStartCode + else return ()+ else return ()+ alexMonadScan++-- perform an action for this token, and set the start code to a new value+-- andBegin :: AlexAction result -> Int -> AlexAction result+(action `andBegin` code) input len = do alexSetStartCode code; action input len++alexEOF :: Alex Keyword+alexEOF = return EOF++++}+++
@@ -0,0 +1,894 @@+module Scyther.Theory.Parser (++ -- * Lexing+ Token+ , Keyword(..)+ , scanString+ , scanFile++ -- * Parsing+ , Parser+ , parseFile++ -- ** Additional combinators+ , liftMaybe+ , liftMaybe'+ , token++ -- ** Keyword combinations+ , kw+ , betweenKWs+ , commaSep+ , commaSep1+ , list+ , braced+ , parens+ , brackets+ , singleQuoted+ , doubleQuoted+ , identifier+ , string+ , strings+ , integer+ , genFunOpen+ , genFunApp+ , funOpen+ , funApp+ + -- ** Security protocol theorys for the free-algebra+ , protocol+ , claims+ , theory+ , parseTheory++ -- * Extended patterns+ , mkLTSPat+ , mkMultIdentityPat+ , mkExpPat+ , mkMultPat+ , destLTSPat+ , destMultIdentityPat+ , destExpPat+ , destMultPat+ ) where++import Data.Char+import Data.List+import qualified Data.Set as S+import Data.DAG.Simple+import Data.Foldable (asum)++import Control.Arrow ( (***) )+import Control.Monad hiding (sequence)++import Control.Applicative hiding (empty, many, optional)++import Text.Parsec hiding (token, (<|>), string )+import qualified Text.Parsec as P+import Text.Parsec.Pos++import qualified Scyther.Equalities as E+import Scyther.Facts as F hiding (protocol)+import Scyther.Sequent+import Scyther.Proof+import Scyther.Theory+import Scyther.Theory.Lexer++------------------------------------------------------------------------------+-- Specializing Parsec to our needs+------------------------------------------------------------------------------++-- Scanner+----------++-- | The tokens delivered by our Alex based scanner+type Token = (SourcePos, Keyword)++-- | Scan a string using the given filename in the error messages.+--+-- NOTE: Lexical errors are thrown using 'error'.+scanString :: FilePath -> String -> [Token]+scanString filename s = + case runAlex s gatherUntilEOF of+ Left err -> error err+ Right kws -> kws+ where+ gatherUntilEOF = do+ AlexPn _ line col <- alexGetPos+ let pos = newPos filename line col+ k <- alexMonadScan+ case k of + EOF -> return [(pos,EOF)]+ _ -> do kws <- gatherUntilEOF+ return $ (pos,k) : kws++-- Parser+---------++-- | A parser with an arbitrary user state for a stream of tokens.+type Parser s a = Parsec [Token] s a++-- | Lift a maybe to a monad plus action.+liftMaybe :: MonadPlus m => Maybe a -> m a+liftMaybe = maybe mzero return++-- | Lift a maybe to a monad action with the given failure message.+liftMaybe' :: Monad m => String -> Maybe a -> m a+liftMaybe' msg = maybe (fail msg) return++-- | Parse a token based on the acceptance condition+token :: (Keyword -> Maybe a) -> Parser s a+token p = P.token (show . snd) fst (p . snd)++-- | Parse a term.+kw :: Keyword -> Parser s ()+kw t = token check+ where + check t' | t == t' = Just () | otherwise = Nothing++-- | Parse content between keywords.+betweenKWs :: Keyword -> Keyword -> Parser s a -> Parser s a+betweenKWs l r = between (kw l) (kw r)++-- | Between braces.+braced :: Parser s a -> Parser s a+braced = betweenKWs LBRACE RBRACE++-- | Between parentheses.+parens :: Parser s a -> Parser s a+parens = betweenKWs LPAREN RPAREN++-- | Between parentheses.+brackets :: Parser s a -> Parser s a+brackets = betweenKWs LBRACKET RBRACKET++-- | Between single quotes.+singleQuoted :: Parser s a -> Parser s a+singleQuoted = betweenKWs SQUOTE SQUOTE++-- | Between double quotes.+doubleQuoted :: Parser s a -> Parser s a+doubleQuoted = betweenKWs DQUOTE DQUOTE++-- | Parse an identifier as a string+identifier :: Parser s String+identifier = token extract+ where extract (IDENT name) = Just $ name+ extract _ = Nothing++-- | Parse a fixed string which could be an identifier.+string :: String -> Parser s ()+string cs = (try $ do { i <- identifier; guard (i == cs) }) <?> ('`' : cs ++ "'")++-- | Parse a sequence of fixed strings.+strings :: [String] -> Parser s ()+strings = mapM_ string++-- | Parse an integer.+integer :: Parser s Int+integer = do i <- identifier+ guard (all isDigit i)+ return (read i)++-- | A comma separated list of elements.+commaSep :: Parser s a -> Parser s [a]+commaSep = (`sepBy` kw COMMA)++-- | A comma separated non-empty list of elements.+commaSep1 :: Parser s a -> Parser s [a]+commaSep1 = (`sepBy1` kw COMMA)++-- | Parse a list of items '[' item ',' ... ',' item ']'+list :: Parser s a -> Parser s [a]+list p = kw LBRACKET *> commaSep p <* kw RBRACKET+++------------------------------------------------------------------------------+-- Lexing, parsing and proving theory files+------------------------------------------------------------------------------++-- Lexing+---------++-- | Scan a file+scanFile :: FilePath -> IO [Token]+scanFile f = do+ s <- readFile f+ return $ scanString f s++-- Parsing+----------++-- | Parser s a theory file.+parseFile :: Parser s a -> s -> FilePath -> IO a+parseFile parser state f = do+ s <- readFile f+ case runParser parser state f (scanString f s) of+ Right p -> return p+ Left err -> error $ show err++-- | Parse a security protocol theory given as a string using the given+-- filename for the error messages +parseTheory :: FilePath -> IO Theory+parseTheory = parseFile theory ()++------------------------------------------------------------------------------+-- Parsing Patterns and Messages+------------------------------------------------------------------------------++-- | An identifier.+ident :: Parser s Id+ident = Id <$> identifier++-- | Left-hand-side of a function application written with the given delimiter.+genFunOpen :: Parser s a -> Parser s b -> Parser s a+genFunOpen ldelim f = try $ f *> ldelim++-- | Left-hand-side of a function application.+genFunApp :: Parser s a -> Parser s b -> Parser s d -> Parser s c -> Parser s c+genFunApp ldelim rdelim f arg = genFunOpen ldelim f *> arg <* rdelim++-- | Left-hand-side of a function application.+funOpen :: String -> Parser s ()+funOpen = genFunOpen (kw LPAREN) . string++-- | A function application.+funApp :: String -> Parser s a -> Parser s a+funApp = genFunApp (kw LPAREN) (kw RPAREN) . string++-- Extended patterns supported by the parser but not by the underlying free+-- term algebra. They are used in the 'scyther-ac-proof' application.+---------------------------------------------------------------------------++mkLTSPat :: Pattern -> Pattern+mkLTSPat x = PHash (PTup (PConst (Id "PARSE_LTS")) x)++mkMultIdentityPat :: Pattern+mkMultIdentityPat = PHash (PConst (Id "PARSE_MULT_IDENTITY"))++mkExpPat :: Pattern -> Pattern -> Pattern+mkExpPat x y = PHash (PTup (PConst (Id "PARSE_EXP")) (PTup x y))++mkMultPat :: Pattern -> Pattern -> Pattern+mkMultPat x y = PHash (PTup (PConst (Id "PARSE_MULT")) (PTup x y))++destLTSPat :: Pattern -> Maybe Pattern+destLTSPat (PHash (PTup (PConst (Id "PARSE_LTS")) x)) = return x+destLTSPat _ = mzero++destMultIdentityPat :: Pattern -> Maybe ()+destMultIdentityPat (PHash (PConst (Id "PARSE_MULT_IDENTITY"))) = return ()+destMultIdentityPat _ = mzero++destExpPat :: Pattern -> Maybe (Pattern, Pattern)+destExpPat (PHash (PTup (PConst (Id "PARSE_EXP")) (PTup x y))) = return (x,y)+destExpPat _ = mzero++destMultPat :: Pattern -> Maybe (Pattern, Pattern)+destMultPat (PHash (PTup (PConst (Id "PARSE_MULT")) (PTup x y))) = return (x,y)+destMultPat _ = mzero++++-- Patterns+-----------++-- | Parse a pattern.+-- NOTE: All local atoms (MFresh, MMVar, MAVar) are set to MMVar with a space+-- preceding the identifier to mark it for later resolution.+--+-- TODO: Remove this ugly string hack.+pattern :: Parser s Pattern+pattern = asum+ [ string "1" *> pure mkMultIdentityPat+ , PConst <$> singleQuoted ident+ , PMVar <$> (kw QUESTIONMARK *> ident)+ , PAVar <$> (kw DOLLAR *> ident)+ , PFresh <$> (kw TILDE *> ident)+ , parens tuplepattern+ , PHash <$> funApp "h" tuplepattern+ , mkLTSPat <$> funApp "lts" tuplepattern+ , PSymK <$> (try (funOpen "k") *> multpattern <* kw COMMA) <*> (multpattern <* kw RPAREN)+ , PShrK <$> (try (string "k" *> kw LBRACKET) *> multpattern <* kw COMMA)+ <*> (multpattern <* kw RBRACKET)+ , PAsymPK <$> funApp "pk" tuplepattern+ , PAsymSK <$> funApp "sk" tuplepattern+ , PEnc <$> braced tuplepattern <*> pattern+ , PSign <$> genFunApp (kw LBRACE) (kw RBRACE) (string "sign") tuplepattern <*> pattern+ , PMVar <$> tempIdentifier+ ]+ where+ tempIdentifier = do i <- identifier+ if isLetter (head i)+ then return (Id (' ':i))+ else fail $ "invalid variable name '" ++ i +++ "': variable names must start with a letter"++-- | Parse multiple ^ applications as a left-associative list of exponentations+-- hackily marked using hashes and constant identifiers.+exppattern :: Parser s Pattern+exppattern = chainl1 pattern (mkExpPat <$ kw HAT)++-- | Parse multiple ^ applications as a left-associative list of+-- multiplications hackily marked using hashes and constant identifiers.+multpattern :: Parser s Pattern+multpattern = chainl1 exppattern (mkMultPat <$ kw STAR)++-- | Parse a comma separated list of patterns as a sequence of+-- right-associative tuples.+tuplepattern :: Parser s Pattern+tuplepattern = chainr1 multpattern (PTup <$ kw COMMA)++-- | Drops the space prefix used for identifying identifiers that need to be+-- resolved later.+dropSpacePrefix :: Id -> Id+dropSpacePrefix (Id (' ':i)) = Id i+dropSpacePrefix i = i++-- | Resolve the type of a local identifier according to the sets of agent+-- variables and the set of message variables. Fresh messages are the ones+-- which are in none these sets.+resolveId :: S.Set Id -> S.Set Id -> Id -> Pattern+resolveId avars mvars i+ | i `S.member` avars = PAVar i+ | i `S.member` mvars = PMVar i+ | otherwise = PFresh i++-- | Resolve all identifiers in the pattern.+resolveIds :: S.Set Id -> S.Set Id -> Pattern -> Pattern+resolveIds avars mvars = go+ where + resolve = resolveId avars mvars+ go pt@(PConst _) = pt+ go pt@(PFresh _) = pt+ go pt@(PAVar _) = pt+ go pt@(PMVar i) = case getId i of+ ' ':i' -> resolve (Id i') -- marked for resolution+ _ -> pt+ go (PHash pt) = PHash (go pt)+ go (PTup pt1 pt2) = PTup (go pt1) (go pt2)+ go (PEnc pt1 pt2) = PEnc (go pt1) (go pt2)+ go (PSign pt1 pt2) = PSign (go pt1) (go pt2)+ go (PSymK pt1 pt2) = PSymK (go pt1) (go pt2)+ go (PShrK pt1 pt2) = PShrK (go pt1) (go pt2)+ go (PAsymPK pt) = PAsymPK (go pt)+ go (PAsymSK pt) = PAsymSK (go pt)++-- | Resolve identifiers as identifiers of the given role.+-- PRE: The role must use disjoint identifiers for fresh messages, agent+-- variables, and message variables.+resolveIdsLocalToRole :: Role -> Pattern -> Pattern+resolveIdsLocalToRole role = resolveIds (roleFAV role) (roleFMV role) +++-- Messages+-----------++-- | Parse a thread identifier.+threadId :: Parser s TID+threadId = TID <$> (kw SHARP *> integer)++-- | Parse a local identifier.+localIdentifier :: Parser s LocalId+localIdentifier = LocalId <$> ((,) <$> ident <*> threadId)++-- | Resolve a thread identifier+resolveTID :: MonadPlus m => E.Mapping -> TID -> m Role+resolveTID mapping tid =+ liftMaybe' ("resolveTID: no role assigned to thread "++show tid) + (E.threadRole tid (E.getMappingEqs mapping))++-- | Resolve a local identifier.+-- PRE: Thread id must be in the role equalities.+resolveLocalId :: MonadPlus m => E.Mapping -> LocalId -> m Message+resolveLocalId mapping (LocalId (i, tid)) = + do role <- resolveTID mapping tid+ return $ inst tid (resolveId (roleFAV role) (roleFMV role) i)+ `mplus`+ (fail $ "resolveLocalId: no role defined for thread " ++ show tid)++-- | Resolve an executed step.+resolveStep :: MonadPlus m => E.Mapping -> TID -> String -> m RoleStep+resolveStep mapping tid stepId = do+ role <- resolveTID mapping tid+ let roleId = roleName role+ if isPrefixOf roleId stepId+ then liftMaybe' ("resolveStep: step '"++stepId++"' not part of role '"++roleName role++"'") + (lookupRoleStep (drop (length roleId + 1) stepId) role)+ else fail ("resolveStep: role of step '"++stepId++"' does not agree to role '"+ ++roleName role++"' of thread "++show tid) ++-- | Parse an instantiation of a pattern.+instantiation :: MonadPlus m => Parser s (E.Mapping -> m Message)+instantiation = do + tid <- TID <$> (funOpen "inst" *> integer <* kw COMMA)+ m <- (do i <- identifier + let (stepId, iTyp) = splitAt (length i - 3) i+ when (iTyp /= "_pt") (fail $ "inst: could not resolve pattern '"++i++"'")+ return $ \mapping -> do+ step <- resolveStep mapping tid stepId+ return (inst tid $ stepPat step)+ `mplus`+ do pt <- pattern+ return $ \mapping -> do+ role <- resolveTID mapping tid+ return (inst tid $ resolveIds (roleFAV role) (roleFMV role) pt)+ )+ kw RPAREN+ return m++-- Parse a message.+message :: MonadPlus m => Parser s (E.Mapping -> m Message)+message = asum+ [ instantiation+ , (pure . return . MConst) <$> betweenKWs SQUOTE SQUOTE ident+ , parens tuplemessage+ , (liftA $ liftM MHash) <$> funApp "h" tuplemessage+ , (liftA2 $ liftM2 MSymK) <$> (funOpen "k" *> message) <*> (kw COMMA *> message <* kw RPAREN)+ , (liftA $ liftM MAsymPK) <$> funApp "pk" message+ , (liftA $ liftM MAsymSK) <$> funApp "sk" message+ , (liftA2 $ liftM2 MEnc) <$> braced tuplemessage <*> message+ , (liftA $ liftM MInvKey) <$> funApp "inv" tuplemessage+ , (flip resolveLocalId) <$> localIdentifier+ ]++-- | Parse a comma separated list of patterns as a sequence of+-- right-associative tuples.+tuplemessage :: MonadPlus m => Parser s (E.Mapping -> m Message)+tuplemessage = chainr1 message ((liftA2 $ liftM2 MTup) <$ kw COMMA)+++------------------------------------------------------------------------------+-- Parsing Alice and Bob Protocol Specifications+------------------------------------------------------------------------------++{- EBNF for the Alice and Bob protocol language++TODO: Update to new syntax++Protocol := "protocol" Identifier "{" Transfer+ "}"+Transfer := Identifier "->" Identifier ":" Term + | Identifier "->" ":" Term "<-" Identifier ":" Term+ | Identifier "<-" ":" Term "->" Identifier ":" Term+Term := "{" Term "}" Key+ | Term "," Term+ | Identifier+Key := "sk(" Identifier ")"+ | "pk(" Identifier ")"+ | "k(" Identifier, Identifier ")"+ | Term+Identifier := [A..Za..z-_]++-}++-- | Parse a single transfer.+transfer :: Parser s [(Id, RoleStep)]+transfer = do+ lbl <- Label <$> identifier <* kw DOT+ (do right <- kw RIGHTARROW *> ident <* kw COLON+ pt <- tuplepattern+ return [(right, Recv lbl pt)]+ <|>+ do right <- kw LEFTARROW *> ident <* kw COLON+ ptr <- tuplepattern+ (do left <- try $ ident <* kw LEFTARROW <* kw COLON+ ptl <- tuplepattern+ return [(left, Recv lbl ptl),(right, Send lbl ptr)]+ <|>+ return [(right, Send lbl ptr)]+ )+ <|>+ do left <- ident+ (do kw RIGHTARROW+ (do right <- ident <* kw COLON+ pt <- tuplepattern+ return [(left,Send lbl pt), (right, Recv lbl pt)]+ <|>+ do ptl <- kw COLON *> tuplepattern+ (do right <- kw RIGHTARROW *> ident <* kw COLON+ ptr <- tuplepattern+ return [(left,Send lbl ptl), (right, Recv lbl ptr)]+ <|>+ do return [(left, Send lbl ptl)]+ )+ )+ <|>+ do kw LEFTARROW+ (do pt <- kw COLON *> tuplepattern+ return [(left, Recv lbl pt)]+ <|>+ do right <- ident <* kw COLON+ pt <- tuplepattern+ return [(left, Recv lbl pt), (right, Send lbl pt)]+ )+ )+ ) ++-- | Parse a protocol.+protocol :: Parser s Protocol+protocol = do+ name <- string "protocol" *> identifier + transfers <- concat <$> braced (many1 transfer)+ -- convert parsed transfers into role scripts+ let roleIds = S.fromList $ map fst transfers+ roles = do+ actor <- S.toList roleIds+ let steps = [ step | (i, step) <- transfers, i == actor ]+ return $ Role (getId actor) + (ensureFreshSteps actor (S.map addSpacePrefix roleIds) steps)+ return $ Protocol name roles+ where+ addSpacePrefix = Id . (' ':) . getId+ dropSpacePrefixes = S.map dropSpacePrefix+ -- | Ensure message variables are received before they are sent.+ ensureFreshSteps actor possibleAvars = + go (S.singleton (addSpacePrefix actor)) S.empty S.empty+ where+ go _ _ _ [] = []+ go avars mvars fresh (Send l pt : rs) = + let avars' = avars `S.union` (((patFMV pt `S.intersection` possibleAvars) + `S.difference` mvars) `S.difference` fresh)+ fresh' = fresh `S.union` ((patFMV pt `S.difference` avars') `S.difference` mvars)+ pt' = resolveIds (dropSpacePrefixes avars') (dropSpacePrefixes mvars) pt+ in Send l pt' : go avars' mvars fresh' rs+ go avars mvars fresh (Recv l pt : rs) = + let mvars' = mvars `S.union` ((patFMV pt `S.difference` avars) `S.difference` fresh)+ pt' = resolveIds (dropSpacePrefixes avars) (dropSpacePrefixes mvars') pt+ in Recv l pt' : go avars mvars' fresh rs++------------------------------------------------------------------------------+-- Parse Claims+------------------------------------------------------------------------------++-- | Parse a claim. +claims :: (String -> Maybe Protocol) -> Parser s [ThyItem]+claims protoMap = do+ let mkAxiom (name, se) = ThyTheorem (name, Axiom se)+ (multiplicity, mkThyItem) <- + (string "property" *> pure (id, ThySequent)) <|> + (string "properties" *> pure ((concat <$>) . many1, ThySequent)) <|>+ (string "axiom" *> pure (id, mkAxiom ))+ protoId <- kw LPAREN *> string "of" *> identifier+ proto <- liftMaybe' ("unknown protocol '"++protoId++"'") $ protoMap protoId + kw RPAREN+ multiplicity $ do+ claimId <- try $ identifier <* kw COLON+ when ('-' `elem` claimId) (fail $ "hyphen '-' not allowed in property name '"++claimId++"'")+ let mkThySequent (mkClaimId, se) = mkThyItem (mkClaimId claimId, se)+ singleSequents = map (liftM (return . (,) id) . ($ proto))+ [ niagreeSequent, secrecySequent, parseAtomicitySequent, implicationSequent ]+ multiSequents = map ($ proto)+ [ parseNonceSecrecy, parseFirstSends+ , parseTransferTyping, parseAutoProps ]+ sequents <- asum $ multiSequents ++ singleSequents+ return $ map mkThySequent sequents++-- | Auto-generated simple properties: first-sends, ltk-secrecy, nonce-secrecy,+-- weak-atomicity, msc-typing+parseAutoProps :: Protocol -> Parser s [(String -> String,Sequent)]+parseAutoProps proto =+ string "auto" *> kw MINUS *> string "properties" *> + pure (concat+ [ transferTyping proto, firstSendSequents proto, nonceSecrecySequents proto ])++-- | Create secrecy claims for nonces and variables.+parseNonceSecrecy :: Protocol -> Parser s [(String -> String,Sequent)]+parseNonceSecrecy proto = + string "nonce" *> kw MINUS *> string "secrecy" *> pure (nonceSecrecySequents proto)++-- | Create secrecy claims for nonces and variables.+nonceSecrecySequents :: Protocol -> [(String -> String,Sequent)]+nonceSecrecySequents proto = + concatMap mkSequent . toposort $ protoOrd proto+ where+ mkSequent (step, role) = case step of+ Send _ pt -> do+ n@(PFresh i) <- S.toList $ subpatterns pt+ guard (not (plainUse pt n) && firstUse n)+ return $ secrecySe (MFresh . Fresh) i+ Recv _ pt -> do+ v@(PMVar i) <- S.toList $ subpatterns pt+ guard (not (plainUse pt v) && firstUse v)+ return $ secrecySe (MMVar . MVar) i+ where+ (tid, prem0) = freshTID (empty proto)+ (prefix, _) = break (step ==) $ roleSteps role+ firstUse = (`S.notMember` (S.unions $ map (subpatterns . stepPat) prefix))+ plainUse pt = (`S.member` splitpatterns pt)+ avars = [ MAVar (AVar (LocalId (v,tid)))+ | (PAVar v) <- S.toList . S.unions . map (subpatterns.stepPat) $ roleSteps role ]+ secrecySe constr i =+ ( (++("_"++roleName role++"_sec_"++getId i))+ , Sequent prem (FAtom AFalse)+ )+ -- flip (Sequent proto) FFalse $ FFacts $+ -- insertEv (Learn (constr (LocalId (i,tid)))) $ + -- insertEv (Step tid step) $ + -- foldr uncompromise (insertRole tid role emptyFacts) avars+ where+ -- here we know that conjunction will work, as we build it by ourselves+ Just (Just prem) = conjoinAtoms atoms prem0+ atoms = [ AEq (E.TIDRoleEq (tid, role))+ , AEv (Step tid step)+ , AEv (Learn (constr (LocalId (i, tid))))+ ] ++ map AUncompr avars++parseFirstSends :: Protocol -> Parser s [(String -> String,Sequent)]+parseFirstSends proto =+ string "first" *> kw MINUS *> string "sends" *> pure (firstSendSequents proto)++firstSendSequents :: Protocol -> [(String -> String,Sequent)]+firstSendSequents proto = + concatMap mkRoleSequents $ protoRoles proto+ where+ mkRoleSequents role = + concatMap mkStepSequents $ zip (inits steps) steps+ where+ steps = roleSteps role+ (tid, prem0) = freshTID (empty proto)+ mkStepSequents (_, Recv _ _ ) = []+ mkStepSequents (prefix, step@(Send _ pt)) = do+ n@(PFresh i) <- S.toList $ splitpatterns pt+ guard (n `S.notMember` S.unions (map (subpatterns.stepPat) prefix))+ let learn = (Learn (MFresh (Fresh (LocalId (i, tid)))))+ atoms = [ AEq (E.TIDRoleEq (tid, role)), AEv learn ]+ Just (Just prem) = conjoinAtoms atoms prem0+ concl = FAtom (AEvOrd (Step tid step, learn))+ return ( (++("_" ++ getId i)), Sequent prem concl)++parseTransferTyping :: Protocol -> Parser s [(String -> String, Sequent)]+parseTransferTyping proto =+ string "msc" *> kw MINUS *> string "typing" *> pure (transferTyping proto)++transferTyping :: Protocol -> [(String -> String, Sequent)]+transferTyping proto = case mscTyping proto of+ Just typing -> pure+ ((++"_msc_typing"), Sequent (empty proto) (FAtom (ATyping typing)))+ Nothing -> fail "transferTyping: failed to construct typing"++-- | Parse secrecy formula.+secrecySequent :: Protocol -> Parser s Sequent+secrecySequent proto = do+ let (tid, prem0) = freshTID (empty proto)+ roleId <- funOpen "secret" *> identifier+ role <- liftMaybe' ("could not find role '"++roleId++"'") $ lookupRole roleId proto+ lbl <- kw COMMA *> (identifier <|> kw MINUS *> pure "-")+ stepAtoms <- + (do step <- liftMaybe $ lookupRoleStep lbl role+ return $ [AEv (Step tid step)]+ `mplus` return [])+ kw COMMA+ (msgMod, pt) <- asum+ [ ((,) MInvKey) <$> funApp "inv" tuplepattern+ , ((,) id) <$> pattern ]+ let m = msgMod . inst tid . resolveIdsLocalToRole role $ pt+ kw COMMA+ uncompromised <- map (inst tid . resolveIdsLocalToRole role) <$> msgSet+ kw RPAREN+ -- construct secrecy claim + let atoms = [ AEq (E.TIDRoleEq (tid, role)), AEv (Learn m) ] ++ stepAtoms ++ + map AUncompr uncompromised+ prem = case conjoinAtoms atoms prem0 of+ Just (Just prem1) -> prem1+ Just Nothing -> error "secrecySequent: secrecy claim is trivially true"+ Nothing -> error "secrecySequent: failed to construct secrecy claim"+ + return $ Sequent prem (FAtom AFalse)+ where+ msgSet = braced $ sepBy pattern (kw COMMA)++-- | Parse non-injective agreement claim.+niagreeSequent :: Protocol -> Parser s Sequent+niagreeSequent proto = do+ funOpen "niagree"+ (roleCom, stepCom, patCom) <- roleStepPattern+ kw RIGHTARROW+ (roleRun, stepRun, patRun) <- roleStepPattern+ kw COMMA+ uncompromised <- map (AUncompr . instPat tidCom roleCom) <$> patSet+ kw RPAREN+ let premAtoms = [ AEq (E.TIDRoleEq (tidCom, roleCom))+ , AEv (Step tidCom stepCom) + ] ++ + uncompromised++ conclAtoms = [ AEq (E.TIDRoleEq (tidRun, roleRun))+ , AEv (Step tidRun stepRun) + , AEq (E.MsgEq ( instPat tidRun roleRun patRun+ , instPat tidCom roleCom patCom ))+ ]+ concl = FExists (Left tidRun) (foldr1 FConj $ map FAtom conclAtoms)+ prem = case conjoinAtoms premAtoms prem0 of+ Just (Just prem1) -> prem1+ Just Nothing -> error "niagreeSequent: claim is trivially true"+ Nothing -> error "niagreeSequent: failed to construct claim"++ return (Sequent prem concl)+ where+ (tidCom, prem0) = freshTID (empty proto)+ tidRun = succ tidCom+ + patSet = braced $ sepBy pattern (kw COMMA)+ instPat tid role = inst tid . resolveIdsLocalToRole role++ -- parse a step and a local pattern; e.g., 'B_1[A,B,TNA,Text1]'+ roleStepPattern = do+ stepId <- identifier+ let (lbl, roleId) = (reverse *** (init . reverse)) (break ('_' ==) $ reverse stepId)+ role <- liftMaybe' ("could not find role '" ++ roleId ++ + "' in protocol '" ++ protoName proto ++ "'")+ (lookupRole roleId proto)++ step <- liftMaybe' ("unknown label '" ++ lbl ++ "' in role '" ++ roleId ++ "'") + (lookupRoleStep lbl role)+ pat <- kw LBRACKET *> tuplepattern <* kw RBRACKET+ return (role, step, pat)+++-- | Parse a weak atomicity formula+parseAtomicitySequent :: Protocol -> Parser s Sequent+parseAtomicitySequent proto = + string "weakly" *> kw MINUS *> string "atomic" *> pure (atomicitySequent proto)++atomicitySequent :: Protocol -> Sequent+atomicitySequent proto = Sequent (empty proto) (FAtom (ATyping WeaklyAtomic))++-- General premises parsing+---------------------------++-- | A raw fact: Either a premise modifier parametrized over a set of role+-- equalities or a single role equality. We'll use these facts to allow for+-- late binding of thread ids to roles.+data RawFact m =+ RawAtom (E.Mapping -> m Atom)+ | RawTIDRoleEq TID String++-- | Extract the role equalities from a list of raw facts.+extractRoleEqs :: MonadPlus m => Protocol -> [RawFact m] -> m [(TID, Role)]+extractRoleEqs proto facts =+ mapM mkEq [(tid, roleId) | RawTIDRoleEq tid roleId <- facts]+ where+ mkEq (tid, roleId) = case lookupRole roleId proto of+ Just role -> return (tid, role)+ Nothing -> fail $ "mkRoleEqs: role '"++roleId++"' does not occur in protocol '"+ ++protoName proto++"'"++-- | Parse a role equality.+roleEqFact :: MonadPlus m => Parser s (RawFact m)+roleEqFact = RawTIDRoleEq <$> (TID <$> (string "role" *> parens integer))+ <*> (kw EQUAL *> identifier)++-- | Parse a knowledge fact.+knowsFact :: MonadPlus m => Parser s (RawFact m)+knowsFact = do+ m <- funApp "knows" message+ return $ RawAtom (liftM (AEv . Learn) <$> m)++-- | Parsing an executed role step.+rawStep :: MonadPlus m => Parser s (E.Mapping -> m Event)+rawStep = parens $ do+ tid <- TID <$> integer+ stepId <- kw COMMA *> identifier+ let step = resolveStep <*> pure tid <*> pure stepId+ return $ (liftM (Step tid) <$> step)++-- | Parse a step fact.+stepFact :: MonadPlus m => Parser s (RawFact m)+stepFact = do+ step <- string "step" *> rawStep+ return $ RawAtom (liftM AEv <$> step)++-- | Parse an honesty assumption.+honestFact :: MonadPlus m => Parser s [RawFact m]+honestFact = do+ string "uncompromised"+ msgs <- parens (sepBy1 message (kw COMMA))+ -- let mod prems = foldr uncompromise prems lids+ return $ [RawAtom (liftM AUncompr <$> m) | m <- msgs]++-- | Parses a learn or a step event.+event :: MonadPlus m => Parser s (E.Mapping -> m Event)+event = asum [ string "St" *> rawStep+ , (liftM Learn <$>) <$> (string "Ln" *> message)+ , (liftM Learn <$>) <$> instantiation ]++-- | Parse a series of ordering facts.+orderFacts :: MonadPlus m => Parser s [RawFact m]+orderFacts = do+ ev <- event <* kw LESS+ evs <- sepBy1 event (kw LESS)+ let mkAtom e1 e2 = RawAtom $ \mapping -> do+ e1' <- e1 mapping+ e2' <- e2 mapping+ return $ AEvOrd (e1', e2')+ return $ zipWith mkAtom (ev:evs) evs++-- | Parse an equality fact.+eqFact :: MonadPlus m => Parser s (RawFact m)+eqFact = do+ m1 <- message <* kw EQUAL+ m2 <- message+ return $ RawAtom (liftM2 (\x y -> AEq (E.MsgEq (x , y))) <$> m1 <*> m2)++-- | Parse a raw fact.+rawFacts :: MonadPlus m => Parser s [RawFact m]+rawFacts = foldl1 (<|>) + ( [try orderFacts, honestFact] ++ + map (liftM return) [roleEqFact, knowsFact, stepFact, eqFact] )++-- | Parse the conclusion "False".+falseConcl :: Parser s Formula+falseConcl = doubleQuoted (string "False" *> pure (FAtom AFalse))++-- | Parse a conclusion stating existence of some threads of a specific+-- structure.+existenceConcl :: Protocol -> E.Mapping -> Parser s Formula+existenceConcl proto mapping = do+ tids <- map (Left . TID) <$> (threads <|> pure [])+ facts <- concat <$> doubleQuoted (sepBy1 rawFacts (kw AND))+ roleeqs <- extractRoleEqs proto facts+ let mapping' = foldr (uncurry E.addTIDRoleMapping) mapping roleeqs+ atoms <- (map (AEq . E.TIDRoleEq) roleeqs ++) `liftM`+ sequence [ mkAtom mapping' | RawAtom mkAtom <- facts ]+ return $ foldr FExists (foldr1 FConj . map FAtom $ atoms) tids+ where+ singleThread = pure <$> (strings ["a", "thread"] *> integer)+ multiThreads = strings ["threads"] *> sepBy1 integer (kw COMMA) + threads = (singleThread <|> multiThreads) <* strings ["such","that"] + +-- | Parse a conclusion.+-- currently only contradiction supported+conclusion :: Protocol -> E.Mapping -> Parser s Formula+conclusion proto mapping = asum+ [try falseConcl, existenceConcl proto mapping]++-- | Parse a general implication claim.+implicationSequent :: Protocol -> Parser s Sequent+implicationSequent proto = do + facts <- concat <$> (string "premises" *> many (doubleQuoted rawFacts))+ roleeqs <- extractRoleEqs proto facts+ let mapping = foldr (uncurry E.addTIDRoleMapping) (E.Mapping E.empty) roleeqs+ quantifiers = map fst roleeqs+ atoms <- (map (AEq . E.TIDRoleEq) roleeqs ++) `liftM`+ sequence [ mkAtom mapping | RawAtom mkAtom <- facts ]+ prems0 <- foldM (flip quantifyTID) (F.empty proto) quantifiers+ optPrems <- conjoinAtoms atoms prems0+ prems <- maybe (fail "contradictory premises") return optPrems+ string "imply"+ concl <- conclusion proto mapping+ return $ Sequent prems concl++{-+-- | Construct the premise modifier. The given set of role equalities is used+-- for thread identfier lookup.+mkPremiseMod :: MonadPlus m => E.Mapping -> [RawFact m] -> Facts -> m Facts+mkPremiseMod mapping rawfacts facts = do+ atoms <- sequence [ mkAtom mapping | RawAtom mkAtom <- rawfacts ]+ optFacts <- conjoinAtoms atoms facts + maybe (error "mkPremiseMod: contradictory facts") return $ optFacts+-}+ + ------------------------------------------------------------------------------ + -- Parse a theory+ ------------------------------------------------------------------------------ ++ +-- | Parse a theory.+theory :: Parser s Theory+theory = do+ string "theory"+ thyId <- identifier+ string "begin" *> addItems (Theory thyId []) <* string "end"+ where+ addItems :: Theory -> Parser s (Theory)+ addItems thy = + do p <- protocol+ case lookupProtocol (protoName p) thy of+ Just _ -> fail $ "duplicate protocol '" ++ protoName p ++ "'"+ Nothing -> addItems (insertItem (ThyProtocol p) thy)+ <|>+ do cs <- claims (flip lookupProtocol thy)+ addItems (foldl' (flip insertItem) thy cs)+ <|>+ do return thy+
@@ -0,0 +1,728 @@+{-# LANGUAGE GeneralizedNewtypeDeriving, FlexibleInstances, FlexibleContexts #-}+-- | Pretty printing a security protocol theory.+module Scyther.Theory.Pretty (+ TaggedIdentityT(..)+ , runTaggedIdentityT+ , SlimOutput(..)+ , MarkupMonad(..)+ , PrettyMonad(..)+ , prettyTheory+ , prettySoundness+) where++import Data.Maybe+import Data.List+import qualified Data.Set as S+import Data.Traversable (sequenceA)++import Control.Basics+import Control.Monad.Identity+import Control.Monad.State+import Control.Monad.Reader++import Text.Isar+import Text.Dot (Dot)++import qualified Scyther.Equalities as E+import Scyther.Facts +import Scyther.Sequent+import Scyther.Proof+import Scyther.Theory+import Scyther.Theory.Dot++------------------------------------------------------------------------------+-- Additional Helper Functions+------------------------------------------------------------------------------++-- FIXME: Remove this too general instance.+instance (Document d, Applicative f) => Document (f d) where+ char = pure . char+ text = pure . text+ zeroWidthText = pure . zeroWidthText+ emptyDoc = pure emptyDoc+ (<>) = liftA2 (<>)+ (<->) = liftA2 (<->)+ hcat = liftA hcat . sequenceA+ hsep = liftA hsep . sequenceA+ ($$) = liftA2 ($$)+ ($-$) = liftA2 ($-$)+ vcat = liftA vcat . sequenceA+ sep = liftA sep . sequenceA+ cat = liftA cat . sequenceA+ fsep = liftA fsep . sequenceA+ fcat = liftA fcat . sequenceA+ nest = liftA2 nest . pure+ caseEmptyDoc = liftA3 caseEmptyDoc++ ++------------------------------------------------------------------------------+-- A type-tagging identity monad transformer+------------------------------------------------------------------------------++newtype TaggedIdentityT t m a = TaggedIdentityT { unTaggedIdentityT :: m a }+ deriving( Functor, Applicative, Monad )++instance MonadTrans (TaggedIdentityT t) where+ lift = TaggedIdentityT ++runTaggedIdentityT :: t -> TaggedIdentityT t m a -> m a+runTaggedIdentityT _ = unTaggedIdentityT+++------------------------------------------------------------------------------+-- Monad Classes+------------------------------------------------------------------------------++-- | A monad for inserting markup into output.+class (Applicative m, Monad m) => MarkupMonad m where+ withGraph :: Document d => Dot a -> m d -> m d+ withExplanation :: Document d => String -> m d -> m d+ theoremRef :: Document d => Protocol -> String -> m d+ theoremDef :: Document d => Theorem -> m d -> m d+ keyword :: Document d => String -> m d -> m d+ noteCases :: Document d => Dot a + -> [(String, Dot b)] -- ^ named non-trivial cases+ -> [(String, Dot b)] -- ^ named trivial cases+ -> m d -> m d++ withGraph _ = id+ withExplanation _ = id+ theoremRef _ = text+ theoremDef _ = id+ keyword _ = id+ noteCases _ _ _ = id++-- | A pretty printing monad allowing for economically replacing parts of the+-- pretty printer.+class MarkupMonad m => PrettyMonad m where+ -- components output+ prettyTID :: TID -> m Doc+ prettyAgentId :: AgentId -> m Doc+ prettyMessage :: Message -> m Doc+ prettyFacts :: Facts -> m ([Doc],[Doc],[Doc])+ prettyFormula :: E.Mapping -> Formula -> m Doc+ prettySequent :: Sequent -> m Doc+ -- proof output+ ensureProofMode :: (Bool, Bool) -> m Doc+ withFactsMode :: (Bool, Bool) -> m Doc -> m Doc+ prettyTrivial :: Sequent -> TrivReason -> m Doc+ prettyMissing :: Sequent -> String -> m Doc+ prettySaturate :: Sequent -> m Doc+ prettyForwardContradiction :: m Doc -> m Doc+ prettyForwardResolution :: m Doc -> Sequent -> E.Mapping -> m Doc+ prettyNextCase :: m Doc+ prettyChainRuleSplitCases :: [ChainRuleCase] -> m ([ChainRuleCase],[ChainRuleCase])+ prettyChainRuleApplication :: m Doc -> m Doc+ prettyChainRuleCase :: (String, [Either TID AgentId]) -> m Doc+ prettyChainRuleQED :: Message -> [ChainRuleCase] -> m Doc+ prettyTypeCheckInduction :: Protocol -> String -> Typing -> (m Doc, m Doc -> m Doc, m Doc)+ prettyTypingCase :: String -> Typing -> String -> Sequent -> m Doc+ prettySplitEqCase :: PrettyMonad m => String -> m Doc+ prettySplitEqApplication :: PrettyMonad m => E.MsgEq -> m Doc+ prettySplitEqQed :: PrettyMonad m => m Doc+ -- theory output+ prettyComment :: String -> m Doc+ prettyProtoDef :: Protocol -> [Theorem] -> m Doc+ prettyTheorem :: Theorem -> m Doc+ prettyTheoryDef :: String -> Doc -> m Doc++-- | Abbreviation for one of the signature of 'prettyChainRuleSplitCases'.+type ChainRuleCase = ((String, [Either TID AgentId]), Proof)++------------------------------------------------------------------------------+-- Functions shared by the different monad instances+------------------------------------------------------------------------------++-- Markup Monad+---------------++explainSequent :: Sequent -> String+explainSequent = + render . runIdentity . runTaggedIdentityT SlimOutput . prettySequent++withExplainedSequent :: (Document d, MarkupMonad m) => Sequent -> m d -> m d+withExplainedSequent = withExplanation . explainSequent++withSequent :: (MarkupMonad m, Document d) => Sequent -> m d -> m d+withSequent se = withGraph (dotSequentMarked S.empty se) . withExplainedSequent se++withProofSequent :: (MarkupMonad m, Document d) => Proof -> m d -> m d+withProofSequent = withSequent . prfSequent+++-- Pretty Printing Monad+------------------------++-- | Split a list of cases that can be converted to a proof into cases being+-- trivial due to one of the given triviality reasons, non trivial cases, and a+-- list of the trivial sequents together with the reasons occurring.+genericChainRuleSplitCases :: (a -> Proof) -> [a] -> (([a],[a]), [(Sequent, TrivReason)])+genericChainRuleSplitCases sel cases =+ (partition (isNothing . check) cases, mapMaybe check cases)+ where+ check = extractTrivial . sel+ extractTrivial (Trivial se reason) = case reason of+ TrivContradictoryPremises -> Just (se, reason)+ TrivLongTermKeySecrecy _ -> Nothing+ TrivPremisesImplyConclusion -> + case seConcl se of + FAtom (AHasType _ _) -> Just (se, reason)+ _ -> Nothing+ extractTrivial _ = Nothing++-- | Pretty print a sequent with quantifiers, logical, and meta-logical facts for+-- the premise and a single document representing the conclusion.+prettySequentParts :: PrettyMonad m => Sequent -> m (([Doc], [Doc], [Doc]), Doc)+prettySequentParts (Sequent prem concl) = do+ ppPrem <- prettyFacts prem+ ppConcl <- prettyFormula (eqsToMapping prem) concl+ return (ppPrem, ppConcl)++-- | Pretty print a proof.+prettyProof :: PrettyMonad m => + String -- ^ Name of the theorem that is proven+ -> (Bool, Bool) -- ^ (facts are loaded, thesis is being proven)+ -> Proof + -> m Doc+prettyProof _ _ (Axiom _) = emptyDoc++prettyProof _ prfConf (Trivial se reason) = + ensureProofMode prfConf <-> prettyTrivial se reason++prettyProof _ _ (Missing se reason showSequent)+ | showSequent = withSequent se $ prettyMissing se reason+ | otherwise = withSequent se $ prettyComment reason++prettyProof _ _ (PossibleAttack _ attack) =+ withSequent attack $ prettyMissing attack "possible attack found:"++prettyProof thName prfConf (RuleApp se Saturate [prf]) =+ withFactsMode prfConf $+ withProofSequent prf (prettySaturate se) $-$+ prettyProof thName (True, False) prf++-- A forward resolution that lead to no further proofs+prettyProof _ prfConf (RuleApp se (ForwardResolution (thName, _) _) []) =+ ensureProofMode prfConf <-> + prettyForwardContradiction (theoremRef (seProto se) thName)+-- a forward resolution with a single successor.+prettyProof outerThName prfConf (RuleApp se (ForwardResolution (thName, thSe) tideqs) [prf]) =+ wrapper $+ withProofSequent prf + (prettyForwardResolution (theoremRef (seProto se) thName) thSe tideqs) $-$ + prettyProof outerThName newMode prf+ where+ isTyping = isTypingFormula . seConcl $ thSe+ (wrapper, newMode) | isTyping = (id, prfConf )+ | otherwise = (withFactsMode prfConf, (True, False))+-- Note that all our forward resolutions currently have zero or one successor+-- proofs. Hence, this case is impossible.+prettyProof _ _ (RuleApp _ (ForwardResolution _ _) _) =+ error "prettyProof: forward resolution with more than one successors"++prettyProof thName prfConf (RuleApp se (ChainRule m names) prfs) = do+ (nonTrivialCases, trivialCases) <- prettyChainRuleSplitCases $ zip names prfs+ ppCases <- mapM selectCase nonTrivialCases+ let mkDot dotSe = dotSequentMarked (S.singleton . substEv (sePrem dotSe) $ Learn m) dotSe+ mkInfo ((caseName, _), prf) = (caseName, mkDot $ prfSequent prf)+ noteCases (mkDot se) (map mkInfo nonTrivialCases) (map mkInfo trivialCases)+ (withExplanation (explainSequent se)+ (ensureProofMode prfConf <-> prettyChainRuleApplication (prettyMessage m)))+ $-$+ vcat (intersperse prettyNextCase (map (pure . nest 2) ppCases)) $-$+ prettyChainRuleQED m trivialCases+ where + selectCase (info, prf) =+ withProofSequent prf (prettyChainRuleCase info) $-$ prettyProof thName (True, False) prf++prettyProof thName _ (RuleApp se (TypingCases names) prfs) = do+ ppCases <- mapM ppCase $ zip names prfs+ let mkDot = dotSequentMarked S.empty . prfSequent+ nonTrivialCases = zip names $ map mkDot prfs+ noteCases (dotSequentMarked S.empty se) nonTrivialCases []+ (withExplanation (explainSequent se) pre) + $-$+ modifier (vcat . intersperse prettyNextCase $ map (nest 2 . pure) ppCases) $-$+ post+ where+ optTyp = fromMaybe errMsg $ destTypingFormula (seConcl se)+ errMsg = error "prettyProof: type checking lemma applied to non-typing conclusion."+ (pre, modifier, post) = prettyTypeCheckInduction (seProto se) thName optTyp+ ppCase (name, prf) =+ let caseDoc = prettyTypingCase thName optTyp name (prfSequent prf)+ in withProofSequent prf caseDoc $-$ prettyProof thName (True, True) prf++prettyProof thName _ (RuleApp se (SplitEq eq@(MShrK _ _, MShrK _ _) [True,True]) prfs) = do+ ppCases <- mapM ppCase $ zip ["noswap","swapped"] prfs+ withExplanation (explainSequent se) (prettySplitEqApplication eq) $-$+ (vcat . intersperse prettyNextCase $ map (nest 2 . pure) ppCases) $-$+ prettySplitEqQed+ where+ ppCase (name, prf) =+ withProofSequent prf (prettySplitEqCase name) $-$ + prettyProof thName (True, False) prf++prettyProof _ _ (RuleApp _ rule _) = error $ "prettyProof: unmatched rule\n" ++ show rule+ +-- | Pretty print a theory item.+--+-- Note that this also ensures that quantifiers are made unique.+prettyThyItem :: PrettyMonad m => [ThyItem] -> ThyItem -> m Doc+prettyThyItem items (ThyProtocol proto) = prettyProtoDef proto + [th | ThyTheorem th <- items, isAxiom th, thmProto th == proto]+prettyThyItem _ (ThySequent (name, se)) = + prettyTheorem (name, Missing (uniqueTIDQuantifiers se) ("proof to be done") False)+prettyThyItem _ (ThyTheorem (name, prf)) = + prettyTheorem (name, prf)+prettyThyItem _ (ThyText txt) = prettyComment txt++-- | Pretty print a theory.+prettyTheory :: PrettyMonad m => Theory -> m Doc+prettyTheory (Theory name items) = do+ ppItems <- mapM (prettyThyItem items) items+ prettyTheoryDef name (vcat $ intersperse (text "") ppItems)++-- | Pretty print soundness information.+prettySoundness :: Applicative f => Theory -> f Doc+prettySoundness thy = case unsoundTheorems thy of+ [] -> emptyDoc+ ths -> vcat $ + map text ["", "(* NOTE that the proofs of the following theorems are UNSOUND:", ""] ++ + map ppThm ths +++ map text ["*)"]+ where+ ppThm (p, name) = nest 5 $ text $ name ++ " (of " ++ protoName p ++ ")"++------------------------------------------------------------------------------+-- Monad Instances+------------------------------------------------------------------------------++-- Markup Monad+---------------++instance MarkupMonad Identity where+ -- deliberately empty: use default implementations++instance MarkupMonad m => MarkupMonad (ReaderT r m) where+ withGraph dot d = ReaderT $ \r -> withGraph dot (runReaderT d r)+ withExplanation e d = ReaderT $ \r -> withExplanation e (runReaderT d r)+ theoremRef proto = lift . theoremRef proto+ theoremDef thm d = ReaderT $ \r -> theoremDef thm (runReaderT d r)+ keyword tag d = ReaderT $ \r -> keyword tag (runReaderT d r)+ noteCases se ntc tc d = ReaderT $ \r -> noteCases se ntc tc (runReaderT d r)++instance MarkupMonad m => MarkupMonad (TaggedIdentityT t m) where+ withGraph dot = TaggedIdentityT . withGraph dot . unTaggedIdentityT+ withExplanation e = TaggedIdentityT . withExplanation e . unTaggedIdentityT+ theoremRef proto = lift . theoremRef proto+ theoremDef thm = TaggedIdentityT . theoremDef thm . unTaggedIdentityT+ keyword tag = TaggedIdentityT . keyword tag . unTaggedIdentityT + noteCases se ntc tc = TaggedIdentityT . noteCases se ntc tc . unTaggedIdentityT+++-- ISAR Pretty Printing+-----------------------++-- | Convert a triviality reason to a string representing the corresponding+-- Isabelle tactic.+isaTactic :: Sequent -> TrivReason -> String+isaTactic _ TrivContradictoryPremises = "((clarsimp, order?) | order)"+isaTactic _ (TrivLongTermKeySecrecy _) = "(fastsimp dest!: ltk_secrecy)"+isaTactic se TrivPremisesImplyConclusion = + case seConcl se of+ FAtom (AHasType _ Nothing) -> -- weakly atomic+ "(fastsimp simp: SumT_def KnownT_def dest!: state.extract_knows_hyps)"+ FAtom (AHasType _ (Just _)) -> + "(fastsimp intro: event_predOrdI split: if_splits)" + _ -> + "(fastsimp intro: event_predOrdI split: if_splits)" ++-- | Isabelle proof of long-term key secrecy.+isaLongTermKeySecrecyProof :: Protocol -> Doc+isaLongTermKeySecrecyProof p = vcat $ map text+ [ "text{* Prove secrecy of long-term keys. *}"+ , "context " ++ stateLocale p ++ " begin"+ , ""+ , " (* This rule is unsafe in general, but OK here, \n as we are only reasoning about static compromise. \n *)\n lemma static_longterm_key_reveal[dest!]:\n \"predOrd t (LKR a) e ==> RLKR a : reveals t\"\n by (auto intro: compr_predOrdI)\n\n lemma longterm_private_key_secrecy:\n assumes facts:\n \"SK m : knows t\"\n \"RLKR m ~: reveals t\"\n shows \"False\"\n using facts by (sources \"SK m\")\n\n lemma longterm_sym_ud_key_secrecy:\n assumes facts:\n \"K m1 m2 : knows t\"\n \"RLKR m1 ~: reveals t\"\n \"RLKR m2 ~: reveals t\"\n shows \"False\"\n using facts by (sources \"K m1 m2\")\n\n lemma longterm_sym_bd_key_secrecy:\n assumes facts:\n \"Kbd m1 m2 : knows t\"\n \"RLKR m1 ~: reveals t\"\n \"RLKR m2 ~: reveals t\"\n \"m1 : Agent\"\n \"m2 : Agent\"\n shows \"False\"\n proof -\n from facts \n have \"KShr (agents {m1, m2}) : knows t\"\n by (auto simp: Kbd_def)\n thus ?thesis using facts\n proof (sources \"KShr (agents {m1, m2})\")\n qed (auto simp: agents_def Agent_def)\n qed\n\n lemmas ltk_secrecy =\n longterm_sym_ud_key_secrecy\n longterm_sym_ud_key_secrecy[OF in_knows_predOrd1]\n longterm_sym_bd_key_secrecy\n longterm_sym_bd_key_secrecy[OF in_knows_predOrd1]\n longterm_private_key_secrecy\n longterm_private_key_secrecy[OF in_knows_predOrd1]"+ , ""+ , "end"+ ]++-- | Pretty print a sequent as an Isabelle proposition.+isaSequentProp :: MarkupMonad m => Sequent -> ReaderT IsarConf m Doc+isaSequentProp se = do+ conf <- ask+ ( (premTids, ppPremFacts, _), ppConcl ) <- prettySequentParts se+ let quantify q vs = case vs of + [] -> id+ _ -> ((q conf <> fsep vs <> char '.') $$) . nest 2+ doc | nullFacts (sePrem se) = ppConcl+ | otherwise = quantify isaMetaAll premTids . sep $+ [ fsep . (isaLBrack conf:) . map (nest 2) $ punctuate semi ppPremFacts+ , fsep [ isaRBrack conf <-> isaLongRightArrow conf , ppConcl ]+ ]+ pure doc++-- | Convert the name of the typing theorem to the name of the corresponding+-- locale.+typingLocale :: String -> String+typingLocale = (++ "_state")++-- | Pretty printing as an ISAR theory file is accomplished by using a reader+-- monad transformer with an ISAR output configuration as the environment.+instance MarkupMonad m => PrettyMonad (ReaderT IsarConf m) where+ -- components output+ prettyTID tid = isar <$> ask <*> pure tid+ prettyAgentId aid = isar <$> ask <*> pure aid+ prettyMessage m = isar <$> ask <*> pure m+ prettyFacts f = isaFacts <$> ask <*> pure f+ prettyFormula mapping form = do+ conf <- ask+ pure $ isaFormula conf mapping form+ -- case form of+ -- FFalse -> singleFact $ text "False"+ -- (FFacts facts) -> isaFacts <$> ask <*> pure moreRoleEqs <*> pure facts+ -- (FHasType lid Nothing) -> do+ -- conf <- ask+ -- singleFact $ text "weakly-atomic" <> parens (isar conf lid)+ -- (FHasType lid (Just ty)) -> do+ -- conf <- ask+ -- singleFact $ text "has-type" <> parens (isar conf lid <> comma <-> isar conf ty)+ -- FTyping Nothing -> singleFact $ text "weakly-atomic"+ -- FTyping (Just typing) -> do+ -- conf <- ask+ -- singleFact $ isar conf typing+ -- where+ -- singleFact f = return ([], [f], [])+ prettySequent se = do+ ( (_, ppPremFacts, _), ppConcl) <- prettySequentParts se+ let doc | nullFacts (sePrem se) = doubleQuotes ppConcl+ | otherwise =+ text "assumes facts:" $-$+ (nest 2 . vcat $ map doubleQuotes ppPremFacts) $-$+ sep [text "shows", nest 2 $ doubleQuotes ppConcl]+ pure doc+ -- proof output+ ensureProofMode (factsLoaded, proofMode) =+ (if proofMode then emptyDoc else text "thus ?thesis") <-> + (if factsLoaded then emptyDoc else text "using facts")++ withFactsMode (_, proofMode) doc+ | proofMode = vcat [kwProof <-> text "-", nest 2 doc, kwQED]+ | otherwise = doc++ prettyTrivial se reason = kwBy <-> text (isaTactic se reason)+ prettyMissing se reason =+ nestShort' "(*" "*)" (text reason $-$ prettySequent se) <-> text "oops"+ prettySaturate _ =+ text "note_prefix_closed facts = facts"++ prettyForwardContradiction thRef =+ kwBy <-> text "(fastsimp dest:" <-> thRef <-> text "intro: event_predOrdI)"+ prettyForwardResolution thRef thSe mapping+ | isJust . destTypingFormula . seConcl $ thSe = emptyDoc+ | otherwise = do+ conf <- ask+ let mappedPrems = applyMapping mapping $ sePrem thSe+ ppPrems = zip [1..] . map (isaAtom conf (eqsToMapping mappedPrems)) $ + toAtoms mappedPrems+ ppPremProve (i, premFact) = + text "have f" <> int i <> colon <-> doubleQuotes premFact <->+ text "using facts by (auto intro: event_predOrdI)"+ ppProven = pure . vcat $ map ppPremProve ppPrems+ ppResolve = + thRef <> text "[OF" <> (hcat $ map ((text " f" <>) . int . fst) ppPrems) <> + text ", simplified]"+ ppProven $-$+ kwNote <-> text ("facts = facts") <-> ppResolve++ prettyNextCase = kwNext+ prettyChainRuleSplitCases = return . fst . genericChainRuleSplitCases snd + prettyChainRuleApplication m =+ sep [ kwProof <> text "(sources! \"", nest 4 m <-> text "\")"]+ prettyChainRuleCase (name, newVars) =+ kwCase <-> selector <-> text "note_unified facts = this facts"+ where+ ppNewVar (Left tid) = prettyTID tid+ ppNewVar (Right aid) = prettyAgentId aid+ selector+ | any (`isPrefixOf` name) ["ik0", "fake"] || null newVars = text name+ | otherwise = parens $ text name <-> hsep (map ppNewVar newVars)+ prettyChainRuleQED _ trivCases+ | null tactics = kwQED <-> text "(insert facts, fastsimp+)?" -- be conservative+ | otherwise = + kwQED <-> text "(insert facts, (" <> hsep (intersperse (text "|") tactics) <> text ")+)?"+ where+ tactics = map (text . uncurry isaTactic) . nub . snd $ genericChainRuleSplitCases snd trivCases++ prettyTypeCheckInduction p typName typ = + ( kwProof <-> text "-" $$+ ( nest 2 $ vcat+ [ text "have" <-> doubleQuotes + (text "(t,r,s)" <-> (isaIn <$> ask) <-> text wellTypedStates)+ , kwProof <> text "(cases rule: reachable_in_approxI_ext"+ , text " [OF" <-> text monoTyp <> text ", completeness_cases_rule])" + ]+ )+ , nest 2+ , (nest 2 $ vcat+ [ kwQED+ , text "thus" <-> doubleQuotes (text typLocale <-> text "t r s") <->+ text "by unfold_locales auto" + ]+ ) $$ kwQED+ )+ where+ (wellTypedStates, monoTyp, typLocale) = case typ of+ WeaklyAtomic -> ("approx weakly_atomic", "monoTyp_weakly_atomic", weakAtomicityLocale p)+ Typing _ -> ("approx " ++ typName, typName ++ ".monoTyp", typingLocale typName)++ prettyTypingCase typName typ name se = + do kwCase <-> text ("("++ name ++" t r s") <-> prettyTID 0 <> text") note facts = this" $-$+ text ("then interpret state: "++ typLocale ++" t r s") $-$+ nest 2 (text "by unfold_locales auto") $-$+ text "show ?case using facts" + where+ typLocale = case typ of+ WeaklyAtomic -> weakAtomicityLocale (seProto se)+ Typing _ -> typingLocale typName++ -- equality splitting+ prettySplitEqCase name = + text "case" <-> text name <-> text "note_unified facts = this facts"++ prettySplitEqApplication eq =+ (fsep [ text "hence" <-> pure (doubleQuotes (isar defaultIsarConf (E.MsgEq eq)))+ , nest 2 $ text "by simp"+ , text "note facts = this facts" ]+ ) $-$+ (text "thus ?thesis proof(cases rule: Kbd_cases)")++ prettySplitEqQed = text "qed (fastsimp+)?"+ + -- theory output+ prettyComment comment = text "(*" <-> text comment <-> text "*)"+ prettyProtoDef proto axioms = + withGraph (dotProtocol proto) $+ (isar <$> ask <*> pure proto) $-$+ text "" $-$+ (text restrictedLocaleDecl) $-$+ (nest 2 . vcat . map ppAxiom $ axioms)+ where+ restrictedLocaleDecl = concat + [ "locale ", restrictedStateLocale proto, " = "++stateLocale proto+ , if null axioms then "" else " +" ]+ ppAxiom axiom = + text "assumes" <-> text (thmName axiom) <> colon $-$ + (nest 2 . doubleQuotes . isaSequentProp $ thmSequent axiom)++ prettyTheorem th@(name, prf) + | isAxiom th = emptyDoc+ | otherwise = case destTypingFormula (seConcl se) of + Just typ -> ppTypingLocale typ+ Nothing -> ppLemma+ where+ p = prfProto prf+ se = prfSequent prf+ ppPrf = prettyProof name (False, True) prf+ + -- pretty print a lemma+ ppLemma = ppProp $-$ ppPrf+ where+ locale = "(in " ++ restrictedStateLocale (seProto $ prfSequent prf) ++ ") "+ ppName = keyword "property" (text "lemma") <-> text (locale ++ name ++ ":")+ ppProp = withProofSequent prf $ + theoremDef th ppName $-$ nest 2 (prettySequent $ prfSequent prf)+ -- pretty print a typing locale definition + ppTypingLocale typ = do+ conf <- ask+ let (inv_name, inv_locale, inv_def) = case typ of + WeaklyAtomic -> weakAtomicityInfo+ Typing _ -> typingInfo conf+ vcat + [ keyword "property" (text "type_invariant") <-> + text inv_name <->+ text "for" <-> text (protoName p)+ , inv_def+ , text ""+ , keyword "property" (text "sublocale") <-> + text (stateLocale p) <-> isaSublocale conf <-> text inv_locale+ , ppPrf+ , text ""+ , pure $ isaLongTermKeySecrecyProof p+ ]+ where+ weakAtomicityInfo = + ( weakAtomicityInvariant p+ , weakAtomicityLocale p+ , text "where" <-> doubleQuotes (text (weakAtomicityLocale p) <-> + text "= weakly_atomic")+ )+ typingInfo conf =+ ( name+ , typingLocale name+ , text "where \"" <> text name <-> text "= mk_typing" $$+ nest 2 (pure $ isar conf typ) <> char '"'+ ) ++ prettyTheoryDef name body =+ text "theory" <-> doubleQuotes (text name) $-$+ text "imports" $-$+ nest 2 (vcat $ map (text . (++"\"") . ('"':)) imports) $-$+ text "begin" $-$ text "" $-$+ pure body $-$+ text "" $-$ text "end"+ where+ imports = ["../ESPLogic"]+++-- Slim Pretty Printing+-----------------------++-- | Phantom type marking slim output.+data SlimOutput = SlimOutput++-- | A slim output mode for better readability.+instance MarkupMonad m => PrettyMonad (TaggedIdentityT SlimOutput m) where+ -- components output+ prettyTID = pure . sptTID+ prettyAgentId = pure . sptAgentId+ prettyMessage = pure . sptMessage+ prettyFacts = pure . sptFacts + prettyFormula mapping form = pure $ sptFormula mapping form+ -- case form of+ -- FFalse -> singleFact $ text "False"+ -- FFacts facts -> pure $ sptFacts moreRoleEqs facts+ -- FHasType lid Nothing -> singleFact $ text "weakly-atomic" <> parens (sptLocalId lid)+ -- FHasType lid (Just ty) -> + -- singleFact $ text "hasType" <> parens (sptLocalId lid <> comma <-> sptType sptRoleStep ty)+ -- FTyping Nothing -> singleFact $ text "weakly-atomic"+ -- FTyping (Just typing) -> singleFact $ sptTyping typing+ -- where+ -- singleFact f = return ([], [f], [])+ prettySequent se = do+ ( (premQuantified, ppPremRepr, ppPremNonRepr), ppConclRaw) <- prettySequentParts se+ let ppPremFacts = ppPremRepr ++ ppPremNonRepr+ premQuantifier = pure $ case premQuantified of+ [] -> text "premises"+ _ -> text "for all" <-> fsep premQuantified <-> text "the premises"+ ppConcl = kwFact . pure $ doubleQuotes ppConclRaw+ doc | nullFacts (sePrem se) = ppConcl+ | otherwise =+ premQuantifier $-$+ (nest 2 . vcat $ map (kwFact . pure . doubleQuotes) ppPremFacts) $-$+ (sep [text "imply", nest 2 ppConcl])+ doc+ -- proof output+ ensureProofMode _ = emptyDoc+ withFactsMode _ = id+ prettyTrivial _ reason = case reason of+ TrivPremisesImplyConclusion -> text "tautology"+ TrivLongTermKeySecrecy key -> + text "contradicts secrecy of" <-> pure (sptMessage key)+ _ -> emptyDoc+ prettyMissing se reason = + nestShort' "(*" "*)" (text reason $-$ prettySequent se)+ prettySaturate _ = keyword "proof" $ text "saturate"+ prettyForwardContradiction thRef = text "contradictory due to '" <> thRef <> text "'"+ prettyForwardResolution thRef _ mapping = + keyword "proof" (text "resolve") <-> text "'" <> thRef <> ppMapping+ where+ ppMapping | null (E.toAnyEqs (E.getMappingEqs mapping)) = emptyDoc+ | otherwise = text "' mapping" <-> ppTidEqs+ ppTidEqs = pure . hsep . punctuate comma . map E.sptAnyEq . E.toAnyEqs $ + E.getMappingEqs mapping+ prettyNextCase = kwNext+ prettyChainRuleSplitCases = return . fst . genericChainRuleSplitCases snd + prettyChainRuleApplication m = + sep [ keyword "proof" (text "sources") <> lparen, + nest 4 (m <-> rparen)]+ prettyChainRuleCase (name, newVars) =+ kwCase <-> selector+ where+ ppNewVar (Left tid) = prettyTID tid+ ppNewVar (Right aid) = prettyAgentId aid+ selector+ | any (`isPrefixOf` name) ["ik0", "fake"] || null newVars = text name+ | otherwise = parens $ text name <-> hsep (map ppNewVar newVars)+ prettyChainRuleQED _ trivCases = case trivCases of+ [] -> kwQED+ _ -> kwQED <-> parens (int (length trivCases) <-> text "trivial")++ prettyTypeCheckInduction _ _ _ = (kwProof, id, kwQED)+ prettyTypingCase _ _ name _ = kwCase <-> text name++ -- equality splitting+ prettySplitEqCase name = text "case" <-> text name++ prettySplitEqApplication eq =+ sep [ keyword "proof" (text "split") <> lparen, + nest 4 (pure $ E.sptAnyEq (E.MsgEq eq) <-> rparen)]++ prettySplitEqQed = text "qed"+ + -- theory output+ prettyComment comment = text "/*" <-> text comment <-> text "*/"+ prettyProtoDef proto _ = withGraph (dotProtocol proto) (pure $ sptProtocol proto)++ -- | Pretty print a theorem.+ prettyTheorem th@(name, prf) =+ withProofSequent prf ppProp $-$ ppPrf+ where+ p = prfProto prf+ thmType | isAxiom th = "axiom" + | otherwise = "property"+ ppName = keyword "property" (text thmType) <-> + text ("(of "++protoName p++") "++name++":")+ ppProp = theoremDef th ppName $-$ nest 2 (prettySequent $ prfSequent prf)+ ppPrf = prettyProof name (False, True) prf++ prettyTheoryDef name body = vcat [+ keyword "theory" (text "theory") <-> text name <-> + keyword "theory" (text "begin")+ , text ""+ , pure body+ , text "" + , keyword "theory" (text "end") ]++kwFact :: (MarkupMonad m, Document d) => m d -> m d+kwFact = keyword "fact"++kwProof :: (MarkupMonad m, Document d) => m d+kwProof = keyword "proof" $ text "proof"++kwCase :: (MarkupMonad m, Document d) => m d+kwCase = keyword "proof" $ text "case"++kwNext :: (MarkupMonad m, Document d) => m d+kwNext = keyword "proof" $ text "next"++kwQED :: (MarkupMonad m, Document d) => m d+kwQED = keyword "proof" $ text "qed"++kwBy :: (MarkupMonad m, Document d) => m d+kwBy = keyword "proof" $ text "by"++kwNote :: (MarkupMonad m, Document d) => m d+kwNote = keyword "proof" $ text "note"++------------------------------------------------------------------------------+-- ISAR Output+------------------------------------------------------------------------------++{-+instance Isar Sequent where+ isar conf se = runReader (prettySequent se) conf+instance Isar Proof where+ isar conf prf = runReader (prettyProof "" (False, True) prf) conf+ +-- instance Isar Theorem where+ -- isar conf thm = runReader (prettyTheorem thm Nothing) conf++instance Isar ThyItem where+ isar conf item = runReader (prettyThyItem [] item) conf++instance Isar Theory where+ isar conf thy = runReader (prettyTheory thy) conf+-}
@@ -0,0 +1,186 @@+{-# LANGUAGE TypeSynonymInstances, DeriveDataTypeable #-}+-- | Building typing invariants for security protocol in order to enable+-- verification in an untyped model.+module Scyther.Typing (+ -- * Data types+ Type(..)+ , Typing(..)++ -- ** Construction typings+ , mscTyping++ -- ** Pretty Printing+ , isaType+ , isaOptType+ , sptType+ , sptOptType+ , sptTyping+) where++import qualified Data.Set as S+import qualified Data.Map as M+import Data.DAG.Simple+import Data.Data++import Control.Basics+import Control.Monad.State++import Scyther.Protocol+import Scyther.Message+import qualified Scyther.Equalities as E+import Text.Isar+++data Type =+ AgentT + | ConstT Id+ | NonceT Role Id+ | HashT Type+ | EncT Type Type+ | TupT Type Type+ | SymKT Type Type+ | AsymPKT Type+ | AsymSKT Type+ | KnownT RoleStep+ | SumT Type Type+ deriving( Eq, Ord, Show, Data, Typeable )++-- | A type assignment for variables of several roles.+data Typing = + WeaklyAtomic+ | Typing (M.Map (Id, Role) Type)+ deriving( Eq, Ord, Show, Data, Typeable )++-- | Compute a typing from the message sequence chart of the protocol+-- implicitly given by the corresponding labels.+--+-- FIXME: This is quite a hack and could be done much better: do it!+mscTyping :: Protocol -> Maybe Typing+mscTyping proto = + fmap Typing $ (`execStateT` M.empty) $ foldM typeStep E.empty steps+ where+ roleeqs = M.fromList $ zip [1..] (protoRoles proto)+ rolemap = M.fromList $ zip (protoRoles proto) [1..]+ steps = map (second (rolemap M.!)) . toposort $ protoOrd proto++ typeStep eqs (Send _ _, _) = do+ return eqs+ typeStep eqs (recv@(Recv lR ptR), tidR) =+ case [ send | send@(Send lS _, _) <- steps, lS == lR ] of+ [] -> do+ -- no matching send: assume intruder knows all message variables+ -- in the received pattern that are not yet mapped.+ sequence_ $ do PMVar v <- S.toList $ subpatterns ptR+ return (knownAtRecv v)+ return eqs+ ((Send _ ptS, tidS):_) -> do+ eqs' <- lift $ E.solve [E.MsgEq (inst tidR ptR, inst tidS ptS)] eqs+ mapM_ typeMVar (E.getMVarEqs eqs')+ -- variables not mapped yet are mapped to they known type.+ sequence_ $ do PMVar v <- S.toList $ subpatterns ptR+ return (knownAtRecv v)+ return eqs'+ _ -> error "mscTyping: the impossible happened"+ where+ typeMVar (MVar (LocalId (v, vTid)), m) + | vTid == tidR && PMVar v `S.member` splitpatterns ptR =+ noteType (KnownT recv)+ | otherwise = + noteType $ maybe (KnownT recv) (SumT (KnownT recv)) (typeMsg m)+ where+ noteType = modify . M.insertWith keepSimpler (v, roleeqs M.! vTid)+ -- prefer non-sum-types and then the existing one+ keepSimpler _ x@(KnownT _) = x+ keepSimpler x@(KnownT _) _ = x+ keepSimpler _ x = x++ knownAtRecv v = + modify (M.insertWith keepExisting (v, roleeqs M.! tidR) (KnownT recv))+ where+ keepExisting _new old = old+ + typeMsg (MFresh (Fresh fr)) = pure $ NonceT (roleeqs M.! lidTID fr) (lidId fr)+ typeMsg (MConst c) = pure $ ConstT c+ typeMsg (MAVar _) = pure $ AgentT+ typeMsg (MMVar _) = Nothing+ typeMsg (MHash m) = HashT <$> typeMsg m+ typeMsg (MTup m1 m2) = TupT <$> typeMsg m1 <*> typeMsg m2+ typeMsg (MEnc m1 m2) = EncT <$> typeMsg m1 <*> typeMsg m2+ typeMsg (MSymK m1 m2) = SymKT <$> typeMsg m1 <*> typeMsg m2+ typeMsg (MAsymPK m) = AsymPKT <$> typeMsg m+ typeMsg (MAsymSK m) = AsymSKT <$> typeMsg m+ typeMsg (MAgent _) = error $ "mscTyping: agent variable encountered"+ typeMsg (MInvKey _) = error $ "mscTyping: key inversion encountered"+ typeMsg (MShrK _ _) = error $ "mscTyping: bi-directional shared key encountered"++-- | Pretty print a type in Isar syntax; paramatrized over the role of the+-- variable that this type describes. This role is used for abbreviating role+-- steps by the 'role_label' constant symbols defined in Isabelle.+isaType :: IsarConf -> Maybe Role -> Type -> Doc+isaType conf optRole = go+ where+ go ty = case ty of+ AgentT -> text "AgentT"+ ConstT i -> parens $ text "ConstT" <-> isar conf i+ NonceT role i -> parens $ text "NonceT" <-> text (roleName role) <-> isar conf i+ HashT ty1 -> parens $ text "HashT" <-> go ty1+ EncT ty1 ty2 -> parens $ text "EncT" <-> go ty1 <-> go ty2+ TupT ty1 ty2 -> parens $ text "TupT" <-> go ty1 <-> go ty2+ AsymPKT ty1 -> parens $ text "PKT" <-> go ty1+ AsymSKT ty1 -> parens $ text "SKT" <-> go ty1+ SymKT ty1 ty2 -> parens $ text "KT" <-> go ty1 <-> go ty2+ KnownT step -> parens $ text "KnownT" <-> isaRoleStep conf optRole step+ SumT ty1 ty2 -> parens $ text "SumT" <-> go ty1 <-> go ty2++-- | Pretty print a type that may be a weak atomicity type.+isaOptType :: IsarConf -> Maybe Role -> Maybe Type -> Doc+isaOptType _ _ Nothing = text "weakly_atomic"+isaOptType conf optRole (Just ty) = isaType conf optRole ty++-- | Pretty print a type in security protocol theory format. If the role is+-- given then the type describes a variable of this role. The steps of this+-- role are abbreviated accordingly.+sptType :: Maybe Role -> Type -> Doc+sptType optRole = go+ where+ go ty = case ty of+ AgentT -> text "Agent"+ ConstT i -> text $ "'" ++ getId i ++ "'"+ NonceT role i -> text $ getId i ++ "@" ++ roleName role+ HashT ty1 -> text "h" <> parens (go ty1)+ EncT ty1 ty2 -> braces (go ty1) <> go ty2+ TupT ty1 ty2 -> parens (go ty1 <> comma <-> go ty2)+ AsymPKT ty1 -> text "pk" <> parens (go ty1)+ AsymSKT ty1 -> text "sk" <> parens (go ty1)+ SymKT ty1 ty2 -> text "k" <> parens (go ty1 <> comma <-> go ty2)+ KnownT step -> text "Known@" <> sptRoleStep optRole step+ SumT ty1 ty2 -> sep [parens (go ty1) <-> text "|", parens (go ty2)]++-- | Pretty print a type that may be a weak atomicity type in the security+-- protocol theory format.+sptOptType :: Maybe Role -> Maybe Type -> Doc+sptOptType _ Nothing = text "weakly-atomic"+sptOptType optRole (Just ty) = sptType optRole ty+++sptTyping :: Typing -> Doc+sptTyping WeaklyAtomic = text "weakly-atomic"+sptTyping (Typing typ) = vcat . map ppTyEq . M.toList $ typ+ where+ ppTyEq ((v,role),ty) = + sep [ text $ getId v ++ "@" ++ roleName role+ , nest 2 $ text "::" <-> sptType (Just role) ty ]++instance Isar Type where+ isar conf = isaType conf Nothing++instance Isar Typing where+ isar _ WeaklyAtomic = text "weakly-atomic"+ isar conf (Typing typ) = + ($$ rbrack) . vcat . zipWith (<->) seps . map ppTyEq . M.toList $ typ+ where+ seps = map char $ '[' : repeat ','+ ppTyEq ((v,role),ty) = parens $+ sep [ parens (text (roleName role) <> comma <-> isar conf v) <> comma+ , isaType conf (Just role) ty ]+
@@ -0,0 +1,121 @@+-- | Using Isabelle to check theory files.+--+-- Requirements:+--+-- 1. A working installation of Isabelle2009-1 (http://isabelle.in.tum.de/)+-- 2. The \'isabelle\' command must be on the PATH.+--+module System.Isabelle (+ checkTheoryFile+) where++import Data.Maybe+import Data.List++import System.FilePath+import System.Directory+import System.Process+import System.IO++import Control.Concurrent+import Control.Monad+import Control.Exception++------------------------------------------------------------------------------+-- Utilities: TODO MOVE INTO GENERAL FILE+------------------------------------------------------------------------------++-- | Create and use a temporary file ensuring that it is closed if the+-- computation fails.+--+-- See 'openTempFile' for more information on the parameters.+withTempFile :: FilePath -> String -> ((FilePath, Handle) -> IO a) -> IO (a, FilePath)+withTempFile dir nameTemplate io = + bracket (openTempFile dir nameTemplate) (hClose . snd) + (\args@(file,_) -> do{ x <- io args; return (x, file) })++-- | Like 'withTempFile' buth without returning the results of the inner+-- computation.+withTempFile_ :: FilePath -> String -> ((FilePath, Handle) -> IO a) -> IO FilePath+withTempFile_ dir nameTemplate io = snd `liftM` withTempFile dir nameTemplate io++-- | Waits the given amount of microseconds before trying to terminate the+-- process using 'terminateProcess'.+waitForProcessTimeout :: Int -> ProcessHandle -> IO Bool+waitForProcessTimeout maxTime hProc+ | maxTime <= 0 = do _<- waitForProcess hProc; return False+ | otherwise = do+ timeout <- newMVar False+ _ <- forkIO $ do+ threadDelay maxTime+ modifyMVar_ timeout (return . const True)+ terminateProcess hProc+ _ <- waitForProcess hProc+ readMVar timeout+ ++------------------------------------------------------------------------------+-- Isabelle commands+------------------------------------------------------------------------------++-- | Use Isabelle to check the correctness of a theory file.+checkTheoryFile :: FilePath -- ^ Path to 'isabelle' binary.+ -> Maybe Int -- ^ Number of parallel thread to use while checking.+ -> Int -- ^ Maximal available time in micro-seconds+ -> String -- ^ Logic Image to use+ -> FilePath -- ^ Path to file to be checked+ -> IO (IO String, Maybe String)+ -- ^ If the check went through, log-file content only, otherwise+ -- also an error message.+checkTheoryFile isabelleTool threads maxTime logic thyFile = do+ let thyName = takeBaseName thyFile+ rootName = "ROOT-" ++ thyName ++ ".ML"+ sessionName = "scyther-proof-" ++ thyName+ -- create ROOT.ML file+ tmpDir <- getTemporaryDirectory+ rootFile <- withTempFile_ tmpDir rootName + (\(_, hRootFile) -> + hPutStrLn hRootFile $ "use_thy \"" ++ dropExtension thyFile ++ "\""+ )+ -- call "isabelle usedir"+ finally + (do let cmd = isabelleTool ++ + " usedir -f " ++ rootFile ++ + " -s " ++ sessionName ++ + " -M " ++ maybe "0" show threads +++ " " ++ logic ++ " ."+ (_, _, hErr, hProc) <- runInteractiveCommand cmd+ isaOutVar <- newEmptyMVar+ _ <-forkIO $ redirect hErr isaOutVar+ timeout <- waitForProcessTimeout maxTime hProc+ isaOut <- takeMVar isaOutVar+ if timeout+ then do return (return $ isaOut ++ "Interrupted due to timeout!"+ , Just $ "timeout: " ++ + show ((fromIntegral maxTime / 10E6)::Double) ++ "s")+ else do return $ parseIsaOutput sessionName isaOut+ )+ (do removeFile rootFile)+ where+ -- | Redirect the contents of a the given handle into the message variable.+ redirect hIn mvar = hGetContents hIn >>= putMVar mvar++ -- | extract the log file name from the isabelle output+ logFileName str = fromMaybe "no log file" $ do+ let logIndicator = "(see also "+ line <- find (logIndicator `isPrefixOf`) (lines str) + init `liftM` stripPrefix logIndicator line+ + -- | Extract the error message from the isabelle output+ errMsg str = case break ("***" `isPrefixOf`) (lines str) of+ (_,[]) -> str+ (_,first:ls) -> case break ("***" `isPrefixOf`) ls of+ (_,[]) -> unlines (first : ls)+ (ls',(fin:_)) -> unlines (first : ls'++[fin])++ -- | Parse the Isabelle output.+ parseIsaOutput sessionName str+ | ("Finished "++logic++"-"++sessionName) `isInfixOf` str = (return str, Nothing)+ | otherwise = (readFile (logFileName str), Just (errMsg str))++
@@ -0,0 +1,20 @@+-- | A simple module for timing IO action.+module System.Timing (+ timed+ , timed_+) where++import Control.Monad+import Data.Time.Clock++-- | Execute an IO action and return its result plus the time it took to execute it.+timed :: IO a -> IO (a, NominalDiffTime)+timed io = do+ t0 <- getCurrentTime+ x <- io+ t1 <- getCurrentTime+ return (x, diffUTCTime t1 t0)++-- | Execute an IO action and return the time it took to execute it.+timed_ :: IO a -> IO NominalDiffTime+timed_ = (snd `liftM`) . timed
@@ -0,0 +1,274 @@+-- |+-- Module: Text.Dot+-- Copyright: Andy Gill+-- License: BSD3+--+-- Maintainer: Andy Gill <andygill@ku.edu>+-- Stability: unstable+-- Portability: portable+--+-- This module provides a simple interface for building .dot graph files, for input into the dot and graphviz tools. +-- It includes a monadic interface for building graphs.++module Text.Dot + ( + -- * Dot+ Dot -- abstract+ -- * Nodes+ , node+ , NodeId -- abstract+ , userNodeId+ , userNode+ -- * Edges+ , edge+ -- * Showing a graph+ , showDot+ -- * Other combinators+ , scope+ , attribute+ , nodeAttributes+ , edgeAttributes+ , graphAttributes+ , share+ , same+ , cluster+ -- * Record specification+ , Record -- abstract+ , field+ , portField+ , hcat+ , hcat'+ , vcat+ , vcat'+ -- * Record node construction+ , record+ , record'+ , record_+ + , mrecord+ , mrecord'+ , mrecord_+ ) where++import Data.List (intersperse)+import Control.Monad (liftM)++data NodeId = NodeId String+ | UserNodeId Int++instance Show NodeId where+ show (NodeId str) = str+ show (UserNodeId i) + | i < 0 = "u_" ++ show (negate i)+ | otherwise = "u" ++ show i++data GraphElement = GraphAttribute String String+ | GraphNode NodeId [(String,String)]+ | GraphEdge NodeId NodeId [(String,String)]+ | Scope [GraphElement]+ | SubGraph NodeId [GraphElement]++data Dot a = Dot { unDot :: Int -> ([GraphElement],Int,a) }++instance Monad Dot where+ return a = Dot $ \ uq -> ([],uq,a)+ m >>= k = Dot $ \ uq -> case unDot m uq of+ (g1,uq',r) -> case unDot (k r) uq' of+ (g2,uq2,r2) -> (g1 ++ g2,uq2,r2)++-- | 'node' takes a list of attributes, generates a new node, and gives a 'NodeId'.+node :: [(String,String)] -> Dot NodeId+node attrs = Dot $ \ uq -> let nid = NodeId $ "n" ++ show uq + in ( [ GraphNode nid attrs ],succ uq,nid)+++-- | 'userNodeId' allows a user to use their own (Int-based) node id's, without needing to remap them.+userNodeId :: Int -> NodeId+userNodeId i = UserNodeId i++-- | 'userNode' takes a NodeId, and adds some attributes to that node. +userNode :: NodeId -> [(String,String)] -> Dot ()+userNode nId attrs = Dot $ \ uq -> ( [GraphNode nId attrs ],uq,())++-- | 'edge' generates an edge between two 'NodeId's, with attributes.+edge :: NodeId -> NodeId -> [(String,String)] -> Dot ()+edge from to attrs = Dot (\ uq -> ( [ GraphEdge from to attrs ],uq,()))++-- | 'scope' groups a subgraph together; in dot these are the subgraphs inside "{" and "}".+scope :: Dot a -> Dot a+scope (Dot fn) = Dot (\ uq -> case fn uq of+ ( elems,uq',a) -> ([Scope elems],uq',a))++-- | 'share' is when a set of nodes share specific attributes. Usually used for layout tweaking.+share :: [(String,String)] -> [NodeId] -> Dot ()+share attrs nodeids = Dot $ \ uq -> + ( [ Scope ( [ GraphAttribute name val | (name,val) <- attrs]+ ++ [ GraphNode nodeid [] | nodeid <- nodeids ]+ ) + ], uq, ())++-- | 'same' provides a combinator for a common pattern; a set of 'NodeId's with the same rank.+same :: [NodeId] -> Dot ()+same = share [("rank","same")]+++-- | 'cluster' builds an explicit, internally named subgraph (called cluster). +cluster :: Dot a -> Dot (NodeId,a)+cluster (Dot fn) = Dot (\ uq -> + let cid = NodeId $ "cluster_" ++ show uq + in case fn (succ uq) of+ (elems,uq',a) -> ([SubGraph cid elems],uq',(cid,a)))++-- | 'attribute' gives a attribute to the current scope.+attribute :: (String,String) -> Dot ()+attribute (name,val) = Dot (\ uq -> ( [ GraphAttribute name val ],uq,()))++-- | 'nodeAttributes' sets attributes for all the following nodes in the scope.+nodeAttributes :: [(String,String)] -> Dot ()+nodeAttributes attrs = Dot (\uq -> ([ GraphNode (NodeId "node") attrs],uq,()))++-- | 'edgeAttributes' sets attributes for all the following edges in the scope.+edgeAttributes :: [(String,String)] -> Dot ()+edgeAttributes attrs = Dot (\uq -> ([ GraphNode (NodeId "edge") attrs],uq,()))++-- | 'graphAttributes' sets attributes for current graph.+graphAttributes :: [(String,String)] -> Dot ()+graphAttributes attrs = Dot (\uq -> ([ GraphNode (NodeId "graph") attrs],uq,()))+++-- 'showDot' renders a dot graph as a 'String'.+showDot :: Dot a -> String+showDot (Dot dm) = case dm 0 of+ (elems,_,_) -> "digraph G {\n" ++ unlines (map showGraphElement elems) ++ "\n}\n"++showGraphElement :: GraphElement -> String+showGraphElement (GraphAttribute name val) = showAttr (name,val) ++ ";"+showGraphElement (GraphNode nid attrs) = show nid ++ showAttrs attrs ++ ";"+showGraphElement (GraphEdge from to attrs) = show from ++ " -> " ++ show to ++ showAttrs attrs ++ ";"+showGraphElement (Scope elems) = "{\n" ++ unlines (map showGraphElement elems) ++ "\n}"+showGraphElement (SubGraph nid elems) = "subgraph " ++ show nid ++ " {\n" ++ unlines (map showGraphElement elems) ++ "\n}"++showAttrs :: [(String, String)] -> String+showAttrs [] = ""+showAttrs xs = "[" ++ showAttrs' xs ++ "]"+ where+ -- never empty list+ showAttrs' [a] = showAttr a+ showAttrs' (a:as) = showAttr a ++ "," ++ showAttrs' as+ showAttrs' [] = error "showAttrs: the impossible happended"++showAttr :: (String, String) -> String+showAttr (name,val) = name ++ "=\"" ++ concatMap escape val ++ "\""+ where escape '\n' = "\\l"+ escape '"' = "\\\""+ escape c = [c]+++------------------------------------------------------------------------------+-- Records+------------------------------------------------------------------------------++-- | Specifies the construction of a record; i.e., mentions all fields possibly+-- together with ports and their horizontal and vertical nesting. (see: record+-- shapes in the DOT documentation.)+data Record a =+ Field (Maybe a) String+ | HCat [Record a]+ | VCat [Record a]+ deriving( Eq, Ord, Show )++-- | A simple field of a record.+field :: String -> Record a+field = Field Nothing++-- | A field together with a port which can be used to create direct edges to+-- this field. Note that you can use any type to identify the ports. When+-- creating a record node you will get back an association list between your+-- record identifiers and their concrete node ids.+portField :: a -> String -> Record a+portField port = Field (Just port)++-- | Concatenate records horizontally.+hcat :: [Record a] -> Record a+hcat = HCat++-- | Concatenate a list strings interpreted as simple fields horizontally.+hcat' :: [String] -> Record a+hcat' = hcat . map field++-- | Concatenate records vertically.+vcat :: [Record a] -> Record a+vcat = VCat++-- | Concatenate a list strings interpreted as simple fields vertically.+vcat' :: [String] -> Record a+vcat' = vcat . map field++-- | Render a record in the Dot monad. It exploits the internal counter in+-- order to generate unique port-ids. However, they must be combined with the+-- actual node id of the node with the record shape. Thus the returned+-- association list is parametrized over this missing node id.+renderRecord :: Record a -> Dot (String, NodeId -> [(a,NodeId)])+renderRecord = render True+ where+ render _ (Field Nothing l) = return (escape l, const [])+ render _ (Field (Just p) l) = + Dot $ \uq -> let pid = "n" ++ show uq+ lbl = "<"++pid++"> "++escape l+ in ([], succ uq, (lbl, \nId -> [(p,NodeId (show nId++":"++pid))]))+ render horiz (HCat rs) = do+ (lbls, ids) <- liftM unzip $ mapM (render True) rs+ let rawLbl = concat (intersperse "|" lbls)+ lbl = if horiz then "{{"++rawLbl++"}}" else "{"++rawLbl++"}"+ return (lbl, \nId -> concatMap (\i -> i nId) ids)+ render horiz (VCat rs) = do+ (lbls, ids) <- liftM unzip $ mapM (render False) rs+ let rawLbl = concat (intersperse "|" lbls)+ lbl = if horiz then "{"++rawLbl++"}" else "{{"++rawLbl++"}}"+ return (lbl, \nId -> concatMap (\i -> i nId) ids)+ -- escape chars used for record label construction+ escape = concatMap esc+ esc '|' = "\\|"+ esc '{' = "\\{"+ esc '}' = "\\}"+ esc '<' = "\\<"+ esc '>' = "\\>"+ esc c = [c]++-- | A generic version of record creation.+genRecord :: String -> Record a -> [(String,String)] -> Dot (NodeId, [(a,NodeId)])+genRecord shape rec attrs = do+ (lbl, ids) <- renderRecord rec+ i <- node ([("shape",shape),("label",lbl)] ++ attrs)+ return (i, ids i)++-- | Create a record node with the given attributes. It returns the node-id of+-- the created node together with an association list mapping the port+-- idenfiers given in the record to their corresponding node-ids. This list is+-- ordered according to a left-to-rigth traversal of the record description.+record :: Record a -> [(String,String)] -> Dot (NodeId, [(a,NodeId)])+record = genRecord "record"++-- | A variant of "record" ignoring the port identifiers.+record' :: Record a -> [(String,String)] -> Dot (NodeId, [NodeId])+record' rec attrs = do (nId, ids) <- record rec attrs+ return (nId, map snd ids)++-- | A variant of "record" ignoring the port to node-id association list.+record_ :: Record a -> [(String,String)] -> Dot NodeId+record_ rec attrs = liftM fst $ record rec attrs++-- | Like "record", but creates record nodes with rounded corners; i.e. uses+-- the \"Mrecord\" shape instead of the \"record\" shape.+mrecord :: Record a -> [(String,String)] -> Dot (NodeId, [(a,NodeId)])+mrecord = genRecord "Mrecord"++-- | A variant of "mrecord" ignoring the port identifiers.+mrecord' :: Record a -> [(String,String)] -> Dot (NodeId, [NodeId])+mrecord' rec attrs = do (nId, ids) <- mrecord rec attrs+ return (nId, map snd ids)++-- | A variant of "mrecord" ignoring the port to node-id association list.+mrecord_ :: Record a -> [(String,String)] -> Dot NodeId+mrecord_ rec attrs = liftM fst $ mrecord rec attrs+
@@ -0,0 +1,312 @@+-- | Generating Isabelle/ISAR theory files using 'Text.PrettyPrint'.+module Text.Isar (+ -- * ISAR Output+ Isar(..)+ -- ** Configuration+ , IsarStyle(..)+ , IsarConf(..)+ , defaultIsarConf+ , isPlainStyle+ , isarPlain+ , isarXSymbol++ -- ** Constructions of our security protocol verification theory+ , isaExecutionSystemState++ -- ** Special Symbols+ , isarightArrow+ , isaLongRightArrow+ , isaLParr+ , isaRParr+ , isaLBrack+ , isaRBrack+ , isaMetaAll+ , isaExists+ , isaAnd+ , isaNotIn+ , isaIn+ , isaSubsetEq+ , isaAlpha+ , isaSublocale++ -- * Extensions of 'Text.PrettyPrint'+ , module Text.PrettyPrint.Class+ , nestBetween+ , nestShort+ , nestShort'+ , nestShortNonEmpty+ , nestShortNonEmpty'+ , fixedWidthText+ , symbol+ , numbered+ , numbered'++) where++import Data.List++import Extension.Prelude++import Text.PrettyPrint.Class++-- | The ISAR style to be used for output.+data IsarStyle = + PlainText + | XSymbol+ deriving( Eq, Show )++-- | The configuration to be used for output. Apart from the ISAR style, the+-- configuration also stores the representation of the reachable state of the+-- protocol which we are reasoning about. +data IsarConf = IsarConf {+ isarStyle :: IsarStyle+ , isarTrace :: Doc -- ^ The ISAR code of the trace+ , isarPool :: Doc -- ^ The ISAR code of the thread pool+ , isarSubst :: Doc -- ^ The ISAR code of the substitution+ }+ deriving( Show )++-- | Default configuration: plaintext ISAR style and reachable state @(t,r,s)@.+defaultIsarConf :: IsarConf+defaultIsarConf = IsarConf PlainText (char 't') (char 'r') (char 's') ++-- | Check if the plaintext style was chosen.+isPlainStyle :: IsarConf -> Bool+isPlainStyle = (PlainText ==) . isarStyle+++-- | Values that can be output as ISAR code. +--+-- Minimal definition: 'isar'+class Isar a where+ isar :: IsarConf -> a -> Doc++-- | Output as ISAR code using 'defaultIsarConf'.+isarPlain :: Isar a => a -> Doc+isarPlain = isar defaultIsarConf++-- | Output as ISAR code using 'defaultIsarConf'+-- with the XSymbol style.+isarXSymbol :: Isar a => a -> Doc+isarXSymbol = isar (defaultIsarConf { isarStyle = XSymbol })++------------------------------------------------------------------------------+-- General pretty printing combinators+------------------------------------------------------------------------------++-- | Nest a document surrounded by a leading and a finishing document breaking+-- lead, body, and finish onto separate lines, if they don't fit on a single+-- line.+nestBetween :: Document d =>+ Int -- ^ Indent of body+ -> d -- ^ Leading document+ -> d -- ^ Finishing document+ -> d -- ^ Body document+ -> d+nestBetween n l r x = sep [l, nest n x, r]++-- | Nest a document surrounded by a leading and a finishing document with an+-- non-compulsory break between lead and body.+nestShort :: Document d =>+ Int -- ^ Indent of body+ -> d -- ^ Leading document+ -> d -- ^ Finishing document+ -> d -- ^ Body document+ -> d+nestShort n lead finish body = sep [lead $$ nest n body, finish]++-- | Nest document between two strings and indent body by @length lead + 1@.+nestShort' :: Document d => String -> String -> d -> d+nestShort' lead finish = + nestShort (length lead + 1) (text lead) (text finish)++-- | Like 'nestShort' but doesn't print the lead and finish, if the document is+-- empty.+nestShortNonEmpty :: Document d => Int -> d -> d -> d -> d+nestShortNonEmpty n lead finish body =+ caseEmptyDoc emptyDoc (nestShort n lead finish body) body++-- | Like 'nestShort'' but doesn't print the lead and finish, if the document is+-- empty.+nestShortNonEmpty' :: Document d => String -> String -> d -> d+nestShortNonEmpty' lead finish = + nestShortNonEmpty (length lead + 1) (text lead) (text finish)++-- | Output text with a fixed width: if it is smaller then nothing happens,+-- otherwise care is taken to make the text appear having the given width.+fixedWidthText :: Document d => Int -> String -> d+fixedWidthText n cs+ | length cs <= n = text cs+ | otherwise = text as <> zeroWidthText bs+ where + (as,bs) = splitAt n cs++-- | Print string as symbol having width 1.+symbol :: Document d => String -> d+symbol = fixedWidthText 1++-- | Number a list of documents that are vertically separated by the given+-- separator.+numbered :: Document d => d -> [d] -> d+numbered _ [] = emptyDoc+numbered vsep ds = + foldr1 ($-$) $ intersperse vsep $ map pp $ zip [(1::Int)..] ds+ where+ n = length ds+ nWidth = length (show n)+ pp (i, d) = text (flushRight nWidth (show i)) <> d+ +-- | Number a list of documents with numbers terminated by "." and vertically+-- separate using an empty line.+numbered' :: Document d => [d] -> d+numbered' = numbered (text "") . map (text ". " <>)+++------------------------------------------------------------------------------+-- Operational Semantics Constructions+------------------------------------------------------------------------------++-- | Isabelle representation of the exeuction system state of our operational+-- semantics.+isaExecutionSystemState :: IsarConf -> Doc+isaExecutionSystemState conf = + parens . hcat . punctuate comma $ + [isarTrace conf, isarPool conf, isarSubst conf]+++------------------------------------------------------------------------------+-- Isabelle symbols in both styles.+------------------------------------------------------------------------------++-- | A 'not in' symbol: @~:@+isaNotIn :: Document d => IsarConf -> d+isaNotIn conf+ | isPlainStyle conf = text "~:"+ | otherwise = symbol "\\<notin>"++-- | An 'in' symbol: @:@+isaIn :: Document d => IsarConf -> d+isaIn conf+ | isPlainStyle conf = text ":"+ | otherwise = symbol "\\<in>"++-- | A left parenthesis with an additional vertical line: @(|@+isaLParr :: Document d => IsarConf -> d+isaLParr conf+ | isPlainStyle conf = text "(|"+ | otherwise = symbol "\\<lparr>"++-- | A right parenthesis with an additional vertical line: @|)@+isaRParr :: Document d => IsarConf -> d+isaRParr conf+ | isPlainStyle conf = text "|)"+ | otherwise = symbol "\\<rparr>"++-- | A left bracket with an additional vertical line: @[|@+isaLBrack :: Document d => IsarConf -> d+isaLBrack conf+ | isPlainStyle conf = text "[|"+ | otherwise = symbol "\\<lbrakk>"++-- | A right bracket with an additional vertical line: @|]@+isaRBrack :: Document d => IsarConf -> d+isaRBrack conf+ | isPlainStyle conf = text "|]"+ | otherwise = symbol "\\<rbrakk>"++-- | A short right arrow: @->@+isarightArrow :: Document d => IsarConf -> d+isarightArrow conf+ | isPlainStyle conf = text "->"+ | otherwise = fixedWidthText 2 "\\<rightarrow>"++-- | A long double right arrow: @==>@+isaLongRightArrow :: Document d => IsarConf -> d+isaLongRightArrow conf+ | isPlainStyle conf = text "==>"+ | otherwise = fixedWidthText 3 "\\<Longrightarrow>"+++-- | The greek letter alpha: @\\<alpha>@+isaAlpha :: Document d => IsarConf -> d+isaAlpha conf+ | isPlainStyle conf = text "\\<alpha>"+ | otherwise = symbol "\\<alpha>"++-- | The meta all quantifier: @!!@+isaMetaAll :: Document d => IsarConf -> d+isaMetaAll conf+ | isPlainStyle conf = text "!! "+ | otherwise = symbol "\\<And>"++-- | The exists symbol: @?@+isaExists :: Document d => IsarConf -> d+isaExists conf+ | isPlainStyle conf = text "? "+ | otherwise = symbol "\\<exists>"++-- | The logical and symbol: @&@+isaAnd :: Document d => IsarConf -> d+isaAnd conf+ | isPlainStyle conf = text "&"+ | otherwise = symbol "\\<and>"++-- | The non-strict subset symbol.+isaSubsetEq :: Document d => IsarConf -> d+isaSubsetEq conf+ | isPlainStyle conf = text "<="+ | otherwise = symbol "\\<subseteq>"++-- | The sublocale sign.+isaSublocale :: Document d => IsarConf -> d+isaSublocale conf+ | isPlainStyle conf = text "<"+ | otherwise = symbol "\\<subseteq>"++------------------------------------------------------------------------------+-- Isabelle theory components+------------------------------------------------------------------------------++{- TODO: Finish, if it is used++isaTheory :: Document d =>+ String -- ^ Theory name+ -> [String] -- ^ Imported theories+ -> d -- ^ Theory body+ -> d -- ^ The complete theory statement.+isaTheory name imports body =+ text "theory" <-> text name $-$+ text "imports" $-$+ nest 2 (vcat $ map (text . (++"\"") . ('"':)) imports) $-$+ text "begin" $-$ text "" $-$+ body $-$+ text "" $-$ text "end"+++-- | An logic identifier; properly escaped if needed.+-- TODO: Add escaping+logicIdent :: String -> Doc+logicIdent = text+++-- | A generic text command.+genTextCmd :: String -> String -> Doc+genTextCmd name content = + sep [text name <> text "{*", nest 2 (fsep . map text $ words content), text "*}"]++chapter = genTextCmd "chapter"+section = genTextCmd "section"+subsection = genTextCmd "subsection"+subsubsection = genTextCmd "subsubsection"+paragraph = genTextCmd "text"++-- | A comment.+comment :: String -> Doc+comment content = nestShort' "(*" "*)" (fsep $ map text $ words content)++-- | Switch into a proof context.+context :: String -> Doc -> Doc+context name body = vcat [text name <-> text "begin", body, text "end"]++-}+
@@ -0,0 +1,136 @@+-- | 'Document' class allowing to have different interpretations of the+-- HughesPJ pretty-printing combinators.+module Text.PrettyPrint.Class (+ P.Doc+ , Document(..)+ , P.isEmpty+ , P.render+ , P.renderStyle+ , P.style+ , P.Style(..)+ , P.Mode(..)++ , ($--$)+ , semi + , colon+ , comma+ , space+ , equals+ , lparen+ , rparen+ , lbrack+ , rbrack+ , lbrace+ , rbrace+ + , int+ , integer+ , float+ , double+ , rational+ , quotes+ , doubleQuotes+ , parens+ , brackets+ , braces+ + , hang+ , punctuate+) where++import Prelude+import qualified Text.PrettyPrint.HughesPJ as P++infixl 6 <> +infixl 6 <->+infixl 5 $$, $-$, $--$++class Document d where+ char :: Char -> d+ text :: String -> d+ zeroWidthText :: String -> d+ emptyDoc :: d+ (<>) :: d -> d -> d+ (<->) :: d -> d -> d+ hcat :: [d] -> d+ hsep :: [d] -> d+ ($$) :: d -> d -> d+ ($-$) :: d -> d -> d+ vcat :: [d] -> d+ sep :: [d] -> d+ cat :: [d] -> d+ fsep :: [d] -> d+ fcat :: [d] -> d+ nest :: Int -> d -> d+ caseEmptyDoc :: d -> d -> d -> d++instance Document P.Doc where+ char = P.char+ text = P.text+ zeroWidthText = P.zeroWidthText+ emptyDoc = P.empty+ (<>) = (P.<>)+ (<->) = (P.<+>)+ hcat = P.hcat+ hsep = P.hsep+ ($$) = (P.$$)+ ($-$) = (P.$+$)+ vcat = P.vcat+ sep = P.sep+ cat = P.cat+ fsep = P.fsep+ fcat = P.fcat+ nest = P.nest+ caseEmptyDoc yes no d = if P.isEmpty d then yes else no++-- | Vertical concatentation of two documents with an empty line in between.+($--$) :: Document d => d -> d -> d+d1 $--$ d2 = + caseEmptyDoc d2 (caseEmptyDoc d1 (d1 $-$ text "" $-$ d2) d2) d1++semi, colon, comma, space, equals, + lparen, rparen, lbrack, rbrack, lbrace, rbrace :: Document d => d++semi = char ';'+colon = char ':'+comma = char ','+space = char ' '+equals = char '='+lparen = char '('+rparen = char ')'+lbrack = char '['+rbrack = char ']'+lbrace = char '{'+rbrace = char '}'++int :: Document d => Int -> d+int n = text (show n)++integer :: Document d => Integer -> d+integer n = text (show n)++float :: Document d => Float -> d+float n = text (show n)++double :: Document d => Double -> d+double n = text (show n)++rational :: Document d => Rational -> d+rational n = text (show n)++quotes, doubleQuotes, parens, brackets, braces :: Document d => d -> d+quotes p = char '\'' <> p <> char '\''+doubleQuotes p = char '"' <> p <> char '"'+parens p = char '(' <> p <> char ')'+brackets p = char '[' <> p <> char ']'+braces p = char '{' <> p <> char '}'++hang :: Document d => d -> Int -> d -> d+hang d1 n d2 = sep [d1, nest n d2]++punctuate :: Document d => d -> [d] -> [d]+punctuate _ [] = []+punctuate p (d:ds) = go d ds+ where+ go d' [] = [d']+ go d' (e:es) = (d' <> p) : go e es