<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY rfc1034 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.1034.xml">
<!ENTITY rfc1035 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.1035.xml">
<!ENTITY rfc2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY rfc2136 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2136.xml">
<!ENTITY rfc2181 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2181.xml">
<!ENTITY rfc2308 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2308.xml">
<!ENTITY rfc3110 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3110.xml">
<!ENTITY rfc3447 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.3447.xml">
<!ENTITY rfc4033 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4033.xml">
<!ENTITY rfc4034 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4034.xml">
<!ENTITY rfc4035 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4035.xml">
<!ENTITY rfc4648 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4648.xml">
<!ENTITY rfc5114 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5114.xml">
<!ENTITY rfc5155 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5155.xml">
<!ENTITY rfc6234 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6234.xml">
<!ENTITY rfc6605 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6605.xml">
<!ENTITY rfc6781 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.6781.xml">
<!ENTITY rfc7129 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7129.xml">
<!ENTITY rfc7748 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.7748.xml">
<!ENTITY draft-dnskey-ed25519 SYSTEM "http://xml2rfc.ietf.org/public/rfc/bibxml3/reference.I-D.draft-ietf-curdle-dnskey-ed25519-01.xml">
]>
<?rfc toc="yes"?>
<?rfc symrefs="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<?rfc strict="no"?>
<?rfc rfcedstyle="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>

<rfc category="std" docName="draft-vcelak-nsec5-02" ipr="trust200902">
    <front>
        <title abbrev="NSEC5">NSEC5, DNSSEC Authenticated Denial of Existence</title>

        <author fullname="Jan Vcelak" initials="J." surname="Vcelak">
            <organization>CZ.NIC</organization>
            <address>
                <postal>
                    <street>Milesovska 1136/5</street>
                    <city>Praha</city>
                    <code>130 00</code>
                    <country>CZ</country>
                </postal>
                <email>jan.vcelak@nic.cz</email>
            </address>
        </author>

        <author fullname="Sharon Goldberg" initials="S." surname="Goldberg">
            <organization>Boston University</organization>
            <address>
                <postal>
                    <street>111 Cummington St, MCS135</street>
                    <city>Boston</city>
                    <region>MA</region>
                    <code>02215</code>
                    <country>USA</country>
                </postal>
                <email>goldbe@cs.bu.edu</email>
            </address>
        </author>

        <author fullname="Dimitrios Papadopoulos" initials="D." surname="Papadopoulos">
            <organization>Boston University</organization>
            <address>
                <postal>
                    <street>111 Cummington St, MCS135</street>
                    <city>Boston</city>
                    <region>MA</region>
                    <code>02215</code>
                    <country>USA</country>
                </postal>
                <email>dipapado@bu.edu</email>
            </address>
        </author>

        <date year="2016" />

        <!-- <workgroup></workgroup> -->

        <keyword>DNS</keyword>
        <keyword>DNSSEC</keyword>
        <keyword>NSEC</keyword>
        <keyword>authenticated denial</keyword>

    <abstract>

        <!--
            Keep it brief. Remember, don't put any citations in the abstract, and expand your acronyms.
        <-->

        <t>
            The Domain Name System Security (DNSSEC) Extensions introduced the NSEC resource
            record (RR) for authenticated denial of existence and the NSEC3 for hashed
            authenticated denial of existence.

            The NSEC RR allows for the entire zone contents to be enumerated if a server is
            queried for carefully chosen domain names; N queries suffice to enumerate a zone
            containing N names. The NSEC3 RR adds domain-name hashing, which makes the zone
            enumeration harder, but not impossible.

            This document introduces NSEC5, which provides an cryptographically-proven mechanism
            that prevents zone enumeration. NSEC5 has the additional advantage of not requiring
            private zone-signing keys to be present on all authoritative servers for the zone.
        </t>

    </abstract>

</front>

<middle>
    <section title="Introduction">

        <section title="Rationale">

            <!--
                You can echo the abstract in the Introduction, providing citations here, but you
                should provide more than just the abstract.
            -->

            <t>
                The DNS Security Extensions (DNSSEC) provides data integrity protection using
                public-key cryptography, while not requiring that authoritative servers compute signatures
                on-the-fly. The content of the zone is usually pre-computed and served as is.
                The evident advantages of this approach are reduced performance requirements
                per query, as well as not requiring private zone-signing keys to be present
                on nameservers facing the network.
            </t>

            <t>
                With DNSSEC, each resource record (RR) set in the zone is signed. The signature
                is retained as an RRSIG RR directly in the zone. This enables response
                authentication for data existing in the zone. To ensure integrity of denying
                answers, an NSEC chain of all existing domain names in the zone is constructed.
                The chain is made of RRs, where each RR represents two consecutive domain names in
                canonical order present in the zone. The NSEC RRs are signed the same way as
                any other RRs in the zone. Non-existence of a name can be thus proven by
                presenting a NSEC RR which covers the name.
            </t>

            <t>
                As side-effect, however, the NSEC chain allows for enumeration of the zone's
                contents by sequentially querying for the names immediately following those
                in the most-recently retrieved NSEC record; N queries suffice to enumerate
                a zone containing N names. As such, the
                NSEC3 hashed denial of existence was introduced to prevent zone enumeration.
                In NSEC3, the original domain names in the NSEC chain are replaced by their
                cryptographic hashes.  While NSEC3 makes zone enumeration more difficult, offline
                dictionary attacks are still possible and have been demonstrated; this is
                because hashes may be computed offline and the space of possible domain names
                is restricted <xref target="nsec3walker" /><xref target="nsec3gpu" />.
            </t>

            <t>
                Zone enumeration can be prevented with NSEC3 if having the authoritative server
                compute NSEC3 RRs on-the-fly, in response to queries with denying responses. Usually,
                this is done with Minimally Covering NSEC Records or NSEC3 White Lies
                <xref target="RFC7129" />. The disadvantage of this
                approach is a required presence of the private key on all authoritative servers
                for the zone. This is often undesirable, as the holder of the private key can
                tamper with the zone contents, and having private keys on many network-facing servers
                increases the risk that keys can be compromised.
            </t>

            <t>
                To prevent zone content enumeration without keeping private keys on all
                authoritative servers, NSEC5 replaces the unkeyed cryptographic hash function used
                in NSEC3 with a public-key hashing scheme. Hashing in NSEC5 is performed with
                a separate NSEC5 key. The public portion of this key is distributed in an
                NSEC5KEY RR, and is used to validate NSEC5 hash values.  The private portion
                of the NSEC5 key is present on all authoritative servers for the zone, and is
                used to compute hash values.
            </t>

            <t>
                Importantly, the NSEC5KEY key cannot be used to
                modify the contents of the zone. Thus, any compromise of the private NSEC5 key
                does not lead to a compromise of zone contents. All that is lost is privacy against
                zone enumeration, effectively downgrading the security of NSEC5 to that of NSEC3.
                NSEC5 comes with a cryptographic proof of security, available in
                <xref target="nsec5" />.
            </t>

            <t>
                The NSEC5 is not intended to replace NSEC or NSEC3. It is designed as an
                alternative mechanism for authenticated denial of existence.
            </t>
        </section>

        <section title="Requirements">
            <t>
                The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
                "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
                document are to be interpreted as described in
                <xref target="RFC2119" />.
            </t>
        </section>

        <section title="Terminology">

            <t>
                The reader is assumed to be familiar with the basic DNS and DNSSEC concepts
                described in
                <xref target="RFC1034" />,
                <xref target="RFC1035" />,
                <xref target="RFC4033" />,
                <xref target="RFC4034" />,
                <xref target="RFC4035" />, and subsequent RFCs that update them:
                <xref target="RFC2136" />,
                <xref target="RFC2181" />,
                <xref target="RFC2308" />, and
                <xref target="RFC5155" />.
            </t>

            <t>
                The following terminology is used through this document:
            </t>

            <t>
                <list style="hanging">
                    <t hangText="Base32hex:">
                        The "Base 32 Encoding with Extended Hex Alphabet" as specified
                        in <xref target="RFC4648" />. The padding characters ("=") are not
                        used in NSEC5 specification.
                    </t>
                    <t hangText="Base64:">
                        The "Base 64 Encoding" as specified in <xref target="RFC4648" />.
                    </t>
                    <t hangText="NSEC5 proof:">
                        A signed hash of a domain name (hash-and-sign paradigm). A holder of the
                        private key (e.g., authoritative server) can compute the proof. Anyone
                        knowing the public key (e.g., client) can verify it's validity.
                    </t>
                    <t hangText="NSEC5 hash:">
                        A cryptographic hash (digest) of an NSEC5 proof. If the NSEC5
                        proof is known, anyone can compute and verify it's NSEC5 hash.
                    </t>
                    <t hangText="NSEC5 algorithm:">
                        A pair of algorithms used to compute NSEC5 proofs and NSEC5 hashes.
                    </t>
                </list>
            </t>
        </section>

    </section>

    <section title="Backward Compatibility">
        <t>
            The specification describes a protocol change that is not backward compatible
            with <xref target="RFC4035" /> and <xref target="RFC5155" />. NSEC5-unaware
            resolver will fail to validate responses introduced by this document.
        </t>

        <t>
            To prevent NSEC5-unaware resolvers from attempting to validate the responses, new
            DNSSEC algorithms identifiers are introduced, the identifiers alias with existing
            algorithm numbers. The zones signed according to this specification MUST use only
            these algorithm identifiers, thus NSEC5-unaware resolvers will treat the zone as
            insecure.
        </t>

        <t>
            The new algorithm identifiers defined by this document are listed in
            <xref target="iana_considerations" />.
        </t>
    </section>

    <section title="How NSEC5 Works">
        <t>
            To prove non-existence of a domain name in a zone, NSEC uses a chain built from
            domain names present in the zone. NSEC3 replaces the original domain names by
            their cryptographic hashes. NSEC5 is very similar to NSEC3, except that the
            cryptographic hash is replaced by hashes computed using a verifiable random function (VRF).
            A VRF is essentially the public-key version of a keyed cryptographic hash.
            A VRF comes with a public/private key pair, and only the holder of the private key
            can compute the hash, but anyone with public key can verify the hash.
        </t>

        <t>
            In NSEC5, the original domain name is hashed twice:
        </t>

        <t>
            <list style="numbers">
                <t>
                    First, the domain name is hashed using a VRF keyed with the NSEC5 private key;
                    the result is called the NSEC5 proof.  Only an authoritative server that knows the
                    private NSEC5 key can compute the NSEC5 proof.  Any client that knows
                    the public NSEC5 key can validate the NSEC5 proof.
                </t>
                <t>
                    Second, the NSEC5 proof is hashed. The result is called the NSEC5 hash value.
                    This hash can be computed by any party that knows the input NSEC5 proof.
                </t>
            </list>
        </t>

        <t>
            The NSEC5 hash determines the position of a domain name in an NSEC5 chain.
            That is, all the NSEC5 hashes for a zone are sorted in their canonical order,
            and each consecutive pair forms an NSEC5 RR.
        </t>

        <t>
            To prove an non-existence of a particular domain name in response to a query, the
            server computes the NSEC5 proof (using the private NSEC5 key) on the fly. Then it
            uses the NSEC5 proof to compute the corresponding NSEC5 hash. It then identifies
            the NSEC5 RR that covers the NSEC5 hash. In the response message, the server returns the
            NSEC5 RR, it's corresponding signature (RRSIG RRset), and synthesized NSEC5PROOF RR
            containing the NSEC5 proof it computed on the fly.
        </t>

        <t>
            To validate the response, the client first uses the public NSEC5 key (stored in the
            zone as an NSEC5KEY RR) to verify that the NSEC5 proof corresponds with the domain
            name to be disproved. Then, the client computes the NSEC5 hash from the NSEC5 proof
            and checks that it is covered by the NSEC5 RR. Finally, it checks that the signature on
            the NSEC5 RR is valid.
        </t>

    </section>

    <section title="NSEC5 Algorithms">

        <t>
            The algorithms used for NSEC5 authenticated denial are independent of the algorithms
            used for DNSSEC signing. An NSEC5 algorithm defines how the NSEC5 proof and the
            NSEC5 hash is computed and validated.
        </t>

        <t>
            The input for the NSEC5 proof computation is an RR owner name in the canonical form
            in the wire format and an NSEC5 private key; the output is an octet string.
        </t>

        <t>
            The input for the NSEC5 hash computation is the corresponding NSEC5 proof; the output
            is an octet string.
        </t>

        <t>
            This document defines RSAFDH-SHA256-SHA256 NSEC5 algorithm as follows:
        </t>

        <t>
            <list style="symbols">
                <t>
                    NSEC5 proof is computed using an RSA based Full Domain Hash (FDH) signature
                    with SHA-256 hash function used internally for input preprocessing. The
                    signature and verification is formally specified in <xref target="fdh" />.
                </t>
                <t>
                    NSEC5 hash is computed by hashing the NSEC5 proof with the SHA-256 hash
                    function as specified in <xref target="RFC6234" />.
                </t>
                <t>
                    The public key format to be used in NSEC5KEY RR is defined in Section 2 of
                    <xref target="RFC3110" /> and thus is the same as the format used to store
                    RSA public keys in DNSKEY RRs.
                </t>
            </list>
        </t>

        <t>
            This document defines EC-P256-SHA256 NSEC5 algorithm as follows:
        </t>

        <t>
            <list style="symbols">
                <t>
                    NSEC5 proof is computed using an Elliptic Curve VRF with
                    FIPS 186-3 P-256 curve.
                    The proof computation and verification is formally specified in
                    <xref target="ecvrf" />.
                    The curve parameters are specified in
                    <xref target="FIPS-186-3" /> (Section D.1.2.3) and
                    <xref target="RFC5114" /> (Section 2.6).
                </t>
                <t>
                    NSEC5 hash is x-coordinate of the group element gamma
                    from the NSEC5 proof (specified in <xref target="ecvrf" />),
                    encoded as a fixed-width 32-octet unsigned integer
                    in network byte order. In practice, the hash is a substring
                    of the proof ranging from 2nd to 33th octet of the proof
                    inclusive.
                </t>
                <t>
                    The public key format to be used in NSEC5KEY RR is defined in Section 4 of
                    <xref target="RFC6605" /> and thus is the same as the format used to store
                    ECDSA public keys in DNSKEY RRs.
                </t>
            </list>
        </t>

        <t>
            This document defines EC-ED25519-SHA256 NSEC5 as follows:
        </t>

        <t>
            <list style="symbols">
                <t>
                    NSEC5 proof is the same as with EC-P256-SHA256 but using Ed25519
                    elliptic curve with parameters defined in <xref target="RFC7748" />
                    (Section 4.1).
                </t>
                <t>
                    NSEC5 hash is the same as with EC-P256-SHA256.
                </t>
                <t>
                    The public key format to be used in NSEC5KEY RR is defined in Section 3 of
                    <xref target="I-D.ietf-curdle-dnskey-ed25519" /> and thus is the same as the
                    format used to store Ed25519 public keys in DNSKEY RRs.
                </t>
            </list>
        </t>
    </section>

    <section title="The NSEC5KEY Resource Record">

        <t>
            The NSEC5KEY RR stores an NSEC5 public key. The key allows clients to verify a
            validity of NSEC5 proof sent by a server.
        </t>

        <section title="NSEC5KEY RDATA Wire Format">
            <t>
                The RDATA for NSEC5KEY RR is as shown below:
            </t>

            <figure align="center">
                <artwork><![CDATA[
                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   Algorithm   |                  Public Key                   /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                ]]></artwork>
            </figure>

            <t>
                Algorithm is a single octet identifying NSEC5 algorithm.
            </t>
            <t>
                Public Key is a variable sized field holding public key material for NSEC5
                proof verification.
            </t>
        </section>

        <section title="NSEC5KEY RDATA Presentation Format">
            <t>
                The presentation format of the NSEC5KEY RDATA is as follows:
            </t>

            <t>
                The Algorithm field is represented as an unsigned decimal integer.
            </t>

            <t>
                The Public Key field is represented in Base64 encoding. Whitespace is allowed
                within the Base64 text.
            </t>
        </section>
    </section>

    <section title="The NSEC5 Resource Record">
        <t>
            The NSEC5 RR provides authenticated denial of existence for an RRset. One NSEC5 RR
            represents one piece of an NSEC5 chain, proving existence of RR types present at
            the original domain name and also non-existence of other domain names in a part of
            the hashed domain name space.
        </t>

        <section title="NSEC5 RDATA Wire Format">
            <t>
                The RDATA for NSEC5 RR is as shown below:
            </t>

            <figure align="center">
                <artwork><![CDATA[
                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            Key Tag            |     Flags     |  Next Length  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                     Next Hashed Owner Name                    /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
/                         Type Bit Maps                         /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                ]]></artwork>
            </figure>

            <t>
                Key Tag field contains the key tag value of the NSEC5KEY RR that validates the
                NSEC5 RR, in network byte order. The value is computed from the NSEC5KEY RDATA
                using the same algorithm, which is used to compute key tag values for DNSKEY RRs.
                The algorithm is defined in <xref target="RFC4034" />.
            </t>
            <t>
                Flags field is a single octet. The meaning of individual bits of the field is
                defined in <xref target="nsec5_flags" />.
            </t>
            <t>
                Next length is an unsigned single octet specifying the length of the Next Hashed
                Owner Name field in octets.
            </t>
            <t>
                Next Hashed Owner Name field is a sequence of binary octets. It contains an NSEC5
                hash of the next domain name in the NSEC5 chain.
            </t>
            <t>
                Type Bit Maps is a variable sized field encoding RR types present at the original
                owner name matching the NSEC5 RR. The format of the field is equivalent to the
                format used in NSEC3 RR, described in <xref target="RFC5155" />.
            </t>
        </section>

        <section title="NSEC5 Flags Field" anchor="nsec5_flags">
            <t>
                The following one-bit NSEC5 flags are defined:
            </t>

            <figure align="center">
                <artwork><![CDATA[
 0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|           |W|O|
+-+-+-+-+-+-+-+-+
                ]]></artwork>
            </figure>

            <t>
                <list>
                    <t>O - Opt-Out flag</t>
                    <t>W - Wildcard flag</t>
                </list>
            </t>

            <t>
                All the other flags are reserved for future use and MUST be zero.
            </t>

            <t>
                The Opt-Out flag has the same semantics as in NSEC3. The definition and
                considerations in <xref target="RFC5155" /> are valid, except that NSEC3
                is replaced by NSEC5.
            </t>

            <t>
                The Wildcard flag indicates that a wildcard synthesis is possible at the
                original domain name level (i.e., there is a wildcard node immediately
                descending from the immediate ancestor of the original domain name). The
                purpose of the Wildcard flag is to reduce a maximum number of RRs required for
                authenticated denial of existence proof.
            </t>
        </section>

        <section title="NSEC5 RDATA Presentation Format">
            <t>
                The presentation format of the NSEC5 RDATA is as follows:
            </t>

            <t>
                The Key Tag field is represented as an unsigned decimal integer.
            </t>

            <t>
                The Flags field is represented as an unsigned decimal integer.
            </t>

            <t>
                The Next Length field is not represented.
            </t>

            <t>
                The Next Hashed Owner Name field is represented as a sequence
                of case-insensitive Base32hex digits without any whitespace and
                without padding.
            </t>

            <t>
                The Type Bit Maps representation is equivalent to the representation
                used in NSEC3 RR, described in <xref target="RFC5155" />.
            </t>
        </section>
    </section>

    <section title="The NSEC5PROOF Resource Record">
        <t>
            The NSEC5PROOF record is synthesized by the authoritative server on-the-fly. The
            record contains the NSEC5 proof, proving a position of the owner name in an
            NSEC5 chain.
        </t>

        <section title="NSEC5PROOF RDATA Wire Format" anchor="nsec5proof_rdata">
            <t>
                The RDATA for NSEC5PROOF is as as shown below:
            </t>

            <figure align="center">
                <artwork><![CDATA[
                     1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            Key Tag            |        Owner Name Hash        /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                ]]></artwork>
            </figure>

            <t>
                Key Tag field contains the key tag value of the NSEC5KEY RR that validates
                the NSEC5PROOF RR, in network byte order.
            </t>
            <t>
                Owner Name Hash is a variable sized sequence of binary octets encoding the NSEC5
                proof of the owner name of the RR.
            </t>
        </section>

        <section title="NSEC5PROOF RDATA Presentation Format">
            <t>
                The presentation format of the NSEC5PROOF RDATA is as follows:
            </t>

            <t>
                The Key Tag field is represented as an unsigned decimal integer.
            </t>

            <t>
                The Owner Name Hash is represented in Base64 encoding. Whitespace
                is allowed within the Base64 text.
            </t>
        </section>
    </section>

    <section title="NSEC5 Proofs" anchor="nsec5_proofs">

        <t>
            This section summarizes all possible types of authenticated denial of existence.
            For each type the following lists are included:
        </t>

        <t>
            <list style="numbers">
                <t>
                    Facts to prove. The minimum amount of information an authoritative server
                    must provide to a client to assure the client that the response content is
                    valid.
                </t>
                <t>
                    Authoritative server proofs. NSEC5 RRs an authoritative server must include
                    in a response to prove the listed facts.
                </t>
                <t>
                    Validator checks. Individual checks a validating server is required to
                    perform on a response. The response content is considered valid only if all
                    the checks pass.
                </t>
            </list>
        </t>

        <t>
            If NSEC5 is said to match a domain name, the owner name of the NSEC5 RR has to be
            equivalent to an NSEC5 hash of that domain name. If an NSEC5 RR is said to cover
            a domain name, the NSEC5 hash of the domain name must lay strictly between that
            NSEC5 RR's Owner Name and  Next Hashed Owner Name.
        </t>

        <section title="Name Error Responses">

            <t>
                Facts to prove:
                <list>
                    <t>No RRset matching the QNAME exactly exists.</t>
                    <t>No RRset matching the QNAME via wildcard expansion exists.</t>
                    <t>The QNAME does not fall into a delegation.</t>
                    <t>The QNAME does not fall into a DNAME redirection.</t>
                </list>
            </t>

            <t>
                Authoritative server proofs:
                <list>
                    <t>Closest encloser.</t>
                    <t>Next closer name.</t>
                </list>
            </t>

            <t>
                Validator checks:
                <list>
                    <t>Closest encloser belongs to the zone.</t>
                    <t>Closest encloser has the Wildcard flag cleared.</t>
                    <t>Closest encloser does not have NS without SOA in the Type Bit Map.</t>
                    <t>Closest encloser does not have DNAME in the Type Bit Maps.</t>
                    <t>Next closer name is derived correctly.</t>
                </list>
            </t>

        </section>

        <section title="No Data Responses">

            <t>
                The processing of a No Data response for DS QTYPE differs if the Opt-Out is in
                effect. For DS QTYPE queries, the validator has two possible checking paths.
                The correct path can be simply decided by inspecting if the NSEC5 RR in the
                response matches the QNAME.
            </t>

            <t>
                Note that the Opt-Out is valid only for DS QTYPE queries.
            </t>

            <section title="No Data Response, Opt-Out Not In Effect">

                <t>
                    Facts to prove:
                    <list>
                        <t>An RRset matching the QNAME exists.</t>
                        <t>No QTYPE RRset matching the QNAME exists.</t>
                        <t>No CNAME RRset matching the QNAME exists.</t>
                    </list>
                </t>

                <t>
                    Authoritative server proofs:
                    <list>
                        <t>QNAME.</t>
                    </list>
                </t>

                <t>
                    Validator checks:
                    <list>
                        <t>The NSEC5 RR exactly matches the QNAME.</t>
                        <t>The NSEC5 RR does not have QTYPE in the Type Bit Map.</t>
                        <t>The NSEC5 RR does not have CNAME in the Type Bit Map.</t>
                    </list>
                </t>

            </section>

            <section title="No Data Response, Opt-Out In Effect">

                <t>
                    Facts to prove:
                    <list>
                        <t>The delegation is not covered by the NSEC5 chain.</t>
                    </list>
                </t>

                <t>
                    Authoritative server proofs:
                    <list>
                        <t>Closest provable encloser.</t>
                    </list>
                </t>

                <t>
                    Validator checks:
                    <list>
                        <t>Closest provable encloser is in zone.</t>
                        <t>Closest provable encloser covers (not matches) the QNAME.</t>
                        <t>Closest provable encloser has the Opt-Out flag set.</t>
                    </list>
                </t>

            </section>

        </section>

        <section title="Wildcard Responses">

            <t>
                Facts to prove:
                <list>
                    <t>No RRset matching the QNAME exactly exists.</t>
                    <t>No wildcard closer to the QNAME exists.</t>
                </list>
            </t>

            <t>
                Authoritative server proofs:
                <list>
                    <t>Next closer name.</t>
                </list>
            </t>
            <t>
                Validator checks:
                <list>
                    <t>Next closer name is derived correctly.</t>
                    <t>Next closer name covers (not matches).</t>
                </list>
            </t>

        </section>

        <section title="Wildcard No Data Responses">

            <t>
                Facts to prove:
                <list>
                    <t>No RRset matching the QNAME exactly exists.</t>
                    <t>No QTYPE RRset exists at the wildcard matching the QNAME.</t>
                    <t>No CNAME RRset exists at the wildcard matching the QNAME.</t>
                    <t>No wildcard closer to the QNAME exists.</t>
                </list>
            </t>

            <t>
                Authoritative server proofs:
                <list>
                    <t>Source of synthesis (i.e., wildcard at closest encloser).</t>
                    <t>Next closer name.</t>
                </list>
            </t>

            <t>
                Validator checks:
                <list>
                    <t>Source of synthesis matches exactly the QNAME.</t>
                    <t>Source of synthesis does not have QTYPE in the Type Bit Map.</t>
                    <t>Source of synthesis does not have CNAME in the Type Bit Map.</t>
                    <t>Next closer name is derived correctly.</t>
                    <t>Next closer name covers (not matches).</t>
                </list>
            </t>

        </section>
    </section>

    <section title="Authoritative Server Considerations">

        <section title="Zone Signing" anchor="zone_signing">
            <t>
                Zones using NSEC5 MUST satisfy the same properties as described in Section 7.1
                of <xref target="RFC5155" />, with NSEC3 replaced by NSEC5. In addition, the
                following conditions MUST be satisfied as well:
            </t>

            <t>
                <list style="symbols">
                    <t>
                        If the original owner name has a wildcard label immediately descending
                        from the original owner name, the corresponding NSEC5 RR MUST have the
                        Wildcard flag set in the Flags field. Otherwise, the flag MUST be cleared.
                    </t>
                    <t>
                        The zone apex MUST include an NSEC5KEY RRset containing a NSEC5 public
                        key allowing verification of the current NSEC5 chain.
                    </t>
                </list>
            </t>

            <t>
                The following steps describe one possible method to properly add required NSEC5
                related records into a zone. This is not the only such existing method.
            </t>

            <t>
                <list style="numbers">
                    <t>
                        Select an algorithm for NSEC5.  Generate the public and private NSEC5 keys.
                    </t>
                    <t>
                        Add a NSEC5KEY RR into the zone apex containing the public NSEC5 key.
                    </t>
                    <t>
                        For each unique original domain name in the zone and each empty
                        non-terminal, add an NSEC5 RR. If Opt-Out is used, owner names of
                        unsigned delegations MAY be excluded.
                        <list style="letters">
                            <t>
                                The owner name of the NSEC5 RR is the NSEC5 hash of the
                                original owner name encoded in Base32hex without padding,
                                prepended as a single label to the zone name.
                            </t>
                            <t>
                                Set the Key Tag field to be the key tag corresponding
                                to the public NSEC5 key.
                            </t>
                            <t>
                                Clear the Flags field. If Opt-Out is being used, set the Opt-Out
                                flag. If there is a wildcard label directly descending from the
                                original domain name, set the Wildcard flag. Note that the
                                wildcard can be an empty non-terminal (i.e., the wildcard synthesis
                                does not take effect and therefore the flag is not to be set).
                            </t>
                            <t>
                                Set the Next Length field to a value determined by the used
                                NSEC5 algorithm. Leave the Next Hashed Owner Name field blank.
                            </t>
                            <t>
                                Set the Type Bit Maps field based on the RRsets present at the
                                original owner name.
                            </t>
                        </list>
                    </t>
                    <t>
                        Sort the set of NSEC5 RRs into canonical order.
                    </t>
                    <t>
                        For each NSEC5 RR, set the Next Hashed Owner Name field by using the owner
                        name of the next NSEC5 RR in the canonical order. If the updated NSEC5 is
                        the last NSEC5 RR in the chain, the owner name of the first NSEC5 RR
                        in the chain is used instead.
                    </t>
                </list>
            </t>

            <t>
                The NSEC5KEY and NSEC5 RRs MUST have the same class as the zone SOA RR. Also
                the NSEC5 RRs SHOULD have the same TTL value as the SOA minimum TTL field.
            </t>

            <t>
                Notice that a use of Opt-Out is not indicated in the zone. This does not affect
                the ability of a server to prove insecure delegations. The Opt-Out MAY be part
                of the zone-signing tool configuration.
            </t>

        </section>

        <section title="Zone Serving">
            <t>
                This specification modifies DNSSEC-enabled DNS responses generated by
                authoritative servers. In particular, it replaces use of NSEC or NSEC3 RRs in
                such responses with NSEC5 RRs and adds on-the-fly computed NSEC5PROOF RRs.
            </t>

            <t>
                The authenticated denial of existence proofs in NSEC5 are almost the same
                as in NSEC3. However, due to introduction of Wildcard flag in NSEC5 RRs, the
                NSEC5 proof consists from (up to) two NSEC5 RRs, instead of (up to) three.
            </t>

            <t>
                According to a type of a response, an authoritative server MUST include NSEC5 RRs
                in a response as defined in <xref target="nsec5_proofs" />. For each NSEC5 RR
                in the response a matching RRSIG RRset and a synthesized NSEC5PROOF MUST be added
                as well.
            </t>

            <t>
                A synthesized NSEC5PROOF RR has the owner name set to a domain name exactly
                matching the name required for the proof. The class and TTL of the RR MUST
                be the same as the class and TTL value of the corresponding NSEC5 RR. The RDATA
                are set according to the description in <xref target="nsec5proof_rdata" />.
            </t>

            <t>
                Notice, that the NSEC5PROOF owner name can be a wildcard (e.g., source of
                synthesis proof in wildcard No Data responses). The name also always matches
                the domain name required for the proof while the NSEC5 RR may only cover
                (not match) the name in the proof (e.g., closest encloser in Name Error responses).
            </t>

            <t>
                If NSEC5 is used, an answering server MUST use exactly one NSEC5 chain for
                one signed zone.
            </t>

            <t>
                NSEC5 MUST NOT be used in parallel with NSEC, NSEC3, or any other authenticated
                denial of  existence mechanism that allows for enumeration of zone contents.
            </t>

            <t>
                Similarly to NSEC3, the owner names of NSEC5 RRs are not represented in the
                NSEC5 chain and therefore NSEC5 records deny their own existence. The desired
                behavior caused by this paradox is the same as described in Section 7.2.8
                of <xref target="RFC5155" />.
            </t>

        </section>

        <section title="NSEC5KEY Rollover Mechanism">
            <t>
                Replacement of the NSEC5 key implies generating a new NSEC5 chain. The NSEC5KEY
                rollover mechanism is similar to "Pre-Publish Zone Signing Key Rollover" as
                specified in <xref target="RFC6781" />. The NSEC5KEY rollover MUST be
                performed as a sequence of the following steps:
            </t>

            <t>
                <list style="numbers">
                    <t>
                        A new public NSEC5 key is added into the NSEC5KEY RRset in the zone apex.
                    </t>
                    <t>
                        The old NSEC5 chain is replaced by a new NSEC5 chain constructed
                        using the new key. This replacement MUST happen as a single atomic
                        operation; the server MUST NOT be responding with RRs from
                        both the new and old chain at the same time.
                    </t>
                    <t>
                        The old public key is removed from the NSEC5KEY RRset in the zone apex.
                    </t>
                </list>
            </t>

            <t>
                The minimal delay between the steps 1. and 2. MUST be the time it takes for the
                data to propagate to the authoritative servers, plus the TTL value of the old
                NSEC5KEY RRset.
            </t>

            <t>
                The minimal delay between the steps 2. and 3. MUST be the time it takes for the
                data to propagate to the authoritative servers, plus the maximum zone TTL value
                of any of the data in the previous version of the zone.
            </t>
        </section>

        <section title="Secondary Servers">
            <t>
                This document does not define mechanism to distribute NSEC5 private keys.
                See <xref target="keyleak" />
                for discussion on the security requirements for NSEC5 private keys.
            </t>
        </section>

        <section title="Zones Using Unknown Hash Algorithms">
            <t>
                Zones that are signed with unknown NSEC5 algorithm or by an unavailable NSEC5
                private key cannot be effectively served. Such zones SHOULD be rejected when
                loading and servers SHOULD respond with RCODE=2 (Server failure) when handling
                queries that would fall under such zones.
            </t>
        </section>

        <section title="Dynamic Updates">
            <t>
                A zone signed using NSEC5 MAY accept dynamic updates. The changes to the zone
                MUST be performed in a way, that the zone satisfies the properties specified
                in <xref target="zone_signing" /> at any time.
            </t>

            <t>
                It is RECOMMENDED that the server rejects all updates containing changes to
                the NSEC5 chain (or related RRSIG RRs) and performs itself any required
                alternations of the NSEC5 chain induced by the update.
            </t>

            <t>
                Alternatively, the server MUST verify that all the properties are satisfied
                prior to performing the update atomically.
            </t>
        </section>

    </section>

    <section title="Resolver Considerations">

        <t>
            The same considerations as described in Section 9 of <xref target="RFC5155" />
            for NSEC3 apply to NSEC5. In addition, as NSEC5 RRs can be validated only with
            appropriate NSEC5PROOF RRs, the NSEC5PROOF RRs MUST be all together cached and
            included in responses with NSEC5 RRs.
        </t>

    </section>

    <section title="Validator Considerations">
        <section title="Validating Responses">
            <t>
                The validator MUST ignore NSEC5 RRs with Flags field values other than the ones
                defined in <xref target="nsec5_flags" />.
            </t>

            <t>
                The validator MAY treat responses as bogus if the response contains NSEC5 RRs
                that refer to a different NSEC5KEY.
            </t>

            <t>
                According to a type of a response, the validator MUST verify all conditions defined
                in <xref target="nsec5_proofs" />. Prior to making decision based on the content
                of NSEC5 RRs in a response, the NSEC5 RRs MUST be validated.
            </t>

            <t>
                To validate a denial of existence, zone NSEC5 public keys are required in addition
                to DNSSEC public keys. Similarly to DNSKEY RRs, the NSEC5KEY RRs are present in
                the zone apex.
            </t>

            <t>
                The NSEC5 RR is validated as follows:

                <list style="numbers">
                    <t>
                        Select a correct NSEC5 public key to validate the NSEC5PROOF. The Key Tag
                        value of the NSEC5PROOF RR must match with the key tag value computed
                        from the NSEC5KEY RDATA.
                    </t>
                    <t>
                        Validate the NSEC5 proof present in the NSEC5PROOF Owner Name Hash field
                        using the NSEC5 public key. If there are multiple NSEC5KEY RRs matching
                        the key tag, at least one of the keys must validate the NSEC5 proof.
                    </t>
                    <t>
                        Compute the NSEC5 hash value from the NSEC5 proof and check if the
                        response contains NSEC5 RR matching or covering the computed NSEC5 hash.
                        The TTL values of the NSEC5 and NSEC5PROOF RRs must be the same.
                    </t>
                    <t>
                        Validate the signature of the NSEC5 RR.
                    </t>
                </list>
            </t>

            <t>
                If the NSEC5 RR fails to validate, it MUST be ignored. If some of the conditions
                required for an NSEC5 proof is not satisfied, the response MUST be treated as
                bogus.
            </t>

            <t>
                Notice that determining closest encloser and next closer name in NSEC5 is easier
                than in NSEC3. NSEC5 and NSEC5PROOF RRs are always present in pairs in responses
                and the original owner name of the NSEC5 RR matches the owner name of the
                NSEC5PROOF RR.
            </t>

        </section>

        <section title="Validating Referrals to Unsigned Subzones">
            <t>
                The same considerations as defined in Section 8.9 of <xref target="RFC5155" />
                for NSEC3 apply to NSEC5.
            </t>
        </section>

        <section title="Responses With Unknown Hash Algorithms">
            <t>
                A validator MUST ignore NSEC5KEY RRs with unknown NSEC5 algorithms. The
                practical result of this is that zones sighed with unknown algorithms will
                be considered bogus.
            </t>
        </section>
    </section>

    <section title="Special Considerations">

        <section title="Transition Mechanism">

            <t>
                TODO: Not finished. Following information will be covered:

                <list style="symbols">
                    <t>Transition from NSEC or NSEC3.</t>
                    <t>Transition from NSEC5 to NSEC/NSEC3</t>
                    <t>Transition to new algorithms within NSEC5</t>
                </list>
            </t>

            <t>
                Quick notes on transition from NSEC/NSEC3 to NSEC5:
                <list style="numbers">
                    <t>Publish NSEC5KEY RR.</t>
                    <t>Wait for data propagation to slaves and cache expiration.</t>
                    <t>Instantly switch answering from NSEC/NSEC3 to NSEC5.</t>
                </list>
            </t>

            <t>
                Quick notes on transition from NSEC5 to NSEC/NSEC3:
                <list style="numbers">
                    <t>Instantly switch answering from NSEC5 to NSEC/NSEC3.</t>
                    <t>Wait for NSEC5 RRs expiration in caches.</t>
                    <t>Remove NSEC5KEY RR from the zone.</t>
                </list>
            </t>

        </section>

        <section title="NSEC5 Private Keys">
            <t>
                This document does not define format to store NSEC5 private key. Use of
                standardized and adopted format is RECOMMENDED.
            </t>

            <t>
                The NSEC5 private key MAY be shared between multiple zones, however a separate
                key is RECOMMENDED for each zone.
            </t>
        </section>

        <section title="Domain Name Length Restrictions">

            <t>
                The NSEC5 creates additional restrictions on domain name lengths. In particular,
                zones with names that, when converted into hashed owner names exceed the 255
                octet length limit imposed by <xref target="RFC1035" />, cannot use this
                specification.
            </t>

            <t>
                The actual maximum length of a domain name depends on the length of the zone
                name and used NSEC5 algorithm.
            </t>

            <t>
                All NSEC5 algorithms defined in this document use 256-bit NSEC5 hash values.
                Such a value can be encoded in 52 characters in Base32hex without padding. When
                constructing the NSEC5 RR owner name, the encoded hash is prepended to the name
                of the zone as a single label which includes the length field of a single octet.

                The maximal length of the zone name in wire format is
                therefore 202 octets (255 - 53).
            </t>

        </section>

    </section>

    <section title="Performance Considerations">

        <t>
            This section compares NSEC, NSEC3, and NSEC5 with regards to the size of
            denial-of-existence responses and performance impact on the DNS components.
        </t>

        <section title="Performance of Cryptographic Operations">

<!--

Intel(R) Core(TM) i7-5600U CPU @ 2.60GHz
OpenSSL 1.0.2h-dev (1.0.2g)

Raw signing performance (openssl speed):

                  sign    verify    sign/s verify/s
rsa 1024 bits 0.000118s 0.000008s   8493.2 131800.0
rsa 1024 bits 0.000112s 0.000007s   8893.0 140316.2
rsa 1024 bits 0.000103s 0.000007s   9737.1 151930.2
rsa 2048 bits 0.000769s 0.000023s   1300.7  43904.4
rsa 2048 bits 0.000770s 0.000021s   1299.4  46795.1
rsa 2048 bits 0.000664s 0.000020s   1507.0  50344.6
rsa 4096 bits 0.005319s 0.000075s    188.0  13279.2
rsa 4096 bits 0.004724s 0.000074s    211.7  13493.9
rsa 4096 bits 0.004796s 0.000068s    208.5  14744.0

                              sign    verify    sign/s verify/s
 256 bit ecdsa (nistp256)   0.0001s   0.0002s   7513.1   4078.3
 256 bit ecdsa (nistp256)   0.0001s   0.0002s   7544.7   4032.7
 256 bit ecdsa (nistp256)   0.0001s   0.0003s   7033.7   3878.4
 256 bit ecdsa (nistp256)   0.0000s   0.0001s  22985.7  10769.2 (asm)
 256 bit ecdsa (nistp256)   0.0000s   0.0001s  23077.8  11633.2 (asm)
 256 bit ecdsa (nistp256)   0.0000s   0.0001s  25084.0  11335.6 (asm)
 384 bit ecdsa (nistp384)   0.0002s   0.0009s   4775.7   1152.5
 384 bit ecdsa (nistp384)   0.0002s   0.0008s   5102.7   1248.2
 384 bit ecdsa (nistp384)   0.0002s   0.0008s   5139.5   1246.5

Hashing:

SHA-1 on 32-byte blocks, 1e8 iterations
% for x in 1 2 3; do time ./main sha1; done
./main sha1  24,78s user 0,00s system 99% cpu 24,868 total
./main sha1  26,12s user 0,01s system 99% cpu 26,222 total
./main sha1  24,77s user 0,01s system 99% cpu 24,897 total

SHA-256 on 32-byte blocks, 1e8 iterations
% for x in 1 2 3; do time ./main sha256; done
./main sha256  34,09s user 0,00s system 99% cpu 34,092 total
./main sha256  33,95s user 0,01s system 99% cpu 34,091 total
./main sha256  33,41s user 0,01s system 99% cpu 33,614 total

sha1   3948043.74 hash/s
sha256 2947041.66 hash/s

NSEC5 RSA, 3e4 signatures, 3e6 verifications

% for i in $(seq 3); do time ./demo_openssl sha256 rsa_1024.pem sign; done
./demo_openssl sha256 rsa_1024.pem sign  3,16s user 0,00s system 99% cpu 3,169 total
./demo_openssl sha256 rsa_1024.pem sign  3,18s user 0,00s system 99% cpu 3,178 total
./demo_openssl sha256 rsa_1024.pem sign  3,14s user 0,00s system 99% cpu 3,148 total
% for i in $(seq 3); do time ./demo_openssl sha256 rsa_1024.pem verify; done
./demo_openssl sha256 rsa_1024.pem verify  8,46s user 0,00s system 99% cpu 8,510 total
./demo_openssl sha256 rsa_1024.pem verify  8,66s user 0,00s system 99% cpu 8,678 total
./demo_openssl sha256 rsa_1024.pem verify  8,05s user 0,00s system 99% cpu 8,080 total

% for i in $(seq 3); do time ./demo_openssl sha256 rsa_2048.pem sign; done
./demo_openssl sha256 rsa_2048.pem sign  20,21s user 0,00s system 99% cpu 20,215 total
./demo_openssl sha256 rsa_2048.pem sign  20,25s user 0,00s system 99% cpu 20,261 total
./demo_openssl sha256 rsa_2048.pem sign  20,25s user 0,00s system 99% cpu 20,257 total
% for i in $(seq 3); do time ./demo_openssl sha256 rsa_2048.pem verify; done
./demo_openssl sha256 rsa_2048.pem verify  21,60s user 0,00s system 99% cpu 21,634 total
./demo_openssl sha256 rsa_2048.pem verify  21,34s user 0,00s system 99% cpu 21,445 total
./demo_openssl sha256 rsa_2048.pem verify  21,35s user 0,00s system 99% cpu 21,409 total

% for i in $(seq 3); do time ./demo_openssl sha256 rsa_4096.pem sign; done
./demo_openssl sha256 rsa_4096.pem sign  132,38s user 0,00s system 99% cpu 2:12,47 total
./demo_openssl sha256 rsa_4096.pem sign  132,98s user 0,01s system 99% cpu 2:13,07 total
./demo_openssl sha256 rsa_4096.pem sign  135,21s user 0,02s system 99% cpu 2:15,74 total
% for i in $(seq 3); do time ./demo_openssl sha256 rsa_4096.pem verify; done
./demo_openssl sha256 rsa_4096.pem verify  70,38s user 0,00s system 99% cpu 1:10,39 total
./demo_openssl sha256 rsa_4096.pem verify  72,30s user 0,00s system 99% cpu 1:12,31 total
./demo_openssl sha256 rsa_4096.pem verify  74,95s user 0,00s system 99% cpu 1:15,00 total

1024: 9494.67 sign/s   119189.51 verify/s
2048: 1482.46 sign/s    46223.54 verify/s
4096:  224.68 sign/s    13916.72 verify/s

NSEC5 EC-P256-SHA256

% wc -l /usr/share/dict/words
479828 /usr/share/dict/words

% for x in $(seq 3); do time ./ecc ecc-secp256r1.pem sign; done
./ecc ecc-secp256r1.pem sign  101,80s user 0,01s system 99% cpu 1:41,86 total
./ecc ecc-secp256r1.pem sign  102,40s user 0,01s system 99% cpu 1:42,45 total
./ecc ecc-secp256r1.pem sign  101,84s user 0,01s system 99% cpu 1:41,88 total

% for x in $(seq 3); do time ./ecc ecc-secp256r1.pem verify; done
./ecc ecc-secp256r1.pem verify  129,26s user 0,10s system 99% cpu 2:09,69 total
./ecc ecc-secp256r1.pem verify  116,57s user 0,02s system 99% cpu 1:56,61 total
./ecc ecc-secp256r1.pem verify  116,74s user 0,02s system 99% cpu 1:56,91 tota

4703.27 hash/s
3969.69 verify/s

-->
            <t>
                Additional performance costs depend on the costs of cryptographic operations
                to a great extent. The following results were retrieved with OpenSSL 1.0.2g,
                running an ordinary laptop on a single-core of a CPU manufactured in 2016. The
                parameters of cryptographic operations were chosen to reflect the parameters
                used in the real-world application of DNSSEC.
            </t>

            <section title="NSEC3 Hashing Performance">

                <t>
                    NSEC3 uses multiple iterations of the SHA-1 function with an arbitrary salt.
                    The input of the first iteration is the domain name in wire format together
                    with binary salt; the input of the subsequent iterations is the binary
                    digest and the salt. We can assume that the input size will be smaller
                    than 32 octets for most executions.
                </t>
                <t>
                    The measured implementation gives a stable performance for small input
                    blocks up to 32 octets. About 4e6 hashes per second can be computed given
                    these parameters.
                </t>
                <t>
                    The number of additional iterations in NSEC3 parameters will probably
                    vary between 0 and 20 in reality. Therefore we can expect the NSEC3 hash
                    computation performance to be between 2e5 and 4e6 hashes per second.
                </t>

            </section>

            <section title="NSEC5 Hashing Performance">

                <t>
                    The NSEC5 hash is computed in two steps: NSEC5 proof computation followed
                    by hashing of the result. As the proof computation involves relatively
                    expensive RSA/EC cryptographic operations, the final hashing will have
                    insignificant impact on the overall performance. We can also expect
                    difference between NSEC5 hashing (signing) and verification time.
                </t>
                <t>
                    The measurement results for various NSEC5 algorithms and key sizes are
                    summarized in the following table:
                </t>

                <texttable>
                    <ttcol>NSEC5 algorithm</ttcol>
                    <ttcol align="right">Key size (bits)</ttcol>
                    <ttcol align="right">Proof size (octets)</ttcol>
                    <ttcol align="right">Perf. (hash/s)</ttcol>
                    <ttcol align="right">Perf. (verify/s)</ttcol>
                    <c>RSAFDH-SHA256-SHA256</c> <c>1024</c> <c>128</c> <c>9500</c> <c>120000</c>
                    <c>RSAFDH-SHA256-SHA256</c> <c>2048</c> <c>256</c> <c>1500</c> <c>46000</c>
                    <c>RSAFDH-SHA256-SHA256</c> <c>4096</c> <c>512</c> <c>200</c>  <c>14000</c>
                    <c>EC-P256-SHA256</c>       <c>256</c>  <c>81</c>  <c>4700</c> <c>4000</c>
                </texttable>

                <t>
                    Picking a moderate key size of 2048-bits for RSAFDH-SHA256-SHA256, the NSEC5
                    hash computation performance will be in the order of 10^3 issued hashes per
                    second and 10^4 validated hashes per second.
                </t>

                <t>
                    EC-P256-SHA256 trades off verification performance for shorter proof size and faster query processing at the nameserver. In that case, both hash
                    computation and verification performance will be in the order of 10^3 hashes
                    per second.
                </t>

            </section>

            <section title="DNSSEC Signing Performance">
                <t>
                    For completeness, the following table sumarrizes the signing and verification
                    performance for different DNSSEC signing algorithms:
                </t>

                <texttable>
                    <ttcol>Algorithm</ttcol>
                    <ttcol align="right">Key size (bits)</ttcol>
                    <ttcol align="right">Signature size (octets)</ttcol>
                    <ttcol align="right">Performance (sign/s)</ttcol>
                    <ttcol align="right">Performance (verify/s)</ttcol>
                    <c>RSASHA256</c>       <c>1024</c> <c>128</c> <c>9000</c>  <c>140000</c>
                    <c>RSASHA256</c>       <c>2048</c> <c>256</c> <c>1500</c>  <c>47000</c>
                    <c>RSASHA256</c>       <c>4096</c> <c>512</c> <c>200</c>   <c>14000</c>
                    <c>ECDSAP256SHA256</c> <c>256</c>  <c>64</c>  <c>7400</c>  <c>4000</c>
                    <c>ECDSAP384SHA384</c> <c>384</c>  <c>96</c>  <c>5000</c>  <c>1000</c>
                    <c>ECDSAP256SHA256*</c><c>256</c>  <c>64</c>  <c>24000</c> <c>11000</c>
                </texttable>

                <t>* highly optimized implementation</t>

                <t>
                    The retrieved values are important primarily for the purpose of evaluating
                    performance of response validation. The signing performance is usually not that important
                    because the zone is signed offline. However, when online signing is used,
                    signing performace is also important.
                </t>

            </section>
        </section>

        <section title="Authoritative Server Startup">

            <t>
                This section compares additional server startup cost based on the used
                authenticated denial mechanism.
            </t>

            <t><list style="hanging">
                <t hangText="NSEC">
                    There are no special requirements on processing of a NSEC-signed zone during
                    an authoritative server startup. The server handles the NSEC RRs the same way
                    as any other records in the zone.
                </t>

                <t hangText="NSEC3">
                    The authoritative server can precompute NSEC3 hashes for all domain names in
                    the NSEC3-signed zone on startup. With respect to query answering, this can
                    speed up inclusion of NSEC3 RRs for existing domain names (i.e., Closest
                    provable encloser and QNAME for No Data response).
                </t>

                <t hangText="NSEC5">
                    Very similar considerations apply for NSEC3 and NSEC5. There is a strong
                    motivation to precompute the NSEC5 proofs because they are costly to compute.
                    A possible solution to reduce the startup time is to store the precomputed
                    NSEC5 proofs and NSEC5 hashes in a persistent storage.
                </t>
            </list></t>

            <t>
                The impact of NSEC3 and NSEC5 on the authoritative server startup performance
                is greatly implementation specific. The server software vendor has to seek balance
                between answering performance, startup slowdown, and additional storage cost.
            </t>

        </section>

        <section title="NSEC5 Answer Generating and Processing">

            <t>
                An authenticated denial proof is required for No Data, Name Error, Wildcard
                Match, and Wildcard No Data answer. The number of required records depends on
                used authenticated denial mechanism. Their size, generation cost, and validation
                cost depend on various zone and signing parameters.
            </t>

            <t>
                In the worst case, the following additional records authenticating the denial
                will be included into the response:
            </t>

            <t><list style="symbols">
                <t hangText="NSEC">
                    Up to two NSEC records and their associated RRSIG records.
                </t>

                <t hangText="NSEC3">
                    Up to three NSEC3 records and their associated RRSIG records.
                </t>

                <t hangText="NSEC5">
                    Up to two NSEC5 records and their associated NSEC5PROOF and RRSIG records.
                </t>
            </list></t>

            <t>
                The following list summarizes additional cryptographic operations performed
                by the authoritative server for authenticated denial worst-case scenario:
            </t>

            <t><list style="symbols">
                <t>
                    NSEC:
                    <list style="symbols">
                        <t>No cryptographic operations required.</t>
                    </list>
                </t>
                <t>
                    NSEC3:
                    <list style="symbols">
                        <t>NSEC3 hash for Closest provable encloser (possibly precomputed)</t>
                        <t>NSEC3 hash for Next closer name</t>
                        <t>NSEC3 hash for wildcard at the closest encloser</t>
                    </list>
                </t>
                <t>
                    NSEC5:
                    <list style="symbols">
                        <t>NSEC5 proof and hash for Closest provable encloser (possibly precomputed)</t>
                        <t>NSEC5 proof and hash for Next closer name</t>
                    </list>
                </t>
            </list></t>

    </section>
    <section title="Response Lengths">

<t>
    <xref target="nsec5ecc" /> precisely measured response lengths for
    NSEC, NSEC3 and NSEC5 using empirical data from a sample second-level domain
    containing about 1000 names.  The sample zone was signed several times with
    different DNSSEC signing algorithms and different authenticated denial of existence
    mechanisms.
</t>

<t>
    For DNSKEY algorithms, RSASHA256 (2048-bit) and ECDSAPSHA256 were considered.
    For authenticated denial, NSEC, NSEC3, NSEC5 with RSAFDH-SHA256-SHA256 (2048-bit), and
    NSEC5 with EC-P256-SHA256 were considered.
    (Note that NSEC5 with EC-ED25519-SHA256 is identical to EC-P256-SHA256 as for response size.)
</t>

<t>
    For each instance of the signed zone, Name Error responses were collected by issuing DNS
    queries with a random five-character label prepended to each actual record name from the zone.
    The average and standard deviation of the length of these responses are shown below.
</t>

<texttable>
        <ttcol></ttcol>
        <ttcol>DNSKEY algorithm</ttcol>
        <ttcol align="right">Average length (octets)</ttcol>
        <ttcol align="right">Standard deviation (octets)</ttcol>
        <c>NSEC</c>      <c>RSA</c>   <c>1116</c> <c>48</c>
        <c>NSEC</c>      <c>ECDSA</c> <c>543</c>  <c>24</c>
        <c>NSEC3</c>     <c>RSA</c>   <c>1440</c> <c>170</c>
        <c>NSEC3</c>     <c>ECDSA</c> <c>752</c>  <c>84</c>
        <c>NSEC5/RSA</c> <c>RSA</c>   <c>1767</c> <c>7</c>
        <c>NSEC5/EC</c>  <c>ECDSA</c> <c>839</c>  <c>7</c>
</texttable>

    </section>
    <section title="Summary">

    <t>
    As anticipated, NSEC and NSEC3 are the most efficient authenticated denial mechanisms,
    in terms of computation for authoritative server and resolver.  NSEC also has the shortest
    response lengths. However, these mechanisms do not prevent zone enumeration.
    </t>

    <t> Regarding mechanisms that do prevent zone enumeration, NSEC5 should be examined in
    contrast with Minimally Covering NSEC Records or NSEC3 White Lies <xref target="RFC7129" />.
    The following table summarizes their comparison in terms of
    response size, performance at the authoritative server, and performance at the resolver.
    For NSEC3 White Lies, RSASHA256 (2048-bit) and ECDSAPSHA256 were considered,
    and for NSEC5, RSAFDH-SHA256-SHA256 (2048-bit) and EC-P256-SHA256 were considered.
    </t>
<texttable>
        <ttcol>Algorithm</ttcol>
        <ttcol align="right">Response length (octets)</ttcol>
        <ttcol align="right">Authoritative (ops/sec)</ttcol>
        <ttcol align="right">Resolver (ops/sec)</ttcol>
        <c>NSEC3WL/RSA</c>   <c>1440</c> <c>1500</c>  <c>47000</c>
        <c>NSEC3WL/ECDSA</c> <c>752</c>  <c>7400</c>  <c>4000</c>
        <c>NSEC5/RSA</c>     <c>1767</c> <c>1500</c>  <c>46000</c>
        <c>NSEC5/EC</c>      <c>839</c>  <c>4700</c>  <c>4000</c>
</texttable>

    <t>
    NSEC5 responses lengths are only slighly longer than NSEC3 response lengths:
    NSEC5/RSA has responses that are about 22% longer than NSEC3/RSA, while NSEC5/EC has
    responses that are about 13% longer than NSEC3/ECDSA. For both NSEC3 and NSEC5,
    it is clear that EC-based solutions give much shorter responses. </t>

    <t>
    Regarding the computation performance, with RSA the difference is negligible for both
    nameserver and resolver, whereas with the EC-based schemes there is no slowdown for the
    resolver, and a slowdown of 1.5x for the server. Importantly, we expect the slowdown to be smaller
    in practice because NSEC3 entails three signing/verifying computations per query in the worst
    case (closest encloser, next closer, wildcard at closest encloser) whereas NSEC5 requires only two.
    The table above does not capture this issue, it just measures number of signing/verifying
    operations per second. Future versions of this draft will more accurately measure and compare
    NSEC5 performance.
    </t>

    <t>
    Note also that while NSEC3 White Lies outperforms NSEC5 for certain cases,
    NSEC3 White Lies require authoratitive nameserver to store the private zone-signing
    key, making each nameserver a potential point of compromise.
    </t>

        </section>

    </section>

    <section title="Security Considerations">
        <section title="Zone Enumeration Attacks" anchor="zea">
        <t>
         NSEC5 is robust to zone enumeration via offline dictionary attacks by any
         attacker that does not know the NSEC5 private key.  Without the private NSEC5 key,
         that attacker cannot compute the NSEC5 proof that corresponds to a given name;
         the only way it can learn the NSEC5 proof value for a given name is by sending
         a queries for that name to the authoritative server. Without the NSEC5 proof value,
         the attacker cannot learn the NSEC5 hash value. Thus, even an attacker that
         collects the entire chain of NSEC5 RR for a zone cannot use offline attacks to
         "reverse" that NSEC5 hash values in these NSEC5 RR and thus learn which names are
         present in the zone.  A formal cryptographic proof of this property is in
         <xref target="nsec5" />.
        </t>
        </section>

        <section title="Hash Collisions" anchor="hashcol">
        <t>
         Hash collisions between QNAME and the owner name of an NSEC5 RR may
        occur.  When they do, it will be impossible to prove the non-
        existence of the colliding QNAME.  However, with SHA-256, this is
        highly unlikely (on the order of 1 in 2^128).  Note that DNSSEC
        already relies on the presumption that a cryptographic hash function
        is collision resistant, since these hash functions are used
        for generating and validating signatures and DS RRs. See also the
        discussion on key lengths in <xref target="nsec5" />.
        </t>
        </section>

        <section title="Compromise of the Private NSEC5 Key" anchor="keyleak">
        <t>
        NSEC5 requires authoritative servers to hold the private NSEC5 key, but
        not the private zone-signing keys or the private key-signing keys for the zone.
        </t>
        <t>
        The private NSEC5 key needs only be as secure as the DNSSEC records
        whose the privacy (against zone-enumeration attacks) that NSEC5 is protecting.
        This is because even an adversary that knows the private NSEC5 key cannot modify
        the contents of the zone; this is because the zone contents are signed using the
        private zone-signing key, while the private NSEC5 key is only used to compute
        NSEC5 proof values.  Thus, a compromise of the private NSEC5 keys does not lead to
        a compromise of the integrity of the DNSSEC record in the zone; instead,
        all that is lost is privacy against zone enumeration, if the attacker that knows
        the private NSEC5 key can compute NSEC5 hashes offline, and thus launch offline
        dictionary attacks.  Thus, a compromise of the private NSEC5 key effectively
        downgrades the security of NSEC5 to that of NSEC3.  A formal cryptographic proof
        of this property is in  <xref target="nsec5" />.
        </t>

        <t>If a zone owner
        wants to preserve this property of NSEC5, the zone owner SHOULD
        choose the NSEC5 private key to be different from the private
        zone-signing keys or key-signing keys for the zone.
        </t>
        </section>

        <section title="Key Length Considerations" anchor="keylen">
        <t>
        The NSEC5 key must be long enough to withstand attacks
        for as long as the privacy of the zone is important. Even if the NSEC5 key
        is rolled frequently, its length cannot be too short, because zone privacy
        may be important for a period of time longer than the lifetime of the key.
        (For example, an attacker might collect the entire chain of NSEC5 RR for the
        zone over one short period, and then, later (even after the NSEC5 key expires)
        perform an offline dictionary attack that  attempt to "reverse" the NSEC5
        hash values present in the NSEC5 RRs.)
        This is in contrast to zone-signing and key-signing keys used in DNSSEC; these
        keys, which ensure the authenticity and integrity of the zone contents
        need to remain secure only during their lifetime.
        </t>
        </section>

         <section title="Transitioning to a New NSEC5 Algorithm" anchor="transAlgo">
         <t>
            Although the NSEC5KEY RR formats include a hash algorithm
            parameter, this document does not define a particular mechanism for
            safely transitioning from one NSEC5 algorithm to another.  When
            specifying a new hash algorithm for use with NSEC5, a transition
            mechanism MUST also be defined.  It is possible that the only
            practical and palatable transition mechanisms may require an
            intermediate transition to an insecure state, or to a state that uses
            NSEC or NSEC3 records instead of NSEC5.
            <!-- Sharon: copied this directly from the NSEC3 rfc -->
         </t>
        </section>

    </section>

    <section title="IANA Considerations" anchor="iana_considerations">

        <t>
            This document updates the IANA registry "Domain Name System (DNS)
            Parameters" in subregistry "Resource Record (RR) TYPEs", by
            defining the following new RR types:
        </t>

        <t>
            <list>
                <t>NSEC5KEY   value XXX.</t>
                <t>NSEC5      value XXX.</t>
                <t>NSEC5PROOF value XXX.</t>
            </list>
        </t>

        <t>
            This document creates a new IANA registry for NSEC5 algorithms.
            This registry is named "DNSSEC NSEC5 Algorithms". The initial
            content of the registry is:
        </t>

        <t>
            <list>
                <t>0     is Reserved.</t>
                <t>1     is RSAFDH-SHA256-SHA256.</t>
                <t>2     is EC-P256-SHA256.</t>
                <t>3     is EC-ED25519-SHA256.</t>
                <t>4-255 is Available for assignment.</t>
            </list>
        </t>

        <t>
            This document updates the IANA registry "DNS Security Algorithm Numbers" by
            defining following aliases:
        </t>

        <t>
            <list>
                <t>XXX is NSEC5-RSASHA256, alias for RSASHA256 (8).</t>
                <t>XXX is NSEC5-RSASHA512, alias for RSASHA512 (10).</t>
                <t>XXX is NSEC5-ECDSAP256SHA256 alias for ECDSAP256SHA256 (13).</t>
                <t>XXX is NSEC5-ECDSAP384SHA384 alias for ECDSAP384SHA384 (14).</t>
            </list>
        </t>

    </section>

    <section title="Contributors">
        <t>
            This document would not be possible without help of
            Moni Naor (Weizmann Institute),
            Sachin Vasant (Cisco Systems),
            Leonid Reyzin (Boston University), and
            Asaf Ziv (Weizmann Institute)
            who contributed to the design of NSEC5, and
            Ondrej Sury (CZ.NIC Labs)
            who provided advice on its implementation.
        </t>
    </section>

</middle>

<back>
    <!-- References Section -->

<!--
     Section 4.7f of [RFC2223bis] specifies the requirements for the
     references sections.  In particular, there MUST be separate lists of
     normative and informative references, each in a separate section.
     The style SHOULD follow that of recently published RFCs.

     In general, each normative reference SHOULD reference the most recent
     version of the specification in question.
-->

    <references title="Normative References">
        &rfc1034;
        &rfc1035;
        &rfc2119;
        &rfc2136;
        &rfc2181;
        &rfc2308;
        &rfc3110;
        &rfc3447;
        &rfc4033;
        &rfc4034;
        &rfc4035;
        &rfc4648;
        &rfc5114;
        &rfc5155;
        &rfc6234;
        &rfc6605;
        &rfc7748;
        &draft-dnskey-ed25519;

        <reference anchor="FIPS-186-3">
            <front>
                <title>Digital Signature Standard (DSS)</title>
                <author><organization>National Institute for Standards and Technology</organization></author>
                <date year="2009" month="June" />
            </front>
            <seriesInfo name="FIPS" value="PUB 186-3" />
        </reference>

        <reference anchor="SECG1" target="http://www.secg.org/sec1-v2.pdf">
            <front>
                <title>SEC 1: Elliptic Curve Cryptography</title>
                <author><organization>Standards for Efficient Cryptography Group (SECG)</organization></author>
                <date year="2009" month="May" />
            </front>
            <seriesInfo name="Version" value="2.0" />
        </reference>

    </references>

    <references title="Informative References">

        <reference anchor="nsec5">
            <front>
                <title>NSEC5: Provably Preventing DNSSEC Zone Enumeration</title>
                <author initials="S." surname="Goldberg"><organization /></author>
                <author initials="M." surname="Naor"><organization /></author>
                <author initials="D." surname="Papadopoulos"><organization /></author>
                <author initials="L." surname="Reyzin"><organization /></author>
                <author initials="S." surname="Vasant"><organization /></author>
                <author initials="A." surname="Ziv"><organization /></author>
                <date year="2014" month="July" />
            </front>
             <seriesInfo name="in" value="NDSS'15" />
        </reference>

        <reference anchor="nsec5ecc">
            <front>
                <title>NSEC5 from Elliptic Curves</title>
                <author initials="S." surname="Goldberg"><organization /></author>
                <author initials="M." surname="Naor"><organization /></author>
                <author initials="D." surname="Papadopoulos"><organization /></author>
                <author initials="L." surname="Reyzin"><organization /></author>
                <date year="2016" month="January" />
            </front>
            <seriesInfo name="in" value="ePrint Cryptology Archive 2016/083" />
        </reference>

        <reference anchor="nsec3gpu">
            <front>
                <title>GPU-Based NSEC3 Hash Breaking</title>
                <author initials="M." surname="Wander"><organization /></author>
                <author initials="L." surname="Schwittmann"><organization /></author>
                <author initials="C." surname="Boelmann"><organization /></author>
                <author initials="T." surname="Weis"><organization /></author>
                <date year="2014" />
            </front>
            <seriesInfo name="in" value="IEEE Symp. Network Computing and Applications (NCA)" />
        </reference>

        <reference anchor="nsec3walker" target="http://dnscurve.org/nsec3walker.html">
            <front>
                <title>Nsec3 walker</title>
                <author initials="D. J." surname="Bernstein"><organization /></author>
                <date year="2011" />
            </front>
        </reference>

        &rfc6781;
        &rfc7129;

    </references>

    <section title="RSA Full Domain Hash Algorithm" anchor="fdh">
        <t>
            The Full Domain Hash (FDH) is a RSA-based scheme that allows authentication of
            hashes using public-key cryptography.
        </t>

        <t>
            In this document, the notation from <xref target="RFC3447" /> is used.
        </t>

        <t>
            Used parameters:
            <list>
                <t>(n, e) - RSA public key</t>
                <t>K - RSA private key</t>
                <t>k - length of the RSA modulus n in octets</t>
            </list>
        </t>

        <t>
            Fixed options:
            <list>
                <t>Hash - hash function to be used with MGF1</t>
            </list>
        </t>

        <t>
            Used primitives:
            <list>
                <t>
                    I2OSP - Coversion of a nonnegative integer to an octet string as defined in
                    Section 4.1 of <xref target="RFC3447" />
                </t>
                <t>
                    OS2IP - Coversion of an octet string to a nonnegative integer as defined in
                    Section 4.2 of <xref target="RFC3447" />
                </t>
                <t>
                    RSASP1 - RSA signature primitive as defined in
                    Section 5.2.1 of <xref target="RFC3447" />
                </t>
                <t>
                    RSAVP1 - RSA verification primitive as defined in
                    Section 5.2.2 of <xref target="RFC3447" />
                </t>
                <t>
                    MGF1 - Mask Generation Function based on a hash function as defined in
                    Section B.2.1 of <xref target="RFC3447" />
                </t>
            </list>
        </t>

        <section title="FDH signature">
            <t>
                FDH_SIGN(K, M)
            </t>

            <t>
                Input:
                <list>
                    <t>K - RSA private key</t>
                    <t>M - message to be signed, an octet string</t>
                </list>
            </t>

            <t>
                Output:
                <list>
                    <t>S - signature, an octet string of length k</t>
                </list>
            </t>

            <t>
                Steps:
                <list style="numbers">
                    <t>EM = MGF1(M, k - 1)</t>
                    <t>m = OS2IP(EM)</t>
                    <t>s = RSASP1(K, m)</t>
                    <t>S = I2OSP(s, k)</t>
                    <t>Output S</t>
                </list>
            </t>
        </section>

        <section title="FDH verification">
            <t>
                FDH_VERIFY((n, e), M, S)
            </t>

            <t>
                Input:
                <list>
                    <t>(n, e) - RSA public key</t>
                    <t>M - message whose signature is to be verified, an octet string</t>
                    <t>S - signature to be verified, an octet string of length k</t>
                </list>
            </t>

            <t>
                Output:
                <list>
                    <t>"valid signature" or "invalid signature"</t>
                </list>
            </t>

            <t>
                Steps:
                <list style="numbers">
                    <t>s = OS2IP(S)</t>
                    <t>m = RSAVP1((n, e), s)</t>
                    <t>EM = I2OSP(m, k - 1)</t>
                    <t>EM' = MGF1(M, k - 1)</t>
                    <t>
                        If EM and EM' are the same, output "valid signature";
                        else output "invalid signature".
                    </t>
                </list>
            </t>
        </section>
    </section>

    <section title="Elliptic Curve VRF" anchor="ecvrf">
        <t>
            The Elliptic Curve Verifiable Random Function (VRF) is a EC-based scheme
            that allows authentication of hashes using public-key cryptography.
        </t>

        <t>
            Fixed options:
            <list>
                <t>G - EC group</t>
            </list>
        </t>

        <t>
            Used parameters:
            <list>
                <t>g^x - EC public key</t>
                <t>x - EC private key</t>
                <t>q - primer order of group G</t>
                <t>g - generator of group G</t>
            </list>
        </t>

        <t>
            Used primitives:
            <list>
                <t>"" - empty octet string</t>
                <t>|| - octet string concatenation</t>
                <t>p^k - EC point multiplication</t>
                <t>p1*p2 - EC point addition</t>
                <t>SHA256 - hash function SHA-256 as specified in <xref target="RFC6234" /></t>
                <t>ECP2OS - EC point to octet string conversion with point compression as specified in Section 2.3.3 of <xref target="SECG1" /></t>
                <t>OS2ECP - octet string to EC point conversion with point compression as specified in Section 2.3.4 of <xref target="SECG1" /></t>
            </list>
        </t>

        <section title="ECVRF Hash To Curve">
            <t>
                ECVRF_hash_to_curve(m)
            </t>
            <t>
                Input:
                <list>
                    <t>m - value to be hashed, an octet string</t>
                </list>
            </t>
            <t>
                Output:
                <list>
                    <t>h - hashed value, EC point</t>
                </list>
            </t>
            <t>
                Steps:
                <list style="numbers">
                    <t>c = 0</t>
                    <t>C = I2OSP(c, 4)</t>
                    <t>xc = SHA256(m || C)</t>
                    <t>p = 0x02 || xc</t>
                    <t>If p is not a valid octet string representing encoded compressed point in G:
                        <list style="letters">
                            <t>c = c + 1</t>
                            <t>Go to step 2.</t>
                        </list>
                    </t>
                    <t>h = OS2ECP(p)</t>
                    <t>Output h</t>
                </list>
            </t>

        </section>

        <section title="ECVRF Auxiliary Functions">

        <section title="ECVRF Hash Points">
            <t>
                ECVRF_hash_points(p_1, p_2, ..., p_n)
            </t>
            <t>
                Input:
                <list>
                    <t>p_x - EC point in G</t>
                </list>
            </t>
            <t>
                Output:
                <list>
                    <t>h - hash value, integer between 0 and 2^128-1</t>
                </list>
            </t>
            <t>
                Steps:
                <list style="numbers">
                    <t>P = ""</t>
                    <t>for p in [p_1, p_2, ... p_n]:
                       <vspace/>P = P || ECP2OS(p)
                    </t>
                    <t>h' = SHA256(P)</t>
                    <t>h = OS2IP(first 16 octets of h')</t>
                    <t>Output h</t>
                </list>
            </t>
        </section>

        <section title="ECVRF Proof To Hash">
            <t>
                ECVRF_proof_to_hash(gamma)
            </t>
            <t>
                Input:
                <list>
                    <t>gamma - VRF proof, EC point in G with coordinates (x, y)</t>
                </list>
            </t>
            <t>
                Output:
                <list>
                    <t>beta - VRF hash, octet string (32 octets)</t>
                </list>
            </t>
            <t>
                Steps:
                <list style="numbers">
                    <t>beta = I2OSP(x, 32)</t>
                    <t>Output beta</t>
                </list>
            </t>
            <t>
                Note: Because of the format of compressed form of an elliptic curve, the hash can
                be retrieved from an encoded gamma simply by omitting the first octet of the gamma.
            </t>
        </section>

        <section title="ECVRF Decode Proof">
            <t>
                ECVRF_decode_proof(pi)
            </t>
            <t>
                Input:
                <list>
                    <t>pi - VRF proof, octet string (81 octets)</t>
                </list>
            </t>
            <t>
                Output:
                <list>
                    <t>gamma - EC point</t>
                    <t>c - integer between 0 and 2^128-1</t>
                    <t>s - integer between 0 and 2^256-1</t>
                </list>
            </t>
            <t>
                Steps:
                <list style="numbers">
                    <t>let gamma', c', s' be pi split after 33-rd and 49-th octet</t>
                    <t>gamma = OS2ECP(gamma')</t>
                    <t>c = OS2IP(c')</t>
                    <t>s = OS2IP(s')</t>
                    <t>Output gamma, c, and s</t>
                </list>
            </t>
        </section>

        </section><!-- Auxiliary Functions -->

        <section title="ECVRF Signing">
            <t>
                ECVRF_sign(g^x, x, alpha)
            </t>

            <t>
                Input:
                <list>
                    <t>g^x - EC public key</t>
                    <t>x - EC private key</t>
                    <t>alpha - message to be signed, octet string</t>
                </list>
            </t>

            <t>
                Output:
                <list>
                    <t>pi - VRF proof, octet string (81 octets)</t>
                    <t>beta - VRF hash, octet string (32 octets)</t>
                </list>
            </t>

            <t>
                Steps:
                <list style="numbers">
                    <t>h = ECVRF_hash_to_curve(alpha)</t>
                    <t>gamma = h^x</t>
                    <t>choose a nonce k from [0, q-1]</t>
                    <t>c = ECVRF_hash_points(g, h, g^x, h^x, g^k, h^k)</t>
                    <t>s = k - c*q mod q</t>
                    <t>pi = ECP2OS(gamma) || I2OSP(c, 16) || I2OSP(s, 32)</t>
                    <t>beta = h2(gamma)</t>
                    <t>Output pi and beta</t>
                </list>
            </t>
        </section>

        <section title="ECVRF Verification">
            <t>
                ECVRF_VERIFY(g^x, pi, alpha)
            </t>

            <t>
                Input:
                <list>
                    <t>g^x - EC public key</t>
                    <t>pi - VRF proof, octet string</t>
                    <t>alpha - message to verify, octet string</t>
                </list>
            </t>

            <t>
                Output:
                <list>
                    <t>"valid signature" or "invalid signature"</t>
                    <t>beta - VRF hash, octet string (32 octets)</t>
                </list>
            </t>

            <t>
                Steps:
                <list style="numbers">
                    <t>gamma, c, s = ECVRF_decode_proof(pi)</t>
                    <t>u = (g^x)^c * g^s</t>
                    <t>h = ECVRF_hash_to_curve(alpha)</t>
                    <t>v = gamma^c * h^s</t>
                    <t>c' = ECVRF_hash_points(g, h, g^x, gamma, u, v)</t>
                    <t>beta = ECVRF_proof_to_hash(gamma)</t>
                    <t>
                        If c and c' are the same, output "valid signature";
                        else output "invalid signature". Output beta.
                    </t>
                </list>
            </t>

            <t><cref source="Jan">TODO: check validity of gamma before hashing</cref></t>
        </section>

    </section>

    <section title="Change Log">
        <t>
            Note to RFC Editor: if this document does not obsolete an existing RFC,
            please remove this appendix before publication as an RFC.
        </t>

        <t>
            <list>
                <t>
                    pre 00 - initial version of the document submitted to mailing list only
                </t>
                <t>
                    00 - fix NSEC5KEY rollover mechanism, clarify NSEC5PROOF RDATA, clarify
                    inputs and outputs for NSEC5 proof and NSEC5 hash computation
                </t>
                <t>
                    01 - added Performance Considerations section
                </t>
                <t>
                    02 - Elliptic Curve based VRF for NSEC5 proofs; response sizes based on empirical data
                </t>
            </list>
        </t>
    </section>

    <section title="Open Issues">
        <t>
            Note to RFC Editor: please remove this appendix before publication as an RFC.
        </t>

        <t>
            <list style="numbers">
                <t>
                    Consider alternative way to signalize NSEC5 support. The NSEC5 could use
                    only one DNSSEC algorithm identifier, and the actual algorithm to be used
                    for signing can be the first octet in DNSKEY public key field and RRSIG
                    signature field. Similar approach is used by PRIVATEDNS and PRIVATEOID
                    defined in <xref target="RFC4034" />.
                </t>
                <t>
                    How to add new NSEC5 hashing algorithm. We will need to add new DNSSEC
                    algorithm identifiers again.
                </t>
                <t>
                    NSEC and NSEC3 define optional steps for hash collisions detection. We don't
                    have a way to avoid them if they really appear (unlikely). We would have
                    to drop the signing key and generate a new one. Which cannot be done
                    instantly.
                </t>
                <t>
                    Write Special Considerations section.
                </t>
                <t>
                    Contributor list has to be completed.
                </t>
            </list>
        </t>
    </section>
  </back>
</rfc>
<!-- vim: et ts=4 sts=4 sw=4 colorcolumn=100 spell :
-->
