@@ -315,6 +315,8 @@ static OQS_STATUS sig_kg_vector(const char *method_name,
315315 OQS_SIG * sig = NULL ;
316316 uint8_t * public_key = NULL ;
317317 uint8_t * secret_key = NULL ;
318+ uint8_t * derand_public_key = NULL ;
319+ uint8_t * derand_secret_key = NULL ;
318320 OQS_STATUS rc , ret = OQS_ERROR ;
319321
320322 void (* randombytes_init )(const uint8_t * , const uint8_t * ) = NULL ;
@@ -370,6 +372,34 @@ static OQS_STATUS sig_kg_vector(const char *method_name,
370372 } else {
371373 ret = OQS_ERROR ;
372374 fprintf (stderr , "[vectors_sig] %s ERROR: public key or private key doesn't match!\n" , method_name );
375+ goto cleanup ;
376+ }
377+
378+ /* For schemes exposing derandomized keygen (ML-DSA), the ACVP keyGen seed is
379+ * exactly FIPS-204's xi. Feed it straight to OQS_SIG_keypair_derand and require
380+ * the result to match the same known-answer pk/sk, proving the public API really
381+ * computes ML-DSA.KeyGen_internal(xi). */
382+ if (sig -> keypair_derand != NULL ) {
383+ if (sig -> length_keypair_seed != MLDSA_RNDBYTES ) {
384+ fprintf (stderr , "[vectors_sig] %s ERROR: unexpected length_keypair_seed %zu for derand keyGen vector!\n" , method_name , sig -> length_keypair_seed );
385+ goto err ;
386+ }
387+ derand_public_key = OQS_MEM_malloc (sig -> length_public_key );
388+ derand_secret_key = OQS_MEM_malloc (sig -> length_secret_key );
389+ if ((derand_public_key == NULL ) || (derand_secret_key == NULL )) {
390+ fprintf (stderr , "[vectors_sig] %s ERROR: OQS_MEM_malloc failed!\n" , method_name );
391+ goto err ;
392+ }
393+ rc = OQS_SIG_keypair_derand (sig , derand_public_key , derand_secret_key , prng_output_stream );
394+ if (rc ) {
395+ fprintf (stderr , "[vectors_sig] %s ERROR: OQS_SIG_keypair_derand failed!\n" , method_name );
396+ goto err ;
397+ }
398+ if (memcmp (derand_public_key , kg_pk , sig -> length_public_key ) || memcmp (derand_secret_key , kg_sk , sig -> length_secret_key )) {
399+ ret = OQS_ERROR ;
400+ fprintf (stderr , "[vectors_sig] %s ERROR: derandomized public key or private key doesn't match!\n" , method_name );
401+ goto cleanup ;
402+ }
373403 }
374404 goto cleanup ;
375405
@@ -383,11 +413,13 @@ static OQS_STATUS sig_kg_vector(const char *method_name,
383413cleanup :
384414 if (sig != NULL ) {
385415 OQS_MEM_secure_free (secret_key , sig -> length_secret_key );
416+ OQS_MEM_secure_free (derand_secret_key , sig -> length_secret_key );
386417 }
387418 if (randombytes_free != NULL ) {
388419 randombytes_free ();
389420 }
390421 OQS_MEM_insecure_free (public_key );
422+ OQS_MEM_insecure_free (derand_public_key );
391423 OQS_SIG_free (sig );
392424 return ret ;
393425}
0 commit comments