<?xml version="1.0" encoding="utf-8"?>
<!-- name="GENERATOR" content="github.com/mmarkdown/mmark Mmark Markdown Processor - mmark.miek.nl" -->
<rfc version="3" ipr="trust200902" docName="draft-kaizer-dnsop-ml-dsa-mtl-dnssec-00" submissionType="IETF" category="info" xml:lang="en" xmlns:xi="http://www.w3.org/2001/XInclude" indexInclude="true">

<front>
<title abbrev="ML-DSA-MTL-DNSSEC">Module-Lattice-Based Signatures with Merkle Tree Ladders (ML-DSA-MTL) for DNSSEC</title><seriesInfo value="draft-kaizer-dnsop-ml-dsa-mtl-dnssec-00" stream="IETF" status="informational" name="Draft"></seriesInfo>
<author initials="A." surname="Kaizer" fullname="A. Kaizer"><organization>Verisign Labs</organization><address><postal><street>12061 Bluemont Way</street>
<city>Reston</city>
<code>20190</code>
<country>USA</country>
<region>VA</region>
</postal><email>akaizer@verisign.com</email>
<uri>https://www.verisignlabs.com/</uri>
</address></author><author initials="J." surname="Harvey" fullname="J. Harvey"><organization>Verisign Labs</organization><address><postal><street>12061 Bluemont Way</street>
<city>Reston</city>
<code>20190</code>
<country>USA</country>
<region>VA</region>
</postal><email>jsharvey@verisign.com</email>
<uri>https://www.verisignlabs.com/</uri>
</address></author><author initials="B." surname="Kaliski" fullname="B. Kaliski"><organization>Verisign Labs</organization><address><postal><street>12061 Bluemont Way</street>
<city>Reston</city>
<code>20190</code>
<country>USA</country>
<region>VA</region>
</postal><email>bkaliski@verisign.com</email>
<uri>https://www.verisignlabs.com/</uri>
</address></author><author initials="S." surname="Sheth" fullname="S. Sheth"><organization>Verisign Labs</organization><address><postal><street>12061 Bluemont Way</street>
<city>Reston</city>
<code>20190</code>
<country>USA</country>
<region>VA</region>
</postal><email>ssheth@verisign.com</email>
<uri>https://www.verisignlabs.com/</uri>
</address></author><date year="2026" month="July" day="6"></date>
<area>Internet</area>
<workgroup>DNSOP Working Group</workgroup>
<keyword>Signature</keyword>
<keyword>DNSSEC</keyword>
<keyword>Algorithm</keyword>

<abstract>
<t>This document describes how to apply the Module-Lattice-Based Digital Signature Algorithm (ML-DSA) and Merkle Tree Ladders (MTL) as a conservative post-quantum cryptographic algorithm for DNS Security Extensions (DNSSEC).  This combination is referred to as the ML-DSA-MTL Signature scheme.  This document describes how to specify ML-DSA-MTL keys and signatures in DNSSEC, specifically for ML-DSA-44 with SHAKE-128.  This document also provides guidance for use of EDNS(0) in signature retrieval.</t>
</abstract>

</front>

<middle>

<section anchor="introduction"><name>Introduction</name>
<t>The Domain Name System Security Extensions (DNSSEC), which are broadly defined in <xref target="RFC4033"></xref>, <xref target="RFC4034"></xref> and <xref target="RFC4035"></xref>, use cryptographic keys and digital signatures to provide data origin authentication and data integrity in the DNS.</t>
<t>This document describes the application of Merkle Tree Ladders (MTL) <xref target="MTL-MODE"></xref> to the Module-Lattice-Based Digital Signature Algorithm (ML-DSA) <xref target="FIPS204"></xref>, referred to generally as ML-DSA-MTL.  This document specifically defines the use of ML-DSA-44 with SHAKE-128 as the ML-DSA-44-MTL-SHAKE-128 signature scheme for DNSSEC.  Other combinations are possible for MTLs (e.g., SLH-DSA or ML-DSA with SHA256) and may be described in separate documents.</t>
<t>As described herein, a DNSKEY resource record (RR) for an ML-DSA-MTL key contains a ML-DSA key. The ML-DSA key is used for verifying signatures on MTL authentication data. An RRSIG resource record for an ML-DSA-MTL Signature contains a Merkle proof (authentication path) and optional signed MTL. The Merkle proof is verifiable using a MTL. A signed MTL with a Merkle proof can be verified in a single response, similar to how existing DNSSEC algorithms operate today.</t>
<t>This draft focuses on the code-points applicable to DNSKEY and RRSIG formulation and how to retrieve MTL signatures. Later versions may describe DNSSEC protocol and/or operational guidance for zone signing, zone composition, zone updates, zone transfer, name server processing, resolver signature processing, and resolver caching related to MTLs signatures.</t>

<section anchor="motivation"><name>Motivation</name>
<t>This document provides a conservatively designed PQC algorithm for DNSSEC as described in <xref target="I-D.sheth-pqc-dnssec-strategy"></xref> using MTL <xref target="MTL-MODE"></xref> and ML-DSA <xref target="FIPS204"></xref>.  The cryptographic operations for applying MTL to ML-DSA in the DNSSEC use case are specified within this document.  The reader does not need to be familiar with the more general <xref target="MTL-MODE"></xref> specification to implement the ML-DSA-MTL signature scheme for DNSSEC.</t>
<t>MTL is designed to reduce the size, memory, and computational impact of PQC signature algorithms.  For DNSSEC, the size impact reduction is achieved when signatures provided in RRSIG RRs are primarily comprised of &quot;condensed signatures&quot; (Merkle proofs / authentication paths) and are only occasionally comprised of &quot;full signatures&quot; that contain both a condensed signature and a signed MTL, where the signed MTL includes a signature using the underlying PQC signature algorithm, i.e., ML-DSA.  MTL reduces the memory requirements for PQC signatures as the signature data in the zone database or cache is primarily comprised of Merkle proofs and only occasionally of signed MTLs <xref target="CTRSAMTL"></xref>. It also reduces the computational requirements when many condensed signatures are included under a full signature as only the full signature incurs the signing and/or verification overhead of the underlying algorithm.</t>
<t>ML-DSA was formally published as a standard by NIST in August 2024 <xref target="FIPS204"></xref>.  This document selected ML-DSA as one application of MTL to DNSSEC because lattice-based techniques are well understood and offer a conservative choice for long-term security relative to newer NIST candidate post-quantum signature schemes.</t>
</section>

<section anchor="definitions"><name>Definitions</name>
<t>The provided terms in alphabetical order describe concepts utilized in this document.</t>

<dl spacing="compact">
<dt>Authentication Path</dt>
<dd>The set of sibling hash values from a leaf hash value to a rung.</dd>
<dt>Index</dt>
<dd>An integer value I that identifies a leaf node in a node set.  Indexes start at 0 and are consecutively assigned.</dd>
<dt>Index Pair<br />
</dt>
<dd>A pair of integer values (L,R) that together identify a node in a node set based on the lowest and highest indexes of the consecutively-indexed leaf nodes that the node authenticates.  For a leaf node, the index pair is (I,I) which is used interchangeably with the leaf index I.</dd>
<dt>Internal Node</dt>
<dd>A node in a node set whose value is the hash of two child nodes.</dd>
<dt>Ladder/Merkle Tree Ladder (MTL)</dt>
<dd>A collection of one or more rungs that can be used to verify an authentication path.</dd>
<dt>Leaf Node</dt>
<dd>A node in a node set whose value is the hash of a single message.</dd>
<dt>Message</dt>
<dd>A set of bytes that are intended to be signed and later verified.</dd>
<dt>Node Set</dt>
<dd>An evolving set of hash nodes, each of which is part of a union of tree structures either as a leaf node or an internal node. A node set is acyclic, i.e., every node is either a leaf node or the ancestor of two or more leaf nodes, and no node is an ancestor of itself. Every node set has one or more root nodes.</dd>
<dt>Root Node</dt>
<dd>A node in a node set that has no ancestors.</dd>
<dt>Series Identifier (SID)</dt>
<dd>A cryptographically unique value associated with an instance of a MTL node set.</dd>
<dt>Rung</dt>
<dd>A node from a node set that can be used to authenticate one or more leaf nodes within that node set. A rung may be a root node.</dd>
</dl>
</section>

<section anchor="rung_strategy"><name>Binary Rung Strategy</name>
<t>In the MTL operations in this document, the ladder is selected according to what is called the binary rung strategy.  In this strategy, the index pairs for the rungs are based on the binary representation of the number of messages in the message series. More specifically, the first rung is the apex of the largest perfect binary tree that can be formed from the leaf nodes corresponding to the messages, starting from the left; the second rung is the apex of the largest perfect binary tree that can be formed from the remaining leaf nodes; and so on.  The sizes of the trees decrease from left to right.</t>
<t>The following figure shows a node set with 14 leaf nodes based on this strategy. The internal node hash function is denoted H and the leaf node hash function is not shown. The rungs are marked with asterisks (*).</t>

<artwork anchor="fig6"><![CDATA[              (0,7)*
                |
                H
        /------/ \------\
      (0,3)           (4,7)           (8,11)*
        |               |               |
        H               H               H
    /--/ \--\       /--/ \--\       /--/ \--\ 
  (0,1)   (2,3)   (4,5)   (6,7)   (8,9)  (10,11) (12,13)*
    |       |       |       |       |       |       |
    H       H       H       H       H       H       H
   / \     / \     / \     / \     / \     / \     / \
  0   1   2   3   4   5   6   7   8   9  10  11  12  13
]]>
</artwork>
<t>Merkle tree authentication paths in binary rung strategy are constructed from the perfect binary tree that a given rung covers.  For example, the authentication path for leaf 9 would include the hash of leaf 8 and (10,11) which is sufficient to re-create rung (8,11) which covers leaf 9.</t>
<t>The following table gives examples of ladders for values of N up to 19 to showcase how the rungs evolve as new messages are appended to a given node set.</t>

<artwork anchor="fig5"><![CDATA[          Number of Messages    |      Ladder Rungs
                    N           | 
        -------------------------------------------------
                    1           | (0,0)
                    2           | (0,1)
                    3           | (0,1) (2,2)
                    4           | (0,3)
                    5           | (0,3) (4,4)
                    6           | (0,3) (4,5)
                    7           | (0,3) (4,5) (6,6)
                    8           | (0,7)
                    9           | (0,7) (8,8)
                   10           | (0,7) (8,9)
                   11           | (0,7) (8,9) (10,10)
                   12           | (0,7) (8,11) 
                   13           | (0,7) (8,11) (12,12)
                   14           | (0,7) (8,11) (12,13)
                   15           | (0,7) (8,11) (12,13) (14,14)
                   16           | (0,15)
                   17           | (0,15) (16,16)
                   18           | (0,15) (16,17)
                   19           | (0,15) (16,17) (18,18)
]]>
</artwork>
<t>Different rung strategies may result in rungs and authentication paths that differ from the above.  This document does not limit to any specific rung strategy, although for interoperability in constructing/evaluating authentication paths the current draft assumes each rung is a perfect binary tree.  Additional rung strategies may be defined in updates to this draft or in future drafts.</t>

<section anchor="related_work"><name>Related Work</name>
<t>The binary rung strategy appears under different names in other cryptographic constructions based on Merkle trees. Champine defines a binary numeral tree <xref target="BIN-NUM-TREES"></xref> with similar structure (the successive perfect binary subtrees are called eigentrees). Other similar Merkle tree-based constructions include Crosby and Wallach's history trees <xref target="HISTORY-TREE"></xref>, Todd's Merkle mountain ranges <xref target="MERKLE_MOUNTAIN"></xref>, and Reyzin and Yakoubov's cryptographic accumulator <xref target="CRYPTO-ACC"></xref>.</t>
</section>
</section>
</section>

<section anchor="conventions-used-in-this-document"><name>Conventions Used in This Document</name>
<t>The key words &quot;MUST&quot;, &quot;MUST NOT&quot;, &quot;REQUIRED&quot;, &quot;SHALL&quot;, &quot;SHALL NOT&quot;, &quot;SHOULD&quot;, &quot;SHOULD NOT&quot;, &quot;RECOMMENDED&quot;, &quot;NOT RECOMMENDED&quot;, &quot;MAY&quot;, and &quot;OPTIONAL&quot; in this document are to be interpreted as described in BCP 14 <xref target="RFC2119"></xref> <xref target="RFC8174"></xref> when, and only when, they appear in all capitals, as shown here.</t>
<t>The single pipe character, &quot;|&quot;, is used to denote concatenation as is done in <xref target="RFC4034"></xref>.</t>
<t>All numeric DNSKEY elements and RRSIG elements specified in this document are unsigned integers in network byte order (big endian order).</t>
</section>

<section anchor="dnskey-resource-records"><name>DNSKEY Resource Records</name>
<t>ML-DSA-44 public keys are stored in the Public Key field of a DNSKEY resource record as the fixed-length, 1312-octet output of the ML-DSA-44 public key, as specified in <xref target="FIPS204"></xref> Algorithm 22.  The Algorithm field of the DNSKEY RR MUST be set to the value allocated for ML-DSA-44 (see <xref target="iana_considerations"></xref>).</t>
</section>

<section anchor="RRSIG_records"><name>RRSIG Resource Records</name>
<t>The value of the signature field in the RRSIG RR consists of a variable-length value starting with one-octet MTL-Type and followed by MTL Authentication Data:</t>

<artwork anchor="rrsig_signature"><![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
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|   MTL-Type    |                                               |
+-+-+-+-+-+-+-+-+                                               |
|                    MTL Authentication Data                    |
/                                                               /
/                                                               /
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
]]>
</artwork>
<t>The MTL-Type octet is one of condensed (0) or full (1). The MTL Authentication Data includes the signature information of the specified type. Condensed signatures are described in <xref target="condensed_sig"></xref> and full signatures are described in <xref target="full_sig"></xref>. How these signatures can be leveraged for dynamic signing is described in <xref target="dynamic_signing"></xref>.</t>
</section>

<section anchor="mtl_struct"><name>MTL Implementation Details</name>
<t>This section describes the data structures for each MTL-Type in <xref target="data_struct"></xref>, how to instantiate the hashing algorithms in <xref target="hashes"></xref>, and summarizes what data is included for each MTL-Type in <xref target="mtl_type_data"></xref>.  Taken together, it allows a signer or verifier to sign and verify MTL DNSSEC signatures in a consistent, interoperable manner. <xref target="signer_steps"></xref> and <xref target="verifier_steps"></xref> include high-level steps a signer or verifier could take to implement these concepts.</t>
<t>The octets required in this section are based on the values for ML-DSA-44 as specified in <xref target="FIPS204"></xref> and could be different if other underlying signature algorithms were supported.</t>

<section anchor="data_struct"><name>MTL Data Structures</name>
<t>This section describes the format of the MTL Authentication Data referred to in <xref target="RRSIG_records"></xref>.</t>

<section anchor="condensed_sig"><name>Condensed Signatures</name>
<t>An application MAY convey a &quot;condensed&quot; signature comprised of a Merkle tree proof only, which is convenient for reducing the size impact compared to a full signature. However, it requires the verifier to obtain the rest of the full signature, i.e., the signed ladder, from a separate source, e.g., with a separate query.</t>
<t>A condensed MTL signature consists of:</t>

<artwork anchor="fig19"><![CDATA[                         1 1 1 1 1 1 
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
    +-------------------------------+
    |             Flags             |
    +-------------------------------+    
    |                               |
    //             SID             //
    |          (32-octets)          |
    +-------------------------------+
    |                               |
    //          Randomizer         //
    |          (16-octets)          |
    +-------------------------------+
    |                               |
    |          Leaf Index           |
    |          (8-octets)           |
    |                               |
    +-------------------------------+
    |                               |
    |     Target Rung Left Index    |
    |          (8-octets)           |
    |                               |
    +-------------------------------+
    |                               |
    |    Target Rung Right Index    |
    |          (8-octets)           |
    |                               |
    +-------------------------------+
    |      Sibling Hash Count       |
    +-------------------------------+
    |                               |
    //     Sibling Hash Values     //
    |    (16-octets per sibling)    |
    +-------------------------------+
]]>
</artwork>
<t>Where:</t>

<ul spacing="compact">
<li>flags, string providing future extensibility; it MUST be 0 for this version of the document</li>
<li>SID, series identifier of the node set</li>
<li>randomizer, randomizer value associated with leaf_index</li>
<li>leaf_index, the leaf index of the message being authenticated, a non-negative integer between 0 and 2^64-1</li>
<li>rung_left, the left index of the target rung, a non-negative integer between 0 and 2^64-1</li>
<li>rung_right, the right index of the target rung, a non-negative integer between 0 and 2^64-1</li>
<li>sibling_hash_count, the number of sibling hash values in the authentication path, a non-negative integer between 0 and 2^16-1</li>
<li>sibling_hashes, zero or more sibling hash values</li>
</ul>
<t>The SID is RECOMMENDED to be generated from an approved Random Bit Generator <xref target="RFC4086"></xref> and the randomizer MUST be generated from an approved Random Bit Generator.</t>
</section>

<section anchor="full_sig"><name>Full Signatures</name>
<t>An application MAY convey a &quot;full&quot; signature which can be verified on its own. However, it includes the overhead of the ladder and the underlying signature on the ladder.</t>
<t>A full MTL signature consists of two base components:</t>

<artwork anchor="fig18"><![CDATA[                         1 1 1 1 1 1 
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
    +-------------------------------+
    |                               |
    //     Condensed Signature     //
    |       (variable octets)       |
    +-------------------------------+
    |                               |
    //        Signed Ladder        //
    |       (variable octets)       |
    +-------------------------------+
]]>
</artwork>
<t>Where:</t>

<ul spacing="compact">
<li>condensed_signature is described in <xref target="condensed_sig"></xref></li>
<li>signed_ladder is described in <xref target="data_structure_ladder"></xref></li>
</ul>

<section anchor="data_structure_ladder"><name>Signed Ladder</name>
<t>A signed ladder data structure consists of:</t>

<artwork anchor="fig7"><![CDATA[                         1 1 1 1 1 1 
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
    +-------------------------------+
    |             Flags             |
    +-------------------------------+
    |                               |
    //             SID             //
    |          (32-octets)          |
    +-------------------------------+
    |          Rung Count           |
    +-------------------------------+
    |                               |
    //          Rung Data          //
    |      (32-octets per rung)     |
    +-------------------------------+
    |  Underlying Signature Length  |
    |          (4-octets)           |
    +-------------------------------+
    |                               |
    //    Underlying Signature     //
    |         (2420-octets)         |
    +-------------------------------+    
]]>
</artwork>
<t>Where:</t>

<ul spacing="compact">
<li>flags, string providing future extensibility; the initial value for this field MUST be 0</li>
<li>SID, same value as defined in <xref target="condensed_sig"></xref></li>
<li>rung_count, the number of rungs in the ladder, a positive integer between 1 and 2^16-1</li>
<li>rungs, one or more rung data structures</li>
<li>sig_len, the length in octets of the underlying signature on the ladder, a positive integer between 1 and 2^32-1</li>
<li>sig, the underlying signature on the ladder (i.e., flags, SID, rung_count, and rungs)</li>
</ul>
<t>Each Rung Data consists of:</t>

<artwork anchor="fig8"><![CDATA[                         1 1 1 1 1 1 
     0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
    +-------------------------------+
    |                               |
    |          Left Index           |
    |          (8-octets)           |
    |                               |
    +-------------------------------+
    |                               |
    |          Right Index          |
    |          (8-octets)           |
    |                               |
    +-------------------------------+
    |                               |
    //       Rung Hash Value       //
    |          (16-octets)          |
    +-------------------------------+
]]>
</artwork>
<t>Where:</t>

<ul spacing="compact">
<li>left_index, the left index of the rung, a non-negative integer between 0 and 2^64-1</li>
<li>right_index, the right index of the rung, a non-negative integer between left_index and 2^64-1</li>
<li>hash, the rung hash value</li>
</ul>
</section>
</section>
</section>

<section anchor="hashes"><name>MTL Hash Function Instantiation</name>
<t>This document specifies the use of cSHAKE128 as the hash function for use in MTL as defined in NIST SP 800-185 <xref target="CSHAKE"></xref>.  For MTL the hash algorithm is utilized to generate the Merkle tree(s) that comprise a node set where the inputs to the hash function depend on whether the node is a leaf node or internal node.</t>
<t>For a leaf node, LEAF = (SID | Randomizer | leaf_index | len(ctx_msg) | ctx_msg | msg) where:</t>

<ul spacing="compact">
<li>SID, a 32-octet value as described in <xref target="condensed_sig"></xref></li>
<li>leaf_index, an 8-octet value denoting the leaf node's index</li>
<li>Randomizer, a 16-octet value as described in <xref target="condensed_sig"></xref></li>
<li>len(ctx_msg), a 4-octet value of the length of the included message-specific context string; MUST be 0</li>
<li>ctx_msg, variable length byte array; MUST be null in this draft</li>
<li>msg, variable length byte array containing the message corresponding to the leaf node, i.e., RRSIG_RDATA | RR(1) | RR(2)...</li>
</ul>
<t>The inclusion of ctx_msg is provided for future extensibility and consistency with other recent specifications that support per-message context strings.</t>
<t>For an internal node, INTERNAL = (SID | left_index | right_index | hash_left | hash_right) where:</t>

<ul spacing="compact">
<li>SID, a 32-octet value</li>
<li>left_index, an 8-octet value denoting the internal node's left index</li>
<li>right_index, an 8-octet value denoting the internal node's right index</li>
<li>hash_left, a 16-octet value denoting the left child hash</li>
<li>hash_right, a 16-octet value denoting the right child hash</li>
</ul>
<t>This is then applied to cSHAKE as follows to produce a cSHAKE128 output:</t>

<ul empty="true" spacing="normal">
<li>H_leaf = cSHAKE(LEAF, 128, &quot;&quot;, HASH_CUSTOMIZATION_STRING_LEAF)</li>
<li>H_int = cSHAKE(INTERNAL, 128, &quot;&quot;, HASH_CUSTOMIZATION_STRING_INT)</li>
</ul>
<t>where HASH_CUSTOMIZATION_STRING_LEAF is the user customization string input allowed by cSHAKE and MUST be an octet string represented by &quot;{'M','T','L','L','E','A','F'}&quot; and HASH_CUSTOMIZATION_STRING_INT MUST be an octet string represented by &quot;{'M','T','L','I','N','T'}&quot;.</t>
</section>

<section anchor="mtl_type_data"><name>MTL Signature Coverage</name>
<t>Full and condensed signatures protect the same DNS RRset responses as non-MTL DNSSEC responses because the leaf nodes correspond to the same RRSIG_RDATA | RR(1) | RR(2)... observed in 3.1.8.1 of <xref target="RFC4034"></xref>.  The primary difference between full and condensed responses is what is covered by the signature related data as described next.</t>
<t>A full signature signs a ladder rather than individual DNS RRsets, i.e., signature = sign(FLAGS | SID | RUNG_COUNT | RUNG_DATA).  Meanwhile, the msg input to the leaf node hash operation contains the <xref target="RFC4034"></xref> data.  This enables one signature on a signed ladder to authenticate every RRset included in the given Merkle tree node set rather than signing each RRset individually.</t>
<t>A condensed signature does not provide a signature using sign(...) but provides enough information to prove inclusion in a Merkle tree node set covered by a signed ladder.  The association with a full signature that has sign(...) data covers the condensed signature.</t>
</section>
</section>

<section anchor="algorithm-numbers-for-ds-dnskey-and-rrsig-resource-records"><name>Algorithm Numbers for DS, DNSKEY, and RRSIG Resource Records</name>
<t>The algorithm number associated with the use of MLDSA44MTLSHAKE128 in DS, DNSKEY, and RRSIG resource records is TBD. This registration is fully defined in the IANA Considerations section.</t>
</section>

<section anchor="mtl_edns_option"><name>The mtl-full EDNS(0) Option</name>
<t>To receive full signatures, a MTL-aware client MUST request that signatures be returned in the full format by providing the mtl-full EDNS(0) option in the OPT meta-RR of its query <xref target="RFC6891"></xref>.</t>

<section anchor="option-format"><name>Option Format</name>
<t>The mtl-full option is encoded as follows:</t>

<artwork anchor="option_format"><![CDATA[0                       8                      16
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                  OPTION-CODE                  |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|                 OPTION-LENGTH                 |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
]]>
</artwork>
<t>Where:</t>

<dl spacing="compact">
<dt>OPTION-CODE</dt>
<dd>The EDNS0 option code assigned to mtl-full, TBD.</dd>
<dt>OPTION-LENGTH</dt>
<dd>Always zero.</dd>
</dl>
</section>

<section anchor="use-by-dns-servers"><name>Use by DNS Servers</name>
<t>When a query includes the mtl-full option, the response MUST include one or more full and optionally zero or more condensed signatures.  Each condensed signature in the response MUST be covered by at least one full signature in the response which enables a full response to be self-contained.</t>
<t>A server MUST NOT return a full signature unless mtl-full is provided.  If a server does not have a full signature and one is requested, it MUST return SERVFAIL with a TBD EDE code.</t>
</section>

<section anchor="edns_client"><name>Use by DNS Clients</name>
<t>A client SHOULD first query a server without the mtl-full option, and then, if needed, re-issue the query with the mtl-full option. Since responses to queries with the mtl-full option are expected to be large, it is RECOMMENDED that queries with the mtl-full option be issued over transports (e.g., TCP, TLS, QUIC) that support large responses without truncation and/or fragmentation.</t>
<t>Clients that request a full signature but receive only condensed signatures MUST return SERVFAIL with a TBD EDE code.  If a client does not use the mtl-full option and receives one or more full signatures, it MUST return SERVFAIL with TBD EDE code.</t>
</section>

<section anchor="summary-of-expected-outcomes"><name>Summary of Expected Outcomes</name>
<t>This section summarizes the expected behavior a server and a client follow when encountering a MTL response depending on if mtl-full was used.</t>

<section anchor="authoritative-server"><name>Authoritative Server</name>
<table><name>Expected authoritative behavior
</name>
<thead>
<tr>
<th>mtl-full</th>
<th>Have Full</th>
<th>Return</th>
</tr>
</thead>

<tbody>
<tr>
<td>Y</td>
<td>Y</td>
<td>One or more full + covered condensed</td>
</tr>

<tr>
<td>Y</td>
<td>N</td>
<td>SERVFAIL + EDE</td>
</tr>

<tr>
<td>N</td>
<td>-</td>
<td>One or more condensed</td>
</tr>
</tbody>
</table></section>

<section anchor="client"><name>Client</name>
<table><name>Expected client behavior
</name>
<thead>
<tr>
<th>mtl-full</th>
<th>Response</th>
<th>Action</th>
</tr>
</thead>

<tbody>
<tr>
<td>Y</td>
<td>At least one full</td>
<td>Use</td>
</tr>

<tr>
<td>Y</td>
<td>No full</td>
<td>SERVFAIL + EDE</td>
</tr>

<tr>
<td>N</td>
<td>One or more full</td>
<td>SERVFAIL + EDE</td>
</tr>

<tr>
<td>N</td>
<td>Condensed</td>
<td>Use or request full</td>
</tr>
</tbody>
</table></section>
</section>
</section>

<section anchor="implementation-considerations"><name>Implementation Considerations</name>

<section anchor="batch-signing"><name>Batch Signing</name>
<t>Signing RRsets in batches, i.e., as multiple additions to a node set, rather than as individual additions or as messages can leverage MTL to reduce the number of signature and verification operations performed with the underlying signature algorithm. This results in reducing the average computational overhead per message signed/verified. This practice can also reduce the load on a hardware security module. Batches also benefit the verifier by reducing the number of full signatures required for validation because multiple RRSIGs can be verified by the signed ladder covering a batch. The appropriate batch size will depend on the properties of the zone and the requirements of the zone operator. Batch size needs to be considered carefully to ensure that new signatures are available in a timely manner while still gaining the benefits of batch signing <xref target="MTL-ENDURANCE"></xref>.</t>
</section>

<section anchor="dynamic_signing"><name>Online Signing</name>
<t>MTL can accommodate online signing, also known as dynamic signing, where responses are generated dynamically at query time. How exactly this is achieved is dependent on the operator's requirements.  One example, but not limiting, is to generate a new MTL node set for each query response.  Implementors should be aware that online signing may limit the amortization benefits of MTL to only data within the same query.</t>
</section>
</section>

<section anchor="iana_considerations"><name>IANA Considerations</name>
<t>This document updates the IANA registry for DNSSEC &quot;Domain Name System Security (DNSSEC) Algorithm Numbers&quot; located at <eref target="https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml">https://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml</eref>.  The following entries are requested to be added to the registry subject to the Number update:</t>

<artwork><![CDATA[ML-DSA-44-MTL-SHAKE-128
+--------------+--------------------------------+
| Number       | TBD                            |
| Description  | ML-DSA-44-MTL-SHAKE-128        |
| Mnemonic     | MLDSA44MTLSHAKE128             |
| Zone Signing | Y                              |
| Trans. Sec.  | *                              |
| Reference    | This specification             |
+--------------+--------------------------------+
]]>
</artwork>

<ul spacing="compact">
<li>There has been no determination of standardization of the use of these algorithms with Transaction Security.</li>
</ul>
</section>

<section anchor="implementations"><name>Implementation Status</name>
<t>NOTE: Please remove this section and the reference to RFC 7942 prior to publication as an RFC.</t>
<t>This section records the status of known implementations of the protocol defined by this specification at the time of posting of this Internet-Draft, and is based on a proposal described in RFC 7942.  The description of implementations in this section is intended to assist the IETF in its decision processes in progressing drafts to RFCs.  Please note that the listing of any individual implementation here does not imply endorsement by the IETF.  Furthermore, no effort has been spent to verify the information presented here that was supplied by IETF contributors. This is not intended as, and must not be construed to be, a catalog of available implementations or their features.  Readers are advised to note that other implementations may exist.</t>
<t>According to RFC 7942, &quot;this will allow reviewers and working groups to assign due consideration to documents that have the benefit of running code, which may serve as evidence of valuable experimentation and feedback that have made the implemented protocols more mature.  It is up to the individual working groups to use this information as they see fit&quot;.</t>
<t>For testing purposes, ML-DSA-44-MTL-SHAKE-128 has been implemented in the following DNS open-source applications:</t>

<ul spacing="compact">
<li>LDNS for key generation, zone signing, and zone verification with MTL: <eref target="https://github.com/Verisign/mtl-mode-ldns"></eref></li>
<li>NSD authoritative name server with MTL: <eref target="https://github.com/verisign/mtl-mode-nsd"></eref></li>
<li>Unbound recursive resolver with MTL: <eref target="https://github.com/Verisign/mtl-mode-unbound"></eref></li>
</ul>
<t>These implementations depend on the reference implementation of MTL which is available in C.  The MTL library can be found at <eref target="https://github.com/Verisign/MTL"></eref>.</t>
</section>

<section anchor="security-considerations"><name>Security Considerations</name>
<t>The security considerations of <xref target="FIPS204"></xref> are inherited in the usage of ML-DSA-MTL in DNSSEC.</t>
<t>ML-DSA-44-MTL-SHAKE-128 is intended to operate at around the 128-bit security level against classical attacks and the 64-bit level against quantum attacks, consistent with NIST's security level I and comparable to non-PQC DNSSEC algorithms such as ECDSAP256SHA256 (algorithm 13).  Future documents may describe ML-DSA-65 or ML-DSA-87 if stronger security levels are needed.</t>
<t>A private key used for a DNSSEC zone MUST NOT be used for any other purpose than for that zone.  Otherwise, cross-protocol or cross-application attacks are possible.</t>
<t>Implementers MUST NOT use the same SID for multiple MTL instantiations, e.g., the MTL instantiation for a KSK node set and the MTL instantiation for a ZSK node set MUST use different SIDs.</t>
<t>Post-quantum algorithms in DNSSEC may introduce larger keys, signatures, and/or signing/verifying effort which may lead to differences in resource capacity compared to existing DNS operational profiles.  Accounting for such factors will help mitigate potential resource exhaustion attacks.  The following highlights such factors as it relates to ML-DSA in MTL:</t>

<ul spacing="compact">
<li>ML-DSA signatures will require more space to store in both authoritative and caching resolvers; while condensed signatures help address this challenge at least one full ML-DSA signature will be needed.</li>
<li>Additional TCP traffic compared to non-PQC DNSSEC algorithms is expected.  Full signatures with ML-DSA will always exceed DNS over UDP limits.  Responses containing multiple condensed signatures may also exceed DNS over UDP limits.</li>
<li>Clients concerned about re-tries, e.g., a UDP query being truncated and then re-attempted over TCP, are RECOMMENDED to perform all queries over TCP when encountering a zone signed with MLDSA44MTLSHAKE128.  This trades off potential UDP benefits of MTL for operational certainty.</li>
<li>Signing and verifying times in ML-DSA are competitive with existing non-PQC DNSSEC algorithms.  Even so, clients should test their system's capacity to handle full signature responses signed with ML-DSA.</li>
</ul>
</section>

<section anchor="acknowledgements"><name>Acknowledgements</name>
<t>This I-D has drawn from helpful examples of document structure and specification text from various DNSSEC algorithm RFCs. The authors express their gratitude to the authors of those RFCs for their contributions.</t>
</section>

</middle>

<back>
<references><name>References</name>
<references><name>Normative References</name>
<reference anchor="FIPS204" target="https://doi.org/10.6028/NIST.FIPS.204">
  <front>
    <title>Module-Lattice-Based Digital Signature Standard</title>
    <author>
      <organization>National Institute of Standards and Technology (NIST)</organization>
    </author>
    <date year="2024" month="August" day="13"></date>
  </front>
  <seriesInfo name="FIPS PUB" value="204"></seriesInfo>
  <seriesInfo name="DOI" value="10.6028/NIST.FIPS.204"></seriesInfo>
</reference>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.2119.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4033.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4035.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.6891.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.8174.xml"/>
</references>
<references><name>Informative References</name>
<reference anchor="BIN-NUM-TREES" target="https://eprint.iacr.org/2021/038">
  <front>
    <title>Streaming Merkle Proofs within Binary Numeral Trees</title>
    <author fullname="L. Champine" initials="L." surname="Champine"></author>
    <date year="2021"></date>
  </front>
  <seriesInfo name="Cryptology ePrint Archive" value="Paper 2021/038"></seriesInfo>
</reference>
<reference anchor="CRYPTO-ACC" target="https://doi.org/10.1007/978-3-319-44618-9_16">
  <front>
    <title>Efficient data structures for tamper-evident logging</title>
    <author fullname="L. Reyzin" initials="L." surname="Reyzin"></author>
    <author fullname="S. Yakoubov" initials="S." surname="Yakoubov"></author>
    <date year="2016"></date>
  </front>
  <seriesInfo name="Zikas, V., De Prisco, R. (eds) Security and Cryptography for Networks" value="SCN 2016, LNCS, vol. 9841, pp. 292-309. Springer, Cham"></seriesInfo>
</reference>
<reference anchor="CSHAKE" target="https://doi.org/10.6028/NIST.SP.800-185">
  <front>
    <title>DSHA-3 Derived Functions: cSHAKE, KMAC, TupleHash and ParallelHash</title>
    <author>
      <organization>National Institute of Standards and Technology (NIST)</organization>
    </author>
    <date year="2016" month="December" day="22"></date>
  </front>
  <seriesInfo name="FIPS SP" value="800-185"></seriesInfo>
  <seriesInfo name="DOI" value="10.6028/NIST.SP.800-185"></seriesInfo>
</reference>
<reference anchor="CTRSAMTL" target="">
  <front>
    <title>Merkle Tree Ladder Mode: Reducing the Size Impact of NIST PQC Signature Algorithms in Practice</title>
    <author initials="B" surname="Kaliski">
      <organization>Verisign</organization>
    </author>
    <author initials="A.M." surname="Fregly">
      <organization>Verisign</organization>
    </author>
    <author initials="J." surname="Harvey">
      <organization>Verisign</organization>
    </author>
    <author initials="S." surname="Sheth">
      <organization>Verisign</organization>
    </author>
    <date year="2023"></date>
  </front>
</reference>
<reference anchor="HISTORY-TREE" target="https://dl.acm.org/doi/abs/10.5555/1855768.1855788">
  <front>
    <title>Efficient data structures for tamper-evident logging</title>
    <author fullname="S. Crosby" initials="S." surname="Crosby"></author>
    <author fullname="D. Wallach" initials="D." surname="Wallach"></author>
  </front>
  <seriesInfo name="Proceedings of the 18th USENIX Security Symposium" value="pp. 317-334. USENIX Association (2009)"></seriesInfo>
</reference>
<reference anchor="I-D.sheth-pqc-dnssec-strategy" target="https://datatracker.ietf.org/doc/html/draft-sheth-pqc-dnssec-strategy-00">
  <front>
    <title>Post-Quantum Cryptography Strategy for DNSSEC</title>
    <author fullname="Swapneel Sheth" initials="S." surname="Sheth">
      <organization>Verisign Labs</organization>
    </author>
    <author fullname="Taejoong Chung" initials="T." surname="Chung">
      <organization>Virginia Tech</organization>
    </author>
    <author fullname="Benno Overeinder" initials="B." surname="Overeinder">
      <organization>NLnet Labs</organization>
    </author>
    <date year="2025" month="October" day="16"></date>
  </front>
  <seriesInfo name="Internet-Draft" value="draft-sheth-pqc-dnssec-strategy-00"></seriesInfo>
</reference>
<reference anchor="MERKLE_MOUNTAIN" target="https://github.com/opentimestamps/opentimestamps-server/blob/master/doc/merkle-mountain-range.md">
  <front>
    <title>Merkle Mountain Ranges</title>
    <author fullname="P. Todd" initials="P." surname="Todd"></author>
  </front>
</reference>
<reference anchor="MTL-ENDURANCE" target="https://github.com/IQTF/pq-dnssec-materials/raw/refs/heads/main/IETF122/Tran_Randomized_evaluation_of_SLH-DSA-MTL&#39;s_impact_on_reducing_PQ-DNSSEC_signature_sizes.pdf">
  <front>
    <title>Randomized Evaluation of SLH-DSA-MTL&#39;s Impact on Reducing PQ-DNSSEC Signature Sizes</title>
    <author fullname="Minh Hoang Tran" initials="M." surname="Tran">
      <organization>Virginia Tech</organization>
    </author>
    <author fullname="Tijay Chung" initials="T." surname="Chung">
      <organization>Virginia Tech</organization>
    </author>
    <date year="2025" month="March" day="18"></date>
  </front>
</reference>
<reference anchor="MTL-MODE" target="https://eprint.iacr.org/2022/1730.pdf">
  <front>
    <title>Merkle Tree Ladder Mode: Reducing the Size Impact of NIST PQC Signature Algorithms in Practice</title>
    <author fullname="A. Fregly" initials="A." surname="Fregly"></author>
    <author fullname="J. Harvey" initials="J." surname="Harvey"></author>
    <author fullname="B. Kaliski" initials="B." surname="Kaliski"></author>
    <author fullname="S. Sheth" initials="S." surname="Sheth"></author>
    <date year="2023"></date>
  </front>
  <seriesInfo name="in Rosulek, M. (editor), Lecture Notes in Computer Science" value="VOLUME 13871"></seriesInfo>
  <seriesInfo name="CT-RSA 2023 - Cryptographers Track at the RSA Conference" value="pages 415-441"></seriesInfo>
  <seriesInfo name="DOI" value="10.1007/978-3-031-30872-7_16"></seriesInfo>
</reference>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4034.xml"/>
<xi:include href="https://bib.ietf.org/public/rfc/bibxml/reference.RFC.4086.xml"/>
</references>
</references>

<section anchor="change-log"><name>Change Log</name>

<ul empty="true" spacing="compact">
<li>00: Initial draft of the document.</li>
</ul>
</section>

<section anchor="signer_steps"><name>Signer Steps</name>
<t>A signer, e.g., an authoritative server, performs the following set of operations to sign messages in MTL.</t>
<t>The first step is performed once per key pair:</t>

<ol spacing="compact">
<li>Generate a public / private key pair for ML-DSA-44, e.g., for use as a KSK or ZSK.</li>
</ol>
<t>The second step is performed once per node set to be signed:</t>

<ol spacing="compact" start="2">
<li>Generate a series identifier for the node set and initialize a node set for the series. The message index of the node set is set to 0 in this step.</li>
</ol>
<t>The third and fourth steps are performed once per message to be signed in a node set:</t>

<ol start="3">
<li><t>Sample a randomizer and compute the leaf hash for the message.</t>
</li>
<li><t>Append the leaf hash to the node set. The message index is incremented in this step.</t>
</li>
</ol>
<t>The fifth and sixth steps are performed whenever the signer wants to produce a new signed ladder. The signer could do so after each new message is added, or after a new batch of new messages is added.</t>

<ol start="5">
<li><t>Compute the current ladder for the node set using one or more rungs that collectively authenticate all the nodes in the node set.</t>
</li>
<li><t>Sign the ladder using the ML-DSA-44 private key generated in (1).</t>
</li>
</ol>
<t>The seventh step is performed whenever the signer wants to provide a full signature to a requester, e.g., upon receiving an mtl-full EDNS(0) option.</t>

<ol spacing="compact" start="7">
<li>Provide the full signature as described in <xref target="full_sig"></xref>.</li>
</ol>
<t>The eighth step is performed whenever the signer wants to compute a new authentication path for a message relative to the current ladder. The signer could do so after each new message is added, after a batch of new messages is added, and/or later, as needed, to update the authentication paths for older messages so that they are relative to the current ladder.</t>

<ol spacing="compact" start="8">
<li>Compute an authentication path for the message at a specified message index relative to the current ladder.</li>
</ol>
<t>The ninth step is performed whenever the signer wants to provide authentication information to a requester, e.g., as part of a condensed signature in a response.</t>

<ol spacing="compact" start="9">
<li>Provide the condensed signature(s) as described in <xref target="condensed_sig"></xref>.</li>
</ol>
</section>

<section anchor="verifier_steps"><name>Verifier Steps</name>
<t>A verifier, e.g., a DNSSEC-aware resolver, performs the following to verify signatures in MTL:</t>

<ol spacing="compact">
<li>Obtain the signer's public key, e.g., from appropriate DNSKEY records.</li>
</ol>
<t>The second, third, fifth and sixth steps are performed as needed for each message to be authenticated:</t>

<ol start="2">
<li><t>From a condensed signature in a DNS response, obtain the authentication path (i.e., sibling hash values) and the SID.</t>
</li>
<li><t>Determine whether any of ladders held by the verifier includes a rung compatible with the authentication path. If so, skip to step 5.</t>
</li>
</ol>
<t>The fourth step is performed when the verifier doesn't have a compatible ladder.</t>

<ol start="4">
<li><t>Re-try the DNS request with mtl-full EDNS(0) option to fetch a full signature which includes a signed ladder with an included condensed signature that is covered by that ladder.  Validate the included signed ladder signature against the public key in (1).</t>
</li>
<li><t>Compute a leaf hash from the message as described in <xref target="hashes"></xref>.</t>
</li>
<li><t>Verify the authentication path and leaf hash relative to the compatible rung.</t>
</li>
</ol>
</section>

</back>

</rfc>
