jiebi/CodeConvo huggingface dataset:
encrypt or (successfully) decrypt a message or <del> if a key, nonce or secret derived from S has been consumed.  (This goes both for values derived via Derive-Secret and HKDF-Expand- Label). </del> <ins> if a key, nonce or secret derived from S has been consumed. (This goes both for values derived via Derive-Secret and HKDF-Expand- Label.) </ins> Here, S may be the init_secret, update_secret, epoch_secret, application_secret as well as any secret in the AS Tree or one of the
In this document, we describe a protocol based on tree structures that enable asynchronous group keying with forward secrecy and post- compromise security.  Based on earlier work on "asynchronous <del> ratcheting trees" art, the mechanism presented here use a </del> <ins> ratcheting trees" art, the protocol presented here uses an </ins> asynchronous key-encapsulation mechanism for tree structures.  This mechanism allows the members of the group to derive and update shared keys with costs that scale as the log of the group size.
The recipient of an update processes it with the following steps: <del> Compute the updated path secrets * Identify a node in the direct path for which the local member is in the subtree of the non- updated child * Identify a node in the resolution of the copath node for which this node has a private key * Decrypt the path secret for the parent of the copath node using the private key from the resolution node * Derive path secrets for ancestors of that node using the algorithm described above * The recipient SHOULD verify that the received public keys agree with the public keys derived from the new node_secret values Merge the updated path secrets into the tree * Replace the public keys for nodes on the direct path with the received public keys * For nodes where an updated path secret was computed in step 1, compute the corresponding node secret and node key pair and replace the values stored at the node with the computed values. </del> <ins> Compute the updated path secrets. Identify a node in the direct path for which the local member is in the subtree of the non-updated child. Identify a node in the resolution of the copath node for which this node has a private key. Decrypt the path secret for the parent of the copath node using the private key from the resolution node. Derive path secrets for ancestors of that node using the algorithm described above. The recipient SHOULD verify that the received public keys agree with the public keys derived from the new node_secret values. Merge the updated path secrets into the tree. Replace the public keys for nodes on the direct path with the received public keys. For nodes where an updated path secret was computed in step 1, compute the corresponding node secret and node key pair and replace the values stored at the node with the computed values. </ins> For example, in order to communicate the example update described in the previous section, the sender would transmit the following values: <del> In this table, the value pk(X) represents the public key corresponding derived from the node secret X.  The value E(K, S) represents the public-key encryption of the path secret S to the public key K. </del> <ins> In this table, the value pk(X) represents the public key derived from the node secret X.  The value E(K, S) represents the public-key encryption of the path secret S to the public key K. </ins> 6.
The creator of the group constructs an Init message as follows: <del> Fetch a UserInitKey for each member (including the creator) </del> <ins> Fetch a ClientInitKey for each member (including the creator) </ins> Identify a protocol version and cipher suite that is supported by all proposed members. Construct a ratchet tree with its leaves populated with the public <del> keys and credentials from the UserInitKeys of the members, and all other nodes blank. </del> <ins> keys and credentials from the ClientInitKeys of the members, and all other nodes blank. </ins> Generate a fresh leaf key pair for the first leaf
Blank the intermediate nodes along the path from the removed leaf to the root <ins> 10.1.4. Add and Remove proposals can be constructed and sent to the group by a party that is outside the group.  For example, a Delivery Service might propose to remove a member of a group has been inactive for a long time, or propose adding a newly-hired staff member to a group representing a real-world team.  Proposals originating outside the group are identified by having a "sender" value in the range 0xFFFFFF00 - 0xFFFFFFFF. The specific value 0xFFFFFFFF is reserved for clients proposing that they themselves be added.  Proposals with types other than Add MUST NOT be sent with this sender index.  In such cases, the MLSPlaintext MUST be signed with the private key corresponding to the ClientInitKey in the Add message.  Recipients MUST verify that the MLSPlaintext carrying the Proposal message is validly signed with this key. The remaining values 0xFFFFFF00 - 0xFFFFFFFE are reserved for signer that are pre-provisioned to the clients within a group.  If proposals with these sender IDs are to be accepted within a group, the members of the group MUST be provisioned by the application with a mapping between sender indices in this range and authorized signing keys.  To ensure consistent handling of external proposals, the application MUST ensure that the members of a group have the same mapping and apply the same policies to external proposals. An external proposal MUST be sent as an MLSPlaintext object, since the sender will not have the keys necessary to construct an MLSCiphertext object. [[ TODO: Should recognized external signers be added to some object that the group explicitly agrees on, e.g., as an extension to the GroupContext? ]] </ins> 10.2. A Commit message initiates a new epoch for the group, based on a
14. <del> TODO: Registries for protocol parameters, e.g., ciphersuites </del> <ins> This document requests the creation of the following new IANA registries: MLS Ciphersuites All of these registries should be under a heading of "Message Layer Security", and administered under a Specification Required policy RFC8126. 14.1. The "MLS Ciphersuites" registry lists identifiers for suites of cryptographic algorithms defined for use with MLS.  These are two- byte values, so the maximum possible value is 0xFFFF = 65535.  Values in the range 0xF000 - 0xFFFF are reserved for vendor-internal usage. Template: Value: The two-byte identifier for the ciphersuite Name: The name of the ciphersuite Reference: Where this algorithm is defined The initial contents for this registry are as follows: [[ Note to RFC Editor: Please replace "XXXX" above with the number assigned to this RFC. ]] </ins>
where "node_public_key" is the public key of the node that the path secret is being encrypted for, group_context is the current <del> GroupContext object for the group, and the functions "SetupBaseI" and </del> <ins> GroupContext object for the group, and the functions "SetupBaseS" and </ins> "Seal" are defined according to I-D.irtf-cfrg-hpke. Decryption is performed in the corresponding way, using the private
Application messages <del> The sender information used to look up the key for the content encryption is encrypted under AEAD using a random nonce and the "sender_data_key" which is derived from the "sender_data_secret" as follows: </del> <ins> The sender information used to look up the key for content encryption is encrypted with an AEAD where the key and nonce are derived from both "sender_data_secret" and a sample of the encrypted message content. </ins> For handshake and application messages, a sequence of keys is derived via a "sender ratchet".  Each sender has their own sender ratchet,
each key/nonce pair MUST NOT be used to encrypt more than one message. <del> Keys, nonces and secrets of ratchets are derived using </del> <ins> Keys, nonces, and the secrets in ratchets are derived using </ins> DeriveAppSecret.  The context in a given call consists of the index of the sender's leaf in the ratchet tree and the current position in the ratchet.  In particular, the index of the sender's leaf in the
Set group_id, epoch, content_type and authenticated_data fields from the MLSPlaintext object directly <del> Randomly generate the sender_data_nonce field </del> Identify the key and key generation depending on the content type <del> Encrypt an MLSSenderData object for the encrypted_sender_data field from MLSPlaintext and the key generation Generate and sign an MLSPlaintextTBS object from the MLSPlaintext object </del> Encrypt an MLSCiphertextContent for the ciphertext field using the <del> key identified, the signature, and MLSPlaintext object </del> <ins> key identified and MLSPlaintext object Encrypt the sender data using a key and nonce derived from the "sender_data_secret" for the epoch and a sample of the encrypted MLSCiphertextContent. </ins> <del> Decryption is done by decrypting the metadata, then the message, and then verifying the content signature. </del> <ins> Decryption is done by decrypting the sender data, then the message, and then verifying the content signature. </ins> The following sections describe the encryption and signing processes in detail. 8.1. <del> The "sender data" used to look up the key for the content encryption is encrypted under AEAD using the MLSCiphertext sender_data_nonce and the sender_data_key from the keyschedule.  It is encoded as an object of the following form: MLSSenderData.sender is assumed to be a "member" sender type.  When constructing an MLSSenderData from a Sender object, the sender MUST verify Sender.sender_type is "member" and use Sender.sender for MLSSenderData.sender. The "reuse_guard" field contains a fresh random value used to avoid nonce reuse in the case of state loss or corruption, as described in content-signing-and-encryption. The Additional Authenticated Data (AAD) for the SenderData ciphertext computation is its prefix in the MLSCiphertext, namely: When parsing a SenderData struct as part of message decryption, the recipient MUST verify that the sender field represents an occupied leaf in the ratchet tree.  In particular, the sender index value MUST be less than the number of leaves in the tree. 8.2. The signature field in an MLSPlaintext object is computed using the </del> <ins> The "signature" field in an MLSPlaintext object is computed using the </ins> signing private key corresponding to the credential at the leaf in the tree indicated by the sender field.  The signature covers the plaintext metadata and message content, which is all of MLSPlaintext
GroupContext for the current epoch, so that signatures are specific to a given group and epoch. <del> The ciphertext field of the MLSCiphertext object is produced by </del> <ins> 8.2. The "ciphertext" field of the MLSCiphertext object is produced by </ins> supplying the inputs described below to the AEAD function specified by the ciphersuite in use.  The plaintext input contains content and signature of the MLSPlaintext, plus optional padding.  These values
contains an object of the following form, with the values used to identify the key and nonce: <del> The ciphertext field of the MLSCiphertext object is produced by supplying these inputs to the AEAD function specified by the ciphersuite in use. </del> <ins> 8.3. The "sender data" used to look up the key for the content encryption is encrypted with the ciphersuite's AEAD with a key and nonce derived from both the "sender_data_secret" and a sample of the encrypted content.  Before being encrypted, the sender data is encoded as an object of the following form: MLSSenderData.sender is assumed to be a "member" sender type.  When constructing an MLSSenderData from a Sender object, the sender MUST verify Sender.sender_type is "member" and use Sender.sender for MLSSenderData.sender. The "reuse_guard" field contains a fresh random value used to avoid nonce reuse in the case of state loss or corruption, as described in content-encryption. The key and nonce provided to the AEAD are computed as the KDF of the first "KDF.Nh" bytes of the ciphertext generated in the previous section.  If the length of the ciphertext is less than "KDF.Nh", the whole ciphertext is used without padding.  In pseudocode, the key and nonce are derived as: ``` ciphertext_sample = ciphertext[0..KDF.Nh-1] sender_data_key = ExpandWithLabel(sender_data_secret, "key", ciphertext_sample, AEAD.Nk) sender_data_nonce = ExpandWithLabel(sender_data_secret, "nonce", ciphertext_sample, AEAD.Nn) ``` The Additional Authenticated Data (AAD) for the SenderData ciphertext is all the fields of MLSCiphertext excluding "encrypted_sender_data": When parsing a SenderData struct as part of message decryption, the recipient MUST verify that the sender field represents an occupied leaf in the ratchet tree.  In particular, the sender index value MUST be less than the number of leaves in the tree. </ins> 9.
The mandatory-to-implement ciphersuite for MLS 1.0 is "MLS10_128_HPKE25519_AES128GCM_SHA256_Ed25519" which uses <del> Curve25519, HKDF over SHA2-256 and AES-128-GCM for HPKE, and AES- 128-GCM with Ed25519 for symmetric encryption and signatures. </del> <ins> Curve25519 for key exchange, AES-128-GCM for HPKE, HKDF over SHA2-256, AES for metadata masking, and Ed25519 for signatures. </ins> Values with the first byte 255 (decimal) are reserved for Private Use.
A member of a group authenticates the identities of other participants by means of credentials issued by some authentication system, like a PKI.  Each type of credential MUST express the <del> following data: </del> <ins> following data in the context of the group it is used with: </ins> <del> The public key of a signature key pair </del> <ins> The public key of a signature key pair matching the SignatureScheme specified by the CipherSuite of the group </ins> <del> The identity of the holder of the private key The signature scheme that the holder will use to sign MLS messages </del> <ins> The identity of the holder of the private keys </ins> Credentials MAY also include information that allows a relying party to verify the identity / signing key binding. <ins> Additionally, Credentials SHOULD specify the signature scheme corresponding to each contained public key. </ins> A BasicCredential is a raw, unauthenticated assertion of an identity/ key binding.  The format of the key in the "public_key" field is defined by the relevant ciphersuite: the group ciphersuite for a
A KeyPackage object specifies a ciphersuite that the client supports, as well as providing a public key that others can use for key <del> agreement.  The client's identity key can be updated throughout the </del> <ins> agreement.  The client's signature key can be updated throughout the </ins> lifetime of the group by sending a new KeyPackage with a new <del> identity; the new identity MUST be validated by the authentication service. </del> <ins> signature key; the new signature key MUST be validated by the authentication service. </ins> When used as InitKeys, KeyPackages are intended to be used only once and SHOULD NOT be reused except in case of last resort.  (See
The value for hpke_init_key MUST be a public key for the asymmetric encryption scheme defined by cipher_suite.  The whole structure is <del> signed using the client's identity key.  A KeyPackage object with an </del> <ins> signed using the client's signature key.  A KeyPackage object with an </ins> invalid signature field MUST be considered malformed.  The input to the signature computation comprises all of the fields except for the signature field.
A signed object describing a client's identity and capabilities, and including a hybrid public-key encryption (HPKE I-D.irtf-cfrg- <del> hpke ) public key that can be used to encrypt to that client. </del> <ins> hpke) public key that can be used to encrypt to that client. </ins> A key package that is prepublished by a client, which other clients can use to introduce the client to a new group.
A signature algorithm <del> The HPKE parameters are used to instantiate HPKE I-D.irtf-cfrg-hpke for the purpose of public-key encryption.  The "DeriveKeyPair" function associated to the KEM for the ciphersuite maps octet strings to HPKE key pairs. </del> <ins> MLS uses draft-07 of HPKE I-D.irtf-cfrg-hpke for public-key encryption.  The "DeriveKeyPair" function associated to the KEM for the ciphersuite maps octet strings to HPKE key pairs. </ins> Ciphersuites are represented with the CipherSuite type.  HPKE public keys are opaque values in a format defined by the underlying protocol
Name: The name of the ciphersuite <del> Recommended: Whether support for this extension is recommended by the IETF MLS WG.  Valid values are "Y" and "N".  The "Recommended" column is assigned a value of "N" unless explicitly requested, and adding a value with a "Recommended" value of "Y" requires Standards Action RFC8126.  IESG Approval is REQUIRED for a Y->N transition. </del> <ins> Recommended: Whether support for this ciphersuite is recommended by the IETF MLS WG.  Valid values are "Y" and "N".  The "Recommended" column is assigned a value of "N" unless explicitly requested, and adding a value with a "Recommended" value of "Y" requires Standards Action RFC8126.  IESG Approval is REQUIRED for a Y->N transition. </ins> Reference: The document where this ciphersuite is defined
Name: The name of the credential type <del> Recommended: Whether support for this extension is recommended by </del> <ins> Recommended: Whether support for this credential is recommended by </ins> the IETF MLS WG.  Valid values are "Y" and "N".  The "Recommended" column is assigned a value of "N" unless explicitly requested, and adding a value with a "Recommended" value of "Y" requires Standards Action RFC8126.  IESG Approval is REQUIRED for a Y->N transition. <del> Reference: The document where this extension is defined </del> <ins> Reference: The document where this credential is defined </ins> Initial contents:
in the "PreSharedKeyID" object.  Specifically, "psk_secret" is computed as follows: <del> The "index" field in "PSKLabel" corresponds to the index of the PSK in the "psk" array, while the "count" field contains the total number of PSKs. </del> <ins> Here "0" represents the all-zero vector of length KDF.Nh.  The "index" field in "PSKLabel" corresponds to the index of the PSK in the "psk" array, while the "count" field contains the total number of PSKs.  In other words, the PSKs are chained together with KDF.Extract invocations, as follows: In particular, if there are no PreSharedKey proposals in a given Commit, then the resulting "psk_secret" is "psk_secret_[0]", the all- zero vector. </ins> 8.3.
In this case, the new ratchet tree is the same as the provisional ratchet tree. <del> If one or more PreSharedKey proposals are part of the commit, derive the "psk_secret" as specified in pre-shared-keys, where the </del> <ins> Derive the "psk_secret" as specified in pre-shared-keys, where the </ins> order of PSKs in the derivation corresponds to the order of <del> PreSharedKey proposals in the "proposals" vector.  Otherwise, set "psk_secret" to a zero-length octet string. </del> <ins> PreSharedKey proposals in the "proposals" vector. </ins> Construct an MLSPlaintext object containing the Commit object. Sign the MLSPlaintext using the old GroupContext as context.
Update the confirmed and interim transcript hashes using the new Commit, and generate the new GroupContext. <del> If the "proposals" vector contains any PreSharedKey proposals, derive the "psk_secret" as specified in pre-shared-keys, where the </del> <ins> Derive the "psk_secret" as specified in pre-shared-keys, where the </ins> order of PSKs in the derivation corresponds to the order of <del> PreSharedKey proposals in the "proposals" vector.  Otherwise, set "psk_secret" to 0. </del> <ins> PreSharedKey proposals in the "proposals" vector. </ins> Use the "init_secret" from the previous epoch, the "commit_secret" and the "psk_secret" as defined in the previous steps, and the new
Each leaf is given an _index_ (or _leaf index_), starting at "0" from the left to "n-1" at the right. <ins> Finally, a node in the tree may also be _blank_, indicating that no value is present at that node (i.e. no keying material).  This is often the case when a leaf was recently removed from the tree. </ins> There are multiple ways that an implementation might represent a ratchet tree in memory.  For example, left-balanced binary trees can be represented as an array of nodes, with node relationships computed
The conditions under which each of these values must or must not be present are laid out in views. <del> A node in the tree may also be _blank_, indicating that no value is present at that node.  The _resolution_ of a node is an ordered list of non-blank nodes that collectively cover all non-blank descendants of the node.  The resolution of a non-blank node with no unmerged leaves is just the node itself.  More generally, the resolution of a node is effectively a depth-first, left-first enumeration of the nearest non-blank nodes below the node: </del> <ins> The _resolution_ of a node is an ordered list of non-blank nodes that collectively cover all non-blank descendants of the node.  The resolution of a non-blank node with no unmerged leaves is just the node itself.  More generally, the resolution of a node is effectively a depth-first, left-first enumeration of the nearest non-blank nodes below the node: </ins> The resolution of a non-blank node comprises the node itself, followed by its list of unmerged leaves, if any
"lazy" version of this operation, where only the leaf changes and intermediate nodes are blanked out. <del> The "path" field of a Commit message MUST be populated if the Commit covers at least one Update or Remove proposal.  The "path" field MUST also be populated if the Commit covers no proposals at all (i.e., if the proposals vector is empty).  The "path" field MAY be omitted if the Commit covers only Add proposals.  In pseudocode, the logic for validating a Commit is as follows: </del> <ins> By default, the "path" field of a Commit MUST be populated.  The "path" field MAY be omitted if (a) it covers at least one proposal and (b) none proposals covered by the Commit are of "path required" types.  A proposal type requires a path if it cannot change the group membership in a way that requires the forward secrecy and post- compromise security guarantees that an UpdatePath provides.  The only proposal types defined in this document that do not require a path are: "add" "psk" "app_ack" "reinit" New proposal types MUST state whether they require a path.  If any instance of a proposal type requires a path, then the proposal type requires a path.  This attribute of a proposal type is reflected in the "Path Required" field of the proposal type registry defined in mls-proposal-types. Update and Remove proposals are the clearest examples of proposals that require a path.  An UpdatePath is required to evict the removed member or the old appearance of the updated member. In pseudocode, the logic for validating the "path" field of a Commit is as follows: </ins> To summarize, a Commit can have three different configurations, with different uses:
committer's contribution to the group and provides PCS with regard to the committer. <del> A "partial" Commit that references Add, PreSharedKey, or ReInit proposals but where the path is empty.  Such a commit doesn't provide PCS with regard to the committer. </del> <ins> A "partial" Commit that references proposals that do not require a path, and where the path is empty.  Such a commit doesn't provide PCS with regard to the committer. </ins> A "full" Commit that references proposals of any type, which provides FS with regard to any removed members and PCS for the