lsd0011

LSD0011: The Elligator HPKE KEM
Log | Files | Refs

commit 411556aa19cd9912a2f39da75796f3d75b86ee48
Author: Martin Schanzenbach <schanzen@gnunet.org>
Date:   Fri, 19 Jul 2024 10:28:03 +0200

initial commit

Diffstat:
A.buildbot/build.sh | 3+++
A.buildbot/firefly-x86_64-amdepyc_deploy.sh | 10++++++++++
A.gitignore | 2++
AMakefile | 8++++++++
Adraft-schanzen-hpke-elligator-kem.xml | 509+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Astyle.css | 1149+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 1681 insertions(+), 0 deletions(-)

diff --git a/.buildbot/build.sh b/.buildbot/build.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +make diff --git a/.buildbot/firefly-x86_64-amdepyc_deploy.sh b/.buildbot/firefly-x86_64-amdepyc_deploy.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# Deploy rest api from buildbot + +if [ -e index.html ]; then + rm index.html +fi +ln -s draft-schanzen-hpke-elligator-kem.html index.html +chmod -R ag+rX draft-schanzen-hpke-elligator-kem.* index.html . +rsync --exclude=".*" --exclude="Makefile" -a --delete ./ lsd@firefly.gnunet.org:~/public/lsd0011/ diff --git a/.gitignore b/.gitignore @@ -0,0 +1,2 @@ +draft-schanzen-hpke-elligator-kem.html +draft-schanzen-hpke-elligator-kem.txt diff --git a/Makefile b/Makefile @@ -0,0 +1,8 @@ +all: txt html + +html: + xml2rfc --html --css style.css draft-schanzen-hpke-elligator-kem.xml + +txt: + xml2rfc draft-schanzen-hpke-elligator-kem.xml + diff --git a/draft-schanzen-hpke-elligator-kem.xml b/draft-schanzen-hpke-elligator-kem.xml @@ -0,0 +1,509 @@ +<?xml version='1.0' encoding='utf-8'?> +<!DOCTYPE rfc [ +<!ENTITY RFC1034 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.1034.xml"> +<!ENTITY RFC1035 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.1035.xml"> +<!ENTITY RFC1928 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.1928.xml"> +<!ENTITY RFC2119 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml"> +<!--<!ENTITY RFC2693 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2693.xml">--> +<!ENTITY RFC2782 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2782.xml"> +<!ENTITY RFC3629 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3629.xml"> +<!ENTITY RFC3686 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3686.xml"> +<!ENTITY RFC3826 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3826.xml"> +<!ENTITY RFC4033 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4033.xml"> +<!ENTITY RFC5237 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5237.xml"> +<!--<!ENTITY RFC3912 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3912.xml">--> +<!ENTITY RFC5869 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5869.xml"> +<!ENTITY RFC5890 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5890.xml"> +<!ENTITY RFC5895 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5895.xml"> +<!ENTITY RFC6066 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6066.xml"> +<!ENTITY RFC6761 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6761.xml"> +<!ENTITY RFC6895 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6895.xml"> +<!ENTITY RFC6979 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6979.xml"> +<!ENTITY RFC7363 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7363.xml"> +<!ENTITY RFC8806 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8806.xml"> +<!ENTITY RFC7748 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7748.xml"> +<!ENTITY RFC8126 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8126.xml"> +<!ENTITY RFC8174 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8174.xml"> +<!ENTITY RFC8244 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8244.xml"> +<!ENTITY RFC8324 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8324.xml"> +<!ENTITY RFC8499 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.8499.xml"> +<!ENTITY RFC9106 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.9106.xml"> +<!ENTITY RFC9180 PUBLIC '' "http://xml.resource.org/public/rfc/bibxml/reference.RFC.9180.xml"> +<!ENTITY I-D.ietf-dnsop-alt-tld PUBLIC '' "http://xml.resource.org/public/rfc/bibxml3/reference.I-D.ietf-dnsop-alt-tld.xml"> +]> +<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?> +<?rfc strict="yes" ?> +<?rfc toc="yes" ?> +<?rfc symrefs="yes"?> +<?rfc sortrefs="yes" ?> +<?rfc compact="yes" ?> +<?rfc subcompact="no" ?> +<rfc xmlns:xi="http://www.w3.org/2001/XInclude" + category="info" + docName="draft-schanzen-hpke-elligator-kem-00" + ipr="trust200902" + obsoletes="" updates="" + submissionType="independent" + xml:lang="en" + version="3"> + <!-- xml2rfc v2v3 conversion 2.26.0 --> + <front> + <title abbrev="The HPKE Elligator KEM"> + The HPKE Elligator KEM + </title> + <seriesInfo name="Internet-Draft" value="draft-schanzen-hpke-elligator-kem-00"/> + <author fullname="Martin Schanzenbach" initials="M." surname="Schanzenbach"> + <organization>Fraunhofer AISEC</organization> + <address> + <postal> + <street>Lichtenbergstrasse 11</street> + <city>Garching</city> + <code>85748</code> + <country>DE</country> + </postal> + <email>martin.schanzenbach@aisec.fraunhofer.de</email> + </address> + </author> + <author fullname="Pedram Fardzadeh" initials="P." surname="Fardzadeh"> + <organization>Technischen Universität München</organization> + <address> + <postal> + <street>Boltzmannstrasse 3</street> + <city>Garching</city> + <code>85748</code> + <country>DE</country> + </postal> + <email>pedram.fardzadeh@tum.de</email> + </address> + </author> + + + <!-- Meta-data Declarations --> + <area>General</area> + <workgroup>Independent Stream</workgroup> + <keyword>transport protocols</keyword> + <abstract> + <t> + This document contains the GNUnet communicator + specification. + </t> + <t> + This document defines the normative wire format of communicator protocols, + cryptographic routines and security + considerations for use by implementers. + </t> + <t> + This specification was developed outside the IETF and does not have + IETF consensus. It is published here to inform readers about the + function of GNUnet communicators, guide future communicator implementations, and ensure + interoperability among implementations including with the pre-existing + GNUnet implementation. + </t> + </abstract> + </front> + <middle> + <section anchor="introduction" numbered="true" toc="default"> + <name>Introduction</name> + <t> + This document defines the normative wire format of resource + records, resolution processes, cryptographic routines and + security considerations for use by implementers. + </t> + <t> + This specification was developed outside the IETF and does not have + IETF consensus. It is published here to guide implementers of GNS + and to ensure interoperability among implementations. + </t> + <section numbered="true" toc="default"> + <name>Requirements Notation</name> + <t> + The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", + "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and + "OPTIONAL" in this document are to be interpreted as described in + BCP 14 <xref target="RFC2119"/> <xref target="RFC8174"/> when, and only + when, they appear in all capitals, as shown here. + </t> + </section> + </section> + <section anchor="primitives" numbered="true" toc="default"> + <name>Cryptographic dependencies</name> + <section anchor="elligator_dhkem" numbered="true" toc="default"> + <name>Elligator DHKEM</name> + <t> + While standard Diffie-Hellman-based KEMs securely establish a secret between two parties, an observer can easily identify + the encapsulation as a public key. + In the presence of an active attacker this could lead to packet dropping based on this information, + preventing communication between peers. + The Elligator KEM defined in the following to produce random-looking encapsulations (referred to as a "representative"). + This leaves the attacker with the option to either do nothing or intercept all random-looking packets, + thereby potentially disrupting a large part of today's internet communication. + </t> + <t> + Elligator KEM utilizes Elligator for the encoding and decoding of the ephemeral public keys + as described in Section 5 of <xref target="BHKL13"/>. + The general idea when generating an Elligator key pair is is to create both a random high-order curve point and a low-order curve point. + Adding them together results in a curve point that is evenly distributed on the whole Curve25519. + Not all Curve25519 points are suitable for use with Elligator. + In particular, not all Curve25519 points have the property that the Elligator encoding and subsequent + decoding result in the original point (See <xref target="security_elligator"/> for details). + To create a Curve25519 point that can be used with Elligator, one needs to find a curve point + for which this property holds. + One heurisitic is to generate random key pairs until one such point is found. + </t> + <t> + We define our KEMs analoguous to <xref target="RFC9180"/> Section 4. + The <tt>kem_id</tt> in the <tt>suite_id</tt> for the Elligator KEM is <tt>256</tt> (NOTE: This value is not registered in IANA yet). + </t> + <t> + The value of <tt>suite_id</tt> depends on the KEM used. The <tt>ExtractAndExpand()</tt>, <tt>Encap()</tt> + and <tt>Decap()</tt> functions are used as defined in <xref target="RFC9180"/> for standard DHKEMs. + The communicators use the standard <tt>DHKEM(X25519, HKDF-SHA256)</tt> and a special Elligator-based KEM + defined below which we call <tt>DHKEM(X25519Elligator, HKDF-SHA256)</tt>. + </t> + <section anchor="elligator_dhkem_keygen" numbered="true" toc="default"> + <name>GenerateKeyPair()</name> + <t> + Let G be the generator of the prime order group of Ed25519, H the generator of the low order subgroup of + Ed25519 and EdToCurve() a function which converts Ed25519 points to their corresponding Curve25519 points. + We define "KeyGenElligator" as follows: + </t> +<artwork name="" type="" align="left" alt=""><![CDATA[ +GenerateKeyPair(): + VALID := 0 + while(!VALID): + skX := random(256) + skX[0] &= 248 + skX[31] &= 127 + skX[31] |= 64 + E_high := skX * G + E_low := (skX mod 8) * H + E := E_high + E_low + pkX := EdToCurve(E) + if ElligatorDec(ElligatorEnc(pkX)) == pkX: + return (skX,pkX) + ]]></artwork> + </section> + <section anchor="elligator_dhkem_serialize" numbered="true" toc="default"> + <name>SerializePublicKey()</name> + <t> + The serialization functions incorporate the Elligator encoding and decoding functions to obfuscate a curve + point and are are defined in the following. + The obfuscated curve point is called the Elligator "Representative". + Let A and P be the parameters for Curve25519 as specified in section 4.1 of <xref target="RFC7748"/>. + Further, let X be any valid x-coordinate of a Curve25519 point, L() a function which computes the legendre symbol + of a field element with regard to the odd prime P. + In order for the square root operation sqrt within the encoding function to work deterministically, we need to + define the notion of positive and negative numbers within the field. There are multiple valid ways to partition + the field elements, but a common choice is to define the set {0,..., (P-1)/2} as the set of positive numbers, + and {(P-1)/2 + 1,…,P−1} as the set of the negative numbers. The encoding function also requires a non-square number + U of the finite field. While U could be chosen arbitrarily, small numbers like sqrt(-1) are preferred due to reduce + computation. + The elligator implementations of both peers <bcp14>MUST</bcp14> + use the same definition regarding positive and negative numbers and U to be interoperable. + The encoding function algorithm is: + </t> +<artwork name="" type="" align="left" alt=""><![CDATA[ +SerializeElligatorPublicKey(pkX): + B := random(1) + if B == 1: + pkXm := sqrt(-X / ((X + A) * U)) + else: + pkXm := sqrt(-(X + A) / (U * X)) + return pkXm +]]></artwork> + </section> + <section anchor="elligator_dhkem_deserialize" numbered="true" toc="default"> + <name>DeserializePublicKey()</name> + <t> + The corresponding decoding agorithm is: + </t> + <artwork name="" type="" align="left" alt=""><![CDATA[ +DeserializeElligatorPublicKey(pkXm): + V := -A / (1 + U * R^2) + E := L(V^3 + A * V^2 + V) + pkX := E * V - (1 - E)(A / 2) + return pkX + ]]></artwork> + </section> + </section> + </section> + <section anchor="security" numbered="true" toc="default"> + <name>Security and Privacy Considerations</name> + <section anchor="security_elligator" numbered="true" toc="default"> + <name>Elligator</name> + <t> + In case of Montgomery curves, such as Curve25519, a point [X, Y] on that curve (e.g. the ephemeral public key) follows the equation + Y^2 = X^3 + A * X^2 + X mod P, where A and P are parameters for Curve25519 specified in section 4.1 of <xref target="RFC7748"/>. For any + valid x-coordinate, the left side of the equation is always a quadratic number. An attacker could read the x-coordinate + and verify if this property holds. While this property holds for any valid Curve25519 point, it only holds in about 50% of the cases for a + random number. By observing multiple communication attempts, an attacker can be certain that curve points are being sent if the property consistently holds. + To circumvent this attack, curve points should be encoded into property-less numbers, making valid and invalid curve points indistinguishable + to an outside observer. + The Elligator encoding function "ElligatorEnc" (also known as the "inverse map") and decoding function "ElligatorDec" (also known as the "direct map") implement this feature. + </t> + <t> + The encoding function is defined for the entire Curve25519. Most modern implementations of Curve25519 only generate points from its prime + subgroup to circumvent known attacks for which points not within the prime subgroup are susceptible. In our case, those attacks are not an + issue as we use the ephemeral secret key only once for computing key material. The exclusive use of the prime subgroup is a recognizable + property that an outside observer can easily detect, even in the case of using the encoding function. An attacker could decode the suspected + parts of packets to the corresponding Curve25519 points and check if the resulting points are always in the prime subgroup. To circumvent + this attack, we need to choose the ephemeral key pair randomly from the whole curve as defined in "KeyGenElligator". + </t> + <t> + Note that both for a value R and its negative counterpart -R (in the finite field), the decoding function will result in the same + x-coordinate. Moreover, for two different valid x-coordinates, the resulting representatives of the corresponding encoding calls are + different. Conversely, this means that we can't decode both representatives back to their original x-coordinate. This is why the sender + eventually tries a number of random key pairs in KeyGenElligator() in order to create a valid public key that can be used + for a key exchange. Also note that this effectively reduces the entropy of our public keys by 1 bit, which is tolerable. + </t> + <t> + In the original paper, Elligator's encoding function takes the sign of y-coordinate as an additional input parameter. Its value determines + which of the two terms is used instead of our random selection. We also skip the calculation of the corresponding y-coordinate in the decoding function. + We omitted the y-coordinate parts of both functions because Curve25519 points are solely represented by their x-coordinate in modern crypto systems due to + known attacks. Nevertheless, the desired feature of Elligator is still ensured. + </t> + <t> + Lastly, we emphasize that the resulting representative of the encoding function is strictly smaller than 2^254 - 9. Therefore, the most and second most + significant bit are always zero, which is an obvious property an attacker could observe. We avoid this problem by randomly flipping + both bits. These bits will be ignored by the target peer after reception. + </t> + </section> + </section> + <section anchor="work_in_progress" numbered="true" toc="default"> + <name>Work in Progress</name> + <t> + TRANSPORT API: GNUNET_TRANSPORT_MessageCompletedCallback, GNUNET_TRANSPORT_communicator_receive, and + GNUNET_TRANSPORT_MessageCompletedCallback should follow a generic API for all communicator types. + </t> + <t> + UDP Communicator: RTT (Round-Trip Time) measurement is missing. Values such as the number of shared secrets could be adapted based on the RTT. + </t> + <t> + TCP Communicator: Currently, the only sanity check for a valid TCP handshake message is the verification of the signature. Additional checks, such as + verifying the sender's peer identity, are needed. + The use of the mac-then-encrypt approach within the TCP BOX messages should be analyzed further, specifically regarding padding-oracle attacks. + </t> + </section> + <section anchor="gana" numbered="true" toc="default"> + <name>GANA Considerations</name> + </section> + <!-- gana --> + <section> + <name>IANA Considerations</name> + <t> + This document defines a new KEM as allowed in <xref target="RFC9180"/>. + It is requested that the "HPKE KEM Identifiers" registry is updated with + the values from <xref target="kemid-values"/>. + This section may be removed on publication as an RFC. + </t> + <table anchor="kemid-values" align="center" pn="table-2"> + <name slugifiedName="name-kem-ids">KEM IDs</name> + <thead> + <tr> + <th align="left" colspan="1" rowspan="1">Value</th> + <th align="left" colspan="1" rowspan="1">KEM</th> + <th align="left" colspan="1" rowspan="1">Nsecret</th> + <th align="left" colspan="1" rowspan="1">Nenc</th> + <th align="left" colspan="1" rowspan="1">Npk</th> + <th align="left" colspan="1" rowspan="1">Nsk</th> + <th align="left" colspan="1" rowspan="1">Auth</th> + <th align="left" colspan="1" rowspan="1">Reference</th> + </tr> + </thead> + <tbody> + <tr> + <td align="left" colspan="1" rowspan="1">0x0120</td> + <td align="left" colspan="1" rowspan="1">DHKEM(X25519Elligator, HKDF-SHA256)</td> + <td align="left" colspan="1" rowspan="1">32</td> + <td align="left" colspan="1" rowspan="1">32</td> + <td align="left" colspan="1" rowspan="1">32</td> + <td align="left" colspan="1" rowspan="1">32</td> + <td align="left" colspan="1" rowspan="1">yes</td> + <td align="left" colspan="1" rowspan="1"> + <xref target="LSD0007"/></td> + </tr> + </tbody> + </table> + </section> + <!-- <section> + <name>Implementation and Deployment Status</name> + <t> + FIXME + </t> + </section> + <section> + <name>Acknowledgements</name> + <t> + FIXME + </t> + </section>--> + </middle> + <back> + <references> + <name>Normative References</name> + &RFC2119; + &RFC5869; + &RFC7748; + &RFC8174; + &RFC9180; + + </references> + <references> + <name>Informative References</name> + <reference anchor="BHKL13" target="https://eprint.iacr.org/2013/325.pdf"> + <front> + <title>Elligator: Elliptic-curve points indistinguishable from uniform random strings</title> + <author initials="D.J" surname="Bernstein" + fullname="Daniel J. Bernstein"> + </author> + <author initials="M." surname="Hamburg" + fullname="Mike Hamburg"> + </author> + <author initials="A." surname="Krasnova" + fullname="Anna Krasnova"> + </author> + <author initials="T." surname="Lange" + fullname="Tanja Lange"> + </author> + <date month="August" year="2013" /> + </front> + </reference> + <reference anchor="LSD0007" target="https://lsd.gnunet.org/lsd0007"> + <front> + <title>The GNUnet communicators</title> + <author initials="M" surname="Schanzenbach" + fullname="Martin Schanzenbach"> + </author> + <author initials="C." surname="Grothoff" + fullname="Christian Grothoff"> + </author> + <author initials="P." surname="Fardzadeh" + fullname="Pedram Fardzadeh"> + </author> + <date month="July" year="2024" /> + </front> + </reference> </references> + + + <section> + <name>Elligator implementation</name> + <t> + This section provides test vectors for the different Elligator functions and should aid in verifying implementations. + Note that Elligator has two parameters: the set of positive and negative numbers, and a non-square number U + within the finite field, as described in FIXME. The displayed test vectors assume that the set of positive + numbers is defined as {0,...,(P-1)/2}, the set of negative numbers as {(P-1)/2 + 1,...,P−1} and U is the non-square number + sqrt(-1). Unless indicated otherwise, the test vectors are provided as little-endian hexadecimal byte arrays. + </t> + <section> + <name>ElligatorEnc():</name> + <artwork name="" type="" align="left" alt=""><![CDATA[ + Ephemeral public key (little-endian): + 99 9b 59 1b 66 97 d0 74 + f2 66 19 22 77 d5 54 de + c3 c2 4c 2e f6 10 81 01 + f6 3d 94 f7 ff f3 a0 13 + + Representative (little-endian): + 99 9b 59 1b 66 97 d0 74 + f2 66 19 22 77 d5 54 de + c3 c2 4c 2e f6 10 81 01 + f6 3d 94 f7 ff f3 a0 13 + ]]></artwork> + </section> + <section> + <name>ElligatorDec():</name> + <t> + The Most Significant Bit (MSB) and the second MSB of the representative should be randomly flipped (serialized) before + transmission. The resulting public key for both the original (unserialized) representative and the serialized representative + must be the same. + </t> + <artwork name="" type="" align="left" alt=""><![CDATA[ + Representative unserialized (little-endian): + 95 a1 60 19 04 1d be fe + d9 83 20 48 ed e1 19 28 + d9 03 65 f2 4a 38 aa 7a + ef 1b 97 e2 39 54 10 1b + + Representative serialized (little-endian): + 95 a1 60 19 04 1d be fe + d9 83 20 48 ed e1 19 28 + d9 03 65 f2 4a 38 aa 7a + ef 1b 97 e2 39 54 10 9b + + Ephemeral public key (little-endian): + 79 4f 05 ba 3e 3a 72 95 + 80 22 46 8c 88 98 1e 0b + e5 78 2b e1 e1 14 5c e2 + c3 c6 fd e1 6d ed 53 63 + ]]></artwork> + </section> + <section> + <name>Encap():</name> + <t> + Refer to <xref target="elligator_dhkem"/> for the definition of the utilized Encap and Decap functions. Note + that the receivers public key (aka peer identity) is an Edwards Curve point and need to be transformed + into an X25519 public key. The denoted Representative is the elligator encoding of the ephemeral + public key for which the most significant bit and second most significant bit are set to zero (unserialized). + </t> + + <artwork name="" type="" align="left" alt=""><![CDATA[ + Receivers Edwards public key (little-endian): + 3f eb ad ac 12 2d 39 77 + 25 ff 58 0f 6c e9 a3 e1 + c1 c4 a7 de 19 80 7f 13 + d3 83 f2 f9 b6 46 71 36 + + Ephemeral private key sender (little-endian): + 09 39 59 66 d6 d1 c4 93 + b9 91 7d d1 2c 8d d2 4e + 2c 05 c0 81 c9 8a 67 eb + 2d 6d ff 62 2e c9 c0 69 + + Ephemeral public key sender (little-endian): + 3f 73 ee 0d d1 97 0f f9 + 57 f7 ec 15 e0 b5 15 11 + 66 be 30 46 e6 a8 b0 ee + 53 be ca 39 5b 74 e4 2c + + Representative (little-endian): + 1d 93 07 7a b5 e9 ae c4 + 93 1a 92 21 ad fa 48 a4 + 6f 40 1b 69 9b 8e e7 44 + a2 0b 07 e5 7e 5c c5 be + + Key Material (little-endian): + 68 6d 3c e6 08 a6 b8 77 + 42 4b a2 fb 71 b1 03 f2 + c0 d4 f7 ab e5 f1 e5 2b + 30 97 a8 4a 71 4a c7 7b + ]]></artwork> + </section> + <section> + <name>Decap():</name> + <t> + The depicted "receivers edwards private key" is the corresponding private key of the "receivers Edwards public key" + defined above. The resulting key material should therefore be the same for the same Representative. + </t> + <artwork name="" type="" align="left" alt=""><![CDATA[ + Receivers Edwards private key (little-endian): + f3 38 87 a8 56 2d ad 51 + 51 e9 28 9a 0a fa 13 01 + cc c6 98 91 78 50 d5 6e + a4 09 a9 94 94 97 ba a4 + + Representative (little-endian): + 1d 93 07 7a b5 e9 ae c4 + 93 1a 92 21 ad fa 48 a4 + 6f 40 1b 69 9b 8e e7 44 + a2 0b 07 e5 7e 5c c5 be + + Key Material (little-endian): + 68 6d 3c e6 08 a6 b8 77 + 42 4b a2 fb 71 b1 03 f2 + c0 d4 f7 ab e5 f1 e5 2b + 30 97 a8 4a 71 4a c7 7b + ]]></artwork> + </section> + </section> + </back> +</rfc> diff --git a/style.css b/style.css @@ -0,0 +1,1149 @@ +/* This is the built-in CSS used by xml2rfc without Google Fonts. */ + +/* + + NOTE: Changes at the bottom of this file overrides some earlier settings. + + Once the style has stabilized and has been adopted as an official RFC style, + this can be consolidated so that style settings occur only in one place, but + for now the contents of this file consists first of the initial CSS work as + provided to the RFC Formatter (xml2rfc) work, followed by itemized and + commented changes found necssary during the development of the v3 + formatters. + +*/ + +/* fonts */ +/* @import url('https://fonts.googleapis.com/css?family=Noto+Sans'); /\* Sans-serif *\/ */ +/* @import url('https://fonts.googleapis.com/css?family=Noto+Serif'); /\* Serif (print) *\/ */ +/* @import url('https://fonts.googleapis.com/css?family=Roboto+Mono'); /\* Monospace *\/ */ + +@viewport { + zoom: 1.0; + width: extend-to-zoom; +} +@-ms-viewport { + width: extend-to-zoom; + zoom: 1.0; +} +/* general and mobile first */ +html { +} +body { + max-width: 90%; + margin: 1.5em auto; + color: #222; + background-color: #fff; + font-size: 14px; + font-family: 'Noto Sans', Arial, Helvetica, sans-serif; + line-height: 1.6; + scroll-behavior: smooth; +} +.ears { + display: none; +} + +/* headings */ +#title, h1, h2, h3, h4, h5, h6 { + margin: 1em 0 0.5em; + font-weight: bold; + line-height: 1.3; +} +#title { + clear: both; + border-bottom: 1px solid #ddd; + margin: 0 0 0.5em 0; + padding: 1em 0 0.5em; +} +.author { + padding-bottom: 4px; +} +h1 { + font-size: 26px; + margin: 1em 0; +} +h2 { + font-size: 22px; + margin-top: -20px; /* provide offset for in-page anchors */ + padding-top: 33px; +} +h3 { + font-size: 18px; + margin-top: -36px; /* provide offset for in-page anchors */ + padding-top: 42px; +} +h4 { + font-size: 16px; + margin-top: -36px; /* provide offset for in-page anchors */ + padding-top: 42px; +} +h5, h6 { + font-size: 14px; +} +#n-copyright-notice { + border-bottom: 1px solid #ddd; + padding-bottom: 1em; + margin-bottom: 1em; +} +/* general structure */ +p { + padding: 0; + margin: 0 0 1em 0; + text-align: left; +} +div, span { + position: relative; +} +div { + margin: 0; +} +.alignRight.art-text { + background-color: #f9f9f9; + border: 1px solid #eee; + border-radius: 3px; + padding: 1em 1em 0; + margin-bottom: 1.5em; +} +.alignRight.art-text pre { + padding: 0; +} +.alignRight { + margin: 1em 0; +} +.alignRight > *:first-child { + border: none; + margin: 0; + float: right; + clear: both; +} +.alignRight > *:nth-child(2) { + clear: both; + display: block; + border: none; +} +svg { + display: block; +} +.alignCenter.art-text { + background-color: #f9f9f9; + border: 1px solid #eee; + border-radius: 3px; + padding: 1em 1em 0; + margin-bottom: 1.5em; +} +.alignCenter.art-text pre { + padding: 0; +} +.alignCenter { + margin: 1em 0; +} +.alignCenter > *:first-child { + border: none; + /* this isn't optimal, but it's an existence proof. PrinceXML doesn't + support flexbox yet. + */ + display: table; + margin: 0 auto; +} + +/* lists */ +ol, ul { + padding: 0; + margin: 0 0 1em 2em; +} +ol ol, ul ul, ol ul, ul ol { + margin-left: 1em; +} +li { + margin: 0 0 0.25em 0; +} +.ulCompact li { + margin: 0; +} +ul.empty, .ulEmpty { + list-style-type: none; +} +ul.empty li, .ulEmpty li { + margin-top: 0.5em; +} +ul.ulBare, li.ulBare { + margin-left: 0em !important; +} +ul.compact, .ulCompact, +ol.compact, .olCompact { + line-height: 100%; + margin: 0 0 0 2em; +} + +/* definition lists */ +dl { +} +dl > dt { + float: left; + margin-right: 1em; +} +/* +dl.nohang > dt { + float: none; +} +*/ +dl > dd { + margin-bottom: .8em; + min-height: 1.3em; +} +dl.compact > dd, .dlCompact > dd { + margin-bottom: 0em; +} +dl > dd > dl { + margin-top: 0.5em; + margin-bottom: 0em; +} + +/* links */ +a { + text-decoration: none; +} +a[href] { + color: #22e; /* Arlen: WCAG 2019 */ +} +a[href]:hover { + background-color: #f2f2f2; +} +figcaption a[href], +a[href].selfRef { + color: #222; +} +/* XXX probably not this: +a.selfRef:hover { + background-color: transparent; + cursor: default; +} */ + +/* Figures */ +tt, code, pre, code { + background-color: #f9f9f9; + font-family: 'Roboto Mono', monospace; +} +pre { + border: 1px solid #eee; + margin: 0; + padding: 1em; +} +img { + max-width: 100%; +} +figure { + margin: 0; +} +figure blockquote { + margin: 0.8em 0.4em 0.4em; +} +figcaption { + font-style: italic; + margin: 0 0 1em 0; +} +@media screen { + pre { + overflow-x: auto; + max-width: 100%; + max-width: calc(100% - 22px); + } +} + +/* aside, blockquote */ +aside, blockquote { + margin-left: 0; + padding: 1.2em 2em; +} +blockquote { + background-color: #f9f9f9; + color: #111; /* Arlen: WCAG 2019 */ + border: 1px solid #ddd; + border-radius: 3px; + margin: 1em 0; +} +cite { + display: block; + text-align: right; + font-style: italic; +} + +/* tables */ +table { + width: 100%; + margin: 0 0 1em; + border-collapse: collapse; + border: 1px solid #eee; +} +th, td { + text-align: left; + vertical-align: top; + padding: 0.5em 0.75em; +} +th { + text-align: left; + background-color: #e9e9e9; +} +tr:nth-child(2n+1) > td { + background-color: #f5f5f5; +} +table caption { + font-style: italic; + margin: 0; + padding: 0; + text-align: left; +} +table p { + /* XXX to avoid bottom margin on table row signifiers. If paragraphs should + be allowed within tables more generally, it would be far better to select on a class. */ + margin: 0; +} + +/* pilcrow */ +a.pilcrow { + color: #666; /* Arlen: AHDJ 2019 */ + text-decoration: none; + visibility: hidden; + user-select: none; + -ms-user-select: none; + -o-user-select:none; + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + -webkit-touch-callout: none; +} +@media screen { + aside:hover > a.pilcrow, + p:hover > a.pilcrow, + blockquote:hover > a.pilcrow, + div:hover > a.pilcrow, + li:hover > a.pilcrow, + pre:hover > a.pilcrow { + visibility: visible; + } + a.pilcrow:hover { + background-color: transparent; + } +} + +/* misc */ +hr { + border: 0; + border-top: 1px solid #eee; +} +.bcp14 { + font-variant: small-caps; +} + +.role { + font-variant: all-small-caps; +} + +/* info block */ +#identifiers { + margin: 0; + font-size: 0.9em; +} +#identifiers dt { + width: 3em; + clear: left; +} +#identifiers dd { + float: left; + margin-bottom: 0; +} +/* Fix PDF info block run off issue */ +@media print { + #identifiers dd { + float: none; + } +} +#identifiers .authors .author { + display: inline-block; + margin-right: 1.5em; +} +#identifiers .authors .org { + font-style: italic; +} + +/* The prepared/rendered info at the very bottom of the page */ +.docInfo { + color: #666; /* Arlen: WCAG 2019 */ + font-size: 0.9em; + font-style: italic; + margin-top: 2em; +} +.docInfo .prepared { + float: left; +} +.docInfo .prepared { + float: right; +} + +/* table of contents */ +#toc { + padding: 0.75em 0 2em 0; + margin-bottom: 1em; +} +nav.toc ul { + margin: 0 0.5em 0 0; + padding: 0; + list-style: none; +} +nav.toc li { + line-height: 1.3em; + margin: 0.75em 0; + padding-left: 1.2em; + text-indent: -1.2em; +} +/* references */ +.references dt { + text-align: right; + font-weight: bold; + min-width: 7em; +} +.references dd { + margin-left: 8em; + overflow: auto; +} + +.refInstance { + margin-bottom: 1.25em; +} + +.references .ascii { + margin-bottom: 0.25em; +} + +/* index */ +.index ul { + margin: 0 0 0 1em; + padding: 0; + list-style: none; +} +.index ul ul { + margin: 0; +} +.index li { + margin: 0; + text-indent: -2em; + padding-left: 2em; + padding-bottom: 5px; +} +.indexIndex { + margin: 0.5em 0 1em; +} +.index a { + font-weight: 700; +} +/* make the index two-column on all but the smallest screens */ +@media (min-width: 600px) { + .index ul { + -moz-column-count: 2; + -moz-column-gap: 20px; + } + .index ul ul { + -moz-column-count: 1; + -moz-column-gap: 0; + } +} + +/* authors */ +address.vcard { + font-style: normal; + margin: 1em 0; +} + +address.vcard .nameRole { + font-weight: 700; + margin-left: 0; +} +address.vcard .label { + font-family: "Noto Sans",Arial,Helvetica,sans-serif; + margin: 0.5em 0; +} +address.vcard .type { + display: none; +} +.alternative-contact { + margin: 1.5em 0 1em; +} +hr.addr { + border-top: 1px dashed; + margin: 0; + color: #ddd; + max-width: calc(100% - 16px); +} + +/* temporary notes */ +.rfcEditorRemove::before { + position: absolute; + top: 0.2em; + right: 0.2em; + padding: 0.2em; + content: "The RFC Editor will remove this note"; + color: #9e2a00; /* Arlen: WCAG 2019 */ + background-color: #ffd; /* Arlen: WCAG 2019 */ +} +.rfcEditorRemove { + position: relative; + padding-top: 1.8em; + background-color: #ffd; /* Arlen: WCAG 2019 */ + border-radius: 3px; +} +.cref { + background-color: #ffd; /* Arlen: WCAG 2019 */ + padding: 2px 4px; +} +.crefSource { + font-style: italic; +} +/* alternative layout for smaller screens */ +@media screen and (max-width: 1023px) { + body { + padding-top: 2em; + } + #title { + padding: 1em 0; + } + h1 { + font-size: 24px; + } + h2 { + font-size: 20px; + margin-top: -18px; /* provide offset for in-page anchors */ + padding-top: 38px; + } + #identifiers dd { + max-width: 60%; + } + #toc { + position: fixed; + z-index: 2; + top: 0; + right: 0; + padding: 0; + margin: 0; + background-color: inherit; + border-bottom: 1px solid #ccc; + } + #toc h2 { + margin: -1px 0 0 0; + padding: 4px 0 4px 6px; + padding-right: 1em; + min-width: 190px; + font-size: 1.1em; + text-align: right; + background-color: #444; + color: white; + cursor: pointer; + } + #toc h2::before { /* css hamburger */ + float: right; + position: relative; + width: 1em; + height: 1px; + left: -164px; + margin: 6px 0 0 0; + background: white none repeat scroll 0 0; + box-shadow: 0 4px 0 0 white, 0 8px 0 0 white; + content: ""; + } + #toc nav { + display: none; + padding: 0.5em 1em 1em; + overflow: auto; + height: calc(100vh - 48px); + border-left: 1px solid #ddd; + } +} + +/* alternative layout for wide screens */ +@media screen and (min-width: 1024px) { + body { + max-width: 724px; + margin: 42px auto; + padding-left: 1.5em; + padding-right: 29em; + } + #toc { + position: fixed; + top: 42px; + right: 42px; + width: 25%; + margin: 0; + padding: 0 1em; + z-index: 1; + } + #toc h2 { + border-top: none; + border-bottom: 1px solid #ddd; + font-size: 1em; + font-weight: normal; + margin: 0; + padding: 0.25em 1em 1em 0; + } + #toc nav { + display: block; + height: calc(90vh - 84px); + bottom: 0; + padding: 0.5em 0 0; + overflow: auto; + } + img { /* future proofing */ + max-width: 100%; + height: auto; + } +} + +/* pagination */ +@media print { + body { + + width: 100%; + } + p { + orphans: 3; + widows: 3; + } + #n-copyright-notice { + border-bottom: none; + } + #toc, #n-introduction { + page-break-before: always; + } + #toc { + border-top: none; + padding-top: 0; + } + figure, pre { + page-break-inside: avoid; + } + figure { + overflow: scroll; + } + h1, h2, h3, h4, h5, h6 { + page-break-after: avoid; + } + h2+*, h3+*, h4+*, h5+*, h6+* { + page-break-before: avoid; + } + pre { + white-space: pre-wrap; + word-wrap: break-word; + font-size: 10pt; + } + table { + border: 1px solid #ddd; + } + td { + border-top: 1px solid #ddd; + } +} + +/* This is commented out here, as the string-set: doesn't + pass W3C validation currently */ +/* +.ears thead .left { + string-set: ears-top-left content(); +} + +.ears thead .center { + string-set: ears-top-center content(); +} + +.ears thead .right { + string-set: ears-top-right content(); +} + +.ears tfoot .left { + string-set: ears-bottom-left content(); +} + +.ears tfoot .center { + string-set: ears-bottom-center content(); +} + +.ears tfoot .right { + string-set: ears-bottom-right content(); +} +*/ + +@page :first { + padding-top: 0; + @top-left { + content: normal; + border: none; + } + @top-center { + content: normal; + border: none; + } + @top-right { + content: normal; + border: none; + } +} + +@page { + size: A4; + margin-bottom: 45mm; + padding-top: 20px; + /* The follwing is commented out here, but set appropriately by in code, as + the content depends on the document */ + /* + @top-left { + content: 'Internet-Draft'; + vertical-align: bottom; + border-bottom: solid 1px #ccc; + } + @top-left { + content: string(ears-top-left); + vertical-align: bottom; + border-bottom: solid 1px #ccc; + } + @top-center { + content: string(ears-top-center); + vertical-align: bottom; + border-bottom: solid 1px #ccc; + } + @top-right { + content: string(ears-top-right); + vertical-align: bottom; + border-bottom: solid 1px #ccc; + } + @bottom-left { + content: string(ears-bottom-left); + vertical-align: top; + border-top: solid 1px #ccc; + } + @bottom-center { + content: string(ears-bottom-center); + vertical-align: top; + border-top: solid 1px #ccc; + } + @bottom-right { + content: '[Page ' counter(page) ']'; + vertical-align: top; + border-top: solid 1px #ccc; + } + */ + +} + +/* Changes introduced to fix issues found during implementation */ +/* Make sure links are clickable even if overlapped by following H* */ +a { + z-index: 2; +} +/* Separate body from document info even without intervening H1 */ +section { + clear: both; +} + + +/* Top align author divs, to avoid names without organization dropping level with org names */ +.author { + vertical-align: top; +} + +/* Leave room in document info to show Internet-Draft on one line */ +#identifiers dt { + width: 8em; +} + +/* Don't waste quite as much whitespace between label and value in doc info */ +#identifiers dd { + margin-left: 1em; +} + +/* Give floating toc a background color (needed when it's a div inside section */ +#toc { + background-color: white; +} + +/* Make the collapsed ToC header render white on gray also when it's a link */ +@media screen and (max-width: 1023px) { + #toc h2 a, + #toc h2 a:link, + #toc h2 a:focus, + #toc h2 a:hover, + #toc a.toplink, + #toc a.toplink:hover { + color: white; + background-color: #444; + text-decoration: none; + } +} + +/* Give the bottom of the ToC some whitespace */ +@media screen and (min-width: 1024px) { + #toc { + padding: 0 0 1em 1em; + } +} + +/* Style section numbers with more space between number and title */ +.section-number { + padding-right: 0.5em; +} + +/* prevent monospace from becoming overly large */ +tt, code, pre, code { + font-size: 95%; +} + +/* Fix the height/width aspect for ascii art*/ +pre.sourcecode, +.art-text pre { + line-height: 1.12; +} + + +/* Add styling for a link in the ToC that points to the top of the document */ +a.toplink { + float: right; + margin-right: 0.5em; +} + +/* Fix the dl styling to match the RFC 7992 attributes */ +dl > dt, +dl.dlParallel > dt { + float: left; + margin-right: 1em; +} +dl.dlNewline > dt { + float: none; +} + +/* Provide styling for table cell text alignment */ +table td.text-left, +table th.text-left { + text-align: left; +} +table td.text-center, +table th.text-center { + text-align: center; +} +table td.text-right, +table th.text-right { + text-align: right; +} + +/* Make the alternative author contact informatio look less like just another + author, and group it closer with the primary author contact information */ +.alternative-contact { + margin: 0.5em 0 0.25em 0; +} +address .non-ascii { + margin: 0 0 0 2em; +} + +/* With it being possible to set tables with alignment + left, center, and right, { width: 100%; } does not make sense */ +table { + width: auto; +} + +/* Avoid reference text that sits in a block with very wide left margin, + because of a long floating dt label.*/ +.references dd { + overflow: visible; +} + +/* Control caption placement */ +caption { + caption-side: bottom; +} + +/* Limit the width of the author address vcard, so names in right-to-left + script don't end up on the other side of the page. */ + +address.vcard { + max-width: 30em; + margin-right: auto; +} + +/* For address alignment dependent on LTR or RTL scripts */ +address div.left { + text-align: left; +} +address div.right { + text-align: right; +} + +/* Provide table alignment support. We can't use the alignX classes above + since they do unwanted things with caption and other styling. */ +table.right { + margin-left: auto; + margin-right: 0; +} +table.center { + margin-left: auto; + margin-right: auto; +} +table.left { + margin-left: 0; + margin-right: auto; +} + +/* Give the table caption label the same styling as the figcaption */ +caption a[href] { + color: #222; +} + +@media print { + .toplink { + display: none; + } + + /* avoid overwriting the top border line with the ToC header */ + #toc { + padding-top: 1px; + } + + /* Avoid page breaks inside dl and author address entries */ + .vcard { + page-break-inside: avoid; + } + +} +/* Tweak the bcp14 keyword presentation */ +.bcp14 { + font-variant: small-caps; + font-weight: bold; + font-size: 0.9em; +} +/* Tweak the invisible space above H* in order not to overlay links in text above */ + h2 { + margin-top: -18px; /* provide offset for in-page anchors */ + padding-top: 31px; + } + h3 { + margin-top: -18px; /* provide offset for in-page anchors */ + padding-top: 24px; + } + h4 { + margin-top: -18px; /* provide offset for in-page anchors */ + padding-top: 24px; + } +/* Float artwork pilcrow to the right */ +@media screen { + .artwork a.pilcrow { + display: block; + line-height: 0.7; + margin-top: 0.15em; + } +} +/* Make pilcrows on dd visible */ +@media screen { + dd:hover > a.pilcrow { + visibility: visible; + } +} +/* Make the placement of figcaption match that of a table's caption + by removing the figure's added bottom margin */ +.alignLeft.art-text, +.alignCenter.art-text, +.alignRight.art-text { + margin-bottom: 0; +} +.alignLeft, +.alignCenter, +.alignRight { + margin: 1em 0 0 0; +} +/* In print, the pilcrow won't show on hover, so prevent it from taking up space, + possibly even requiring a new line */ +@media print { + a.pilcrow { + display: none; + } +} +/* Styling for the external metadata */ +div#external-metadata { + background-color: #eee; + padding: 0.5em; + margin-bottom: 0.5em; + display: none; +} +div#internal-metadata { + padding: 0.5em; /* to match the external-metadata padding */ +} +/* Styling for title RFC Number */ +h1#rfcnum { + clear: both; + margin: 0 0 -1em; + padding: 1em 0 0 0; +} +/* Make .olPercent look the same as <ol><li> */ +dl.olPercent > dd { + margin-bottom: 0.25em; + min-height: initial; +} +/* Give aside some styling to set it apart */ +aside { + border-left: 1px solid #ddd; + margin: 1em 0 1em 2em; + padding: 0.2em 2em; +} +aside > dl, +aside > ol, +aside > ul, +aside > table, +aside > p { + margin-bottom: 0.5em; +} +/* Additional page break settings */ +@media print { + figcaption, table caption { + page-break-before: avoid; + } +} +/* Font size adjustments for print */ +@media print { + body { font-size: 10pt; line-height: normal; max-width: 96%; } + h1 { font-size: 1.72em; padding-top: 1.5em; } /* 1*1.2*1.2*1.2 */ + h2 { font-size: 1.44em; padding-top: 1.5em; } /* 1*1.2*1.2 */ + h3 { font-size: 1.2em; padding-top: 1.5em; } /* 1*1.2 */ + h4 { font-size: 1em; padding-top: 1.5em; } + h5, h6 { font-size: 1em; margin: initial; padding: 0.5em 0 0.3em; } +} +/* Sourcecode margin in print, when there's no pilcrow */ +@media print { + .artwork, + .sourcecode { + margin-bottom: 1em; + } +} +/* Avoid narrow tables forcing too narrow table captions, which may render badly */ +table { + min-width: 20em; +} +/* ol type a */ +ol.type-a { list-style-type: lower-alpha; } +ol.type-A { list-style-type: upper-alpha; } +ol.type-i { list-style-type: lower-roman; } +ol.type-I { list-style-type: lower-roman; } +/* Apply the print table and row borders in general, on request from the RPC, +and increase the contrast between border and odd row background sligthtly */ +table { + border: 1px solid #ddd; +} +td { + border-top: 1px solid #ddd; +} +tr:nth-child(2n+1) > td { + background-color: #f8f8f8; +} +/* Use style rules to govern display of the TOC. */ +@media screen and (max-width: 1023px) { + #toc nav { display: none; } + #toc.active nav { display: block; } +} +/* Add support for keepWithNext */ +.keepWithNext { + break-after: avoid-page; + break-after: avoid-page; +} +/* Add support for keepWithPrevious */ +.keepWithPrevious { + break-before: avoid-page; +} +/* Change the approach to avoiding breaks inside artwork etc. */ +figure, pre, table, .artwork, .sourcecode { + break-before: auto; + break-after: auto; +} +/* Avoid breaks between <dt> and <dd> */ +dl { + break-before: auto; + break-inside: auto; +} +dt { + break-before: auto; + break-after: avoid-page; +} +dd { + break-before: avoid-page; + break-after: auto; + orphans: 3; + widows: 3 +} +span.break, dd.break { + margin-bottom: 0; + min-height: 0; + break-before: auto; + break-inside: auto; + break-after: auto; +} +/* Undo break-before ToC */ +@media print { + #toc { + break-before: auto; + } +} +/* Text in compact lists should not get extra bottim margin space, + since that would makes the list not compact */ +ul.compact p, .ulCompact p, +ol.compact p, .olCompact p { + margin: 0; +} +/* But the list as a whole needs the extra space at the end */ +section ul.compact, +section .ulCompact, +section ol.compact, +section .olCompact { + margin-bottom: 1em; /* same as p not within ul.compact etc. */ +} +/* The tt and code background above interferes with for instance table cell + backgrounds. Changed to something a bit more selective. */ +tt, code { + background-color: transparent; +} +p tt, p code, li tt, li code { + background-color: #f8f8f8; +} +/* Tweak the pre margin -- 0px doesn't come out well */ +pre { + margin-top: 0.5px; +} +/* Tweak the comact list text */ +ul.compact, .ulCompact, +ol.compact, .olCompact, +dl.compact, .dlCompact { + line-height: normal; +} +/* Don't add top margin for nested lists */ +li > ul, li > ol, li > dl, +dd > ul, dd > ol, dd > dl, +dl > dd > dl { + margin-top: initial; +} +/* Elements that should not be rendered on the same line as a <dt> */ +/* This should match the element list in writer.text.TextWriter.render_dl() */ +dd > div.artwork:first-child, +dd > aside:first-child, +dd > figure:first-child, +dd > ol:first-child, +dd > div:first-child > pre.sourcecode, +dd > table:first-child, +dd > ul:first-child { + clear: left; +} +/* fix for weird browser behaviour when <dd/> is empty */ +dt+dd:empty::before{ + content: "\00a0"; +} +/* Make paragraph spacing inside <li> smaller than in body text, to fit better within the list */ +li > p { + margin-bottom: 0.5em +} +/* Don't let p margin spill out from inside list items */ +li > p:last-of-type { + margin-bottom: 0; +} + +.label-expires,.expires { + display: none; +}