diff options
author | trevnoise <noise@trevp.net> | 2017-11-13 02:14:06 +0000 |
---|---|---|
committer | trevnoise <noise@trevp.net> | 2017-11-13 02:14:06 +0000 |
commit | f860cf501b3415e1e42f153ad4359369dc007800 (patch) | |
tree | b1d00badec5f349dc065ddf8d1968d33ccf99747 | |
parent | Really update date. (diff) | |
download | noise-f860cf501b3415e1e42f153ad4359369dc007800.tar.xz noise-f860cf501b3415e1e42f153ad4359369dc007800.zip |
Test updating to spectemplate/spectools
-rw-r--r-- | Makefile | 44 | ||||
-rw-r--r-- | extensions/ext_hybrid_forward_secrecy.md | 382 | ||||
-rw-r--r-- | extensions/ext_newhope.md | 97 | ||||
-rw-r--r-- | ieee-with-url.csl | 333 | ||||
-rw-r--r-- | my.bib | 239 | ||||
-rw-r--r-- | noise.md | 3 | ||||
-rw-r--r-- | output/noise.html | 1 | ||||
-rw-r--r-- | output/noise.pdf | bin | 369508 -> 370777 bytes | |||
-rw-r--r-- | patterns/README.md | 9 | ||||
-rw-r--r-- | patterns/ext-hfs-revision-1.txt | 75 | ||||
-rw-r--r-- | patterns/grammar-abnf.txt | 78 | ||||
-rw-r--r-- | patterns/noise-revision-31.txt | 125 | ||||
-rw-r--r-- | patterns/noise-revision-32.txt | 93 | ||||
-rw-r--r-- | scripts/.gitignore | 1 | ||||
-rw-r--r-- | scripts/noise_patterns.py | 500 | ||||
-rwxr-xr-x | scripts/transform_fallback.py | 61 | ||||
-rwxr-xr-x | scripts/transform_hfs.py | 54 | ||||
-rwxr-xr-x | scripts/transform_psk.py | 57 | ||||
-rw-r--r-- | spec_markdown.css | 101 | ||||
-rw-r--r-- | template_pandoc.html | 74 | ||||
-rw-r--r-- | template_pandoc.latex | 259 |
21 files changed, 33 insertions, 2553 deletions
@@ -1,22 +1,40 @@ -default: output/noise.html output/noise.pdf +# Edit SPECNAME for the name your spec +SPECNAME := noise -# Pandoc 1.17.2, Pandoc-citeproc +# Ensure SPECTOOLS points at your spectools +PANDOC := $(SPECTOOLS)/pandoc +CITEPROC := $(SPECTOOLS)/pandoc-citeproc -output/noise.html: noise.md template_pandoc.html spec_markdown.css my.bib - pandoc noise.md -s --toc \ - -f markdown\ - --template template_pandoc.html \ +# Use "make", "make html", "make pdf", or "make clean" +all: html pdf + +html: output/$(SPECNAME).html + +pdf: output/$(SPECNAME).pdf + +output/$(SPECNAME).html: $(SPECNAME).md $(PANDOC)/template_pandoc.html $(PANDOC)/spec_markdown.css $(CITEPROC)/ieee-with-url.csl $(CITEPROC)/general.bib my.bib + pandoc $(SPECNAME).md --standalone --toc \ + --from markdown\ + --template $(PANDOC)/template_pandoc.html \ + --metadata=pdfn:$(SPECNAME).pdf \ --css=spec_markdown.css \ --filter pandoc-citeproc \ - -o output/noise.html + --bibliography=$(CITEPROC)/general.bib \ + --bibliography=my.bib \ + --csl=$(CITEPROC)/ieee-with-url.csl \ + -o output/$(SPECNAME).html + cp $(PANDOC)/spec_markdown.css output -output/noise.pdf: noise.md template_pandoc.latex my.bib - pandoc noise.md -s --toc \ - -f markdown\ - --template template_pandoc.latex \ +output/$(SPECNAME).pdf: $(SPECNAME).md $(PANDOC)/template_pandoc.latex $(CITEPROC)/ieee-with-url.csl $(CITEPROC)/general.bib my.bib + pandoc $(SPECNAME).md --standalone --toc \ + --from markdown\ + --template $(PANDOC)/template_pandoc.latex \ --filter pandoc-citeproc \ - -o output/noise.pdf + --bibliography=$(CITEPROC)/general.bib \ + --bibliography=my.bib \ + --csl=$(CITEPROC)/ieee-with-url.csl \ + -o output/$(SPECNAME).pdf clean: - rm output/noise.html output/noise.pdf + rm -f output/$(SPECNAME).html output/spec_markdown.css output/$(SPECNAME).pdf diff --git a/extensions/ext_hybrid_forward_secrecy.md b/extensions/ext_hybrid_forward_secrecy.md deleted file mode 100644 index 0cbc10f..0000000 --- a/extensions/ext_hybrid_forward_secrecy.md +++ /dev/null @@ -1,382 +0,0 @@ ---- -title: 'Noise Extension: Hybrid Forward Secrecy' -author: 'Rhys Weatherley (rhys.weatherley@gmail.com)' -revision: '1draft-5' -date: '2017-06-17' ---- - -1. Motivation -============= - -Once quantum computers become available it is possible that existing -Noise DH algorithms such as `25519` and `448` will become vulnerable. -This might allow a future adversary armed with a quantum computer to -read archived communications. - -Using currently-known post-quantum cryptography we may be able to -strengthen the secrecy of current communications against future adversaries. - -This document describes an extension to the Noise protocol to augment -handshakes with additional forward secrecy. We describe the general -method here. Separate extensions will describe specific post-quantum -algorithms. - -For demonstration purposes, we assume that `448` is being used to -strengthen a `25519` handshake. This allows us to describe the minimum -changes necessary to Noise to add extra forward secrecy to a handshake -using existing Noise primitives. In a practical implementation, -`448` would of course be replaced by a post-quantum algorithm. - -2. Protocol naming -================== - -The name of the DH function in the protocol name is modified to -include a pair of identifiers separated by a plus sign; for example: - - Noise_XXhfs_25519+448_AESGCM_SHA256 - -The pattern name `XXhfs` indicates that that pattern `XX` has been -transformed using the "hybrid forward secrecy" modifier, which -is defined later. - -The function for the first name in the pair (`25519`) plays the same -role as in regular Noise. The function for the second name in the pair -(`448`) specifies the algorithm that will be used to add hybrid forward -secrecy to an otherwise plain `Noise_XX_25519_AESGCM_SHA256` handshake. - -If a protocol name includes a hybrid forward secrecy function, then the -pattern must include the `"f"` and `"ff"` tokens described later. -Otherwise the protocol name is invalid. - -Conversely, a pattern that includes `"f"` and `"ff"` tokens can only be -used with a protocol name that includes a hybrid forward secrecy function. - -3. Crypto functions -=================== - -The following functions and constant definitions are added to Noise: - - * **`GENERATE_KEYPAIR_F(rf)`**: Generates a new key pair for the - hybrid forward secrecy algorithm relative to a remote public key `rf`. - The `rf` value will be empty for the first `"f"` token in the handshake, - and non-empty for the second `"f"` token. - - * **`FF(key_pair, public_key)`**: Performs a calculation for the hybrid - forward secrecy algorithm that mixes a local key pair with a remote - public key. - - * **`FLEN1`** = A constant specifying the size in bytes of the output - from `GENERATE_KEYPAIR_F(rf)` when `rf` is empty. - - * **`FLEN2`** = A constant specifying the size in bytes of the output - from `GENERATE_KEYPAIR_F(rf)` when `rf` is not empty. - - * **`FFLEN`** = A constant specifying the size in bytes of the output - from `FF()`. - -This extension uses these functions to generate and operate with -ephemeral keys only. - -When a traditional Noise DH function like `448` is used to provide -hybrid forward secrecy, the above definitions are specified as follows: - - * `GENERATE_KEYPAIR_F(rf)` = `GENERATE_KEYPAIR()` - * `FF(key_pair, public_key)` = `DH(key_pair, public_key)` - * `FLEN1` = `FLEN2` = `FFLEN` = `DHLEN` - -The separate extension for the post-quantum New Hope algorithm specifies -the above definitions as follows: - - * `GENERATE_KEYPAIR_F(rf)` = `newhope_keygen()` if `rf` is empty, or - `newhope_sharedb(r)` if `rf` is not empty. - * `FF(key_pair, public_key)` = `newhope_shareda(key_pair, public_key)` - if the `key_pair` was generated by `newhope_keygen()`. - * `FF(key_pair, public_key)` = `key_pair.shared` if the `key_pair` - was generated by `newhope_sharedb()`. - * `FLEN1` = 1824 - * `FLEN2` = 2176 - * `FFLEN` = 32 - -As can be seen, New Hope has different key sizes and behaviors for -the two parties (Alice and Bob). This asymmetric algorithm shape -motivated the addition of `rf` to the parameters for `GENERATE_KEYPAIR_F()` -and the multiple length values `FLEN1`, `FLEN2`, and `FFLEN`. - -4. Changes to HandshakeState -============================ - -4.1. Variables --------------- - -Two extra variables are added to the state: - - * `f`: The local hybrid forward secrecy key pair. - * `rf`: The remote party's hybrid forward secrecy public key. - -Both of these variables are instances of the second function from -the protocol name. If the protocol name does not include a second -function, then the `f` and `rf` variables are not used by the -handshake. - -4.2. Initialization -------------------- - -`Initialize()` is modified to include `f` and `rf` parameters. If either -value is supplied as a pre-message then that value must be hashed -during the fourth pre-message step of the handshake. - -Pre-messages are hashed in the order `e`, `f`, `s`, initiator values first. -The set of valid pre-messages is: - - * `e` - * `s` - * `e, s` - * `e, f` - * `e, f, s` - * empty - -4.3. Tokens ------------ - -Two new tokens are added for use in defining message patterns: -`"f"` and `"ff"`. All other tokens continue to operate as before. - -Token handling for `WriteMessage()` is modified as follows: - - * For `"f"`: Sets `f = GENERATE_KEYPAIR_F(rf)`, overwriting any previous - value for `f`. Appends `EncryptAndHash(f.public_key)` to the buffer. - - * For `"ff"`: Calls `MixKey(FF(f, rf))`. - -Token handling for `ReadMessage()` is modified as follows: - - * For `"f"`: If `f` is empty, then sets `temp` to the next `FLEN1` + 16` - bytes of the message if `HasKey() == True`, or to the next `FLEN1` bytes - otherwise. If `f` is not empty, then sets `temp` to the next `FLEN2 + 16` - bytes of the message if `HasKey() == True`, or to the next `FLEN2` bytes - otherwise. Sets `rf` to `DecryptAndHash(temp)`. - - * For `"ff"`: Calls `MixKey(FF(f, rf))`. - -Note that the `"f"` token values will be encrypted if a `"xy"` token has -already been seen in the pattern, or if pre-shared keys are involved. - -5. Message patterns for hybrid forward secrecy -============================================== - -5.1. The `hfs` pattern modifier -------------------------------- - -This extension defines a pattern modifier named `hfs` that transforms an -existing interactive pattern into one involving hybrid forward secrecy. -The transformation rules are: - - * All occurrences of the `"e"` token in the pre-message and message body - are replaced with `"e, f"`. - * All occurrences of the `"ee"` token in the message body are replaced - with `"ee, ff"`. - * If the pattern contains `"e"` in its parameters, then `"f"` is added - to the parameters. - * If the pattern contains `"re"` in its parameters, then `"rf"` is added - to the parameters. - -The following examples demonstrate the modifier: - - Noise_NNhfs(): - -> e, f - <- e, f, ee, ff - - Noise_XXhfs(s, rs): - -> e, f - <- e, f, ee, ff, s, es - -> s, se - - Noise_IKhfs(s, rs): - <- s - ... - -> e, f, es, s, ss - <- e, f, ee, ff, se - - Noise_XXfallback+hfs(e, f, s, rs): - -> e, f - ... - <- e, f, ee, ff, s, es - -> s, se - -5.2. Pattern validity ---------------------- - -The following validity rules apply: - - * If `f` or `rf` appears in the parameters of a pattern, then the - corresponding `e` or `re` value must also appear in the parameters. - * The `"f"` token for a party must always appear after the corresponding - `"e"` token for that party. - * Only a single `"f"` token can be sent by each party. Alternatively, - a pre-message `f` value for a party can stand in for the token. - * `"ff"` must occur only once in the pattern, after both `"f"` tokens - or their pre-message counterparts. - * `"ff"` must occur after `"ee"`. - -5.3. Hybrid pattern list ------------------------- - -Standard interactive Noise patterns that are modified with `hfs` fall -into two broad categories: fully hybrid and partially hybrid. - -Fully hybrid patterns are those where the first two mixing operations -in the pattern are `"ee"` and `"ff"`. All values that would have been -encrypted in the original pattern are now encrypted with a hybrid key -combining outputs from both algorithms. Any message payloads and -static public key values that were previously sent in the clear are -still in the clear. - -The following patterns are fully hybrid: - - Noise_NNhfs(): - -> e, f - <- e, f, ee, ff - - Noise_NXhfs(rs): - -> e, f - <- e, f, ee, ff, s, es - - Noise_XNhfs(s): - -> e, f - <- e, f, ee, ff - -> s, se - - Noise_XXhfs(s, rs): - -> e, f - <- e, f, ee, ff, s, es - -> s, se - - Noise_KNhfs(s): - -> s - ... - -> e, f - <- e, f, ee, ff, se - - Noise_KXhfs(s, rs): - -> s - ... - -> e, f - <- e, f, ee, ff, se, s, es - - Noise_INhfs(s): - -> e, f, s - <- e, f, ee, ff, se - - Noise_IXhfs(s, rs): - -> e, f, s - <- e, f, ee, ff, se, s, es - - Noise_XXfallback+hfs(e, f, s, rs): - -> e, f - ... - <- e, f, ee, ff, s, es - -> s, se - -Partially hybrid patterns are those where a `"xy"` operation involving a -static public key precedes the first `"ee"` operation. Static public -key values and message payloads that precede the first `"ff"` operation -will be encrypted only with the classical DH algorithm. If that algorithm -falls to a future attack, then message payloads or static public keys that -were previously encrypted may be revealed. - -The following patterns are partially hybrid: - - Noise_NKhfs(rs): - <- s - ... - -> e, f, es - <- e, f, ee, ff - - Noise_XKhfs(s, rs): - <- s - ... - -> e, f, es - <- e, f, ee, ff - -> s, se - - Noise_KKhfs(s, rs): - -> s - <- s - ... - -> e, f, es, ss - <- e, f, ee, ff, se - - Noise_IKhfs(s, rs): - <- s - ... - -> e, f, es, s, ss - <- e, f, ee, ff, se - -As can be seen, all of the standard interactive patterns that end in -`"K"` become partially hybrid when modified with `hfs`. - -It is disappointing that `"IK+hfs"` is partially hybrid because it means -that a post-quantum Noise Pipes is not a simple matter of modifying -`"XX"`, `"IK"`, and `"XXfallback"` with `hfs`. - -6. Future Directions -==================== - -6.1. Other hybrid patterns --------------------------- - -Partially hybrid patterns can be improved by using another modifier -to move static public key values to later in the handshake to hide identity -information: - - Noise_IKhfs+xyz(s, rs): - <- s - ... - -> e, f, es - <- e, f, ee, ff - -> s, ss, se - -The `"es"` token in the first message could also be moved to the -third message. Although for Noise Pipes we would like the first -message to trigger fallback if the initiator is not in possession -of the responder's current static public key. The responder's static -public key value is not as secret as the initator's - any party can -connect to the responder with `"XX"` and retrieve the responder's -static public key without needing to mount an attack against archived -communications. - -Transforming patterns in this way tends to increase the number of -turn-arounds. More experimentation is required before such a -modifier can be standardized. This extension provides the basic -tools that could be used to define such a modifier later. - -6.2. Encryption of hybrid forward secrecy values ------------------------------------------------- - -Given that post-quantum cryptography is very new, it is possible that -weaknesses may be found in whatever algorithm is chosen. Encryption -of `"f"` tokens can help hide patterns in the post-quantum values that -might allow cryptanalysis. - -Encryption of `"f"` tokens may also be useful for implementing an -Elligator-like scheme that converts post-quantum values into something -indistinguishable from random. - -6.3. Post-quantum static keys ------------------------------ - -This extension is solely concerned with augmenting the forward -secrecy of an existing handshake. It is possible to imagine a further -extension whereby the hybrid function also operates on static keys. - -Some post-quantum algorithms like New Hope only support ephemeral -keys, whereas others like SIDHp751 support both ephemeral and -static keys. Static keys could be handled in one of two ways: - - * Use `25519` or `448` for hybrid forward secrecy, and the post-quantum - algorithm for static keys; e.g. `Noise_XXhfs_SIDHp751+448`. - * Extend the facilities here with new tokens to allow static keys for - both algorithms; e.g. `Noise_XXhfs+hstatic_448+SIDHp751`. - -At the moment we do not make any comment as to the wisdom in doing so -or the mechanisms that would be involved. diff --git a/extensions/ext_newhope.md b/extensions/ext_newhope.md deleted file mode 100644 index d1709eb..0000000 --- a/extensions/ext_newhope.md +++ /dev/null @@ -1,97 +0,0 @@ ---- -title: 'Noise Extension: New Hope' -author: 'Rhys Weatherley (rhys.weatherley@gmail.com)' -revision: '1draft-4' -date: '2016-12-19' ---- - -1. Introduction -=============== - -This document describes the post-quantum key exchange algorithm New Hope -and provides information for using it with the Noise protocol. - -New Hope [1,2] is a Diffie-Hellman like key exchange mechanism based on -the Ring Learning with Errors (Ring-LWE) problem. It is believed to be -secure against an adversary with a quantum computer. It provides the -equivalent of 128 bits of security. - -New Hope is unusual in that its key sizes and operations vary based on -the party: - - * Alice generates a 1824-byte public key and a 2048-byte private key. - Her 1824-byte public key is sent to Bob. - * Bob uses Alice's public key to generate his own 2176-byte public key - and a 32-byte shared secret. His 2176-byte public key is sent to Alice. - * Alice uses her 2048-byte private key and Bob's 2176-byte public key - to generate her copy of the 32-byte shared secret. - -New Hope supports ephemeral key exchange only, which makes it suitable -for use with the separate "Hybrid Forward Secrecy" extension to Noise. -While New Hope could be used as a regular DH function with the `NN` -pattern, we do not define that here. - -2. Definition of `NewHope` for use in Noise -=========================================== - -The authors of New Hope have refined the algorithm from the original -paper [1] to produce a simpler version without reconciliation [2]. -It is this "NewHope-Simple" version that we standardize for use in -Noise under the function name `NewHope`. The previous "ref" and -"torref" variants are not used. - -The function and constant definitions for hybrid forward secrecy are -as follows: - - * **`GENERATE_KEYPAIR_F(rf)`**: - * If `rf` is empty, then returns the result of `newhope_keygen()` - which has the two components `private_key` and `public_key`. - * If `rf` is not empty, then returns the result of `newhope_sharedb(r)` - which has the two components `shared` and `public_key`. - - * **`FF(key_pair, public_key)`**: If `key_pair` was generated by - `GENERATE_KEYPAIR_F(rf)` with an empty `rf`, then return the result of - `newhope_shareda(key_pair.private_key, public_key)`. Otherwise - return `key_pair.shared` and ignore `public_key`. - - * **`FLEN1`** = 1824 - - * **`FLEN2`** = 2176 - - * **`FFLEN`** = 32 - -3. Test vector definition -========================= - -The Noise test vector format assumes that fixed ephemeral keys can be -set using only their private key. However, the New Hope API does not -expose a private key in the same sense as `25519` and `448`. - -The reference implementation of New Hope acquires 64 bytes of random -seed data from the system to generate the key pair for Alice and the -public "a" value. The reference implementation acquires 32 bytes of -random seed data from the system to generate the key pair for Bob -relative to "a". - -The 64 or 32 bytes of random seed data can be used as the "private key" -component for ephemeral keys in test vectors. - -4. Examples -=========== - -The following are examples of protocol names involving New Hope: - - * `Noise_XXhfs_25519+NewHope_AESGCM_SHA256` - * `Noise_XXfallback+hfs_448+NewHope_ChaChaPoly_BLAKE2b` - -5. References -============= - -[1] Erdem Alkim, Léo Ducas, Thomas Pöppelmann, and Peter Schwabe: -[Post-quantum key exchange – a new hope](https://cryptojedi.org/papers/#newhope). -Proceedings of the 25th USENIX Security Symposium. - -[2] Erdem Alkim, Léo Ducas, Thomas Pöppelmann, and Peter Schwabe: -[NewHope without reconciliation](https://cryptojedi.org/papers/#newhopesimple). - -[3] [Reference implementation of New Hope](https://cryptojedi.org/crypto/#newhope). diff --git a/ieee-with-url.csl b/ieee-with-url.csl deleted file mode 100644 index a630756..0000000 --- a/ieee-with-url.csl +++ /dev/null @@ -1,333 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<style xmlns="http://purl.org/net/xbiblio/csl" class="in-text" version="1.0" demote-non-dropping-particle="sort-only"> - <info> - <title>IEEE (with URL)</title> - <id>http://www.zotero.org/styles/ieee-with-url</id> - <link href="http://www.zotero.org/styles/ieee-with-url" rel="self"/> - <link href="http://www.ieee.org/documents/style_manual.pdf" rel="documentation"/> - <link href="http://www.ieee.org/documents/auinfo07.pdf" rel="documentation"/> - <author> - <name>Michael Berkowitz</name> - <email>mberkowi@gmu.edu</email> - </author> - <contributor> - <name>Julian Onions</name> - <email>julian.onions@gmail.com</email> - </contributor> - <contributor> - <name>Rintze Zelle</name> - <uri>http://twitter.com/rintzezelle</uri> - </contributor> - <contributor> - <name>Stephen Frank</name> - <uri>http://www.zotero.org/sfrank</uri> - </contributor> - <contributor> - <name>Sebastian Karcher</name> - </contributor> - <category citation-format="numeric"/> - <category field="engineering"/> - <category field="generic-base"/> - <updated>2014-09-03T18:33:58+00:00</updated> - <rights license="http://creativecommons.org/licenses/by-sa/3.0/">This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 License</rights> - </info> - <locale xml:lang="en"> - <terms> - <term name="chapter" form="short">ch.</term> - <term name="presented at">presented at the</term> - <term name="available at">available</term> - </terms> - </locale> - <!-- Macros --> - <macro name="edition"> - <choose> - <if type="bill book chapter graphic legal_case legislation motion_picture paper-conference report song" match="any"> - <choose> - <if is-numeric="edition"> - <group delimiter=" "> - <number variable="edition" form="ordinal"/> - <text term="edition" form="short"/> - </group> - </if> - <else> - <text variable="edition" text-case="capitalize-first" suffix="."/> - </else> - </choose> - </if> - </choose> - </macro> - <macro name="issued"> - <choose> - <if type="article-journal report" match="any"> - <date variable="issued"> - <date-part name="month" form="short" suffix=" "/> - <date-part name="year" form="long"/> - </date> - </if> - <else-if type=" bill book chapter graphic legal_case legislation motion_picture paper-conference song thesis" match="any"> - <date variable="issued"> - <date-part name="year" form="long"/> - </date> - </else-if> - <else> - <date variable="issued"> - <date-part name="day" form="numeric-leading-zeros" suffix="-"/> - <date-part name="month" form="short" suffix="-" strip-periods="true"/> - <date-part name="year" form="long"/> - </date> - </else> - </choose> - </macro> - <macro name="author"> - <names variable="author"> - <name initialize-with=". " delimiter=", " and="text"/> - <label form="short" prefix=", " text-case="capitalize-first"/> - <substitute> - <names variable="editor"/> - <names variable="translator"/> - </substitute> - </names> - </macro> - <macro name="editor"> - <names variable="editor"> - <name initialize-with=". " delimiter=", " and="text"/> - <label form="short" prefix=", " text-case="capitalize-first"/> - </names> - </macro> - <macro name="locators"> - <group delimiter=", "> - <text macro="edition"/> - <group delimiter=" "> - <text term="volume" form="short"/> - <number variable="volume" form="numeric"/> - </group> - <group delimiter=" "> - <number variable="number-of-volumes" form="numeric"/> - <text term="volume" form="short" plural="true"/> - </group> - <group delimiter=" "> - <text term="issue" form="short"/> - <number variable="issue" form="numeric"/> - </group> - </group> - </macro> - <macro name="title"> - <choose> - <if type="bill book graphic legal_case legislation motion_picture song" match="any"> - <text variable="title" font-style="normal"/> - </if> - <else> - <text variable="title" quotes="true"/> - </else> - </choose> - </macro> - <macro name="publisher"> - <choose> - <if type=" bill book chapter graphic legal_case legislation motion_picture paper-conference song" match="any"> - <group delimiter=": "> - <text variable="publisher-place"/> - <text variable="publisher"/> - </group> - </if> - <else> - <group delimiter=", "> - <text variable="publisher"/> - <text variable="publisher-place"/> - </group> - </else> - </choose> - </macro> - <macro name="event"> - <choose> - <if type="paper-conference speech" match="any"> - <choose> - <!-- Published Conference Paper --> - <if variable="container-title"> - <group delimiter=", "> - <group delimiter=" "> - <text term="in"/> - <text variable="container-title" font-style="normal"/> - </group> - <text variable="event-place"/> - </group> - </if> - <!-- Unpublished Conference Paper --> - <else> - <group delimiter=", "> - <group delimiter=" "> - <text term="presented at"/> - <text variable="event"/> - </group> - <text variable="event-place"/> - </group> - </else> - </choose> - </if> - </choose> - </macro> - <macro name="access"> - <choose> - <if variable="URL"> - <group delimiter=". "> - <group delimiter=": "> - <text variable="URL"/> - </group> - <group prefix="[" suffix="]" delimiter=": "> - <text term="accessed" text-case="capitalize-first"/> - <date variable="accessed"> - <date-part name="day" form="numeric-leading-zeros" suffix="-"/> - <date-part name="month" form="short" suffix="-" strip-periods="true"/> - <date-part name="year" form="long"/> - </date> - </group> - </group> - </if> - </choose> - </macro> - <macro name="page"> - <group> - <label variable="page" form="short" suffix=" "/> - <text variable="page"/> - </group> - </macro> - <macro name="citation-locator"> - <group delimiter=" "> - <choose> - <if locator="page"> - <label variable="locator" form="short"/> - </if> - <else> - <label variable="locator" form="short" text-case="capitalize-first"/> - </else> - </choose> - <text variable="locator"/> - </group> - </macro> - <!-- Citation --> - <citation collapse="citation-number"> - <sort> - <key variable="citation-number"/> - </sort> - <layout delimiter=", "> - <group prefix="[" suffix="]" delimiter=", "> - <text variable="citation-number"/> - <text macro="citation-locator"/> - </group> - </layout> - </citation> - <!-- Bibliography --> - <bibliography entry-spacing="0" second-field-align="flush"> - <layout> - <!-- Citation Number --> - <text variable="citation-number" prefix="[" suffix="]"/> - <!-- Author(s) --> - <text macro="author" suffix=", "/> - <!-- Rest of Citation --> - <group suffix=". "> - <choose> - <!-- Specific Formats --> - <if type="article-journal"> - <group delimiter=", "> - <text macro="title"/> - <text variable="container-title" font-style="normal" form="short"/> - <text macro="locators"/> - <text macro="page"/> - <text macro="issued"/> - </group> - </if> - <else-if type="paper-conference"> - <group delimiter=", "> - <text macro="title"/> - <text macro="event"/> - <text macro="issued"/> - <text macro="locators"/> - <text macro="page"/> - </group> - </else-if> - <else-if type="report"> - <group delimiter=", "> - <text macro="title"/> - <text macro="publisher"/> - <group delimiter=" "> - <text variable="genre"/> - <text variable="number"/> - </group> - <text macro="issued"/> - </group> - </else-if> - <else-if type="thesis"> - <group delimiter=", "> - <text macro="title"/> - <text variable="genre"/> - <text macro="publisher"/> - <text macro="issued"/> - </group> - </else-if> - <else-if type="webpage"> - <group delimiter=", " suffix=". "> - <text macro="title"/> - <text variable="container-title" font-style="normal"/> - <text macro="issued"/> - </group> - </else-if> - <else-if type="patent"> - <text macro="title" suffix=", "/> - <text variable="number"/> - <text macro="issued"/> - </else-if> - <!-- Generic/Fallback Formats --> - <else-if type="bill book graphic legal_case legislation motion_picture report song" match="any"> - <group delimiter=", " suffix=". "> - <text macro="title"/> - <text macro="locators"/> - </group> - <group delimiter=", "> - <text macro="publisher"/> - <text macro="issued"/> - <text macro="page"/> - </group> - </else-if> - <else-if type="article-magazine article-newspaper broadcast interview manuscript map patent personal_communication song speech thesis webpage" match="any"> - <group delimiter=", "> - <text macro="title"/> - <text variable="container-title" font-style="normal"/> - <text macro="locators"/> - <text macro="publisher"/> - <text macro="page"/> - <text macro="issued"/> - </group> - </else-if> - <else-if type="chapter paper-conference" match="any"> - <group delimiter=", " suffix=", "> - <text macro="title"/> - <group delimiter=" "> - <text term="in"/> - <text variable="container-title" font-style="normal"/> - </group> - <text macro="locators"/> - </group> - <text macro="editor" suffix=" "/> - <group delimiter=", "> - <text macro="publisher"/> - <text macro="issued"/> - <text macro="page"/> - </group> - </else-if> - <else> - <group delimiter=", " suffix=". "> - <text macro="title"/> - <text variable="container-title" font-style="normal"/> - <text macro="locators"/> - </group> - <group delimiter=", "> - <text macro="publisher"/> - <text macro="page"/> - <text macro="issued"/> - </group> - </else> - </choose> - </group> - <text macro="access"/> - </layout> - </bibliography> -</style> @@ -1,239 +0,0 @@ - -@inproceedings{Rogaway:2002, - author = {Rogaway, Phillip}, - title = "{Authenticated-encryption with Associated-data}", - booktitle = "{Proceedings of the 9th {ACM} Conference on Computer and Communications Security}", - series = {CCS '02}, - year = {2002}, - isbn = {1-58113-612-9}, - location = {Washington, DC, USA}, - doi = {10.1145/586110.586125}, - acmid = {586125}, - publisher = {ACM}, - address = {New York, NY, USA}, - keywords = {OCB, associated-data problem, authenticated-encryption, block-cipher usage, key separation, modes of operation}, - url="http://web.cs.ucdavis.edu/~rogaway/papers/ad.pdf" -} - - -@misc{rfc7748, - author="A. Langley and M. Hamburg and S. Turner", - title="{Elliptic Curves for Security}", - series="Request for Comments", - number="7748", - howpublished="RFC 7748 (Informational)", - publisher="IETF", - organization="Internet Engineering Task Force", - year=2016, - month=jan, - url="http://www.ietf.org/rfc/rfc7748.txt", -} - -@misc{rfc2104, - author="H. Krawczyk and M. Bellare and R. Canetti", - title="{HMAC: Keyed-Hashing for Message Authentication}", - series="Request for Comments", - number="2104", - howpublished="RFC 2104 (Informational)", - publisher="IETF", - organization="Internet Engineering Task Force", - year=1997, - month=feb, - note="Updated by RFC 6151", - url="http://www.ietf.org/rfc/rfc2104.txt", -} - -@misc{rfc5869, - author="H. Krawczyk and P. Eronen", - title="{HMAC-based Extract-and-Expand Key Derivation Function (HKDF)}", - series="Request for Comments", - number="5869", - howpublished="RFC 5869 (Informational)", - publisher="IETF", - organization="Internet Engineering Task Force", - year=2010, - month=may, - url="http://www.ietf.org/rfc/rfc5869.txt", -} - -@misc{hkdfpaper, - author = {Hugo Krawczyk}, - title = {"Cryptographic Extraction and Key Derivation: The HKDF Scheme"}, - howpublished = {Cryptology ePrint Archive, Report 2010/264}, - year = {2010}, - url="http://eprint.iacr.org/2010/264", -} - -@misc{elligator, - author = {Daniel J. Bernstein and Mike Hamburg and Anna Krasnova and Tanja Lange}, - title = "{Elligator: Elliptic-curve points indistinguishable from uniform random strings}", - howpublished = {Cryptology ePrint Archive, Report 2013/325}, - year = {2013}, - url = "http://eprint.iacr.org/2013/325", -} - -@misc{rfc7539, - author="Y. Nir and A. Langley", - title="{ChaCha20 and Poly1305 for IETF Protocols}", - series="Request for Comments", - number="7539", - howpublished="RFC 7539 (Informational)", - publisher="IETF", - organization="Internet Engineering Task Force", - year=2015, - month=may, - url="http://www.ietf.org/rfc/rfc7539.txt", -} - -@techreport{nistgcm, - author = {Dworkin, Morris J.}, - title = "{SP 800-38D. Recommendation for Block Cipher Modes of Operation: Galois/Counter Mode (GCM) and GMAC}", - year = {2007}, - publisher = {National Institute of Standards \& Technology}, - address = {Gaithersburg, MD, United States}, - url="http://nvlpubs.nist.gov/nistpubs/Legacy/SP/nistspecialpublication800-38d.pdf" -} - -@TechReport{nistsha2, - author = "NIST", - key = "FIPS-180-4", - title = "{FIPS 180-4. Secure Hash Standard (SHS)}", - publisher = {National Institute of Standards \& Technology}, - address = {Gaithersburg, MD, United States}, - year = "2012", - URL = "http://csrc.nist.gov/publications/fips/fips180-4/fips-180-4.pdf" -} - -@misc{rfc7693, - - author="M-J. Saarinen and J-P. Aumasson", - title="{The BLAKE2 Cryptographic Hash and Message Authentication Code (MAC)}", - series="Request for Comments", - number="7693", - howpublished="RFC 7693 (Informational)", - publisher="IETF", - organization="Internet Engineering Task Force", - year=2015, - month=nov, - url="http://www.ietf.org/rfc/rfc7693.txt", -} - -@misc{nacl, - author="Daniel J. Bernstein and Tanja Lange and Peter Schwabe", - title="{NaCl: Networking and Cryptography Library}", - url="https://nacl.cr.yp.to/" -} - -@misc{curvecp, - author="Daniel J. Bernstein", - title="{CurveCP: Usable security for the Internet}", - url="https://curvecp.org" -} - -@Inbook{sigma, -author="Krawczyk, Hugo", -title="{SIGMA: The `SIGn-and-MAc' Approach to Authenticated Diffie-Hellman and Its Use in the IKE Protocols}", -bookTitle="{Advances in Cryptology - CRYPTO 2003}", -year="2003", -url="http://webee.technion.ac.il/~hugo/sigma.html" -} - -@misc{homqv, - author = {Shai Halevi and Hugo Krawczyk}, - title = "{One-Pass HMQV and Asymmetric Key-Wrapping}", - howpublished = {Cryptology ePrint Archive, Report 2010/638}, - year = {2010}, - url = {http://eprint.iacr.org/2010/638}, -} - -@article{ntor, - author = {Goldberg, Ian and Stebila, Douglas and Ustaoglu, Berkant}, - title = "{Anonymity and One-way Authentication in Key Exchange Protocols}", - journal = {Design, Codes, and Cryptography}, - issue_date = {May 2013}, - volume = {67}, - number = {2}, - month = may, - year = {2013}, - issn = {0925-1022}, - numpages = {25}, - doi = {10.1007/s10623-011-9604-z}, - acmid = {2458069}, - publisher = {Kluwer Academic Publishers}, - address = {Norwell, MA, USA}, - url="http://cacr.uwaterloo.ca/techreports/2011/cacr2011-11.pdf" -} - -@inproceedings{otr, - author = {Di Raimondo, Mario and Gennaro, Rosario and Krawczyk, Hugo}, - title = "{Secure Off-the-record Messaging}", - booktitle = "{Proceedings of the 2005 ACM Workshop on Privacy in the Electronic Society}", - series = {WPES '05}, - year = {2005}, - isbn = {1-59593-228-3}, - address = {New York, NY, USA}, - url="http://www.dmi.unict.it/diraimondo/web/wp-content/uploads/papers/otr.pdf" -} - -@Inbook{kudla2005, -author="Kudla, Caroline and Paterson, Kenneth G.", -title="{Modular Security Proofs for Key Agreement Protocols}", -bookTitle="{Advances in Cryptology - ASIACRYPT 2005: 11th International Conference on the Theory and Application of Cryptology and Information Security}", -year="2005", -isbn="978-3-540-32267-2", -doi="10.1007/11593447_30", -url="http://www.isg.rhul.ac.uk/~kp/ModularProofs.pdf" -} - -@Inbook{blakewilson1997, -author="Blake-Wilson, Simon and Johnson, Don and Menezes, Alfred", -title="Key agreement protocols and their security analysis", -bookTitle="{Crytography and Coding: 6th IMA International Conference Cirencester, UK, December 17--19, 1997 Proceedings}", -year="1997", -url="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.25.387" -} - -@inproceedings{gapdh, - author = "{Okamoto, Tatsuaki and Pointcheval, David}", - title = "{The Gap-Problems: A New Class of Problems for the Security of Cryptographic Schemes}", - booktitle = "{Proceedings of the 4th International Workshop on Practice and Theory in Public Key Cryptography: Public Key Cryptography}", - series = {PKC '01}, - year = {2001}, - isbn = {3-540-41658-7}, - url = "https://www.di.ens.fr/~pointche/Documents/Papers/2001_pkc.pdf", - publisher = {Springer-Verlag}, - address = {London, UK, UK}, -} - -@online{doubleratchet, - author = {Trevor Perrin and Moxie Marlinspike}, - year = {2016}, - title = "{The Double Ratchet Algorithm}", - url = "https://whispersystems.org/docs/specifications/doubleratchet/" -} - -@misc{moderncryptostrobe, - author = {Mike Hamburg}, - year = {2015}, - title = "{Key Exchange and DuplexWrap-like protocols}", - howpublished = "Noise@moderncrypto.org Mailing List", - url = "https://moderncrypto.org/mail-archive/noise/2015/000098.html" -} -https://moderncrypto.org/mail-archive/noise/2015/000098.html - - -@misc{strobe, - author = "{Mike Hamburg}", - title = "{The STROBE protocol framework}", - howpublished = {Cryptology ePrint Archive, Report 2017/003}, - year = {2017}, - url = "http://eprint.iacr.org/2017/003", -} - -@misc{blinker, - author = "{Markku-Juhani O. Saarinen}", - title = "{Beyond Modes: Building a Secure Record Protocol from a Cryptographic Sponge Permutation}", - howpublished = {Cryptology ePrint Archive, Report 2013/772}, - year = {2013}, - url = "http://eprint.iacr.org/2013/772", -} @@ -2,11 +2,10 @@ title: 'The Noise Protocol Framework' author: 'Trevor Perrin (noise@trevp.net)' revision: '33' +status: official/stable date: '2017-10-04' bibliography: 'my.bib' link-citations: 'true' -pdfn: 'noise.pdf' -csl: 'ieee-with-url.csl' --- 1. Introduction diff --git a/output/noise.html b/output/noise.html index 4b77e3b..71780e2 100644 --- a/output/noise.html +++ b/output/noise.html @@ -16,6 +16,7 @@ <b>Author:</b> Trevor Perrin (noise@trevp.net)<br/> <b>Revision:</b> 33<br/> <b>Date:</b> 2017-10-04<br/> +<b>Status:</b> official/stable<br/> <b>PDF:</b> <a href="noise.pdf">noise.pdf</a><br/> </div> <div id="TOC"> diff --git a/output/noise.pdf b/output/noise.pdf Binary files differindex 0bab236..3809735 100644 --- a/output/noise.pdf +++ b/output/noise.pdf diff --git a/patterns/README.md b/patterns/README.md deleted file mode 100644 index 4229057..0000000 --- a/patterns/README.md +++ /dev/null @@ -1,9 +0,0 @@ - -Noise Pattern Dictionary ------------------------- - -This directory contains machine-readable definitions for patterns from the -Noise specification and extensions. - -The grammar for the format is in the file "grammar-abnf.txt", and uses the -conventions for ABNF from RFC 5234. diff --git a/patterns/ext-hfs-revision-1.txt b/patterns/ext-hfs-revision-1.txt deleted file mode 100644 index 53cce30..0000000 --- a/patterns/ext-hfs-revision-1.txt +++ /dev/null @@ -1,75 +0,0 @@ -// Noise Extension: Hybrid Forward Secrecy, Revision 1 - -// Fully hybrid patterns. - -Noise_NNhfs(): - -> e, f - <- e, f, ee, ff - -Noise_NXhfs(rs): - -> e, f - <- e, f, ee, ff, s, es - -Noise_KNhfs(s): - -> s - ... - -> e, f - <- e, f, ee, ff, se - -Noise_KXhfs(s, rs): - -> s - ... - -> e, f - <- e, f, ee, ff, se, s, es - -Noise_XNhfs(s): - -> e, f - <- e, f, ee, ff - -> s, se - -Noise_XXhfs(s, rs): - -> e, f - <- e, f, ee, ff, s, es - -> s, se - -Noise_INhfs(s): - -> e, f, s - <- e, f, ee, ff, se - -Noise_IXhfs(s, rs): - -> e, f, s - <- e, f, ee, ff, se, s, es - -Noise_XXfallback+hfs(e, f, s, rs): - -> e, f - ... - <- e, f, ee, ff, s, es - -> s, se - -// Partially hybrid patterns. - -Noise_NKhfs(rs): - <- s - ... - -> e, f, es - <- e, f, ee, ff - -Noise_KKhfs(s, rs): - -> s - <- s - ... - -> e, f, es, ss - <- e, f, ee, ff, se - -Noise_XKhfs(s, rs): - <- s - ... - -> e, f, es - <- e, f, ee, ff - -> s, se - -Noise_IKhfs(s, rs): - <- s - ... - -> e, f, es, s, ss - <- e, f, ee, ff, se diff --git a/patterns/grammar-abnf.txt b/patterns/grammar-abnf.txt deleted file mode 100644 index e968d6f..0000000 --- a/patterns/grammar-abnf.txt +++ /dev/null @@ -1,78 +0,0 @@ - -; Defined using the ABNF syntax from RFC 5234. The character set is US-ASCII. -; -; The "pattern-file" element is intended for a pattern dictionary file that -; contains multiple pattern definitions. -; -; The "pattern-single" element is intended for applications that wish to -; provide an API to define the specific pattern to use in a handshake. -; -; The "protocol-name" lexical token describes the structure of Noise -; protocol names in ABNF. -; -; Productions that start with "extension-" apply to extension features like -; Hybrid Forward Secrecy and are not part of the core Noise standard. - -; Syntactic elements - -pattern-file = *(wsp pattern) wsp - -pattern-single = wsp pattern wsp - -pattern = header wsp [pre-message wsp "..." wsp] messages - -header = "Noise_" pattern-name wsp "(" wsp params wsp ")" wsp ":" - -params = param *(wsp "," wsp param) - -param = standard-param / extension-param - -standard-param = "e" / "s" / "re" / "rs" - -extension-param = "f" / "rf" ; Hybrid Forward Secrecy - -pre-message = message-init [wsp message-resp] / message-resp - -messages = *(message-pair wsp) message-init [wsp message-resp] / - message-resp *(wsp message-pair) [wsp message-init] - -message-pair = message-init wsp message-resp - -message-init = "->" wsp message-tokens - -message-resp = "<-" wsp message-tokens - -message-tokens = message-token *(wsp "," wsp message-token) - -message-token = standard-token / extension-token - -standard-token = "e" / "s" / "ee" / "ss" / "se" / "es" / "psk" - -extension-token = "f" / "ff" ; Hybrid Forward Secrecy - -; Lexical tokens - -protocol-name = "Noise_" pattern-name "_" dh-algorithms - "_" cipher-algorithms "_" hash-algorithms - -pattern-name = base-pattern-name [modifier-name *("+" modifier-name)] - -base-pattern-name = 1*(%x41-5A) ; 1 or more uppercase letters - -modifier-name = 1*(%x61-7A / DIGIT) ; Lower case and digits - -dh-algorithms = name-component *("+" name-component) - -cipher-algorithms = name-component *("+" name-component) - -hash-algorithms = name-component *("+" name-component) - -name-component = 1*(ALPHA / DIGIT / "/") - -wsp = *(WSP / eol / comment) - -comment = "//" *(VCHAR / WSP) eol - -eol = CRLF / LF - -; Imported from core ABNF (RFC 5234): VCHAR, WSP, CRLF, LF, ALPHA, DIGIT diff --git a/patterns/noise-revision-31.txt b/patterns/noise-revision-31.txt deleted file mode 100644 index 5afcdb7..0000000 --- a/patterns/noise-revision-31.txt +++ /dev/null @@ -1,125 +0,0 @@ -// Noise Protocol Framework, Revision 31 - -// Section 8.2. One-way patterns - -Noise_N(rs): - <- s - ... - -> e, es - -Noise_K(s, rs): - -> s - <- s - ... - -> e, es, ss - -Noise_X(s, rs): - <- s - ... - -> e, es, s, ss - -// Section 8.3. Interactive patterns - -Noise_NN(): - -> e - <- e, ee - -Noise_NK(rs): - <- s - ... - -> e, es - <- e, ee - -Noise_NX(rs): - -> e - <- e, ee, s, es - -Noise_KN(s): - -> s - ... - -> e - <- e, ee, se - -Noise_KK(s, rs): - -> s - <- s - ... - -> e, es, ss - <- e, ee, se - -Noise_KX(s, rs): - -> s - ... - -> e - <- e, ee, se, s, es - -Noise_XN(s): - -> e - <- e, ee - -> s, se - -Noise_XK(s, rs): - <- s - ... - -> e, es - <- e, ee - -> s, se - -Noise_XX(s, rs): - -> e - <- e, ee, s, es - -> s, se - -Noise_IN(s): - -> e, s - <- e, ee, se - -Noise_IK(s, rs): - <- s - ... - -> e, es, s, ss - <- e, ee, se - -Noise_IX(s, rs): - -> e, s - <- e, ee, se, s, es - -// Section 8.6. More patterns - -Noise_Xnoidh(s, rs): - <- s - ... - -> e, s, es, ss - -Noise_NXnoidh(rs): - -> e - <- e, s, ee, es - -Noise_XXnoidh(s, rs): - -> e - <- e, s, ee, es - -> s, se - -Noise_KXnoidh(s, rs): - -> s - ... - -> e - <- e, s, ee, se, es - -Noise_IKnoidh(s, rs): - <- s - ... - -> e, s, es, ss - <- e, ee, se - -Noise_IXnoidh(s, rs): - -> e, s - <- e, s, ee, se, es - -// Section 9.2. Compound protocols and "Noise Pipes" - -Noise_XXfallback(s, rs, re): - <- e - ... - -> e, ee, s, se - <- s, es diff --git a/patterns/noise-revision-32.txt b/patterns/noise-revision-32.txt deleted file mode 100644 index fd97d5b..0000000 --- a/patterns/noise-revision-32.txt +++ /dev/null @@ -1,93 +0,0 @@ -// Noise Protocol Framework, Revision 32 - -// Section 7.2. One-way patterns - -Noise_N(rs): - <- s - ... - -> e, es - -Noise_K(s, rs): - -> s - <- s - ... - -> e, es, ss - -Noise_X(s, rs): - <- s - ... - -> e, es, s, ss - -// Section 7.3. Interactive patterns - -Noise_NN(): - -> e - <- e, ee - -Noise_NK(rs): - <- s - ... - -> e, es - <- e, ee - -Noise_NX(rs): - -> e - <- e, ee, s, es - -Noise_KN(s): - -> s - ... - -> e - <- e, ee, se - -Noise_KK(s, rs): - -> s - <- s - ... - -> e, es, ss - <- e, ee, se - -Noise_KX(s, rs): - -> s - ... - -> e - <- e, ee, se, s, es - -Noise_XN(s): - -> e - <- e, ee - -> s, se - -Noise_XK(s, rs): - <- s - ... - -> e, es - <- e, ee - -> s, se - -Noise_XX(s, rs): - -> e - <- e, ee, s, es - -> s, se - -Noise_IN(s): - -> e, s - <- e, ee, se - -Noise_IK(s, rs): - <- s - ... - -> e, es, s, ss - <- e, ee, se - -Noise_IX(s, rs): - -> e, s - <- e, ee, se, s, es - -// Section 10.3. Noise Pipes - -Noise_XXfallback(e, s, rs): - -> e - ... - <- e, ee, s, es - -> s, se diff --git a/scripts/.gitignore b/scripts/.gitignore deleted file mode 100644 index 0d20b64..0000000 --- a/scripts/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.pyc diff --git a/scripts/noise_patterns.py b/scripts/noise_patterns.py deleted file mode 100644 index 90a7d6a..0000000 --- a/scripts/noise_patterns.py +++ /dev/null @@ -1,500 +0,0 @@ -""" -Definitions for working with patterns from the Noise Protocol Framework. - -Authors: - Rhys Weatherley <rhys.weatherley@gmail.com> - -This script is placed into the public domain. -""" - -import sys -import re - -__all__ = [ - 'Pattern', 'PatternErrorReporter', 'PatternTokenizer', - 'PatternParser', 'loadPatterns' -] - -NoiseParameters = ['e', 're', 's', 'rs', 'f', 'rf'] -NoiseTokens = ['e', 's', 'ee', 'es', 'se', 'ss', 'psk', 'f', 'ff'] -NoisePremessageTokens = ['e', 's', 'f'] - -class Pattern: - """ - Information about a Noise pattern. - - The 'name' property is the fully-qualified name of the pattern - including transformations; e.g. "XXfallback+hfs". - - The 'parameters' property is a list of strings for the parameters - to the pattern; e.g. ['s', 'rs']. - - The 'initiator_premessage' property is a list of tokens for the - initiator's premessage; e.g. ['s']. - - The 'responder_premessage' property is a list of tokens for the - responder's premessage; e.g. ['e']. - - The 'messages' property is a list of tuples for the messages in - the pattern; e.g. XX is [('->', ['e']), ('<-', ['e', 'ee', 's', 'es']), - ('->', ['s', 'se'])] - - The 'line' property is the line number in the file where the - pattern was read from, or zero if the line number is unknown. - - The 'reporter' property is the error reporting object for the - file the pattern was read from, for reporting errors and warnings - in the pattern after syntactic analysis is finished. - """ - name = '' - parameters = [] - initiator_premessage = [] - responder_premessage = [] - messages = [] - line = 0 - reporter = None - - def isOneWay(self): - """ - Determine if this is a one-way pattern; that is, there is only a - single message in the body of the pattern. - """ - return len(self.messages) == 1 - - def isInteractive(self): - """ - Determine if this is an interactive pattern; that is, there are - multiple messages in the body of the pattern or the first message - is from the responder (implying that there was a previous initiator). - """ - if len(self.messages) >= 2: - return True - if len(self.messages) == 1: - direction, message = self.messages[0] - return direction == '<-' - return False - - def baseName(self): - """ - Returns the base name of the pattern without transformations. - """ - m = re.match('([A-Z]+)', self.name) - if m: - return m.group(1) - else: - return None - - def transformations(self): - """ - Returns the list of transformations that have been applied - to the base name of the pattern. - """ - m = re.match('([A-Z]+)([a-z].*)$', self.name) - if m: - return m.group(2).split('+') - else: - return [] - - def addTransformation(self, t): - """ - Adds a transformation to the name of this pattern. - - This is typically used when constructing a new pattern as a - transformed variation on a pre-existing pattern. - """ - ts = self.transformations() - ts.append(t) - self.name = self.baseName() + '+'.join(ts) - - def __str__(self): - """ - Converts this pattern into its string representation in the - formal Noise pattern syntax. - """ - s = "Noise_" + self.name + "(" - if self.parameters: - s += ", ".join(self.parameters) - s += "):" - if self.initiator_premessage: - s += "\n -> " + ", ".join(self.initiator_premessage) - if self.responder_premessage: - s += "\n <- " + ", ".join(self.responder_premessage) - s += "\n ..." - elif self.responder_premessage: - s += "\n <- " + ", ".join(self.responder_premessage) - s += "\n ..." - for marker, tokens in self.messages: - s += "\n " + marker + " " + ", ".join(tokens) - return s + "\n" - - def error(self, message): - """ - Reports an error message for the pattern with the pattern's - original line number and filename. - """ - if reporter: - reporter.error(line, message) - elif line: - sys.stderr.write(str(line) + ": " + str(message) + "\n") - else: - sys.stderr.write(str(message) + "\n") - - def warning(self, message): - """ - Reports a warning message for the pattern with the pattern's - original line number and filename. - """ - if reporter: - reporter.warning(line, message) - elif line: - sys.stderr.write(str(line) + ": warning: " + str(message) + "\n") - else: - sys.stderr.write("warning: " + str(message) + "\n") - -class PatternErrorReporter: - """ - Reports errors and warnings while processing patterns from an input stream. - """ - - def __init__(self, filename): - """ - Constructs an error reporter for reporting problem - in a specific file. - """ - self._filename = filename - self._errors = 0 - self._warnings = 0 - - def line(self): - """ - Gets the current line being parsed. - """ - return self._linenum - - def error(self, line, message): - """ - Reports an error message on a specific line of the input. - """ - sys.stderr.write(str(self._filename) + ":" + str(line) + ": " + str(message) + "\n") - self._errors += 1 - - def warning(self, line, message): - """ - Reports a warning message on a specific line of the input. - """ - sys.stderr.write(str(self._filename) + ":" + str(line) + ": warning: " + str(message) + "\n") - self._warnings += 1 - - def hasErrors(self): - """ - Determine if we encountered errors while processing the input. - """ - return self._errors != 0 - - def hasWarnings(self): - """ - Determine if we encountered warnings while processing the input. - """ - return self._warnings != 0 - - def errorCount(self): - """ - Returns the number of errors that have occurred so far. - """ - return self._errors - - def warningCount(self): - """ - Returns the number of warnings that have occurred so far. - """ - return self._warnings - -class PatternTokenizer: - """ - Tokenizes Noise pattern definitions. - """ - - def __init__(self, stream, reporter): - """ - Constructs a new pattern tokenizer from the contents of an input stream. - """ - self._reporter = reporter - self._lines = stream.readlines() - self._token = None - self._tokens = [] - self._line = 0 - self._scanner = re.Scanner([ - (r"\bNoise_[A-Za-z0-9]+(\+[A-Za-z0-9]+)*\b", lambda scanner,token:token), - (r"\be\b", lambda scanner,token:"e"), - (r"\bee\b", lambda scanner,token:"ee"), - (r"\bes\b", lambda scanner,token:"es"), - (r"\bs\b", lambda scanner,token:"s"), - (r"\bse\b", lambda scanner,token:"se"), - (r"\bss\b", lambda scanner,token:"ss"), - (r"\bf\b", lambda scanner,token:"f"), - (r"\bff\b", lambda scanner,token:"ff"), - (r"\bre\b", lambda scanner,token:"re"), - (r"\brs\b", lambda scanner,token:"rs"), - (r"\brf\b", lambda scanner,token:"rf"), - (r"\bpsk\b", lambda scanner,token:"psk"), - (r"<-", lambda scanner,token:"<-"), - (r"->", lambda scanner,token:"->"), - (r"\.\.\.", lambda scanner,token:"..."), - (r"[,():]", lambda scanner,token:token), - (r"//[^\n]*\n", None), - (r"\s+", None), - ]) - - def token(self): - """ - Gets the current token from the input stream. - """ - return self._token - - def line(self): - """ - Gets the line number of the current token. - """ - return self._line - - def nextToken(self): - """ - Reads the next token from the input stream. Returns True - if the next token is available or False at EOF. - """ - if self._token == 'eof': - return False - while not self._tokens: - if not self._lines: - self._token = 'eof' - return False - self._line += 1 - self._tokens, rest = self._scanner.scan(self._lines.pop(0)) - if rest: - self._reporter.error(self._line, "invalid token encountered at " + rest.strip()) - self._token = self._tokens.pop(0) - return True - - def reporter(self): - """ - Returns the error reporter that is being used by this tokenizer. - """ - return self._reporter - -class PatternParser: - """ - Parses Noise pattern definitions from an input stream. - """ - - def __init__(self, stream, filename): - """ - Constructs a new pattern parser. - """ - self._reporter = PatternErrorReporter(filename) - self._tokenizer = PatternTokenizer(stream, self._reporter) - self._tokenizer.nextToken() - self._resync(True) - - def _resync(self, report): - """ - Re-synchronizes the input stream on the start of the next pattern - when an error occurs. - """ - while self._tokenizer.token() != 'eof' and not self._tokenizer.token().startswith('Noise_'): - if report: - self._reporter.error(self._tokenizer.line(), "unexpected token '" + self._tokenizer.token() + "', resynchronizing") - report = False - self._tokenizer.nextToken() - - def _expect(self, tokens): - """ - Expects one of a number of tokens to occur next and then skips it. - Reports an error if not. Returns the token that was actually found - or None. - """ - token = self._tokenizer.token() - if type(tokens) is list: - # Expecting one of a number of tokens in a list. - if token in tokens: - self._tokenizer.nextToken() - return token - else: - msg = "one of '" + "', '".join(tokens) + "' expected" - self._reporter.error(self._tokenizer.line(), msg) - return None - else: - # Expecting a specific token. - if token == tokens: - self._tokenizer.nextToken() - return token - else: - self._reporter.error(self._tokenizer.line(), "'" + str(tokens) + "' expected") - return None - - def _peek(self, tokens): - """ - Same as _expect(), but does not skip the token if it matches or - report an error if it doesn't match. - """ - token = self._tokenizer.token() - if type(tokens) is list: - # Expecting one of a number of tokens in a list. - if token in tokens: - return token - else: - return None - else: - # Expecting a specific token. - if token == tokens: - return token - else: - return None - - def _parseMessage(self, messages, initiator): - """ - Parses a token list starting with '->' or '<-'. - """ - if initiator: - if not self._expect('->'): - return False - marker = '->' - else: - if not self._expect('<-'): - return False - marker = '<-' - if not self._tokenizer.token() in NoiseTokens: - self._reporter.error(self._tokenizer.line(), "message token expected") - return False - msgs = [] - msgs.append(self._tokenizer.token()) - self._tokenizer.nextToken() - while self._tokenizer.token() == ',': - self._tokenizer.nextToken() - if not self._tokenizer.token() in NoiseTokens: - self._reporter.error(self._tokenizer.line(), "message token expected after comma") - return False - msgs.append(self._tokenizer.token()) - self._tokenizer.nextToken() - messages.append((marker, msgs)) - return True - - def _setPreMessages(self, pattern, messages): - """ - Sets the pre-messages for a pattern and validates them. - """ - if not messages: - self._reporter.error(self._tokenizer.line(), "pre-message is empty") - return False - for marker, msgs in messages: - for token in msgs: - if not token in NoisePremessageTokens: - self._reporter.error(self._tokenizer.line(), "'" + token + "' is not a valid pre-message token") - return False - if marker == '->': - if pattern.initiator_premessage: - self._reporter.error(self._tokenizer.line(), "multiple initiator pre-messages") - return False - pattern.initiator_premessage = msgs - else: - if pattern.responder_premessage: - self._reporter.error(self._tokenizer.line(), "multiple responder pre-messages") - return False - pattern.responder_premessage = msgs - return True - - def _parsePattern(self, pattern): - """ - Parses a pattern from the input stream, starting at a name token. - """ - pattern.name = self._tokenizer.token()[6:] - pattern.line = self._tokenizer.line() - pattern.reporter = self._reporter - self._tokenizer.nextToken() - - # Parse the parameter list - if not self._expect('('): - return - pattern.parameters = [] - while self._peek(NoiseParameters): - pattern.parameters.append(self._tokenizer.token()) - self._tokenizer.nextToken() - if not self._peek(','): - break - self._tokenizer.nextToken() - if not self._expect(')'): - return - if not self._expect(':'): - return - - messages = [] - initiator = self._peek('->') - while self._peek(['->', '<-']): - if not self._parseMessage(messages, initiator): - return - initiator = not initiator - - if self._peek('...'): - # The previous sequences were pre-messages - validate them. - if not self._setPreMessages(pattern, messages): - return - - # Now parse the actual message body. - self._tokenizer.nextToken() - messages = [] - initiator = self._peek('->') - while self._peek(['->', '<-']): - if not self._parseMessage(messages, initiator): - return - initiator = not initiator - - if not messages: - self._reporter.error(self._tokenizer.line(), "message body is empty") - return - pattern.messages = messages - - def readPattern(self): - """ - Reads the next pattern from the input stream and returns it. - Returns None at the end of the input stream. - """ - report = True - while self._tokenizer.token() != 'eof': - self._resync(report) - report = False - if self._tokenizer.token().startswith('Noise_'): - prevErrorCount = self._reporter.errorCount() - pattern = Pattern() - self._parsePattern(pattern) - if self._reporter.errorCount() == prevErrorCount: - # No errors reported, so the pattern is ok. - return pattern - return None - - def readPatterns(self): - """ - Returns a list of all patterns in the input stream. - """ - patterns = [] - while self._tokenizer.token != 'eof': - pattern = self.readPattern() - if not pattern: - break - patterns.append(pattern) - return patterns - - def reporter(self): - """ - Returns the error reporter that is being used by this parser. - """ - return self._reporter - -def loadPatterns(filename): - """ - Helper function that loads all Noise patterns from a file. - """ - if filename == "-": - parser = PatternParser(sys.stdin, "stdin") - else: - with open(filename) as file: - parser = PatternParser(file, filename) - return parser.readPatterns() diff --git a/scripts/transform_fallback.py b/scripts/transform_fallback.py deleted file mode 100755 index 22c3d74..0000000 --- a/scripts/transform_fallback.py +++ /dev/null @@ -1,61 +0,0 @@ -#!/usr/bin/python -""" -Applies the 'fallback' transformation to Noise patterns. - -Authors: - Rhys Weatherley <rhys.weatherley@gmail.com> - -This script is placed into the public domain. -""" - -import sys -from noise_patterns import * - -def combine(list1, list2): - result = list(list1) - for elem in list2: - if not elem in list1: - result.append(elem) - return result - -def make_fallback(orig): - pattern = Pattern() - pattern.name = orig.name - pattern.addTransformation('fallback') - direction, first_message = orig.messages[0] - pattern.parameters = combine(first_message, orig.parameters) - pattern.initiator_premessage = first_message + orig.initiator_premessage - pattern.responder_premessage = list(orig.responder_premessage) - pattern.messages = [] - for direction, message in orig.messages[1:]: - pattern.messages.append((direction, list(message))) - return pattern - -def fallback_compatible(pattern): - direction, messages = pattern.messages[0]; - if direction != '->': - return False - if messages == ['e'] or messages == ['e', 's']: - return True - return False - -if len(sys.argv) <= 1: - print "Usage: " + sys.argv[0] + " file ..." - sys.exit(1) - -for file in sys.argv[1:]: - patterns = loadPatterns(file) - for pattern in patterns: - if not pattern.isInteractive(): - # Only interactive patterns can be fallback. - continue - if 'fallback' in pattern.transformations(): - # The pattern is already fallback. - continue - if not fallback_compatible(pattern): - # The first message is not fallback-compatible. - continue - fallback = make_fallback(pattern) - print fallback - -sys.exit(0) diff --git a/scripts/transform_hfs.py b/scripts/transform_hfs.py deleted file mode 100755 index 916e409..0000000 --- a/scripts/transform_hfs.py +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/python -""" -Applies the 'hfs' transformation to Noise patterns. - -Authors: - Rhys Weatherley <rhys.weatherley@gmail.com> - -This script is placed into the public domain. -""" - -import sys -from noise_patterns import * - -def hybridize(tokens): - result = [] - for token in tokens: - result.append(token) - if token == 'e': - result.append('f') - elif token == 'ee': - result.append('ff') - elif token == 're': - result.append('rf') - return result - -def make_hfs(orig): - pattern = Pattern() - pattern.name = orig.name - pattern.addTransformation('hfs') - pattern.parameters = hybridize(orig.parameters) - pattern.initiator_premessage = hybridize(orig.initiator_premessage) - pattern.responder_premessage = hybridize(orig.responder_premessage) - pattern.messages = [] - for marker, tokens in orig.messages: - pattern.messages.append((marker, hybridize(tokens))) - return pattern - -if len(sys.argv) <= 1: - print "Usage: " + sys.argv[0] + " file ..." - sys.exit(1) - -for file in sys.argv[1:]: - patterns = loadPatterns(file) - for pattern in patterns: - if not pattern.isInteractive(): - # Only interactive patterns can by hybridized. - continue - if 'hfs' in pattern.transformations(): - # The pattern is already hybrid. - continue - hfs = make_hfs(pattern) - print hfs - -sys.exit(0) diff --git a/scripts/transform_psk.py b/scripts/transform_psk.py deleted file mode 100755 index 90ced04..0000000 --- a/scripts/transform_psk.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/python -""" -Applies the 'pskN' transformations to Noise patterns. - -Authors: - Rhys Weatherley <rhys.weatherley@gmail.com> - -This script is placed into the public domain. -""" - -import sys -from noise_patterns import * - -def make_psk(orig, modifier, psk_num): - pattern = Pattern() - pattern.name = orig.name - pattern.addTransformation(modifier) - pattern.parameters = list(orig.parameters) - pattern.initiator_premessage = list(orig.initiator_premessage) - pattern.responder_premessage = list(orig.responder_premessage) - pattern.messages = [] - if psk_num == 0: - direction, message = orig.messages[0] - pattern.messages.append((direction, ['psk'] + message)) - for direction, message in orig.messages[1:]: - pattern.messages.append((direction, list(message))) - else: - posn = 1 - for direction, message in orig.messages: - if psk_num == posn: - pattern.messages.append((direction, message + ['psk'])) - else: - pattern.messages.append((direction, list(message))) - posn += 1 - return pattern - -if len(sys.argv) <= 2: - print "Usage: " + sys.argv[0] + " N file ..." - sys.exit(1) - -psk_num = int(sys.argv[1]) -modifier = "psk" + sys.argv[1] - -for file in sys.argv[2:]: - patterns = loadPatterns(file) - for pattern in patterns: - if modifier in pattern.transformations(): - # The modifier was already applied to this pattern. - continue - if psk_num > len(pattern.messages): - # Cannot apply the modifier to this pattern because - # there aren't enough messages in it. - continue - psk = make_psk(pattern, modifier, psk_num) - print psk - -sys.exit(0) diff --git a/spec_markdown.css b/spec_markdown.css deleted file mode 100644 index 0b2ff42..0000000 --- a/spec_markdown.css +++ /dev/null @@ -1,101 +0,0 @@ -html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; } - -body{ -color:#444; -font-family:'Helvetica Neue', 'Helvetica', 'Arial'; -font-size:12px; -line-height:1.5em; -padding:1em; -margin:auto; -max-width:42em; -background:#ffffff; -} - -a{ color: #0645ad; text-decoration:none;} -a:hover{ color: #06e; } -a:active{ color:#faa700; } -a:focus{ outline: thin dotted; } -a:hover, a:active{ outline: 0; } - -::-moz-selection{background:rgba(255,255,0,0.3);color:#000} -::selection{background:rgba(255,255,0,0.3);color:#000} - -a::-moz-selection{background:rgba(255,255,0,0.3);color:#0645ad} -a::selection{background:rgba(255,255,0,0.3);color:#0645ad} - -p{ -margin:1em 0; -} - -img{ -max-width:100%; -} - -h1,h2,h3,h4,h5,h6{ -font-weight:normal; -color:#111; -line-height:1em; -} -h4,h5,h6{ font-weight: bold; } -h1{ font-size:2.5em; } -h2{ font-size:2em; } -h3{ font-size:1.5em; } -h4{ font-size:1.2em; } -h5{ font-size:1em; } -h6{ font-size:0.9em; } - -blockquote{ -color:#666666; -margin:0; -padding-left: 3em; -border-left: 0.5em #EEE solid; -} -hr { display: block; height: 2px; border: 0; border-top: 1px solid #aaa;border-bottom: 1px solid #eee; margin: 1em 0; padding: 0; } -pre, code, kbd, samp { font-family: monospace, monospace; _font-family: 'courier new', monospace; font-size: 0.98em; line-height: 1.25em; } -pre { background-color: #FFF; white-space: pre; white-space: pre-wrap; word-wrap: break-word; margin: 0 0; } - -b, strong { font-weight: bold; } - -dfn { font-style: italic; } - -ins { background: #ff9; color: #000; text-decoration: none; } - -mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; } - -sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; } -sup { top: -0.5em; } -sub { bottom: -0.25em; } - -ul, ol { margin: 1em 1; padding: 0 0 0 2em; } -li p:last-child { margin:1 } -dd { margin: 0 0 0 2em; } - -img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; } - -table { border-collapse: collapse; border-spacing: 0; } -td { vertical-align: top; padding: 12px; } - -@media only screen and (min-width: 480px) { -body{font-size:14px;} -} - -@media only screen and (min-width: 768px) { -body{font-size:16px;} -} - -@media print { - * { background: transparent !important; color: black !important; filter:none !important; -ms-filter: none !important; } - body{font-size:12pt; max-width:100%;} - a, a:visited { text-decoration: underline; } - hr { height: 1px; border:0; border-bottom:1px solid black; } - a[href]:after { content: " (" attr(href) ")"; } - abbr[title]:after { content: " (" attr(title) ")"; } - .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } - pre, blockquote { border: 1px solid #999; padding-right: 1em; page-break-inside: avoid; } - tr, img { page-break-inside: avoid; } - img { max-width: 100% !important; } - @page :left { margin: 15mm 20mm 15mm 10mm; } - @page :right { margin: 15mm 10mm 15mm 20mm; } - p, h2, h3 { orphans: 3; widows: 3; } - h2, h3 { page-break-after: avoid; } -} diff --git a/template_pandoc.html b/template_pandoc.html deleted file mode 100644 index 376b096..0000000 --- a/template_pandoc.html +++ /dev/null @@ -1,74 +0,0 @@ -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> -<html xmlns="http://www.w3.org/1999/xhtml"$if(lang)$ lang="$lang$" xml:lang="$lang$"$endif$$if(dir)$ dir="$dir$"$endif$> -<head> - <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> - <meta http-equiv="Content-Style-Type" content="text/css" /> - <meta name="generator" content="pandoc" /> -$for(author-meta)$ - <meta name="author" content="$author-meta$" /> -$endfor$ -$if(date-meta)$ - <meta name="date" content="$date-meta$" /> -$endif$ -$if(keywords)$ - <meta name="keywords" content="$for(keywords)$$keywords$$sep$, $endfor$" /> -$endif$ - <title>$if(title-prefix)$$title-prefix$ – $endif$$pagetitle$</title> - <style type="text/css">code{white-space: pre;}</style> -$if(quotes)$ - <style type="text/css">q { quotes: "“" "”" "‘" "’"; }</style> -$endif$ -$if(highlighting-css)$ - <style type="text/css"> -$highlighting-css$ - </style> -$endif$ -$for(css)$ - <link rel="stylesheet" href="$css$" type="text/css" /> -$endfor$ -$if(math)$ - $math$ -$endif$ -$for(header-includes)$ - $header-includes$ -$endfor$ -</head> -<body> -$for(include-before)$ -$include-before$ -$endfor$ -$if(title)$ -<div id="$idprefix$header"> -<h1 class="title">$title$</h1> -$if(subtitle)$ -<h1 class="subtitle">$subtitle$</h1> -$endif$ -$for(author)$ -<b>Author:</b> $author$<br/> -$endfor$ -$if(revision)$ -<b>Revision:</b> $revision$<br/> -$endif$ -$if(date)$ -<b>Date:</b> $date$<br/> -$endif$ -$if(pdfn)$ -<b>PDF:</b> <a href="$pdfn$">$pdfn$</a><br/> -$endif$ -$if(Copyright)$ -<h3 class="date">Copyright: $Copyright$</h3> -$endif$ -</div> -$endif$ -$if(toc)$ -<div id="$idprefix$TOC"> -<h2 class="toc">Table of Contents</h2> -$toc$ -</div> -$endif$ -$body$ -$for(include-after)$ -$include-after$ -$endfor$ -</body> -</html> diff --git a/template_pandoc.latex b/template_pandoc.latex deleted file mode 100644 index b9babfa..0000000 --- a/template_pandoc.latex +++ /dev/null @@ -1,259 +0,0 @@ -\documentclass[$if(fontsize)$$fontsize$,$endif$$if(lang)$$babel-lang$,$endif$$if(papersize)$$papersize$paper,$endif$$for(classoption)$$classoption$$sep$,$endfor$]{$documentclass$} -$if(fontfamily)$ -\usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$} -$else$ -\usepackage{lmodern} -$endif$ -$if(linestretch)$ -\usepackage{setspace} -\setstretch{$linestretch$} -$endif$ -\usepackage{amssymb,amsmath} -\usepackage{ifxetex,ifluatex} -\usepackage{fixltx2e} % provides \textsubscript -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc} - \usepackage[utf8]{inputenc} -$if(euro)$ - \usepackage{eurosym} -$endif$ -\else % if luatex or xelatex - \ifxetex - \usepackage{mathspec} - \else - \usepackage{fontspec} - \fi - \defaultfontfeatures{Ligatures=TeX,Scale=MatchLowercase} -$if(euro)$ - \newcommand{\euro}{€} -$endif$ -$if(mainfont)$ - \setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$} -$endif$ -$if(sansfont)$ - \setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$} -$endif$ -$if(monofont)$ - \setmonofont[Mapping=tex-ansi$if(monofontoptions)$,$for(monofontoptions)$$monofontoptions$$sep$,$endfor$$endif$]{$monofont$} -$endif$ -$if(mathfont)$ - \setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} -$endif$ -$if(CJKmainfont)$ - \usepackage{xeCJK} - \setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} -$endif$ -\fi -% use upquote if available, for straight quotes in verbatim environments -\IfFileExists{upquote.sty}{\usepackage{upquote}}{} -% use microtype if available -\IfFileExists{microtype.sty}{% -\usepackage{microtype} -\UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts -}{} -$if(geometry)$ -\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry} -$endif$ -\usepackage{hyperref} -$if(colorlinks)$ -\PassOptionsToPackage{usenames,dvipsnames}{color} % color is loaded by hyperref -$endif$ -\hypersetup{unicode=true, -$if(title-meta)$ - pdftitle={$title-meta$}, -$endif$ -$if(author-meta)$ - pdfauthor={$author-meta$}, -$endif$ -$if(keywords)$ - pdfkeywords={$for(keywords)$$keywords$$sep$; $endfor$}, -$endif$ -$if(colorlinks)$ - colorlinks=true, - linkcolor=$if(linkcolor)$$linkcolor$$else$Maroon$endif$, - citecolor=$if(citecolor)$$citecolor$$else$Blue$endif$, - urlcolor=$if(urlcolor)$$urlcolor$$else$Blue$endif$, -$else$ - pdfborder={0 0 0}, -$endif$ - breaklinks=true} -\urlstyle{same} % don't use monospace font for urls -$if(lang)$ -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel} -$if(babel-newcommands)$ - $babel-newcommands$ -$endif$ -\else - \usepackage{polyglossia} - \setmainlanguage[$polyglossia-lang.options$]{$polyglossia-lang.name$} -$for(polyglossia-otherlangs)$ - \setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$} -$endfor$ -\fi -$endif$ -$if(natbib)$ -\usepackage{natbib} -\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$} -$endif$ -$if(biblatex)$ -\usepackage$if(biblio-style)$[style=$biblio-style$]$endif${biblatex} -$if(biblatexoptions)$\ExecuteBibliographyOptions{$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$}$endif$ -$for(bibliography)$ -\addbibresource{$bibliography$} -$endfor$ -$endif$ -$if(listings)$ -\usepackage{listings} -$endif$ -$if(lhs)$ -\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} -$endif$ -$if(highlighting-macros)$ -$highlighting-macros$ -$endif$ -$if(verbatim-in-note)$ -\usepackage{fancyvrb} -\VerbatimFootnotes % allows verbatim text in footnotes -$endif$ -$if(tables)$ -\usepackage{longtable,booktabs} -$endif$ -$if(graphics)$ -\usepackage{graphicx,grffile} -\makeatletter -\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} -\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} -\makeatother -% Scale images if necessary, so that they will not overflow the page -% margins by default, and it is still possible to overwrite the defaults -% using explicit options in \includegraphics[width, height, ...]{} -\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} -$endif$ -$if(links-as-notes)$ -% Make links footnotes instead of hotlinks: -\renewcommand{\href}[2]{#2\footnote{\url{#1}}} -$endif$ -$if(strikeout)$ -\usepackage[normalem]{ulem} -% avoid problems with \sout in headers with hyperref: -\pdfstringdefDisableCommands{\renewcommand{\sout}{}} -$endif$ -$if(indent)$ -$else$ -\IfFileExists{parskip.sty}{% -\usepackage{parskip} -}{% else -\setlength{\parindent}{0pt} -\setlength{\parskip}{6pt plus 2pt minus 1pt} -} -$endif$ -\setlength{\emergencystretch}{3em} % prevent overfull lines -\providecommand{\tightlist}{% - \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} -$if(numbersections)$ -\setcounter{secnumdepth}{5} -$else$ -\setcounter{secnumdepth}{0} -$endif$ -$if(subparagraph)$ -$else$ -% Redefines (sub)paragraphs to behave more like sections -\ifx\paragraph\undefined\else -\let\oldparagraph\paragraph -\renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}} -\fi -\ifx\subparagraph\undefined\else -\let\oldsubparagraph\subparagraph -\renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}} -\fi -$endif$ -$if(dir)$ -\ifxetex - % load bidi as late as possible as it modifies e.g. graphicx - $if(latex-dir-rtl)$ - \usepackage[RTLdocument]{bidi} - $else$ - \usepackage{bidi} - $endif$ -\fi -\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex - \TeXXeTstate=1 - \newcommand{\RL}[1]{\beginR #1\endR} - \newcommand{\LR}[1]{\beginL #1\endL} - \newenvironment{RTL}{\beginR}{\endR} - \newenvironment{LTR}{\beginL}{\endL} -\fi -$endif$ -$for(header-includes)$ -$header-includes$ -$endfor$ - -$if(title)$ -\title{$title$$if(thanks)$\thanks{$thanks$}$endif$} -$endif$ -$if(subtitle)$ -\providecommand{\subtitle}[1]{} -\subtitle{$subtitle$} -$endif$ -$if(author)$ -\author{$for(author)$$author$$sep$ \and $endfor$} -$endif$ -$if(institute)$ -\institute{$for(institute)$$institute$$sep$ \and $endfor$} -$endif$ -\date{Revision $revision$, $date$} - -\begin{document} -$if(title)$ -\maketitle -$endif$ -$if(abstract)$ -\begin{abstract} -$abstract$ -\end{abstract} -$endif$ - -$for(include-before)$ -$include-before$ - -$endfor$ -$if(toc)$ -{ -$if(colorlinks)$ -\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$black$endif$} -$endif$ -\setcounter{tocdepth}{$toc-depth$} -\tableofcontents -} -$endif$ -$if(lot)$ -\listoftables -$endif$ -$if(lof)$ -\listoffigures -$endif$ -$body$ - -$if(natbib)$ -$if(bibliography)$ -$if(biblio-title)$ -$if(book-class)$ -\renewcommand\bibname{$biblio-title$} -$else$ -\renewcommand\refname{$biblio-title$} -$endif$ -$endif$ -\bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$} - -$endif$ -$endif$ -$if(biblatex)$ -\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$ - -$endif$ -$for(include-after)$ -$include-after$ - -$endfor$ -\end{document} |