ML-KEM: remove private key parsing from public interfaces. It looks like seeds will be the official private key format for ML-DSA and ML-KEM. Thus parsing the weird private key format will only be needed for processing NIST's test vectors. Change-Id: Id6273214ba98b73aaf96640ec25ea289801b9bd7 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/73848 Reviewed-by: Bob Beck <bbe@google.com> Commit-Queue: Adam Langley <agl@google.com>
diff --git a/crypto/fipsmodule/bcm_interface.h b/crypto/fipsmodule/bcm_interface.h index 25b0a32..840afe9 100644 --- a/crypto/fipsmodule/bcm_interface.h +++ b/crypto/fipsmodule/bcm_interface.h
@@ -521,6 +521,11 @@ OPENSSL_EXPORT bcm_status BCM_mlkem768_parse_public_key( struct BCM_mlkem768_public_key *out_public_key, CBS *in); +// BCM_mlkem768_parse_private_key parses a private key, in NIST's format for +// private keys, from |in| and writes the result to |out_private_key|. It +// returns one on success or zero on parse error or if there are trailing bytes +// in |in|. This format is verbose and should be avoided. Private keys should be +// stored as seeds and parsed using |BCM_mlkem768_private_key_from_seed|. OPENSSL_EXPORT bcm_status BCM_mlkem768_parse_private_key( struct BCM_mlkem768_private_key *out_private_key, CBS *in); @@ -595,6 +600,11 @@ OPENSSL_EXPORT bcm_status BCM_mlkem1024_parse_public_key( struct BCM_mlkem1024_public_key *out_public_key, CBS *in); +// BCM_mlkem1024_parse_private_key parses a private key, in NIST's format for +// private keys, from |in| and writes the result to |out_private_key|. It +// returns one on success or zero on parse error or if there are trailing bytes +// in |in|. This format is verbose and should be avoided. Private keys should be +// stored as seeds and parsed using |BCM_mlkem1024_private_key_from_seed|. OPENSSL_EXPORT bcm_status BCM_mlkem1024_parse_private_key( struct BCM_mlkem1024_private_key *out_private_key, CBS *in);
diff --git a/crypto/mlkem/mlkem.cc b/crypto/mlkem/mlkem.cc index 21102c2..56a8623 100644 --- a/crypto/mlkem/mlkem.cc +++ b/crypto/mlkem/mlkem.cc
@@ -30,11 +30,8 @@ static_assert(MLKEM_SEED_BYTES == BCM_MLKEM_SEED_BYTES, ""); static_assert(MLKEM768_CIPHERTEXT_BYTES == BCM_MLKEM768_CIPHERTEXT_BYTES, ""); static_assert(MLKEM_SHARED_SECRET_BYTES == BCM_MLKEM_SHARED_SECRET_BYTES, ""); -static_assert(MLKEM768_PRIVATE_KEY_BYTES == BCM_MLKEM768_PRIVATE_KEY_BYTES, ""); static_assert(MLKEM1024_PUBLIC_KEY_BYTES == BCM_MLKEM1024_PUBLIC_KEY_BYTES, ""); static_assert(MLKEM1024_CIPHERTEXT_BYTES == BCM_MLKEM1024_CIPHERTEXT_BYTES, ""); -static_assert(MLKEM1024_PRIVATE_KEY_BYTES == BCM_MLKEM1024_PRIVATE_KEY_BYTES, - ""); void MLKEM768_generate_key( uint8_t out_encoded_public_key[MLKEM768_PUBLIC_KEY_BYTES], @@ -88,11 +85,6 @@ reinterpret_cast<BCM_mlkem768_public_key *>(out_public_key), in)); } -int MLKEM768_parse_private_key(struct MLKEM768_private_key *out_private_key, - CBS *in) { - return bcm_success(BCM_mlkem768_parse_private_key( - reinterpret_cast<BCM_mlkem768_private_key *>(out_private_key), in)); -} static_assert(sizeof(BCM_mlkem1024_private_key) <= sizeof(MLKEM1024_private_key), @@ -158,9 +150,3 @@ return bcm_success(BCM_mlkem1024_parse_public_key( reinterpret_cast<BCM_mlkem1024_public_key *>(out_public_key), in)); } - -int MLKEM1024_parse_private_key(struct MLKEM1024_private_key *out_private_key, - CBS *in) { - return bcm_success(BCM_mlkem1024_parse_private_key( - reinterpret_cast<BCM_mlkem1024_private_key *>(out_private_key), in)); -}
diff --git a/crypto/mlkem/mlkem_test.cc b/crypto/mlkem/mlkem_test.cc index 51e9e47..cd25e9a 100644 --- a/crypto/mlkem/mlkem_test.cc +++ b/crypto/mlkem/mlkem_test.cc
@@ -104,6 +104,18 @@ reinterpret_cast<const BCM_mlkem1024_public_key *>(public_key), entropy); } +int wrapper_768_parse_private_key(struct MLKEM768_private_key *out_private_key, + CBS *in) { + return bcm_success(BCM_mlkem768_parse_private_key( + reinterpret_cast<BCM_mlkem768_private_key *>(out_private_key), in)); +} + +int wrapper_1024_parse_private_key( + struct MLKEM1024_private_key *out_private_key, CBS *in) { + return bcm_success(BCM_mlkem1024_parse_private_key( + reinterpret_cast<BCM_mlkem1024_private_key *>(out_private_key), in)); +} + template <typename PUBLIC_KEY, size_t PUBLIC_KEY_BYTES, typename PRIVATE_KEY, size_t PRIVATE_KEY_BYTES, void (*GENERATE)(uint8_t *, uint8_t *, PRIVATE_KEY *), @@ -192,20 +204,20 @@ TEST(MLKEMTest, Basic768) { BasicTest<MLKEM768_public_key, MLKEM768_PUBLIC_KEY_BYTES, - MLKEM768_private_key, MLKEM768_PRIVATE_KEY_BYTES, + MLKEM768_private_key, BCM_MLKEM768_PRIVATE_KEY_BYTES, MLKEM768_generate_key, MLKEM768_private_key_from_seed, MLKEM768_public_from_private, MLKEM768_parse_public_key, - MLKEM768_marshal_public_key, MLKEM768_parse_private_key, + MLKEM768_marshal_public_key, wrapper_768_parse_private_key, wrapper_768_marshal_private_key, MLKEM768_CIPHERTEXT_BYTES, MLKEM768_encap, MLKEM768_decap>(); } TEST(MLKEMTest, Basic1024) { BasicTest<MLKEM1024_public_key, MLKEM1024_PUBLIC_KEY_BYTES, - MLKEM1024_private_key, MLKEM1024_PRIVATE_KEY_BYTES, + MLKEM1024_private_key, BCM_MLKEM1024_PRIVATE_KEY_BYTES, MLKEM1024_generate_key, MLKEM1024_private_key_from_seed, MLKEM1024_public_from_private, MLKEM1024_parse_public_key, - MLKEM1024_marshal_public_key, MLKEM1024_parse_private_key, + MLKEM1024_marshal_public_key, wrapper_1024_parse_private_key, wrapper_1024_marshal_private_key, MLKEM1024_CIPHERTEXT_BYTES, MLKEM1024_encap, MLKEM1024_decap>(); } @@ -376,16 +388,16 @@ TEST(MLKEMTest, Decap768TestVectors) { FileTestGTest( "crypto/mlkem/mlkem768_decap_tests.txt", - MLKEMDecapFileTest<MLKEM768_private_key, MLKEM768_PRIVATE_KEY_BYTES, - MLKEM768_parse_private_key, MLKEM768_CIPHERTEXT_BYTES, - MLKEM768_decap>); + MLKEMDecapFileTest<MLKEM768_private_key, BCM_MLKEM768_PRIVATE_KEY_BYTES, + wrapper_768_parse_private_key, + MLKEM768_CIPHERTEXT_BYTES, MLKEM768_decap>); } TEST(MLKEMTest, Decap1024TestVectors) { FileTestGTest( "crypto/mlkem/mlkem1024_decap_tests.txt", - MLKEMDecapFileTest<MLKEM1024_private_key, MLKEM1024_PRIVATE_KEY_BYTES, - MLKEM1024_parse_private_key, + MLKEMDecapFileTest<MLKEM1024_private_key, BCM_MLKEM1024_PRIVATE_KEY_BYTES, + wrapper_1024_parse_private_key, MLKEM1024_CIPHERTEXT_BYTES, MLKEM1024_decap>); } @@ -413,15 +425,15 @@ TEST(MLKEMTest, NistDecap768TestVectors) { FileTestGTest( "crypto/mlkem/mlkem768_nist_decap_tests.txt", - MLKEMNistDecapFileTest<MLKEM768_private_key, MLKEM768_parse_private_key, - MLKEM768_decap>); + MLKEMNistDecapFileTest<MLKEM768_private_key, + wrapper_768_parse_private_key, MLKEM768_decap>); } TEST(MLKEMTest, NistDecap1024TestVectors) { FileTestGTest( "crypto/mlkem/mlkem1024_nist_decap_tests.txt", - MLKEMNistDecapFileTest<MLKEM1024_private_key, MLKEM1024_parse_private_key, - MLKEM1024_decap>); + MLKEMNistDecapFileTest<MLKEM1024_private_key, + wrapper_1024_parse_private_key, MLKEM1024_decap>); } template < @@ -482,7 +494,7 @@ // ML-KEM. uint8_t result[32]; IteratedTest<MLKEM768_public_key, MLKEM768_PUBLIC_KEY_BYTES, - MLKEM768_private_key, MLKEM768_PRIVATE_KEY_BYTES, + MLKEM768_private_key, BCM_MLKEM768_PRIVATE_KEY_BYTES, wrapper_768_generate_key_external_seed, MLKEM768_public_from_private, wrapper_768_marshal_private_key, MLKEM768_CIPHERTEXT_BYTES, wrapper_768_encap_external_entropy, @@ -503,7 +515,7 @@ // ML-KEM. uint8_t result[32]; IteratedTest<MLKEM1024_public_key, MLKEM1024_PUBLIC_KEY_BYTES, - MLKEM1024_private_key, MLKEM1024_PRIVATE_KEY_BYTES, + MLKEM1024_private_key, BCM_MLKEM1024_PRIVATE_KEY_BYTES, wrapper_1024_generate_key_external_seed, MLKEM1024_public_from_private, wrapper_1024_marshal_private_key, MLKEM1024_CIPHERTEXT_BYTES, wrapper_1024_encap_external_entropy,
diff --git a/include/openssl/mlkem.h b/include/openssl/mlkem.h index da75868..28ec563 100644 --- a/include/openssl/mlkem.h +++ b/include/openssl/mlkem.h
@@ -121,18 +121,6 @@ OPENSSL_EXPORT int MLKEM768_parse_public_key( struct MLKEM768_public_key *out_public_key, CBS *in); -// MLKEM768_PRIVATE_KEY_BYTES is the length of the data produced by -// |MLKEM768_marshal_private_key|. -#define MLKEM768_PRIVATE_KEY_BYTES 2400 - -// MLKEM768_parse_private_key parses a private key, in NIST's format for -// private keys, from |in| and writes the result to |out_private_key|. It -// returns one on success or zero on parse error or if there are trailing bytes -// in |in|. This format is verbose and should be avoided. Private keys should be -// stored as seeds and parsed using |MLKEM768_private_key_from_seed|. -OPENSSL_EXPORT int MLKEM768_parse_private_key( - struct MLKEM768_private_key *out_private_key, CBS *in); - // ML-KEM-1024 // @@ -226,18 +214,6 @@ OPENSSL_EXPORT int MLKEM1024_parse_public_key( struct MLKEM1024_public_key *out_public_key, CBS *in); -// MLKEM1024_PRIVATE_KEY_BYTES is the length of the data produced by -// |MLKEM1024_marshal_private_key|. -#define MLKEM1024_PRIVATE_KEY_BYTES 3168 - -// MLKEM1024_parse_private_key parses a private key, in NIST's format for -// private keys, from |in| and writes the result to |out_private_key|. It -// returns one on success or zero on parse error or if there are trailing bytes -// in |in|. This format is verbose and should be avoided. Private keys should be -// stored as seeds and parsed using |MLKEM1024_private_key_from_seed|. -OPENSSL_EXPORT int MLKEM1024_parse_private_key( - struct MLKEM1024_private_key *out_private_key, CBS *in); - #if defined(__cplusplus) } // extern C