jiebi/TextFlow huggingface dataset:
Original text:
"extensions" field.  The types of these extensions are omitted when serializing the "extensions" field of the corresponding message.  The "allow_additional" field MUST be 0 (false) or 1 (true), indicating whether additional extensions are allowed here. Static vectors (see static-vectors): <del> "Extension.extension_data" for any extension in "expected_extensions" whose value is self-delimiting (e.g., fixed length).  This applies only to the corresponding message. </del>  The "extensions" field of the corresponding message, if "allow_additional" is false. "expectedExtensions": an array of "ExtensionType" names.  "allowAdditional": "true" or "false". If "predefinedExtensions" or "expectedExtensions" is empty, it MAY be their definition.  When encoding a "static vector", its length prefix is omitted. <del> In addition to the static vectors implied by various template elements, "Extension.extension_data" is always static in cTLS if the extension is any type listed in Section 4.2 of RFC8446 except "padding".  cTLS implementations MUST be able to parse any of these extensions that the other party is permitted to send, but no other support is required. </del> For example, suppose that the cTLS template is: Then, the following structure:

Reviewer comments:
In the case a cTLS handshake uses a self-delimiting extension (in additional extensions) that is not present in section 4.2 of RFC 8446, its length is always serialized. With this PR, the type of this extension can be stored in and its length can be omitted.

Revised text:
"extensions" field.  The types of these extensions are omitted when serializing the "extensions" field of the corresponding message. <ins> The "self_delimiting_extensions" field indicates extensions whose data is self-delimiting.  The cTLS implementation MUST be able to parse all these extensions, and all extensions listed in Section 4.2 of RFC8446. </ins> The "allow_additional" field MUST be 0 (false) or 1 (true), indicating whether additional extensions are allowed here. Static vectors (see static-vectors):  <ins> "Extension.extension_data" for any extension whose type is in "self_delimiting_extensions", or is listed in Section 4.2 of RFC8446 except "padding".  This applies only to the corresponding message. </ins> The "extensions" field of the corresponding message, if "allow_additional" is false. "expectedExtensions": an array of "ExtensionType" names. <ins> "selfDelimitingExtensions": an array of "ExtensionType" names. </ins> "allowAdditional": "true" or "false". If "predefinedExtensions" or "expectedExtensions" is empty, it MAY be their definition.  When encoding a "static vector", its length prefix is omitted.  For example, suppose that the cTLS template is: Then, the following structure:
Original text:
again. For the common (EC)DHE handshake with pre-established certificates, <del> Stream cTLS achieves an overhead of 45 bytes over the minimum </del>  required by the cryptovariables.  For a PSK handshake, the overhead <del> is 21 bytes.  Annotated handshake transcripts for these cases can be found in transcripts. </del>  <del> TODO: Update these values. </del>  cTLS supports the functionality of TLS and DTLS 1.3, and is forward- compatible to future versions of TLS and DTLS.  cTLS itself is In JSON, this value is represented as "true" or "false".  2.1.1.8. Value: a single "CTLSExtensionTemplate" struct:

Reviewer comments:
The example did not account for the record layer, and seemed to overlook some other details as well.
CTLSClientPlaintext and CTLSServerPlaintext seem to be included in the example exchange but CTLSCiphertext seems to be missing. My understanding is that ServerFlight and ClientFlight are sent over CTLSCiphertext which would add a mimimum of 2 * 11 bytes. It is not explained why the signature is 64 bytes. In TLS 1.3, my understanding is that ecdsasecp256r1sha256 is variable length 12-76 bytes with an average length close to 75 bytes. Changing ecdsasecp256r1sha256 to ed25519 (or ecdsasecp256r1sha256_compact) would make it 64 bytes. The introduction promises an example PSK handshake, but that is missing.
NAME Please review , which attempts to fix the example as you've described.

Revised text:
again. For the common (EC)DHE handshake with pre-established certificates,  <ins> Stream cTLS achieves an overhead of 53 bytes over the minimum </ins> required by the cryptovariables.  For a PSK handshake, the overhead  <ins> is 21 bytes.  An annotated handshake transcript can be found in transcripts. </ins>  <ins> TODO: Make a PSK transcript and check the overhead. </ins> cTLS supports the functionality of TLS and DTLS 1.3, and is forward- compatible to future versions of TLS and DTLS.  cTLS itself is In JSON, this value is represented as "true" or "false". <ins> TODO: It seems like there was an intent to elide the "Certificate.certificate_request_context" field, but this is not stated explicitly anywhere. </ins> 2.1.1.8. Value: a single "CTLSExtensionTemplate" struct:
Original text:
Description: ctls_template <del> DTLS-OK: ??? Not clear what to put here. </del>  Reference: (This document)

Reviewer comments:
For the ctls_template message type it is OK to set the DTLS-OK field to "Y". The entire message is not applicable to regular TLS/DTLS and hence there is no harm whatever value is in the IANA registry.
I still think it's unclear what this means, but I agree that it doesn't matter much and "Y" is ... not wrong.

Revised text:
Description: ctls_template  <ins> DTLS-OK: Y </ins> Reference: (This document)
Original text:
This design is not forward secret because the server's ESNI key is static.  However, the window of exposure is bound by the key <del> lifetime.  It is RECOMMEMDED that servers rotate keys frequently. </del>  7.2.6.

Reviewer comments:
There were two minor typos. This PR fixes them. While I was at it, I ran over it, most seemed fine.

Revised text:
This design is not forward secret because the server's ESNI key is static.  However, the window of exposure is bound by the key  <ins> lifetime.  It is RECOMMENDED that servers rotate keys frequently. </ins> 7.2.6.
Original text:
The label associated with the SNI encryption key. <del> A cryptographically random 128-bit nonce </del> The cipher suite used to encrypt the SNI. The original ServerNameList from the "server_name" extension, The SNI encryption key is computed from the DH shared secret Z as follows: <del> The EncryptedSNI.encrypted_sni value is then computed by: </del>  <del> [[OPEN ISSUE: This is a strawman construction.  We do want a nonce to avoid situations where the server somehow reuses a key, but exactly how we mix it in is TBD.  Maybe in both places?]] </del>  This value is placed in an "encrypted_server_name" extension.

Reviewer comments:
You are mixing URL in. That would seem to be sufficient. From that you can generate the AEAD nonce and key as though this were record protection. We don't need another reason for people to complain about exposing the random number generator state to the network.
If servers choose to use the same ESNI and semi-static key, not generating and including a nonce could lead to nonce-reuse for 0-RTT data. We talked about just prohibiting this sort of key sharing for servers, though it's good to have a client-side defense against it.

Revised text:
The label associated with the SNI encryption key.  The cipher suite used to encrypt the SNI. The original ServerNameList from the "server_name" extension, The SNI encryption key is computed from the DH shared secret Z as follows:  <ins> The EncryptedSNI.encrypted_sni value is then computed using the usual TLS 1.3 AEAD: Note: future extensions may end up reusing the server's ESNIKeyShare for other purposes within the same message (e.g., encrypting other values).  Those usages MUST have their own HKDF labels to avoid reuse. </ins>  <ins> [[OPEN ISSUE: If in future you were to reuse these keys for 0-RTT priming, then you would have to worry about potentially expanding twice of Z_extracted.  We should think about how to harmonize these.]] </ins> This value is placed in an "encrypted_server_name" extension.
Original text:
The client MAY either omit the "server_name" extension or provide an innocuous dummy one (this is required for technical conformance with <del> RFC7540; Section 9.2.) </del>  If the server does not negotiate TLS 1.3 or above, then the client MUST abort the connection with an "unsupported_version" alert.  If

Reviewer comments:
Addresses .
An adversary who observes the certificate fingerprint could confirm certificates previously fetched by a ESNI-compatible client.
Fixed in .

Revised text:
The client MAY either omit the "server_name" extension or provide an innocuous dummy one (this is required for technical conformance with  <ins> RFC7540; Section 9.2.).  The client MUST NOT send a "cached_info" extension RFC7924 with a CachedObject entry whose CachedInformationType is "cert". </ins> If the server does not negotiate TLS 1.3 or above, then the client MUST abort the connection with an "unsupported_version" alert.  If
Original text:
complete, perhaps by timing out. In cases where the domain of the A or AAAA records being resolved do <del> not match the SNI Server Name, such as when RFC7838 is being used, the SNI domain should be used for querying the ESNI record. </del>  Servers operating in Split Mode SHOULD have DNS configured to return the same A (or AAAA) record for all ESNI-enabled servers they

Reviewer comments:
The draft currently states: I'm confused about what this means. From reading RFC 7838, I'm not sure the SNI and DNS names do not match when you're querying an alternate name. In particular, RFC 7838 states: Which means, if I understand it correctly, the client will send "URL" in the SNI when trying to query resources from it - the requirement is only that the certificate for "URL" also cover "URL".
Agreed. I'm parsing RFC 7838 the same way. I think we should drop this text.
The problem the text presents is real (though the resolution is arbitrary). no.. that's a misread. See section 2.3 of 7838 The alternate is essentially just a cname for the origin. If host b is an alternate for origin a, in order to use the alternate you look up the DNS a/aaaa of b, do a TCP connect to b, and then use sni=a and expect a certificate valid for a. (indeed the point of the SNI is to tell the server what certificate you expect to see) With esni you would continue to do all of those things, except of course sni=encrypted(a).. and the question becomes where do you find the key used for the encryption. Is it the ESNI DNS record of a (the origin) or b (the alternate host). That's the question the text is trying to resolve - it says to use a (the origin). I could make a case for either choice but I think the text needs to decide
NAME Would you mind suggesting some text with an example to clear this up?
NAME thanks for the clarification and pointer to s2.3 of 7838. After reading that I think the text in the ESNI draft looks fine. (I'd just add a pointer to s2.3 of 7838 instead of just 7838 to help prevent the confusion I had)

Revised text:
complete, perhaps by timing out. In cases where the domain of the A or AAAA records being resolved do  <ins> not match the SNI Server Name, such as when RFC7838 Section 2.3 is being used, the SNI domain should be used for querying the ESNI record. </ins> Servers operating in Split Mode SHOULD have DNS configured to return the same A (or AAAA) record for all ESNI-enabled servers they
Original text:
therefore allow clients to detect and recover from this situation (see esni-resolution for more details). <del> Servers operating in Split Mode SHOULD have DNS configured to return the same A (or AAAA) record for all ESNI-enabled servers they service.  This yields an anonymity set of cardinality equal to the number of ESNI-enabled server domains supported by a given client- facing server.  Thus, even with SNI encryption, an attacker which can enumerate the set of ESNI-enabled domains supported by a client- facing server can guess the correct SNI with probability at least 1/ K, where K is the size of this ESNI-enabled server anonymity set. This probability may be increased via traffic analysis or other mechanisms. </del>  The following sections describe a DNS record format that achieve these goals.

Reviewer comments:
The current text about anonymity sets for records is too restrictive. If I have 100000 names and 100 IPs and for all queries I randomly return four out of my 100 IPs chosen randomly, I still provide the same anonymity set but I violate the SHOULD. The proposed text
The document currently states: I think this is too restrictive. If I have 100000 names and 100 IPs and for all queries I randomly return four out of my 100 IPs chosen randomly, I still provide the same anonymity set but I violate the SHOULD. How about:
Agreed. At a minimum this should reference a set of A and AAAA records rather than "the record" (as many records across the A and AAAA rrsets is very common). I think NAME proposed text is fine.
NAME sgtm, do you plan to open a PR? I made URL but I think your wording is better.
Created
LGTM -- thanks!

Revised text:
therefore allow clients to detect and recover from this situation (see esni-resolution for more details).  <ins> Content providers operating in Split Mode SHOULD ensure that the A and AAAA records for ESNI-enabled server names do not allow identifying the server name from the IP address.  This can for example be achieved by always returning the same records for all ESNI-enabled names, or by having the function that picks addresses from a pool not depend on the server name.  This yields an anonymity set of cardinality equal to the number of ESNI-enabled server domains supported by a given client-facing server.  Thus, even with SNI encryption, an attacker which can enumerate the set of ESNI-enabled domains supported by a client-facing server can guess the correct SNI with probability at least 1/K, where K is the size of this ESNI- enabled server anonymity set.  This probability may be increased via traffic analysis or other mechanisms. </ins> The following sections describe a DNS record format that achieve these goals.
Original text:
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 RFC2119 RFC8174 when, and only when, they appear in all capitals, <del> as shown here. </del>  3.

Reviewer comments:
I believe it will be helpful to understanding this document to either add "Presentation Language" to this document or link to Presentation Language elsewhere. The TLS/1.3 document has something similar in

Revised text:
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 RFC2119 RFC8174 when, and only when, they appear in all capitals,  <ins> as shown here.  All TLS notation comes from RFC8446; Section 3. </ins> 3.
Original text:
A random 16-octet value to be echoed by the server in the "encrypted_server_name" extension. <del> The true SNI, that is, the ServerNameList that would have been sent in the plaintext "server_name" extension. </del>  Zero padding whose length makes the serialized PaddedServerNameList struct have a length equal to

Reviewer comments:
[1] URL
Extensibility failed for SNI, no point in repeating that failure. This is less complex:
Are there other ways we expect servers to select certificates? I can imagine a scenario where clients pin server leaf certificates, and hint servers to the right leaf certificate by sending the leaf SPKI hash in the SNI. Would we want to rule something like that out? The Server Name Indication (SNI) extension in TLS has a provision to provide names other than host names[1]. None have even been defined to my knowledge, but it's there. OpenSSL (and possibly others) have had a long-standing bug[2] (fixed in master) that means that different types of names will cause an error. To be clear: I live in a glass house and am not throwing stones; these things happen. However, it means that a huge fraction of the TLS deployment will not be able to accept a different name type should one ever be defined. (This issue might have been caused by the fact that the original[3] spec didn't define the extension in such a way that unknown name types could be skipped over.) Therefore we (i.e. BoringSSL, and thus Google) are proposing to give up on this and implement our parser such that the SNI extension is only allowed to contain a single host name value. (This is compatible with all known clients.) We're assuming that since this is already the de-facto reality that there will be little objection. I'm sending this mostly to record the fact so that, if someone tries to define a new name type in the future, they won't waste their time. If the community wishes to indicate a different type of name in the future, a new extension can be defined. This is already effectively the case because we wouldn't fight this level of incompatibility when there's any other option. (I think the lesson here is that protocols should have a single joint, and that it should be kept well oiled. For TLS, that means that extensions should have minimal extensionality in themselves and that we should generally rely on the main extensions mechanism for these sorts of things.) [1] URL [2] URL – note that the data pointer is not updated. [3] URL Cheers AGL Adam Langley EMAIL URL

Revised text:
A random 16-octet value to be echoed by the server in the "encrypted_server_name" extension.  <ins> The true SNI DNS name, that is, the HostName value that would have been sent in the plaintext "server_name" extension.  (NameType values other than "host_name" are unsupported since SNI extensibility failed SNIExtensibilityFailed). </ins> Zero padding whose length makes the serialized PaddedServerNameList struct have a length equal to
Original text:
padded_length is greater than 260. A list of extensions that the client can take into consideration <del> when generating a Client Hello message.  The format is defined in RFC8446; Section 4.2.  The purpose of the field is to provide room for additional features in the future.  An extension may be tagged as mandatory by using an extension type codepoint with the high order bit set to 1.  A client which receives a mandatory extension they do not understand must reject the ESNIConfig content. </del>  Clients MUST parse the extension list and check for unsupported mandatory extensions.  If an unsupported mandatory extension is

Reviewer comments:
Followup on . Looks like ESNIConfig is the only ESNI structure that has extensions, now that we've delegated the key delivery to HTTPSSVC. Should I avoid reflowing the text?
states: same type in a given extension block. The ESNI draft should probably explicitly restate this for both and . I'd be happy to make a PR if need be. Thanks!
NAME if you could propose text that takes the new ESNIConfig and HTTPSSVC change into account, that'd be great!
Fixed by .

Revised text:
padded_length is greater than 260. A list of extensions that the client can take into consideration  <ins> when generating a Client Hello message.  The purpose of the field is to provide room for additional features in the future.  The format is defined in RFC8446; Section 4.2.  The same interpretation rules apply: extensions MAY appear in any order, but there MUST NOT be more than one extension of the same type in the extensions block.  An extension may be tagged as mandatory by using an extension type codepoint with the high order bit set to 1.  A client which receives a mandatory extension they do not understand must reject the ESNIConfig content. </ins> Clients MUST parse the extension list and check for unsupported mandatory extensions.  If an unsupported mandatory extension is
Original text:
GREASE I-D.ietf-tls-grease "encrypted_client_hello" extension as follows: <del> Select a supported cipher suite, named group, and padded_length value.  The padded_length value SHOULD be 260 (sum of the maximum DNS name length and TLS encoding overhead) or a multiple of 16 less than 260.  Set the "suite" field to the selected cipher suite.  These selections SHOULD vary to exercise all supported configurations, but MAY be held constant for successive connections to the same server in the same session. Set the "enc" field to a randomly-generated valid encapsulated public key output by the HPKE KEM. </del>  Set the "record_digest" field to a randomly-generated string of hash_length bytes, where hash_length is the length of the hash function associated with the chosen cipher suite. <del> Set the "encrypted_client_hello" field to a randomly-generated string of [TODO] bytes. </del>  If the server sends an "encrypted_client_hello" extension, the client MUST check the extension syntactically and abort the connection with

Reviewer comments:
Also define the length of the randomly-generated "encrypted_ch" field.
NAME NAME

Revised text:
GREASE I-D.ietf-tls-grease "encrypted_client_hello" extension as follows:  <ins> Set the "suite" field to a supported cipher suite.  The selection SHOULD vary to exercise all supported configurations, but MAY be held constant for successive connections to the same server in the same session. </ins> Set the "record_digest" field to a randomly-generated string of hash_length bytes, where hash_length is the length of the hash function associated with the chosen cipher suite.  <ins> Set the "enc" field to a randomly-generated valid encapsulated public key output by the HPKE KEM. Set the "encrypted_ch" field to a randomly-generated string of [TODO] bytes. </ins> If the server sends an "encrypted_client_hello" extension, the client MUST check the extension syntactically and abort the connection with