@@ -270,7 +270,7 @@ int composite_signature_domain_separation(struct lc_hash_ctx *hash_ctx,
270270 /*
271271 * M' = Prefix || Label || len(ctx) || ctx || PH (M)
272272 *
273- * where PH(M) is to be set by caller
273+ * where PH(M) is to be set by caller of this function
274274 *
275275 * See for details: https://lamps-wg.github.io/draft-composite-sigs/draft-ietf-lamps-pq-composite-sigs.html
276276 */
@@ -330,16 +330,56 @@ int signature_domain_separation(struct lc_hash_ctx *hash_ctx,
330330
331331 /* If Composite ML-DSA is requested, use domain as userctx */
332332 if (composite ) {
333- /* Add the composite signature label as context */
333+ const uint8_t * label ;
334+ size_t labellen ;
335+
336+ /*
337+ * The composite signature defines the following for invoking
338+ * ML-DSA:
339+ *
340+ * mldsaSig = ML-DSA.Sign( mldsaSK, M', mldsa_ctx=Label )
341+ *
342+ * where
343+ *
344+ * M' := Prefix || Label || len(ctx) || ctx || PH( M )
345+ *
346+ * Combining that with FIPS 204 algorithm 2 step 10, we get
347+ *
348+ * M' <- BytesToBits(IntegerToBytes(0, 1) || IntegerToBytes(|mldsa_ctx|, 1) || mldsa_ctx || Prefix || Label || len(ctx) || ctx || PH( M )
349+ *
350+ * with a final replacement, this is turned into
351+ *
352+ * M' <- BytesToBits(IntegerToBytes(0, 1) || IntegerToBytes(|Label|, 1) || Label || Prefix || Label || len(ctx) || ctx || PH( M )
353+ */
354+
355+ CKINT (composite_signature_set_label (& label , & labellen ,
356+ nist_category ));
357+
358+ /*
359+ * Set the ML-DSA domain separation:
360+ * BytesToBits(IntegerToBytes(0, 1) || IntegerToBytes(|Label|, 1) || Label
361+ */
362+ CKINT (standalone_signature_domain_separation (
363+ hash_ctx , 0 , label , labellen , mlen , nist_category ));
364+
365+ /*
366+ * Set the Composite domain separation:
367+ * Prefix || Label || len(ctx) || ctx
368+ */
334369 CKINT (composite_signature_domain_separation (
335370 hash_ctx , userctx , userctxlen , nist_category ));
336371 } else {
372+ /*
373+ * Set the ML-DSA domain separation:
374+ * BytesToBits(IntegerToBytes(0, 1) || IntegerToBytes(|ctx|, 1) || ctx
375+ */
337376 CKINT (standalone_signature_domain_separation (
338377 hash_ctx , signature_prehash_type , userctx , userctxlen ,
339378 mlen , nist_category ));
340379 }
341380
342381out :
382+ /* Set the final message, or PH(M) as provided by caller */
343383 lc_hash_update (hash_ctx , m , mlen );
344384 return ret ;
345385}
0 commit comments