From b8c6f781aef89085c8e6e017797a5973c9cd1892 Mon Sep 17 00:00:00 2001 From: Felipe Ventura <37639194+feventura@users.noreply.github.com> Date: Thu, 29 Aug 2024 16:31:20 -0400 Subject: [PATCH 01/25] Update draft-ietf-lamps-pq-composite-sigs.md added context string consideration. --- draft-ietf-lamps-pq-composite-sigs.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 4177870..2b4307d 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -351,8 +351,10 @@ Signature Generation Process: 2. Generate the 2 component signatures independently, by calculating the signature over M' according to their algorithm specifications that might involve the use of the hash-n-sign paradigm. - S1 := Sign( K1, A1, M' ) - S2 := Sign( K2, A2, M' ) + S1 := ML-DSA.Sign( K1, A1, M', ctx="" ) + S2 := TradSign( K2, A2, M' ) + +Since Composite ML-DSA incorporates the domain separator into a pre-hash, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. 3. Encode each component signature S1 and S2 into a BIT STRING according to its algorithm specification. From 2c81704578bd45d89caecaa36fe2fe6679f62cf6 Mon Sep 17 00:00:00 2001 From: Mike Ounsworth Date: Fri, 30 Aug 2024 07:46:25 -0500 Subject: [PATCH 02/25] utf-8 --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 2b4307d..2e02432 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -9,7 +9,7 @@ wg: LAMPS kw: Internet-Draft cat: std -coding: us-ascii +coding: utf-8 pi: # can use array (if all yes) or hash here toc: yes sortrefs: # defaults to yes From ec2fc46b5c9f7d58e4491e09faf4a67508ca9fb7 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 2 Oct 2024 02:13:38 -0400 Subject: [PATCH 03/25] Update draft-ietf-lamps-pq-composite-sigs.md For review with the group... Add proposed Pure and PreHash options in 2 possible ways. 1. Write out full Signature and Verify routines for both Pure signing, and Verifying. 2. Specify the Message format (pure or prehash) and then specify a single Sign and Verify routine that takes a formatted message. I like the 2nd option better as it is more developer friendly and is less verbose and repeatative. --- draft-ietf-lamps-pq-composite-sigs.md | 386 +++++++++++++++++++++++--- 1 file changed, 352 insertions(+), 34 deletions(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 2e02432..607968f 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -316,45 +316,351 @@ The key generation functions MUST be executed for both algorithms. Compliant par Composite schemes' signatures provide important properties for multi-key environments such as non-separability and key-binding. For more information on the additional security properties and their applicability to multi-key or hybrid environments, please refer to {{I-D.hale-pquip-hybrid-signature-spectrums}} and the use of labels as defined in {{Bindel2017}} -Composite signature generation starts with pre-hashing the message that is concatenated with the Domain separator {{sec-oid-concat}}. After that, the signature process for each component algorithm is invoked and the values are then placed in the CompositeSignatureValue structure defined in {{sec-composite-sig-structs}}. +A composite signature's value MUST include two signature components and MUST be in the same order as the components from the corresponding signing key. + +### Pure Message Format Generation + +Composite signature provides two modes of operation, a pure mode and pre-hashing mode. The Message is formatted into M' by applying either the pure or pre-hash message format. After that, the signature process for each component algorithm is invoked and the values are then placed in the CompositeSignatureValue structure defined in {{sec-composite-sig-structs}}. In the pure mode the Domain separator {{sec-oid-concat}} is concatenated with the length of the context in bytes, the context and finally the Message. + +~~~ +Pure-Message-Format (Domain, Message, Context) -> (M') +Input: + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. + + Message The Message to be signed, an octet string + + Context The Message context or Null if it is not used + + IntegerToBytes(c, 1) The length of c in bytes encoded into a single byte value. This + means the value c cannot be more than 255 bytes long. + +Output: + M' The Message Format + +Signature Generation Process: + + 1. If Context > 255: + fail + + 2. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of the Context, the value of the Context and the Message + + M' := Domain || IntegerToBytes(|Context|, 1) || Context || Message + + 3. Output M' + return M' +~~~ +{: #alg-message-format-pure title="Pure-Message-Format(Domain, Message, Context)"} + + +### PreHash Message Format Generation + +In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated with the length of the context in byte, the context, an additional DER encoded value that represents the Hash and finally the Hash of the message. + +~~~ +PreHash-Message-Format (Domain, Message, Context, HASH, HashOID) -> (M') +Input: + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. + + Message The Message to be signed, an octet string + + Context The Message context or Null if it is not used + + IntegerToBytes(c, 1) The length of c in bytes encoded into a single byte value. This + means the value c cannot be more than 255 bytes long. + + HASH The Message Digest Algorithm for pre-hashing. See + section on pre-hashing the message below. + + HashOID The DER Encoding of the Object Identifier of the + PreHash algorithm. + +Output: + M' The Message Format + +Signature Generation Process: + + 1. If Context > 255: + fail + + 2. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of the Context, the value of the Context and the Message + + M' := Domain || IntegerToBytes(|ctx|, 1) || ctx || HashOID || HASH (Message) + + 3. Output M' + return M' +~~~ +{: #alg-message-format-prehash title="PreHash-Message-Format(Domain, Message, Context, HASH, HashOID)"} + +### Composite-ML-DSA-Sign: + +~~~ +Composite-ML-DSA-Sign (sk, M') -> (signature) +Input: + K1, K2 Signing private keys for each component. See note below on + composite inputs. + + A1, A2 Component signature algorithms. See note below on + composite inputs. + + M' The Formatted Message + +Output: + signature The composite signature, a CompositeSignatureValue + +Signature Generation Process: + + 1. Generate the 2 component signatures independently, by calculating the signature over M' + according to their algorithm specifications that might involve the use of the hash-n-sign paradigm. + + S1 := ML-DSA.Sign( K1, A1, M', Context="" ) + S2 := TradSign( K2, A2, M' ) + +Since Composite ML-DSA incorporates the domain separator, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. + + 2. Encode each component signature S1 and S2 into a BIT STRING + according to its algorithm specification. + + signature := NULL + + IF (S1 != NULL) and (S2 != NULL): + signature := Sequence { S1, S2 } + + 3. Output signature + + return signature +~~~ +{: #alg-composite-sign title="Composite-ML-DSA-Sign(sk, Message, M')"} + + +### Composite-ML-DSA-Verify: + +~~~ +Composite-ML-DSA-Verify(pk, M', signature) +Input: + P1, P2 Public verification keys. See note below on + composite inputs. + + M' The Formatted Message + + signature CompositeSignatureValue containing the component + signature values (S1 and S2) to be verified. + + A1, A2 Component signature algorithms. See note + below on composite inputs. + +Output: + Validity (bool) "Valid signature" (true) if the composite + signature is valid, "Invalid signature" + (false) otherwise. + +Signature Verification Procedure:: + 1. Check keys, signatures, and algorithms lists for consistency. + + If Error during Desequencing, or the sequences have + different numbers of elements, or any of the public keys + P1 or P2 and the algorithm identifiers A1 or A2 are + composite then output "Invalid signature" and stop. + + 2. Check each component signature individually, according to its + algorithm specification. + If any fail, then the entire signature validation fails. + + if not verify( P1, M', S1, A1 ) then + output "Invalid signature" + if not verify( P2, M', S2, A2 ) then + output "Invalid signature" + + if all succeeded, then + output "Valid signature" +~~~ +{: #alg-composite-verify title="Composite-ML-DSA-Verify(pk, M', signature)"} + + +### Composite-ML-DSA-Sign pure signature mode: + +In the pure mode the Domain separator {{sec-oid-concat}} is concatenated with the length of the context in bytes, the context and finally the Message. + +The following process is used to generate pure composite signature values. + +~~~ +Composite-ML-DSA-Sign (sk, Message, Context) -> (signature) +Input: + K1, K2 Signing private keys for each component. See note below on + composite inputs. + + A1, A2 Component signature algorithms. See note below on + composite inputs. + + Message The Message to be signed, an octet string + + Context The Message context or Null if it is not used + + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. + + IntegerToBytes(c, 1) The length of the c in bytes encoded into a single byte value. This + means the value c cannot be more than 255 bytes long. + +Output: + signature The composite signature, a CompositeSignatureValue + +Signature Generation Process: + + 1. If Context > 255: + fail + + 2. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of the Context, the value of the Context and the Message + + M' := Domain || IntegerToBytes(|Context|, 1) || Context || Message + + 3. Generate the 2 component signatures independently, by calculating the signature over M' + according to their algorithm specifications that might involve the use of the hash-n-sign paradigm. + + S1 := ML-DSA.Sign( K1, A1, M', Context="" ) + S2 := TradSign( K2, A2, M' ) + +Since Composite ML-DSA incorporates the domain separator, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. + + 4. Encode each component signature S1 and S2 into a BIT STRING + according to its algorithm specification. + + signature := NULL + + IF (S1 != NULL) and (S2 != NULL): + signature := Sequence { S1, S2 } + + 5. Output signature + + return signature +~~~ +{: #alg-composite-sign title="Composite-ML-DSA-Sign(sk, Message, Context)"} + +It is possible to construct `CompositePrivateKey`(s) to generate signatures from component keys stored in separate software or hardware keystores. Variations in the process to accommodate particular private key storage mechanisms are considered to be conformant to this document so long as it produces the same output as the process sketched above. + +### Composite-ML-DSA-Verify pure Verify Mode {#sec-comp-sig-verify} + +Verification of a composite signature involves reconstructing the M' message first by concatenating the Domain separator (i.e., the DER encoding of the used Composite scheme's OID) with the length of the Context, the value of the Context, and the Message itself and then applying each component algorithm's verification process to the new message M'. + +Compliant applications MUST output "Valid signature" (true) if and only if all component signatures were successfully validated, and "Invalid signature" (false) otherwise. + +The following process is used to perform this verification. + + +~~~ +Composite-ML-DSA-Verify(pk, Message, signature, Context) +Input: + P1, P2 Public verification keys. See note below on + composite inputs. + + Message Message whose signature is to be verified, + an octet string. + + signature CompositeSignatureValue containing the component + signature values (S1 and S2) to be verified. + + A1, A2 Component signature algorithms. See note + below on composite inputs. + + Context The Message context or Null if it is not used + + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. + + IntegerToBytes(c, 1) The legnth of the context (c) encoded into a single byte value. This + means the context cannot be more than bytes long. + +Output: + Validity (bool) "Valid signature" (true) if the composite + signature is valid, "Invalid signature" + (false) otherwise. + +Signature Verification Procedure:: + 1. Check keys, signatures, and algorithms lists for consistency. + + If Error during Desequencing, or the sequences have + different numbers of elements, or any of the public keys + P1 or P2 and the algorithm identifiers A1 or A2 are + composite then output "Invalid signature" and stop. + + 2. If Context > 255 + fail + + 3. Format the Message as follows: + + M' = Domain || IntegerToBytes(|Context|, 1) || Context || Message + + 4. Check each component signature individually, according to its + algorithm specification. + If any fail, then the entire signature validation fails. + + if not verify( P1, M', S1, A1 ) then + output "Invalid signature" + if not verify( P2, M', S2, A2 ) then + output "Invalid signature" + + if all succeeded, then + output "Valid signature" +~~~ +{: #alg-composite-verify title="Composite-ML-DSA-Verify(pk, Message, signature, Context)"} + +It is possible to construct `CompositePublicKey`(s) to verify signatures from component keys stored in separate software or hardware keystores. Variations in the process to accommodate particular private key storage mechanisms are considered to be conformant to this document so long as it produces the same output as the process sketched above. + + +## PreHash-Signature Generation {#sec-comp-sig-gen-prehash} + +Composite signature provides two modes of operation, a pure mode and pre-hashing mode. In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated with the length of the context in byte, the context, an additional DER encoded value that represents the Hash and finally the Hash of the message. After that, the signature process for each component algorithm is invoked and the values are then placed in the CompositeSignatureValue structure defined in {{sec-composite-sig-structs}}. A composite signature's value MUST include two signature components and MUST be in the same order as the components from the corresponding signing key. The following process is used to generate composite signature values. +### HASHComposite-ML-DSA-Sign signature mode: + +In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated with the length of the context in byte, the context, an additional DER encoded value that represents the Hash and finally the Hash of the message. + ~~~ -Sign (sk, Message) -> (signature) +HashComposite-ML-DSA-Sign (sk, Message, Context, HASH) -> (signature) Input: - K1, K2 Signing private keys for each component. See note below on - composite inputs. + K1, K2 Signing private keys for each component. See note below on + composite inputs. + + A1, A2 Component signature algorithms. See note below on + composite inputs. + + Message The Message to be signed, an octet string + + HASH The Message Digest Algorithm for pre-hashing. See + section on pre-hashing the message below. - A1, A2 Component signature algorithms. See note below on - composite inputs. + HashOID The DER Encoding of the Object Identifier of the + PreHash algorithm. - Message The Message to be signed, an octet string + Context The Message context or Null if it is not used - HASH The Message Digest Algorithm used for pre-hashing. See section - on pre-hashing below. + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. - Domain Domain separator value for binding the signature to the Composite OID. - See section on Domain Separators below. + IntegerToBytes(c, 1) The legnth of the context (c) encoded into a single byte value. This + means the context cannot be more than bytes long. Output: signature The composite signature, a CompositeSignatureValue Signature Generation Process: - 1. Compute the new Message M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the Hash of the Message + 1. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of the context, the Context, the HashOID and the Hash of the Message. - M' := Domain || HASH(Message) + M' := Domain || IntegerToBytes(|ctx|, 1) || ctx || HashOID || HASH (Message) 2. Generate the 2 component signatures independently, by calculating the signature over M' according to their algorithm specifications that might involve the use of the hash-n-sign paradigm. - S1 := ML-DSA.Sign( K1, A1, M', ctx="" ) + S1 := ML-DSA.Sign( K1, A1, M', Context ="" ) S2 := TradSign( K2, A2, M' ) -Since Composite ML-DSA incorporates the domain separator into a pre-hash, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. +Since HashComposite ML-DSA incorporates the domain separator, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. 3. Encode each component signature S1 and S2 into a BIT STRING according to its algorithm specification. @@ -368,13 +674,13 @@ Since Composite ML-DSA incorporates the domain separator into a pre-hash, which return signature ~~~ -{: #alg-composite-sign title="Composite Sign(sk, Message)"} +{: #alg-composite-sign title="HashComposite-ML-DSA-Sign(sk, Message, Context, HASH)"} It is possible to construct `CompositePrivateKey`(s) to generate signatures from component keys stored in separate software or hardware keystores. Variations in the process to accommodate particular private key storage mechanisms are considered to be conformant to this document so long as it produces the same output as the process sketched above. -### Signature Verify {#sec-comp-sig-verify} +### HashComposite-ML-DSA-Verify {#sec-hash-comp-sig-verify} -Verification of a composite signature involves reconstructing the M' message first by concatenating the Domain separator (i.e., the DER encoding of the used Composite scheme's OID) with the Hash of the original message and then applying each component algorithm's verification process to the new message M'. +Verification of a composite signature involves reconstructing the M' message first by concatenating the Domain separator (i.e., the DER encoding of the used Composite scheme's OID) with the length of the Context, the Context Value, The Der Encoded OID of the Hash Value, and the Hash of the original message and then applying each component algorithm's verification process to the new message M'. Compliant applications MUST output "Valid signature" (true) if and only if all component signatures were successfully validated, and "Invalid signature" (false) otherwise. @@ -384,23 +690,31 @@ The following process is used to perform this verification. ~~~ Composite Verify(pk, Message, signature) Input: - P1, P2 Public verification keys. See note below on - composite inputs. + P1, P2 Public verification keys. See note below on + composite inputs. - Message Message whose signature is to be verified, - an octet string. + Message Message whose signature is to be verified, + an octet string. - signature CompositeSignatureValue containing the component - signature values (S1 and S2) to be verified. + signature CompositeSignatureValue containing the component + signature values (S1 and S2) to be verified. - A1, A2 Component signature algorithms. See note - below on composite inputs. + A1, A2 Component signature algorithms. See note + below on composite inputs. - HASH The Message Digest Algorithm for pre-hashing. See - section on pre-hashing the message below. + HASH The Message Digest Algorithm for pre-hashing. See + section on pre-hashing the message below. - Domain Domain separator value for binding the signature to the Composite OID. - See section on Domain Separators below. + HashOID The DER Encoding of the Object Identifier of the + PreHash algorithm. + + Context The Message context or Null if it is not used + + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. + + IntegerToBytes(c, 1) The legnth of the context (c) encoded into a single byte value. This + means the context cannot be more than bytes long. Output: Validity (bool) "Valid signature" (true) if the composite @@ -415,11 +729,14 @@ Signature Verification Procedure:: P1 or P2 and the algorithm identifiers A1 or A2 are composite then output "Invalid signature" and stop. - 2. Compute a Hash of the Message + 2. If Context > 255 + fail - M' = Domain || HASH(Message) + 3. Compute a Hash of the Message - 3. Check each component signature individually, according to its + M' = Domain || IntegerToBytes(|Context|, 1) || Context || HashOID || HASH (Message) + + 4. Check each component signature individually, according to its algorithm specification. If any fail, then the entire signature validation fails. @@ -431,11 +748,12 @@ Signature Verification Procedure:: if all succeeded, then output "Valid signature" ~~~ -{: #alg-composite-verify title="Composite Verify(pk, Message, signature)"} +{: #alg-composite-verify title="Hash-Composite-ML-DSA-Verify(pk, Message, signature, Context, HASH)"} It is possible to construct `CompositePublicKey`(s) to verify signatures from component keys stored in separate software or hardware keystores. Variations in the process to accommodate particular private key storage mechanisms are considered to be conformant to this document so long as it produces the same output as the process sketched above. + # Composite Key Structures {#sec-composite-structs} In order for signatures to be composed of multiple algorithms, we define encodings consisting of a sequence of signature primitives (aka "component algorithms") such that these structures can be used as a drop-in replacement for existing signature fields such as those found in PKCS#10 [RFC2986], CMP [RFC4210], X.509 [RFC5280], CMS [RFC5652]. From 9b6b149e7d3c77470178a60808b3613ff4072f29 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:41:20 -0400 Subject: [PATCH 04/25] Update draft-ietf-lamps-pq-composite-sigs.md Based on Authors comments, remove format suggestion and just copy and paste Pure and pre-hash modes --- draft-ietf-lamps-pq-composite-sigs.md | 310 +++++++------------------- 1 file changed, 76 insertions(+), 234 deletions(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 607968f..e0a73ba 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -318,202 +318,43 @@ Composite schemes' signatures provide important properties for multi-key environ A composite signature's value MUST include two signature components and MUST be in the same order as the components from the corresponding signing key. -### Pure Message Format Generation - -Composite signature provides two modes of operation, a pure mode and pre-hashing mode. The Message is formatted into M' by applying either the pure or pre-hash message format. After that, the signature process for each component algorithm is invoked and the values are then placed in the CompositeSignatureValue structure defined in {{sec-composite-sig-structs}}. In the pure mode the Domain separator {{sec-oid-concat}} is concatenated with the length of the context in bytes, the context and finally the Message. - -~~~ -Pure-Message-Format (Domain, Message, Context) -> (M') -Input: - Domain Domain separator value for binding the signature to the Composite OID. - See section on Domain Separators below. - - Message The Message to be signed, an octet string - - Context The Message context or Null if it is not used - - IntegerToBytes(c, 1) The length of c in bytes encoded into a single byte value. This - means the value c cannot be more than 255 bytes long. - -Output: - M' The Message Format - -Signature Generation Process: - - 1. If Context > 255: - fail - - 2. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of the Context, the value of the Context and the Message - - M' := Domain || IntegerToBytes(|Context|, 1) || Context || Message - - 3. Output M' - return M' -~~~ -{: #alg-message-format-pure title="Pure-Message-Format(Domain, Message, Context)"} - - -### PreHash Message Format Generation - -In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated with the length of the context in byte, the context, an additional DER encoded value that represents the Hash and finally the Hash of the message. - -~~~ -PreHash-Message-Format (Domain, Message, Context, HASH, HashOID) -> (M') -Input: - Domain Domain separator value for binding the signature to the Composite OID. - See section on Domain Separators below. - - Message The Message to be signed, an octet string - - Context The Message context or Null if it is not used - - IntegerToBytes(c, 1) The length of c in bytes encoded into a single byte value. This - means the value c cannot be more than 255 bytes long. - - HASH The Message Digest Algorithm for pre-hashing. See - section on pre-hashing the message below. - - HashOID The DER Encoding of the Object Identifier of the - PreHash algorithm. - -Output: - M' The Message Format - -Signature Generation Process: - - 1. If Context > 255: - fail - - 2. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of the Context, the value of the Context and the Message - - M' := Domain || IntegerToBytes(|ctx|, 1) || ctx || HashOID || HASH (Message) - - 3. Output M' - return M' -~~~ -{: #alg-message-format-prehash title="PreHash-Message-Format(Domain, Message, Context, HASH, HashOID)"} - -### Composite-ML-DSA-Sign: - -~~~ -Composite-ML-DSA-Sign (sk, M') -> (signature) -Input: - K1, K2 Signing private keys for each component. See note below on - composite inputs. - - A1, A2 Component signature algorithms. See note below on - composite inputs. - - M' The Formatted Message - -Output: - signature The composite signature, a CompositeSignatureValue - -Signature Generation Process: - - 1. Generate the 2 component signatures independently, by calculating the signature over M' - according to their algorithm specifications that might involve the use of the hash-n-sign paradigm. - - S1 := ML-DSA.Sign( K1, A1, M', Context="" ) - S2 := TradSign( K2, A2, M' ) - -Since Composite ML-DSA incorporates the domain separator, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. - - 2. Encode each component signature S1 and S2 into a BIT STRING - according to its algorithm specification. - - signature := NULL - - IF (S1 != NULL) and (S2 != NULL): - signature := Sequence { S1, S2 } - - 3. Output signature - - return signature -~~~ -{: #alg-composite-sign title="Composite-ML-DSA-Sign(sk, Message, M')"} - - -### Composite-ML-DSA-Verify: - -~~~ -Composite-ML-DSA-Verify(pk, M', signature) -Input: - P1, P2 Public verification keys. See note below on - composite inputs. - - M' The Formatted Message - - signature CompositeSignatureValue containing the component - signature values (S1 and S2) to be verified. - - A1, A2 Component signature algorithms. See note - below on composite inputs. - -Output: - Validity (bool) "Valid signature" (true) if the composite - signature is valid, "Invalid signature" - (false) otherwise. - -Signature Verification Procedure:: - 1. Check keys, signatures, and algorithms lists for consistency. - - If Error during Desequencing, or the sequences have - different numbers of elements, or any of the public keys - P1 or P2 and the algorithm identifiers A1 or A2 are - composite then output "Invalid signature" and stop. - - 2. Check each component signature individually, according to its - algorithm specification. - If any fail, then the entire signature validation fails. - - if not verify( P1, M', S1, A1 ) then - output "Invalid signature" - if not verify( P2, M', S2, A2 ) then - output "Invalid signature" - - if all succeeded, then - output "Valid signature" -~~~ -{: #alg-composite-verify title="Composite-ML-DSA-Verify(pk, M', signature)"} - ### Composite-ML-DSA-Sign pure signature mode: -In the pure mode the Domain separator {{sec-oid-concat}} is concatenated with the length of the context in bytes, the context and finally the Message. +In the pure mode the Domain separator {{sec-oid-concat}} is concatenated with the length of the context in bytes, the context and finally the Message. The following process is used to generate pure composite signature values. ~~~ -Composite-ML-DSA-Sign (sk, Message, Context) -> (signature) +Composite-ML-DSA-Sign (sk, M, ctx) -> (signature) Input: - K1, K2 Signing private keys for each component. See note below on - composite inputs. + K1, K2 Signing private keys for each component. See note below on + composite inputs. - A1, A2 Component signature algorithms. See note below on - composite inputs. + A1, A2 Component signature algorithms. See note below on + composite inputs. - Message The Message to be signed, an octet string + M The Message to be signed, an octet string - Context The Message context or Null if it is not used + ctx The Message context or the empty string if it is not used - Domain Domain separator value for binding the signature to the Composite OID. - See section on Domain Separators below. + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. - IntegerToBytes(c, 1) The length of the c in bytes encoded into a single byte value. This - means the value c cannot be more than 255 bytes long. + len(ctx) The length of the context in bytes encoded into a single byte value. This + cannot be more than 255 bytes long. Output: signature The composite signature, a CompositeSignatureValue Signature Generation Process: - 1. If Context > 255: + 1. If ctx > 255: fail - 2. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of the Context, the value of the Context and the Message + 2. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of ctx, the value ctx and the M - M' := Domain || IntegerToBytes(|Context|, 1) || Context || Message + M' := Domain || len(ctx) || ctx || M 3. Generate the 2 component signatures independently, by calculating the signature over M' according to their algorithm specifications that might involve the use of the hash-n-sign paradigm. @@ -535,13 +376,13 @@ Since Composite ML-DSA incorporates the domain separator, which serves theh same return signature ~~~ -{: #alg-composite-sign title="Composite-ML-DSA-Sign(sk, Message, Context)"} +{: #alg-composite-sign title="Composite-ML-DSA-Sign(sk, M, ctx)"} It is possible to construct `CompositePrivateKey`(s) to generate signatures from component keys stored in separate software or hardware keystores. Variations in the process to accommodate particular private key storage mechanisms are considered to be conformant to this document so long as it produces the same output as the process sketched above. ### Composite-ML-DSA-Verify pure Verify Mode {#sec-comp-sig-verify} -Verification of a composite signature involves reconstructing the M' message first by concatenating the Domain separator (i.e., the DER encoding of the used Composite scheme's OID) with the length of the Context, the value of the Context, and the Message itself and then applying each component algorithm's verification process to the new message M'. +Verification of a composite signature involves reconstructing the M' message first by concatenating the Domain separator (i.e., the DER encoding of the used Composite scheme's OID) with the length of the context, the value of the context, and the Message itself and then applying each component algorithm's verification process to the new message M'. Compliant applications MUST output "Valid signature" (true) if and only if all component signatures were successfully validated, and "Invalid signature" (false) otherwise. @@ -549,27 +390,27 @@ The following process is used to perform this verification. ~~~ -Composite-ML-DSA-Verify(pk, Message, signature, Context) +Composite-ML-DSA-Verify(pk, M, signature, ctx) Input: - P1, P2 Public verification keys. See note below on - composite inputs. + P1, P2 Public verification keys. See note below on + composite inputs. - Message Message whose signature is to be verified, - an octet string. + M Message whose signature is to be verified, + an octet string. - signature CompositeSignatureValue containing the component - signature values (S1 and S2) to be verified. + signature CompositeSignatureValue containing the component + signature values (S1 and S2) to be verified. - A1, A2 Component signature algorithms. See note - below on composite inputs. + A1, A2 Component signature algorithms. See note + below on composite inputs. - Context The Message context or Null if it is not used + Context The Message context or the empty string if it is not used - Domain Domain separator value for binding the signature to the Composite OID. - See section on Domain Separators below. + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. - IntegerToBytes(c, 1) The legnth of the context (c) encoded into a single byte value. This - means the context cannot be more than bytes long. + len(ctx) The legnth of the context (c) encoded into a single byte value. This + means the context cannot be more than bytes long. Output: Validity (bool) "Valid signature" (true) if the composite @@ -584,12 +425,12 @@ Signature Verification Procedure:: P1 or P2 and the algorithm identifiers A1 or A2 are composite then output "Invalid signature" and stop. - 2. If Context > 255 + 2. If ctx > 255 fail 3. Format the Message as follows: - M' = Domain || IntegerToBytes(|Context|, 1) || Context || Message + M' = Domain || len(ctx) || ctx || M 4. Check each component signature individually, according to its algorithm specification. @@ -610,7 +451,7 @@ It is possible to construct `CompositePublicKey`(s) to verify signatures from co ## PreHash-Signature Generation {#sec-comp-sig-gen-prehash} -Composite signature provides two modes of operation, a pure mode and pre-hashing mode. In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated with the length of the context in byte, the context, an additional DER encoded value that represents the Hash and finally the Hash of the message. After that, the signature process for each component algorithm is invoked and the values are then placed in the CompositeSignatureValue structure defined in {{sec-composite-sig-structs}}. +Composite signature provides two modes of operation, a pure mode and pre-hashing mode. In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated with the length of the context in bytes, the context, an additional DER encoded value that represents the Hash and finally the Hash of the message. After that, the signature process for each component algorithm is invoked and the values are then placed in the CompositeSignatureValue structure defined in {{sec-composite-sig-structs}}. A composite signature's value MUST include two signature components and MUST be in the same order as the components from the corresponding signing key. @@ -621,29 +462,29 @@ The following process is used to generate composite signature values. In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated with the length of the context in byte, the context, an additional DER encoded value that represents the Hash and finally the Hash of the message. ~~~ -HashComposite-ML-DSA-Sign (sk, Message, Context, HASH) -> (signature) +HashComposite-ML-DSA-Sign (sk, M, ctx, PH) -> (signature) Input: - K1, K2 Signing private keys for each component. See note below on - composite inputs. + K1, K2 Signing private keys for each component. See note below on + composite inputs. - A1, A2 Component signature algorithms. See note below on - composite inputs. + A1, A2 Component signature algorithms. See note below on + composite inputs. - Message The Message to be signed, an octet string + M The Message to be signed, an octet string - HASH The Message Digest Algorithm for pre-hashing. See - section on pre-hashing the message below. + PH The Message Digest Algorithm for pre-hashing. See + section on pre-hashing the message below. - HashOID The DER Encoding of the Object Identifier of the - PreHash algorithm. + HashOID The DER Encoding of the Object Identifier of the + PreHash algorithm (PH) which is passed into the function - Context The Message context or Null if it is not used + ctx The Message context or the empty String if it is not used - Domain Domain separator value for binding the signature to the Composite OID. - See section on Domain Separators below. + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. - IntegerToBytes(c, 1) The legnth of the context (c) encoded into a single byte value. This - means the context cannot be more than bytes long. + len(ctx) The length of the context encoded into a single byte value. This value + cannot be more than bytes long. Output: signature The composite signature, a CompositeSignatureValue @@ -652,7 +493,7 @@ Signature Generation Process: 1. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of the context, the Context, the HashOID and the Hash of the Message. - M' := Domain || IntegerToBytes(|ctx|, 1) || ctx || HashOID || HASH (Message) + M' := Domain || len(ctx) || ctx || HashOID || PH(M) 2. Generate the 2 component signatures independently, by calculating the signature over M' according to their algorithm specifications that might involve the use of the hash-n-sign paradigm. @@ -674,7 +515,7 @@ Since HashComposite ML-DSA incorporates the domain separator, which serves theh return signature ~~~ -{: #alg-composite-sign title="HashComposite-ML-DSA-Sign(sk, Message, Context, HASH)"} +{: #alg-composite-sign title="HashComposite-ML-DSA-Sign(sk, M, ctx, PH)"} It is possible to construct `CompositePrivateKey`(s) to generate signatures from component keys stored in separate software or hardware keystores. Variations in the process to accommodate particular private key storage mechanisms are considered to be conformant to this document so long as it produces the same output as the process sketched above. @@ -688,33 +529,33 @@ The following process is used to perform this verification. ~~~ -Composite Verify(pk, Message, signature) +Composite Verify(pk, M, signature, ctx, PH) Input: - P1, P2 Public verification keys. See note below on - composite inputs. + P1, P2 Public verification keys. See note below on + composite inputs. - Message Message whose signature is to be verified, - an octet string. + M Message whose signature is to be verified, + an octet string. - signature CompositeSignatureValue containing the component - signature values (S1 and S2) to be verified. + signature CompositeSignatureValue containing the component + signature values (S1 and S2) to be verified. - A1, A2 Component signature algorithms. See note - below on composite inputs. + A1, A2 Component signature algorithms. See note + below on composite inputs. - HASH The Message Digest Algorithm for pre-hashing. See - section on pre-hashing the message below. + PH The Message Digest Algorithm for pre-hashing. See + section on pre-hashing the message below. - HashOID The DER Encoding of the Object Identifier of the - PreHash algorithm. + HashOID The DER Encoding of the Object Identifier of the + PreHash algorithm (PH) which is passed into the function - Context The Message context or Null if it is not used + Context The Message context or the empty string if it is not used - Domain Domain separator value for binding the signature to the Composite OID. - See section on Domain Separators below. + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. - IntegerToBytes(c, 1) The legnth of the context (c) encoded into a single byte value. This - means the context cannot be more than bytes long. + len(ctx) The legnth of the context encoded into a single byte value. This + value cannot be more than bytes long. Output: Validity (bool) "Valid signature" (true) if the composite @@ -722,19 +563,20 @@ Output: (false) otherwise. Signature Verification Procedure:: - 1. Check keys, signatures, and algorithms lists for consistency. + + 1. If ctx > 255 + fail + + 2. Check keys, signatures, and algorithms lists for consistency. If Error during Desequencing, or the sequences have different numbers of elements, or any of the public keys P1 or P2 and the algorithm identifiers A1 or A2 are composite then output "Invalid signature" and stop. - 2. If Context > 255 - fail - 3. Compute a Hash of the Message - M' = Domain || IntegerToBytes(|Context|, 1) || Context || HashOID || HASH (Message) + M' = Domain || len(ctx) || ctx || HashOID || PH(M) 4. Check each component signature individually, according to its algorithm specification. @@ -748,7 +590,7 @@ Signature Verification Procedure:: if all succeeded, then output "Valid signature" ~~~ -{: #alg-composite-verify title="Hash-Composite-ML-DSA-Verify(pk, Message, signature, Context, HASH)"} +{: #alg-composite-verify title="Hash-Composite-ML-DSA-Verify(pk, M, signature, ctx, PH)"} It is possible to construct `CompositePublicKey`(s) to verify signatures from component keys stored in separate software or hardware keystores. Variations in the process to accommodate particular private key storage mechanisms are considered to be conformant to this document so long as it produces the same output as the process sketched above. From 6988418019fc952a2c8713e97614099c49397783 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:43:32 -0400 Subject: [PATCH 05/25] Update draft-ietf-lamps-pq-composite-sigs.md Fix silly whitespace error --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index e0a73ba..ce2b38e 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -459,7 +459,7 @@ The following process is used to generate composite signature values. ### HASHComposite-ML-DSA-Sign signature mode: -In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated with the length of the context in byte, the context, an additional DER encoded value that represents the Hash and finally the Hash of the message. +In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated with the length of the context in byte, the context, an additional DER encoded value that represents the Hash and finally the Hash of the message. ~~~ HashComposite-ML-DSA-Sign (sk, M, ctx, PH) -> (signature) From 1f4c5f99d81fa9e131269437d1c007833db9428d Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:46:03 -0400 Subject: [PATCH 06/25] Update draft-ietf-lamps-pq-composite-sigs.md Another silly white space --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index ce2b38e..e342234 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -351,7 +351,7 @@ Signature Generation Process: 1. If ctx > 255: fail - + 2. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of ctx, the value ctx and the M M' := Domain || len(ctx) || ctx || M From 6351668a8d9cd1acea2e814915a25ed0ee862462 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:50:28 -0400 Subject: [PATCH 07/25] Update draft-ietf-lamps-pq-composite-sigs.md References to sign and verify elements duplicated and needed to be fixed. --- draft-ietf-lamps-pq-composite-sigs.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index e342234..ed41201 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -376,7 +376,7 @@ Since Composite ML-DSA incorporates the domain separator, which serves theh same return signature ~~~ -{: #alg-composite-sign title="Composite-ML-DSA-Sign(sk, M, ctx)"} +{: # title="Composite-ML-DSA-Sign(sk, M, ctx)"} It is possible to construct `CompositePrivateKey`(s) to generate signatures from component keys stored in separate software or hardware keystores. Variations in the process to accommodate particular private key storage mechanisms are considered to be conformant to this document so long as it produces the same output as the process sketched above. @@ -515,7 +515,7 @@ Since HashComposite ML-DSA incorporates the domain separator, which serves theh return signature ~~~ -{: #alg-composite-sign title="HashComposite-ML-DSA-Sign(sk, M, ctx, PH)"} +{: #alg-hash-composite-sign title="HashComposite-ML-DSA-Sign(sk, M, ctx, PH)"} It is possible to construct `CompositePrivateKey`(s) to generate signatures from component keys stored in separate software or hardware keystores. Variations in the process to accommodate particular private key storage mechanisms are considered to be conformant to this document so long as it produces the same output as the process sketched above. @@ -590,7 +590,7 @@ Signature Verification Procedure:: if all succeeded, then output "Valid signature" ~~~ -{: #alg-composite-verify title="Hash-Composite-ML-DSA-Verify(pk, M, signature, ctx, PH)"} +{: #alg-hash-composite-verify title="Hash-Composite-ML-DSA-Verify(pk, M, signature, ctx, PH)"} It is possible to construct `CompositePublicKey`(s) to verify signatures from component keys stored in separate software or hardware keystores. Variations in the process to accommodate particular private key storage mechanisms are considered to be conformant to this document so long as it produces the same output as the process sketched above. From 561e6d791854c05ff9d054e2de36830c5f2fb8c0 Mon Sep 17 00:00:00 2001 From: Mike Ounsworth Date: Sun, 6 Oct 2024 04:21:06 -0500 Subject: [PATCH 08/25] Editing pass over the Composite-ML-DSA and HashComposite-ML-DSA proceedures --- draft-ietf-lamps-pq-composite-sigs.md | 205 +++++++++++++++----------- 1 file changed, 115 insertions(+), 90 deletions(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index ed41201..de2c2a0 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -312,67 +312,73 @@ Function KeyGen(): The key generation functions MUST be executed for both algorithms. Compliant parties MUST NOT use or import component keys that are used in other contexts, combinations, or by themselves (i.e., not only in X.509 certificates). -## Signature Generation {#sec-comp-sig-gen} +## Pure Signature Generation {#sec-comp-sig-gen} Composite schemes' signatures provide important properties for multi-key environments such as non-separability and key-binding. For more information on the additional security properties and their applicability to multi-key or hybrid environments, please refer to {{I-D.hale-pquip-hybrid-signature-spectrums}} and the use of labels as defined in {{Bindel2017}} A composite signature's value MUST include two signature components and MUST be in the same order as the components from the corresponding signing key. -### Composite-ML-DSA-Sign pure signature mode: +### Composite-ML-DSA.Sign -In the pure mode the Domain separator {{sec-oid-concat}} is concatenated with the length of the context in bytes, the context and finally the Message. +This mode mirrors `ML-DSA.Sign(sk, M, ctx)` defined in Section 5.2 of [FIPS.204]. The composite domain separator "Domain" {{sec-oid-concat}} is concatenated with the length of the context string `ctx` in bytes, the context string `ctx`, and finally the un-hashed message `M` . -The following process is used to generate pure composite signature values. +The following process is used to generate pure composite signature values and mirrors Algorithm 2 in [FIPS.204]. ~~~ -Composite-ML-DSA-Sign (sk, M, ctx) -> (signature) -Input: - K1, K2 Signing private keys for each component. See note below on - composite inputs. - - A1, A2 Component signature algorithms. See note below on - composite inputs. +Composite-ML-DSA.Sign (sk, M, ctx) -> (signature) +Explicit Input: + sk Composite private key conisting of signing private keys for each component. M The Message to be signed, an octet string - ctx The Message context or the empty string if it is not used + ctx The Message context string, which defaults to the empty string + + +Implicit inputs: - Domain Domain separator value for binding the signature to the Composite OID. - See section on Domain Separators below. + ML-DSA A placeholder for the specific ML-DSA algorithm and + parameter set to use, for example, could be "ML-DSA-65". - len(ctx) The length of the context in bytes encoded into a single byte value. This - cannot be more than 255 bytes long. + Trad A placeholder for the specific ML-DSA algorithm and + parameter set to use, for example "RSASA-PSS with id-sha256" + or "Ed25519". + + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. Output: signature The composite signature, a CompositeSignatureValue Signature Generation Process: - 1. If ctx > 255: - fail + 1. If |ctx| > 255: + return error 2. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of ctx, the value ctx and the M M' := Domain || len(ctx) || ctx || M - 3. Generate the 2 component signatures independently, by calculating the signature over M' + 3. Separate the private key into componet keys. Note, the exact storage format for composite private keys may be as described in this document, or may be implementation-specific. + + (sk1, sk2) := Unmarshal(sk) + + 4. Generate the 2 component signatures independently, by calculating the signature over M' according to their algorithm specifications that might involve the use of the hash-n-sign paradigm. - S1 := ML-DSA.Sign( K1, A1, M', Context="" ) - S2 := TradSign( K2, A2, M' ) + s1 := ML-DSA.Sign( sk1, M', Context="" ) + s2 := Trad.Sign( sk2, M' ) -Since Composite ML-DSA incorporates the domain separator, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. + Since Composite ML-DSA incorporates the domain separator, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. - 4. Encode each component signature S1 and S2 into a BIT STRING - according to its algorithm specification. + If either ML-DSA.Sign() or Trad.Sign() return an error, then this process must return an error. - signature := NULL + 5. Encode each component signature S1 and S2 into a BIT STRING + according to its algorithm specification. - IF (S1 != NULL) and (S2 != NULL): - signature := Sequence { S1, S2 } + signature := Sequence { s1, s2 } - 5. Output signature + 6. Output signature return signature ~~~ @@ -380,9 +386,9 @@ Since Composite ML-DSA incorporates the domain separator, which serves theh same It is possible to construct `CompositePrivateKey`(s) to generate signatures from component keys stored in separate software or hardware keystores. Variations in the process to accommodate particular private key storage mechanisms are considered to be conformant to this document so long as it produces the same output as the process sketched above. -### Composite-ML-DSA-Verify pure Verify Mode {#sec-comp-sig-verify} +### Composite-ML-DSA.Verify {#sec-comp-sig-verify} -Verification of a composite signature involves reconstructing the M' message first by concatenating the Domain separator (i.e., the DER encoding of the used Composite scheme's OID) with the length of the context, the value of the context, and the Message itself and then applying each component algorithm's verification process to the new message M'. +This mode mirrors `ML-DSA.Sign(sk, M, ctx)` defined in Section 5.3 of [FIPS.204]. Verification of a composite signature involves reconstructing the `M'` message by concatenating the composite domain separator "Domain" {{sec-oid-concat}} with the length of the context string `ctx` in bytes, the context string `ctx`, and finally the un-hashed message `M` . Compliant applications MUST output "Valid signature" (true) if and only if all component signatures were successfully validated, and "Invalid signature" (false) otherwise. @@ -390,43 +396,48 @@ The following process is used to perform this verification. ~~~ -Composite-ML-DSA-Verify(pk, M, signature, ctx) -Input: - P1, P2 Public verification keys. See note below on - composite inputs. +Composite-ML-DSA.Verify(pk, M, signature, ctx) +Explicit Inputs: + pk Composite public key conisting of verification public keys for each component. M Message whose signature is to be verified, an octet string. signature CompositeSignatureValue containing the component signature values (S1 and S2) to be verified. + ctx The Message context string, which defaults to the empty string + +Implicit inputs: - A1, A2 Component signature algorithms. See note - below on composite inputs. + ML-DSA A placeholder for the specific ML-DSA algorithm and + parameter set to use, for example, could be "ML-DSA-65". - Context The Message context or the empty string if it is not used + Trad A placeholder for the specific ML-DSA algorithm and + parameter set to use, for example "RSASA-PSS with id-sha256" + or "Ed25519". - Domain Domain separator value for binding the signature to the Composite OID. - See section on Domain Separators below. + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. - len(ctx) The legnth of the context (c) encoded into a single byte value. This - means the context cannot be more than bytes long. Output: Validity (bool) "Valid signature" (true) if the composite signature is valid, "Invalid signature" (false) otherwise. -Signature Verification Procedure:: - 1. Check keys, signatures, and algorithms lists for consistency. +Signature Verification Procedure: + 1. Separate the keys and signatures + + (pk1, pk2) := pk + (s1, s2) := signature If Error during Desequencing, or the sequences have different numbers of elements, or any of the public keys P1 or P2 and the algorithm identifiers A1 or A2 are composite then output "Invalid signature" and stop. - 2. If ctx > 255 - fail + 2. If |ctx| > 255 + return error 3. Format the Message as follows: @@ -436,9 +447,10 @@ Signature Verification Procedure:: algorithm specification. If any fail, then the entire signature validation fails. - if not verify( P1, M', S1, A1 ) then + if not ML-DSA.Verify( pk1, M', s1, ctx="") then output "Invalid signature" - if not verify( P2, M', S2, A2 ) then + + if not Trad.Verify( pk2, M', s2) then output "Invalid signature" if all succeeded, then @@ -451,40 +463,48 @@ It is possible to construct `CompositePublicKey`(s) to verify signatures from co ## PreHash-Signature Generation {#sec-comp-sig-gen-prehash} -Composite signature provides two modes of operation, a pure mode and pre-hashing mode. In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated with the length of the context in bytes, the context, an additional DER encoded value that represents the Hash and finally the Hash of the message. After that, the signature process for each component algorithm is invoked and the values are then placed in the CompositeSignatureValue structure defined in {{sec-composite-sig-structs}}. + +This mode mirrors `HashML-DSA` defined in Section 5.4 of [FIPS.204]. + +In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatenated with the length of the context in bytes, the context, an additional DER encoded value that represents the OID of the Hash function and finally the hash of the message. After that, the signature process for each component algorithm is invoked and the values are then placed in the CompositeSignatureValue structure defined in {{sec-composite-sig-structs}}. A composite signature's value MUST include two signature components and MUST be in the same order as the components from the corresponding signing key. The following process is used to generate composite signature values. -### HASHComposite-ML-DSA-Sign signature mode: +### HASHComposite-ML-DSA-Sign signature mode -In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated with the length of the context in byte, the context, an additional DER encoded value that represents the Hash and finally the Hash of the message. +This mode mirrors `HashML-DSA.Sign(sk, M, ctx, PH)` defined in Section 5.4.1 of [FIPS.204]. + +In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated with the length of the context in bytes, the context, an additional DER encoded value that represents the Hash and finally the pre-hashed message `PH(M)`. ~~~ -HashComposite-ML-DSA-Sign (sk, M, ctx, PH) -> (signature) -Input: - K1, K2 Signing private keys for each component. See note below on - composite inputs. +HashComposite-ML-DSA.Sign (sk, M, ctx, PH) -> (signature) - A1, A2 Component signature algorithms. See note below on - composite inputs. +Explicit Input: + sk Composite private key conisting of signing private keys for each component. M The Message to be signed, an octet string + ctx The Message context string, which defaults to the empty string + PH The Message Digest Algorithm for pre-hashing. See section on pre-hashing the message below. - HashOID The DER Encoding of the Object Identifier of the - PreHash algorithm (PH) which is passed into the function +Implicit inputs: + + ML-DSA A placeholder for the specific ML-DSA algorithm and + parameter set to use, for example, could be "ML-DSA-65". - ctx The Message context or the empty String if it is not used + Trad A placeholder for the specific ML-DSA algorithm and + parameter set to use, for example "RSASA-PSS with id-sha256" + or "Ed25519". - Domain Domain separator value for binding the signature to the Composite OID. - See section on Domain Separators below. + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. - len(ctx) The length of the context encoded into a single byte value. This value - cannot be more than bytes long. + HashOID The DER Encoding of the Object Identifier of the + PreHash algorithm (PH) which is passed into the function Output: signature The composite signature, a CompositeSignatureValue @@ -498,18 +518,15 @@ Signature Generation Process: 2. Generate the 2 component signatures independently, by calculating the signature over M' according to their algorithm specifications that might involve the use of the hash-n-sign paradigm. - S1 := ML-DSA.Sign( K1, A1, M', Context ="" ) - S2 := TradSign( K2, A2, M' ) + s1 := ML-DSA.Sign( sk1, M', ctx ="" ) + s2 := Trad.Sign( sk2, M' ) -Since HashComposite ML-DSA incorporates the domain separator, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. + Since HashComposite ML-DSA incorporates the domain separator, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. 3. Encode each component signature S1 and S2 into a BIT STRING according to its algorithm specification. - signature := NULL - - IF (S1 != NULL) and (S2 != NULL): - signature := Sequence { S1, S2 } + signature := Sequence { s1, s2 } 4. Output signature @@ -521,7 +538,9 @@ It is possible to construct `CompositePrivateKey`(s) to generate signatures from ### HashComposite-ML-DSA-Verify {#sec-hash-comp-sig-verify} -Verification of a composite signature involves reconstructing the M' message first by concatenating the Domain separator (i.e., the DER encoding of the used Composite scheme's OID) with the length of the Context, the Context Value, The Der Encoded OID of the Hash Value, and the Hash of the original message and then applying each component algorithm's verification process to the new message M'. +This mode mirrors `HashML-DSA.Verify(pk, M, signature, ctx, PH)` defined in Section 5.4.1 of [FIPS.204]. + +Verification of a composite signature involves reconstructing the `M'` message by concatenating the composite domain separator "Domain" {{sec-oid-concat}} with the length of the context string `ctx` in bytes, the context string `ctx`, and finally the pre-hashed message `PH(M)` . Compliant applications MUST output "Valid signature" (true) if and only if all component signatures were successfully validated, and "Invalid signature" (false) otherwise. @@ -529,33 +548,35 @@ The following process is used to perform this verification. ~~~ -Composite Verify(pk, M, signature, ctx, PH) -Input: - P1, P2 Public verification keys. See note below on - composite inputs. +HashComposite-ML-DSA.Verify(pk, M, signature, ctx, PH) + +Explicit Inputs: + pk Composite public key conisting of verification public keys for each component. M Message whose signature is to be verified, an octet string. signature CompositeSignatureValue containing the component signature values (S1 and S2) to be verified. - - A1, A2 Component signature algorithms. See note - below on composite inputs. + ctx The Message context string, which defaults to the empty string PH The Message Digest Algorithm for pre-hashing. See section on pre-hashing the message below. - HashOID The DER Encoding of the Object Identifier of the - PreHash algorithm (PH) which is passed into the function +Implicit inputs: - Context The Message context or the empty string if it is not used + ML-DSA A placeholder for the specific ML-DSA algorithm and + parameter set to use, for example, could be "ML-DSA-65". - Domain Domain separator value for binding the signature to the Composite OID. - See section on Domain Separators below. + Trad A placeholder for the specific ML-DSA algorithm and + parameter set to use, for example "RSASA-PSS with id-sha256" + or "Ed25519". - len(ctx) The legnth of the context encoded into a single byte value. This - value cannot be more than bytes long. + Domain Domain separator value for binding the signature to the Composite OID. + See section on Domain Separators below. + + HashOID The DER Encoding of the Object Identifier of the + PreHash algorithm (PH) which is passed into the function Output: Validity (bool) "Valid signature" (true) if the composite @@ -564,16 +585,19 @@ Output: Signature Verification Procedure:: - 1. If ctx > 255 - fail + 1. Separate the keys and signatures - 2. Check keys, signatures, and algorithms lists for consistency. + (pk1, pk2) := pk + (s1, s2) := signature If Error during Desequencing, or the sequences have different numbers of elements, or any of the public keys P1 or P2 and the algorithm identifiers A1 or A2 are composite then output "Invalid signature" and stop. + 2. If |ctx| > 255 + return error + 3. Compute a Hash of the Message M' = Domain || len(ctx) || ctx || HashOID || PH(M) @@ -582,9 +606,10 @@ Signature Verification Procedure:: algorithm specification. If any fail, then the entire signature validation fails. - if not verify( P1, M', S1, A1 ) then + if not ML-DSA.Verify( pk1, M', s1 ) then output "Invalid signature" - if not verify( P2, M', S2, A2 ) then + + if not Trad.Verify( pk2, M', s2 ) then output "Invalid signature" if all succeeded, then From e83a33155ddd22191c1333e8f701ad8a5cc9580a Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 9 Oct 2024 12:09:45 -0400 Subject: [PATCH 09/25] Update draft-ietf-lamps-pq-composite-sigs.md Make sure the pure and pre-ash versions align --- draft-ietf-lamps-pq-composite-sigs.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index de2c2a0..352d9a8 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -482,7 +482,7 @@ In the pre-hash mode the Domain separator {{sec-oid-concat}} is concatendated wi HashComposite-ML-DSA.Sign (sk, M, ctx, PH) -> (signature) Explicit Input: - sk Composite private key conisting of signing private keys for each component. + sk Composite private key consisting of signing private keys for each component. M The Message to be signed, an octet string @@ -511,11 +511,18 @@ Output: Signature Generation Process: - 1. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of the context, the Context, the HashOID and the Hash of the Message. + 1. If |ctx| > 255: + return error + + 2. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of the context, the Context, the HashOID and the Hash of the Message. M' := Domain || len(ctx) || ctx || HashOID || PH(M) - 2. Generate the 2 component signatures independently, by calculating the signature over M' + 3. Separate the private key into componet keys. Note, the exact storage format for composite private keys may be as described in this document, or may be implementation-specific. + + (sk1, sk2) := Unmarshal(sk) + + 4. Generate the 2 component signatures independently, by calculating the signature over M' according to their algorithm specifications that might involve the use of the hash-n-sign paradigm. s1 := ML-DSA.Sign( sk1, M', ctx ="" ) @@ -523,12 +530,12 @@ Signature Generation Process: Since HashComposite ML-DSA incorporates the domain separator, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. - 3. Encode each component signature S1 and S2 into a BIT STRING + 5. Encode each component signature S1 and S2 into a BIT STRING according to its algorithm specification. signature := Sequence { s1, s2 } - 4. Output signature + 6. Output signature return signature ~~~ @@ -551,7 +558,7 @@ The following process is used to perform this verification. HashComposite-ML-DSA.Verify(pk, M, signature, ctx, PH) Explicit Inputs: - pk Composite public key conisting of verification public keys for each component. + pk Composite public key consisting of verification public keys for each component. M Message whose signature is to be verified, an octet string. @@ -791,7 +798,7 @@ This section is not intended to be exhaustive and other authors may define other Some use-cases desire the flexibility for clients to use any combination of supported algorithms, while others desire the rigidity of explicitly-specified combinations of algorithms. -The following table summarizes the details for each explicit composite signature algorithms: +The following tables summarizes the details for each explicit composite signature algorithms: The OID referenced are TBD for prototyping only, and the following prefix is used for each: From 0a01fc351778c40c0ed86a198e5c37c791af8188 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 9 Oct 2024 16:48:06 -0400 Subject: [PATCH 10/25] Update draft-ietf-lamps-pq-composite-sigs.md Added Pre-Hash and Pure modes and changed the Message format to align with FIPS-204. This breaks backwards compatibility will all previous versions * Updated the OID table for new Pre-Hash OIDs and added them to the IANA section * Updated Use in CMS section to reflect content is hashed and pure Composite ML-DSA should be used. * Other typos --- draft-ietf-lamps-pq-composite-sigs.md | 177 +++++++++++++++++++++----- 1 file changed, 146 insertions(+), 31 deletions(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index f7dd93e..cbd9f7f 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -159,6 +159,10 @@ This document introduces a set of signature schemes that use pairs of cryptograp * ASN.1 Module changes: * Renamed the module from Composite-Signatures-2023 -> Composite-MLDSA-2024 * Simplified the ASN.1 module to make it more compiler-friendly (thanks Carl!) -- should not affect wire encodings. + * Added Pre-Hash and Pure modes and changed the Message format to align with FIPS-204. This breaks backwards compatibility will all previous versions + * Updated the OID table for new Pre-Hash OIDs and added them to the IANA section + * Updated Use in CMS section to reflect content is hashed and pure Composite ML-DSA should be used. + * Other typos # Introduction {#sec-intro} @@ -462,7 +466,7 @@ A composite signature's value MUST include two signature components and MUST be The following process is used to generate composite signature values. -### HASHComposite-ML-DSA-Sign signature mode +### HASHComposite-ML-DSA-Sign signature mode This mode mirrors `HashML-DSA.Sign(sk, M, ctx, PH)` defined in Section 5.4.1 of [FIPS.204]. @@ -815,13 +819,13 @@ replace <CompSig> with the String "2.16.840.1.114027.80.8.1" Therefore <CompSig>.21 is equal to 2.16.840.1.114027.80.8.1.21 -Signature public key types: +Pure Signature public key types: -| Composite Signature AlgorithmID | OID | First AlgorithmID | Second AlgorithmID | Pre-Hash | +| Composite Signature AlgorithmID | OID | First AlgorithmID | Second AlgorithmID | Second Alg PreHash | | ----------- | ----------- | ----------- | ----------- | ----------- | | id-MLDSA44-RSA2048-PSS-SHA256 | <CompSig>.21 | id-ML-DSA-44 | id-RSASA-PSS with id-sha256 | id-sha256 | | id-MLDSA44-RSA2048-PKCS15-SHA256 | <CompSig>.22 | id-ML-DSA-44 | sha256WithRSAEncryption | id-sha256 | -| id-MLDSA44-Ed25519-SHA512 | <CompSig>.23 | id-ML-DSA-44 | id-Ed25519 | id-sha512 | +| id-MLDSA44-Ed25519 | <CompSig>.23 | id-ML-DSA-44 | id-Ed25519 | Not Needed | | id-MLDSA44-ECDSA-P256-SHA256 | <CompSig>.24 | id-ML-DSA-44 | ecdsa-with-SHA256 with secp256r1 | id-sha256 | | id-MLDSA65-RSA3072-PSS-SHA512 | <CompSig>.26 | id-ML-DSA-65 | id-RSASA-PSS with id-sha512 | id-sha512 | | id-MLDSA65-RSA3072-PKCS15-SHA512 | <CompSig>.27 | id-ML-DSA-65 | sha512WithRSAEncryption | id-sha512 | @@ -829,14 +833,35 @@ Signature public key types: | id-MLDSA65-RSA4096-PKCS15-SHA512 | <CompSig>.35 | id-ML-DSA-65 | sha512WithRSAEncryption | id-sha512 | | id-MLDSA65-ECDSA-P384-SHA512 | <CompSig>.28 | id-ML-DSA-65 | ecdsa-with-SHA512 with secp384r1 | id-sha512 | | id-MLDSA65-ECDSA-brainpoolP256r1-SHA512 | <CompSig>.29 | id-ML-DSA-65 | ecdsa-with-SHA512 with brainpoolP256r1 | id-sha512 | -| id-MLDSA65-Ed25519-SHA512 | <CompSig>.30 | id-ML-DSA-65 | id-Ed25519 | id-sha512 | +| id-MLDSA65-Ed25519 | <CompSig>.30 | id-ML-DSA-65 | id-Ed25519 | Not Needed | | id-MLDSA87-ECDSA-P384-SHA512 | <CompSig>.31 | id-ML-DSA-87 | ecdsa-with-SHA512 with secp384r1 | id-sha512| | id-MLDSA87-ECDSA-brainpoolP384r1-SHA512 | <CompSig>.32 | id-ML-DSA-87 | ecdsa-with-SHA512 with brainpoolP384r1 | id-sha512 | -| id-MLDSA87-Ed448-SHA512 | <CompSig>.33 | id-ML-DSA-87 | id-Ed448 | id-sha512 | -{: #tab-sig-algs title="Composite Signature Algorithms"} +| id-MLDSA87-Ed448 | <CompSig>.33 | id-ML-DSA-87 | id-Ed448 | Not Needed | +{: #tab-sig-algs title="Pure ML-DSA Composite Signature Algorithms"} + +The table above contains everything needed to implement the listed pure ML-DSA composite signature algorithms. The hash value indicated is used only by the Second algorithm if needed. See the ASN.1 module in section {{sec-asn1-module}} for the explicit definitions of the above Composite signature algorithms. -The table above contains everything needed to implement the listed explicit composite algorithms. See the ASN.1 module in section {{sec-asn1-module}} for the explicit definitions of the above Composite signature algorithms. +HashML-DSA Signature public key types: +| Composite Signature AlgorithmID | OID | First AlgorithmID | Second AlgorithmID | Pre-Hash | +| ----------- | ----------- | ----------- | ----------- | ----------- | +| id-HashMLDSA44-RSA2048-PSS-SHA256 | <CompSig>.40 | id-ML-DSA-44 | id-RSASA-PSS with id-sha256 | id-sha256 | +| id-HashMLDSA44-RSA2048-PKCS15-SHA256 | <CompSig>.41 | id-ML-DSA-44 | sha256WithRSAEncryption | id-sha256 | +| id-HashMLDSA44-Ed25519-SHA512 | <CompSig>.42 | id-ML-DSA-44 | id-Ed25519 | id-sha512 | +| id-HashMLDSA44-ECDSA-P256-SHA256 | <CompSig>.43 | id-ML-DSA-44 | ecdsa-with-SHA256 with secp256r1 | id-sha256 | +| id-HashMLDSA65-RSA3072-PSS-SHA512 | <CompSig>.44 | id-ML-DSA-65 | id-RSASA-PSS with id-sha512 | id-sha512 | +| id-HashMLDSA65-RSA3072-PKCS15-SHA512 | <CompSig>.45 | id-ML-DSA-65 | sha512WithRSAEncryption | id-sha512 | +| id-HashMLDSA65-RSA4096-PSS-SHA512 | <CompSig>.46 | id-ML-DSA-65 | id-RSASA-PSS with id-sha512 | id-sha512 | +| id-HashMLDSA65-RSA4096-PKCS15-SHA512 | <CompSig>.47 | id-ML-DSA-65 | sha512WithRSAEncryption | id-sha512 | +| id-HashMLDSA65-ECDSA-P384-SHA512 | <CompSig>.48 | id-ML-DSA-65 | ecdsa-with-SHA512 with secp384r1 | id-sha512 | +| id-HashMLDSA65-ECDSA-brainpoolP256r1-SHA512 | <CompSig>.49 | id-ML-DSA-65 | ecdsa-with-SHA512 with brainpoolP256r1 | id-sha512 | +| id-HashMLDSA65-Ed25519-SHA512 | <CompSig>.50 | id-ML-DSA-65 | id-Ed25519 | id-sha512 | +| id-HashMLDSA87-ECDSA-P384-SHA512 | <CompSig>.51 | id-ML-DSA-87 | ecdsa-with-SHA512 with secp384r1 | id-sha512| +| id-HashMLDSA87-ECDSA-brainpoolP384r1-SHA512 | <CompSig>.52 | id-ML-DSA-87 | ecdsa-with-SHA512 with brainpoolP384r1 | id-sha512 | +| id-HashMLDSA87-Ed448-SHA512 | <CompSig>.53 | id-ML-DSA-87 | id-Ed448 | id-sha512 | +{: #tab-sig-algs title="Hash ML-DSA Composite Signature Algorithms"} + +The table above contains everything needed to implement the listed hash ML-DSA composite signature algorithms. The Pre-Hash algorithm is used as the PH algorithm and the DER Encoded OID value of this Hash is used as HashOID for the Message format in step 2 of HashML-DSA.Sign in section {{sec-comp-sig-gen-prehash}}. This hash value is also used as the pre-hash of the Second algorithm if needed. See the ASN.1 module in section {{sec-asn1-module}} for the explicit definitions of the above Composite signature algorithms. Full specifications for the referenced algorithms can be found in {{appdx_components}}. @@ -860,7 +885,25 @@ As mentioned above, the OID input value is used as a domain separator for the Co | id-MLDSA87-ECDSA-P384-SHA512 |060B6086480186FA6B5008011F| | id-MLDSA87-ECDSA-brainpoolP384r1-SHA512 |060B6086480186FA6B50080120| | id-MLDSA87-Ed448-SHA512 |060B6086480186FA6B50080121| -{: #tab-sig-alg-oids title="Composite Signature Domain Separators"} +{: #tab-sig-alg-oids title="Pure ML-DSA Composite Signature Domain Separators"} + +| Composite Signature AlgorithmID | Domain Separator (in Hex encoding)| +| ----------- | ----------- | +| id-HashMLDSA44-RSA2048-PSS-SHA256 | 060B6086480186FA6B50080128| +| id-HashMLDSA44-RSA2048-PKCS15-SHA256 |060B6086480186FA6B50080129| +| id-HashMLDSA44-Ed25519-SHA512 |060B6086480186FA6B5008012A| +| id-HashMLDSA44-ECDSA-P256-SHA256 |060B6086480186FA6B5008012B| +| id-HashMLDSA65-RSA3072-PSS-SHA512 |060B6086480186FA6B5008012C| +| id-HashMLDSA65-RSA3072-PKCS15-SHA512 |060B6086480186FA6B5008012D| +| id-HashMLDSA65-RSA4096-PSS-SHA512 |060B6086480186FA6B5008012E| +| id-HashMLDSA65-RSA4096-PKCS15-SHA512 |060B6086480186FA6B5008012F| +| id-HashMLDSA65-ECDSA-P384-SHA512 |060B6086480186FA6B50080130| +| id-HashMLDSA65-ECDSA-brainpoolP256r1-SHA512 |060B6086480186FA6B50080131| +| id-HashMLDSA65-Ed25519-SHA512 |060B6086480186FA6B50080132| +| id-HashMLDSA87-ECDSA-P384-SHA512 |060B6086480186FA6B50080133| +| id-HashMLDSA87-ECDSA-brainpoolP384r1-SHA512 |060B6086480186FA6B50080134| +| id-HashMLDSA87-Ed448-SHA512 |060B6086480186FA6B50080135| +{: #tab-sig-alg-oids title="Hash ML-DSA Composite Signature Domain Separators"} ## Notes on id-MLDSA44-RSA2048-PSS-SHA256 @@ -936,41 +979,43 @@ Composite Signature algorithms MAY be employed for one or more recipients in the When a particular Composite Signature OID is supported in CMS, an implementation SHOULD support the corresponding Secure Hash algorithm identifier in {{tab-cms-shas}} that was used as the pre-hash. -The following table lists the MANDATORY HASH algorithms to preserve security and performance characteristics of each composite algorithm. +The following table lists the MANDATORY Hash algorithms to preserve security and performance characteristics of each composite algorithm. | Composite Signature AlgorithmID | Secure Hash | | ----------- | ----------- | -| id-MLDSA44-RSA2048-PSS-SHA256 | SHA256 | -| id-MLDSA44-RSA2048-PKCS15-SHA256 | SHA256 | -| id-MLDSA44-Ed25519-SHA512 | SHA512 | +| id-MLDSA44-RSA2048-PSS-SHA256 | SHA256 | +| id-MLDSA44-RSA2048-PKCS15-SHA256 | SHA256 | +| id-MLDSA44-Ed25519 | SHA512 | | id-MLDSA44-ECDSA-P256-SHA256 | SHA256 | | id-MLDSA65-RSA3072-PSS-SHA512 | SHA512 | -| id-MLDSA65-RSA3072-PKCS15-SHA512 | SHA512 | +| id-MLDSA65-RSA3072-PKCS15-SHA512 | SHA512 | | id-MLDSA65-RSA4096-PSS-SHA512 | SHA512 | | id-MLDSA65-RSA4096-PKCS15-SHA512 | SHA512 | | id-MLDSA65-ECDSA-P384-SHA512 | SHA512 | | id-MLDSA65-ECDSA-brainpoolP256r1-SHA512 | SHA512 | -| id-MLDSA65-Ed25519-SHA512 | SHA512 | +| id-MLDSA65-Ed25519 | SHA512 | | id-MLDSA87-ECDSA-P384-SHA512 | SHA512| | id-MLDSA87-ECDSA-brainpoolP384r1-SHA512 | SHA512 | -| id-MLDSA87-Ed448-SHA512 | SHA512 | +| id-MLDSA87-Ed448 | SHA512 | {: #tab-cms-shas title="Composite Signature SHA Algorithms"} where: * SHA2 instantiations are defined in [FIPS180]. +Note: The Hash ML-DSA Composite identifiers are not included in this list because the message content is already digested before being passed to the Composite-ML-DSA.Sign() function. + ## SignedData Conventions As specified in CMS [RFC5652], the digital signature is produced from the message digest and the signer's private key. The signature is computed over different values depending on whether signed attributes are absent or present. -When signed attributes are absent, the composite signature is computed over the content. When signed attributes are present, a hash is computed over the content using the same hash function that is used in the composite pre-hash, and then a message-digest attribute is constructed to contain the resulting hash value, and then the result of DER encoding the set of signed attributes, which MUST include a content-type attribute and a message-digest attribute, and then the composite signature is computed over the DER-encoded output. In summary: +When signed attributes are absent, the composite signature is computed over the message digest of the content. When signed attributes are present, a hash is computed over the content using the hash function specified in {{tab-cms-shas}}, and then a message-digest attribute is constructed to contain the resulting hash value, and then the result of DER encoding the set of signed attributes, which MUST include a content-type attribute and a message-digest attribute, and then the composite signature is computed over the DER-encoded output. In summary: ~~~ IF (signed attributes are absent) - THEN Composite_Sign(content) + THEN Composite-ML-DSA.Sign(Hash(content)) ELSE message-digest attribute = Hash(content); - Composite_Sign(DER(SignedAttributes)) + Composite-ML-DSA.Sign(DER(SignedAttributes)) ~~~ When using Composite Signatures, the fields in the SignerInfo are used as follows: @@ -1050,9 +1095,9 @@ EDNOTE to IANA: OIDs will need to be replaced in both the ASN.1 module and in {{ - Description: id-MLDSA44-RSA2048-PKCS15-SHA256 - References: This Document -- id-MLDSA44-Ed25519-SHA512 +- id-MLDSA44-Ed25519 - Decimal: IANA Assigned - - Description: id-MLDSA44-Ed25519-SHA512 + - Description: id-MLDSA44-Ed25519 - References: This Document - id-MLDSA44-ECDSA-P256-SHA256 @@ -1090,9 +1135,9 @@ EDNOTE to IANA: OIDs will need to be replaced in both the ASN.1 module and in {{ - Description: id-MLDSA65-ECDSA-brainpoolP256r1-SHA512 - References: This Document -- id-MLDSA65-Ed25519-SHA512 +- id-MLDSA65-Ed25519 - Decimal: IANA Assigned - - Description: id-MLDSA65-Ed25519-SHA512 + - Description: id-MLDSA65-Ed25519 - References: This Document - id-MLDSA87-ECDSA-P384-SHA512 @@ -1105,9 +1150,79 @@ EDNOTE to IANA: OIDs will need to be replaced in both the ASN.1 module and in {{ - Description: id-MLDSA87-ECDSA-brainpoolP384r1-SHA512 - References: This Document -- id-MLDSA87-Ed448-SHA512 +- id-MLDSA87-Ed448 + - Decimal: IANA Assigned + - Description: id-MLDSA87-Ed448 + - References: This Document + +- id-HashMLDSA44-RSA2048-PSS-SHA256 + - Decimal: IANA Assigned + - Description: id-HashMLDSA44-RSA2048-PSS-SHA256 + - References: This Document + +- id-HashMLDSA44-RSA2048-PKCS15-SHA256 + - Decimal: IANA Assigned + - Description: id-HashMLDSA44-RSA2048-PKCS15-SHA256 + - References: This Document + +- id-HashMLDSA44-Ed25519-SHA512 + - Decimal: IANA Assigned + - Description: id-HashMLDSA44-Ed25519-SHA512 + - References: This Document + +- id-HashMLDSA44-ECDSA-P256-SHA256 + - Decimal: IANA Assigned + - Description: id-HashMLDSA44-ECDSA-P256-SHA256 + - References: This Document + +- id-HashMLDSA65-RSA3072-PSS-SHA512 + - Decimal: IANA Assigned + - Description: id-HashMLDSA65-RSA3072-PSS-SHA512 + - References: This Document + +- id-HashMLDSA65-RSA3072-PKCS15-SHA512 + - Decimal: IANA Assigned + - Description: id-HashMLDSA65-RSA3072-PKCS15-SHA512 + - References: This Document + +- id-HashMLDSA65-RSA4096-PSS-SHA512 + - Decimal: IANA Assigned + - Description: id-HashMLDSA65-RSA4096-PSS-SHA512 + - References: This Document + +- id-HashMLDSA65-RSA4096-PKCS15-SHA512 + - Decimal: IANA Assigned + - Description: id-HashMLDSA65-RSA4096-PKCS15-SHA512 + - References: This Document + +- id-HashMLDSA65-ECDSA-P384-SHA512 + - Decimal: IANA Assigned + - Description: id-HashMLDSA65-ECDSA-P384-SHA512 + - References: This Document + +- id-HashMLDSA65-ECDSA-brainpoolP256r1-SHA512 + - Decimal: IANA Assigned + - Description: id-HashMLDSA65-ECDSA-brainpoolP256r1-SHA512 + - References: This Document + +- id-HashMLDSA65-Ed25519-SHA512 + - Decimal: IANA Assigned + - Description: id-HashMLDSA65-Ed25519-SHA512 + - References: This Document + +- id-HashMLDSA87-ECDSA-P384-SHA512 + - Decimal: IANA Assigned + - Description: id-HashMLDSA87-ECDSA-P384-SHA512 + - References: This Document + +- id-HashMLDSA87-ECDSA-brainpoolP384r1-SHA512 + - Decimal: IANA Assigned + - Description: id-HashMLDSA87-ECDSA-brainpoolP384r1-SHA512 + - References: This Document + +- id-HashMLDSA87-Ed448-SHA512 - Decimal: IANA Assigned - - Description: id-MLDSA87-Ed448-SHA512 + - Description: id-HashMLDSA87-Ed448-SHA512 - References: This Document @@ -1170,9 +1285,9 @@ This section provides references to the full specification of the algorithms use | Component Signature Algorithm ID | OID | Specification | | ----------- | ----------- | ----------- | -| id-ML-DSA-44 | 1.3.6.1.4.1.2.267.12.4.4 | _ML-DSA_: {{I-D.ietf-lamps-dilithium-certificates}} and [FIPS.204-ipd] | -| id-ML-DSA-65 | 1.3.6.1.4.1.2.267.12.6.5 | _ML-DSA_: {{I-D.ietf-lamps-dilithium-certificates}} and [FIPS.204-ipd] | -| id-ML-DSA-87 | 1.3.6.1.4.1.2.267.12.8.7 | _ML-DSA_: {{I-D.ietf-lamps-dilithium-certificates}} and [FIPS.204-ipd] | +| id-ML-DSA-44 | 2.16.840.1.101.3.4.3.17 | _ML-DSA_: [FIPS.204] | +| id-ML-DSA-65 | 2.16.840.1.101.3.4.3.18 | _ML-DSA_: [FIPS.204] | +| id-ML-DSA-87 | 2.16.840.1.101.3.4.3.19 | _ML-DSA_: [FIPS.204] | | id-Ed25519 | iso(1) identified-organization(3) thawte(101) 112 | _Ed25519 / Ed448_: [RFC8410] | | id-Ed448 | iso(1) identified-organization(3) thawte(101) id-Ed448(113) | _Ed25519 / Ed448_: [RFC8410] | | ecdsa-with-SHA256 | iso(1) member-body(2) us(840) ansi-X9-62(10045) signatures(4) ecdsa-with-SHA2(3) 2 | _ECDSA_: [RFC5758] | @@ -1262,9 +1377,9 @@ François Rousseau, Falko Strenzke, Felipe Ventura (Entrust), Alexander Ralien (Siemens), -José Ignacio Escribano and -Jan Oupický -陳志華 (Abel C. H. Chen, Chunghwa Telecom) +José Ignacio Escribano, +Jan Oupický, +陳志華 (Abel C. H. Chen, Chunghwa Telecom) and 林邦曄 (Austin Lin, Chunghwa Telecom) We are grateful to all, including any contributors who may have been inadvertently omitted from this list. From 1aa49c5ee0cd1ebb5fe579522d656a18055ffbdd Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:25:27 -0400 Subject: [PATCH 11/25] Update draft-ietf-lamps-pq-composite-sigs.md Added support for the ML-DSA context String, and use the Composite Domain as the context for the underlying ML-DSA component algorithm. --- draft-ietf-lamps-pq-composite-sigs.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index cbd9f7f..c818c1b 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -160,6 +160,7 @@ This document introduces a set of signature schemes that use pairs of cryptograp * Renamed the module from Composite-Signatures-2023 -> Composite-MLDSA-2024 * Simplified the ASN.1 module to make it more compiler-friendly (thanks Carl!) -- should not affect wire encodings. * Added Pre-Hash and Pure modes and changed the Message format to align with FIPS-204. This breaks backwards compatibility will all previous versions + * Added support for the ML-DSA context String, and use the Composite Domain as the context for the underlying ML-DSA component algorithm. * Updated the OID table for new Pre-Hash OIDs and added them to the IANA section * Updated Use in CMS section to reflect content is hashed and pure Composite ML-DSA should be used. * Other typos @@ -360,10 +361,10 @@ Signature Generation Process: 4. Generate the 2 component signatures independently, by calculating the signature over M' according to their algorithm specifications that might involve the use of the hash-n-sign paradigm. - s1 := ML-DSA.Sign( sk1, M', Context="" ) + s1 := ML-DSA.Sign( sk1, M', ctx=Domain ) s2 := Trad.Sign( sk2, M' ) - Since Composite ML-DSA incorporates the domain separator, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. + The Domain is used as the context separator for the ML-DSA.Sign component. If either ML-DSA.Sign() or Trad.Sign() return an error, then this process must return an error. @@ -466,7 +467,7 @@ A composite signature's value MUST include two signature components and MUST be The following process is used to generate composite signature values. -### HASHComposite-ML-DSA-Sign signature mode +### HashComposite-ML-DSA-Sign signature mode This mode mirrors `HashML-DSA.Sign(sk, M, ctx, PH)` defined in Section 5.4.1 of [FIPS.204]. @@ -519,10 +520,10 @@ Signature Generation Process: 4. Generate the 2 component signatures independently, by calculating the signature over M' according to their algorithm specifications that might involve the use of the hash-n-sign paradigm. - s1 := ML-DSA.Sign( sk1, M', ctx ="" ) + s1 := ML-DSA.Sign( sk1, M', ctx=Domain ) s2 := Trad.Sign( sk2, M' ) - Since HashComposite ML-DSA incorporates the domain separator, which serves theh same purpose as the ML-DSA context string, the ML-DSA context string is the empty string. + The Domain is used as the context separator for the ML-DSA.Sign component. 5. Encode each component signature S1 and S2 into a BIT STRING according to its algorithm specification. From 1f6e098c3322264a9ab3543b05fb7b257629147a Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:29:46 -0400 Subject: [PATCH 12/25] Update draft-ietf-lamps-pq-composite-sigs.md Added the ML-DSA Sign context in the verification methods for the pure and pre-hash modes --- draft-ietf-lamps-pq-composite-sigs.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index c818c1b..c197d62 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -442,7 +442,7 @@ Signature Verification Procedure: algorithm specification. If any fail, then the entire signature validation fails. - if not ML-DSA.Verify( pk1, M', s1, ctx="") then + if not ML-DSA.Verify( pk1, M', s1, ctx=Domain) then output "Invalid signature" if not Trad.Verify( pk2, M', s2) then @@ -608,7 +608,7 @@ Signature Verification Procedure:: algorithm specification. If any fail, then the entire signature validation fails. - if not ML-DSA.Verify( pk1, M', s1 ) then + if not ML-DSA.Verify( pk1, M', s1, ctx=Domain ) then output "Invalid signature" if not Trad.Verify( pk2, M', s2 ) then @@ -1004,7 +1004,7 @@ where: * SHA2 instantiations are defined in [FIPS180]. -Note: The Hash ML-DSA Composite identifiers are not included in this list because the message content is already digested before being passed to the Composite-ML-DSA.Sign() function. +Note: The Hash ML-DSA Composite identifiers are not included in this list because the message content is already digested before being passed to the Composite-ML-DSA.Sign() function. ## SignedData Conventions From 06a24e373646985d98e0586b6eaf08544e596ae8 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Thu, 10 Oct 2024 15:36:21 -0400 Subject: [PATCH 13/25] Update draft-ietf-lamps-pq-composite-sigs.md Fixed naming of new pre-hash OID tables so it doesn't collide --- draft-ietf-lamps-pq-composite-sigs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index c197d62..034ce03 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -860,7 +860,7 @@ HashML-DSA Signature public key types: | id-HashMLDSA87-ECDSA-P384-SHA512 | <CompSig>.51 | id-ML-DSA-87 | ecdsa-with-SHA512 with secp384r1 | id-sha512| | id-HashMLDSA87-ECDSA-brainpoolP384r1-SHA512 | <CompSig>.52 | id-ML-DSA-87 | ecdsa-with-SHA512 with brainpoolP384r1 | id-sha512 | | id-HashMLDSA87-Ed448-SHA512 | <CompSig>.53 | id-ML-DSA-87 | id-Ed448 | id-sha512 | -{: #tab-sig-algs title="Hash ML-DSA Composite Signature Algorithms"} +{: #tab-hash-sig-algs title="Hash ML-DSA Composite Signature Algorithms"} The table above contains everything needed to implement the listed hash ML-DSA composite signature algorithms. The Pre-Hash algorithm is used as the PH algorithm and the DER Encoded OID value of this Hash is used as HashOID for the Message format in step 2 of HashML-DSA.Sign in section {{sec-comp-sig-gen-prehash}}. This hash value is also used as the pre-hash of the Second algorithm if needed. See the ASN.1 module in section {{sec-asn1-module}} for the explicit definitions of the above Composite signature algorithms. @@ -904,7 +904,7 @@ As mentioned above, the OID input value is used as a domain separator for the Co | id-HashMLDSA87-ECDSA-P384-SHA512 |060B6086480186FA6B50080133| | id-HashMLDSA87-ECDSA-brainpoolP384r1-SHA512 |060B6086480186FA6B50080134| | id-HashMLDSA87-Ed448-SHA512 |060B6086480186FA6B50080135| -{: #tab-sig-alg-oids title="Hash ML-DSA Composite Signature Domain Separators"} +{: #tab-hash-sig-alg-oids title="Hash ML-DSA Composite Signature Domain Separators"} ## Notes on id-MLDSA44-RSA2048-PSS-SHA256 From b518e00837bc906c8b6086f57e66e5c0bfb42efa Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:15:27 -0400 Subject: [PATCH 14/25] Update draft-ietf-lamps-pq-composite-sigs.md - Fixed up language around use of PUBLIC-KEYS in the composite signature definition --- draft-ietf-lamps-pq-composite-sigs.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 034ce03..ae2ce44 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -779,14 +779,14 @@ sa-CompositeSignature{OBJECT IDENTIFIER:id, ~~~ The following is an explanation how SIGNATURE-ALGORITHM elements are used -to create Composite Signatures: +to define Composite Signatures: | SIGNATURE-ALGORITHM element | Definition | | --------- | ---------- | | IDENTIFIER | The Object ID used to identify the composite Signature Algorithm | | VALUE | The Sequence of BIT STRINGS for each component signature value | | PARAMS | Parameters are absent | -| PUBLIC-KEYS | The composite key required to produce the composite signature | +| PUBLIC-KEYS | The composite public key type associated with the composite signature | ## CompositeSignatureValue {#sec-compositeSignatureValue} From b4ab950e682867388be1e4f101a7ef97352d9b40 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 16 Oct 2024 10:19:45 -0400 Subject: [PATCH 15/25] Update draft-ietf-lamps-pq-composite-sigs.md Co-authored-by: Mike Ounsworth --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index ae2ce44..4bc74ed 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -311,7 +311,7 @@ The key generation functions MUST be executed for both algorithms. Compliant par Composite schemes' signatures provide important properties for multi-key environments such as non-separability and key-binding. For more information on the additional security properties and their applicability to multi-key or hybrid environments, please refer to {{I-D.hale-pquip-hybrid-signature-spectrums}} and the use of labels as defined in {{Bindel2017}} -A composite signature's value MUST include two signature components and MUST be in the same order as the components from the corresponding signing key. +A composite signature's value MUST include two signature components and MUST be in the same order as the components from the corresponding verification public key. ### Composite-ML-DSA.Sign From e56cb7f978326566cb51aee9495a6a33bd6a33bd Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:52:14 -0400 Subject: [PATCH 16/25] Update draft-ietf-lamps-pq-composite-sigs.md Committing suggested change Co-authored-by: Mike Ounsworth --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 4bc74ed..4043628 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -350,7 +350,7 @@ Signature Generation Process: 1. If |ctx| > 255: return error - 2. Compute the Message format M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of ctx, the value ctx and the M + 2. Compute the Message M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of ctx, the value ctx and the original message M M' := Domain || len(ctx) || ctx || M From bd84ec12ea990ef97767d99da718e694cc3da77b Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:54:25 -0400 Subject: [PATCH 17/25] Update draft-ietf-lamps-pq-composite-sigs.md Agree with text... committing Co-authored-by: Mike Ounsworth --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 4043628..783751d 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -383,7 +383,7 @@ It is possible to construct `CompositePrivateKey`(s) to generate signatures from ### Composite-ML-DSA.Verify {#sec-comp-sig-verify} -This mode mirrors `ML-DSA.Sign(sk, M, ctx)` defined in Section 5.3 of [FIPS.204]. Verification of a composite signature involves reconstructing the `M'` message by concatenating the composite domain separator "Domain" {{sec-oid-concat}} with the length of the context string `ctx` in bytes, the context string `ctx`, and finally the un-hashed message `M` . +This mode mirrors `ML-DSA.Verify(pk, M, signature, ctx)` defined in Section 5.3 of [FIPS.204]. Verification of a composite signature involves reconstructing the `M'` message by concatenating the composite domain separator "Domain" {{sec-oid-concat}} with the length of the context string `ctx` in bytes, the context string `ctx`, and finally the original message `M` . Compliant applications MUST output "Valid signature" (true) if and only if all component signatures were successfully validated, and "Invalid signature" (false) otherwise. From 9be825c58276a875521683ccdf8341d8c401e4e7 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:16:22 -0400 Subject: [PATCH 18/25] Update draft-ietf-lamps-pq-composite-sigs.md Agree with None Co-authored-by: Mike Ounsworth --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 783751d..2f753c5 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -826,7 +826,7 @@ Pure Signature public key types: | ----------- | ----------- | ----------- | ----------- | ----------- | | id-MLDSA44-RSA2048-PSS-SHA256 | <CompSig>.21 | id-ML-DSA-44 | id-RSASA-PSS with id-sha256 | id-sha256 | | id-MLDSA44-RSA2048-PKCS15-SHA256 | <CompSig>.22 | id-ML-DSA-44 | sha256WithRSAEncryption | id-sha256 | -| id-MLDSA44-Ed25519 | <CompSig>.23 | id-ML-DSA-44 | id-Ed25519 | Not Needed | +| id-MLDSA44-Ed25519 | <CompSig>.23 | id-ML-DSA-44 | id-Ed25519 | None | | id-MLDSA44-ECDSA-P256-SHA256 | <CompSig>.24 | id-ML-DSA-44 | ecdsa-with-SHA256 with secp256r1 | id-sha256 | | id-MLDSA65-RSA3072-PSS-SHA512 | <CompSig>.26 | id-ML-DSA-65 | id-RSASA-PSS with id-sha512 | id-sha512 | | id-MLDSA65-RSA3072-PKCS15-SHA512 | <CompSig>.27 | id-ML-DSA-65 | sha512WithRSAEncryption | id-sha512 | From c775ec46cf2a1813ebb56310fe208ca111b04988 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:16:35 -0400 Subject: [PATCH 19/25] Update draft-ietf-lamps-pq-composite-sigs.md Agree. Co-authored-by: Mike Ounsworth --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 2f753c5..174e571 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -834,7 +834,7 @@ Pure Signature public key types: | id-MLDSA65-RSA4096-PKCS15-SHA512 | <CompSig>.35 | id-ML-DSA-65 | sha512WithRSAEncryption | id-sha512 | | id-MLDSA65-ECDSA-P384-SHA512 | <CompSig>.28 | id-ML-DSA-65 | ecdsa-with-SHA512 with secp384r1 | id-sha512 | | id-MLDSA65-ECDSA-brainpoolP256r1-SHA512 | <CompSig>.29 | id-ML-DSA-65 | ecdsa-with-SHA512 with brainpoolP256r1 | id-sha512 | -| id-MLDSA65-Ed25519 | <CompSig>.30 | id-ML-DSA-65 | id-Ed25519 | Not Needed | +| id-MLDSA65-Ed25519 | <CompSig>.30 | id-ML-DSA-65 | id-Ed25519 | None | | id-MLDSA87-ECDSA-P384-SHA512 | <CompSig>.31 | id-ML-DSA-87 | ecdsa-with-SHA512 with secp384r1 | id-sha512| | id-MLDSA87-ECDSA-brainpoolP384r1-SHA512 | <CompSig>.32 | id-ML-DSA-87 | ecdsa-with-SHA512 with brainpoolP384r1 | id-sha512 | | id-MLDSA87-Ed448 | <CompSig>.33 | id-ML-DSA-87 | id-Ed448 | Not Needed | From f34ef8d2f3ca0660d151bd9eb2d00b68d54411a7 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:16:47 -0400 Subject: [PATCH 20/25] Update draft-ietf-lamps-pq-composite-sigs.md Agree Co-authored-by: Mike Ounsworth --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 174e571..de207f2 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -820,7 +820,7 @@ replace <CompSig> with the String "2.16.840.1.114027.80.8.1" Therefore <CompSig>.21 is equal to 2.16.840.1.114027.80.8.1.21 -Pure Signature public key types: +Pure Composite-ML-DSA Signature public key types: | Composite Signature AlgorithmID | OID | First AlgorithmID | Second AlgorithmID | Second Alg PreHash | | ----------- | ----------- | ----------- | ----------- | ----------- | From 12900b41cf1b5df7723d079439d387ee754b4bc8 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:22:55 -0400 Subject: [PATCH 21/25] Update draft-ietf-lamps-pq-composite-sigs.md Agreed Co-authored-by: Mike Ounsworth --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index de207f2..1ecd2de 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -837,7 +837,7 @@ Pure Composite-ML-DSA Signature public key types: | id-MLDSA65-Ed25519 | <CompSig>.30 | id-ML-DSA-65 | id-Ed25519 | None | | id-MLDSA87-ECDSA-P384-SHA512 | <CompSig>.31 | id-ML-DSA-87 | ecdsa-with-SHA512 with secp384r1 | id-sha512| | id-MLDSA87-ECDSA-brainpoolP384r1-SHA512 | <CompSig>.32 | id-ML-DSA-87 | ecdsa-with-SHA512 with brainpoolP384r1 | id-sha512 | -| id-MLDSA87-Ed448 | <CompSig>.33 | id-ML-DSA-87 | id-Ed448 | Not Needed | +| id-MLDSA87-Ed448 | <CompSig>.33 | id-ML-DSA-87 | id-Ed448 | None | {: #tab-sig-algs title="Pure ML-DSA Composite Signature Algorithms"} The table above contains everything needed to implement the listed pure ML-DSA composite signature algorithms. The hash value indicated is used only by the Second algorithm if needed. See the ASN.1 module in section {{sec-asn1-module}} for the explicit definitions of the above Composite signature algorithms. From f4de1945421e07de316b4ddb9c34e49e619a5886 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:23:07 -0400 Subject: [PATCH 22/25] Update draft-ietf-lamps-pq-composite-sigs.md Agreed Co-authored-by: Mike Ounsworth --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 1ecd2de..9dc00e7 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -842,7 +842,7 @@ Pure Composite-ML-DSA Signature public key types: The table above contains everything needed to implement the listed pure ML-DSA composite signature algorithms. The hash value indicated is used only by the Second algorithm if needed. See the ASN.1 module in section {{sec-asn1-module}} for the explicit definitions of the above Composite signature algorithms. -HashML-DSA Signature public key types: +HashComposite-ML-DSA Signature public key types: | Composite Signature AlgorithmID | OID | First AlgorithmID | Second AlgorithmID | Pre-Hash | | ----------- | ----------- | ----------- | ----------- | ----------- | From 86d05eac7aa3f76342646e177fc2d9f95facaa0b Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Wed, 16 Oct 2024 15:36:08 -0400 Subject: [PATCH 23/25] Update draft-ietf-lamps-pq-composite-sigs.md Fixed typos and ordering of context check as suggested by Mike and the authors group --- draft-ietf-lamps-pq-composite-sigs.md | 37 ++++++++++++++------------- 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 9dc00e7..cd21f23 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -354,7 +354,7 @@ Signature Generation Process: M' := Domain || len(ctx) || ctx || M - 3. Separate the private key into componet keys. Note, the exact storage format for composite private keys may be as described in this document, or may be implementation-specific. + 3. Separate the private key into component keys. Note, the exact storage format for composite private keys may be as described in this document, or may be implementation-specific. (sk1, sk2) := Unmarshal(sk) @@ -421,18 +421,19 @@ Output: (false) otherwise. Signature Verification Procedure: - 1. Separate the keys and signatures + + 1. If |ctx| > 255 + return error + + 2. Separate the keys and signatures (pk1, pk2) := pk (s1, s2) := signature - If Error during Desequencing, or the sequences have - different numbers of elements, or any of the public keys - P1 or P2 and the algorithm identifiers A1 or A2 are - composite then output "Invalid signature" and stop. - - 2. If |ctx| > 255 - return error + If Error during Desequencing, or if any of the component + keys or signature values are not of the correct key type or + length for the given component algorithm then output + "Invalid signature" and stop. 3. Format the Message as follows: @@ -513,7 +514,7 @@ Signature Generation Process: M' := Domain || len(ctx) || ctx || HashOID || PH(M) - 3. Separate the private key into componet keys. Note, the exact storage format for composite private keys may be as described in this document, or may be implementation-specific. + 3. Separate the private key into component keys. Note, the exact storage format for composite private keys may be as described in this document, or may be implementation-specific. (sk1, sk2) := Unmarshal(sk) @@ -587,18 +588,18 @@ Output: Signature Verification Procedure:: - 1. Separate the keys and signatures + 1. If |ctx| > 255 + return error + + 2. Separate the keys and signatures (pk1, pk2) := pk (s1, s2) := signature - If Error during Desequencing, or the sequences have - different numbers of elements, or any of the public keys - P1 or P2 and the algorithm identifiers A1 or A2 are - composite then output "Invalid signature" and stop. - - 2. If |ctx| > 255 - return error + If Error during Desequencing, or if any of the component + keys or signature values are not of the correct key type or + length for the given component algorithm then output + "Invalid signature" and stop. 3. Compute a Hash of the Message From 8e5d33e0e001e6bb32abd630736cac9e3fb1d958 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Thu, 17 Oct 2024 14:58:20 -0400 Subject: [PATCH 24/25] Update draft-ietf-lamps-pq-composite-sigs.md Accepted Co-authored-by: Mike Ounsworth --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index cd21f23..0a49deb 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -435,7 +435,7 @@ Signature Verification Procedure: length for the given component algorithm then output "Invalid signature" and stop. - 3. Format the Message as follows: + 3. Compute the Message M' by concatenating the Domain identifier (i.e., the DER encoding of the Composite signature algorithm identifier) with the length of ctx, the value ctx and the original message M M' = Domain || len(ctx) || ctx || M From 43de3e5687ebb887602e2af69474f322dec77404 Mon Sep 17 00:00:00 2001 From: John Gray <55205977+johngray-dev@users.noreply.github.com> Date: Thu, 17 Oct 2024 15:00:17 -0400 Subject: [PATCH 25/25] Update draft-ietf-lamps-pq-composite-sigs.md Accept Co-authored-by: Mike Ounsworth --- draft-ietf-lamps-pq-composite-sigs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/draft-ietf-lamps-pq-composite-sigs.md b/draft-ietf-lamps-pq-composite-sigs.md index 0a49deb..7a75ee2 100644 --- a/draft-ietf-lamps-pq-composite-sigs.md +++ b/draft-ietf-lamps-pq-composite-sigs.md @@ -812,7 +812,7 @@ This section is not intended to be exhaustive and other authors may define other Some use-cases desire the flexibility for clients to use any combination of supported algorithms, while others desire the rigidity of explicitly-specified combinations of algorithms. -The following tables summarizes the details for each explicit composite signature algorithms: +The following tables summarize the details for each explicit composite signature algorithms: The OID referenced are TBD for prototyping only, and the following prefix is used for each: