ML-DSA: drop parsing private keys from the public API.
ML-DSA private keys were a mistake. NIST should not have specified them.
The seed is the correct private key format to use and it looks like
hopefully people mostly agree on this point and thus we don't need an
exposed function to parse the mistaken private key format.
Change-Id: I9511151c07212e72122e075a109bee4f243efd27
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/73647
Reviewed-by: Bob Beck <bbe@google.com>
Commit-Queue: Adam Langley <agl@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/mldsa/mldsa.cc b/crypto/mldsa/mldsa.cc
index 78c4bc6..21f7288 100644
--- a/crypto/mldsa/mldsa.cc
+++ b/crypto/mldsa/mldsa.cc
@@ -88,9 +88,3 @@
return bcm_success(BCM_mldsa65_parse_public_key(
reinterpret_cast<BCM_mldsa65_public_key *>(public_key), in));
}
-
-int MLDSA65_parse_private_key(struct MLDSA65_private_key *private_key,
- CBS *in) {
- return bcm_success(BCM_mldsa65_parse_private_key(
- reinterpret_cast<BCM_mldsa65_private_key *>(private_key), in));
-}
diff --git a/crypto/mldsa/mldsa_test.cc b/crypto/mldsa/mldsa_test.cc
index 3c34850..cb0e4f3 100644
--- a/crypto/mldsa/mldsa_test.cc
+++ b/crypto/mldsa/mldsa_test.cc
@@ -84,17 +84,17 @@
}
}
-template <typename PrivateKey, typename PublicKey, size_t PublicKeyBytes,
- size_t SignatureBytes,
- int (*Generate)(uint8_t *, uint8_t *, PrivateKey *),
- int (*Sign)(uint8_t *, const PrivateKey *, const uint8_t *, size_t,
- const uint8_t *, size_t),
- int (*ParsePublicKey)(PublicKey *, CBS *),
- int (*Verify)(const PublicKey *, const uint8_t *, size_t,
- const uint8_t *, size_t, const uint8_t *, size_t),
- int (*PrivateKeyFromSeed)(PrivateKey *, const uint8_t *, size_t),
- int (*ParsePrivate)(PrivateKey *, CBS *), typename BCMPrivateKey,
- bcm_status (*MarshalPrivate)(CBB *, const BCMPrivateKey *)>
+template <
+ typename PrivateKey, typename PublicKey, size_t PublicKeyBytes,
+ size_t SignatureBytes, int (*Generate)(uint8_t *, uint8_t *, PrivateKey *),
+ int (*Sign)(uint8_t *, const PrivateKey *, const uint8_t *, size_t,
+ const uint8_t *, size_t),
+ int (*ParsePublicKey)(PublicKey *, CBS *),
+ int (*Verify)(const PublicKey *, const uint8_t *, size_t, const uint8_t *,
+ size_t, const uint8_t *, size_t),
+ int (*PrivateKeyFromSeed)(PrivateKey *, const uint8_t *, size_t),
+ typename BCMPrivateKey, bcm_status (*ParsePrivate)(BCMPrivateKey *, CBS *),
+ bcm_status (*MarshalPrivate)(CBB *, const BCMPrivateKey *)>
static void MLDSABasicTest() {
std::vector<uint8_t> encoded_public_key(PublicKeyBytes);
auto priv = std::make_unique<PrivateKey>();
@@ -104,7 +104,8 @@
const std::vector<uint8_t> encoded_private_key =
Marshal(MarshalPrivate, reinterpret_cast<BCMPrivateKey *>(priv.get()));
CBS cbs = bssl::MakeConstSpan(encoded_private_key);
- EXPECT_TRUE(ParsePrivate(priv.get(), &cbs));
+ EXPECT_TRUE(bcm_success(
+ ParsePrivate(reinterpret_cast<BCMPrivateKey *>(priv.get()), &cbs)));
std::vector<uint8_t> encoded_signature(SignatureBytes);
static const uint8_t kMessage[] = {'H', 'e', 'l', 'l', 'o', ' ',
@@ -136,7 +137,7 @@
MLDSA65_PUBLIC_KEY_BYTES, MLDSA65_SIGNATURE_BYTES,
MLDSA65_generate_key, MLDSA65_sign, MLDSA65_parse_public_key,
MLDSA65_verify, MLDSA65_private_key_from_seed,
- MLDSA65_parse_private_key, BCM_mldsa65_private_key,
+ BCM_mldsa65_private_key, BCM_mldsa65_parse_private_key,
BCM_mldsa65_marshal_private_key>();
}
@@ -200,18 +201,12 @@
reinterpret_cast<BCM_mldsa87_public_key *>(public_key), in));
}
-static int MLDSA87_parse_private_key(struct MLDSA87_private_key *private_key,
- CBS *in) {
- return bcm_success(BCM_mldsa87_parse_private_key(
- reinterpret_cast<BCM_mldsa87_private_key *>(private_key), in));
-}
-
TEST(MLDSATest, Basic87) {
MLDSABasicTest<MLDSA87_private_key, MLDSA87_public_key,
BCM_MLDSA87_PUBLIC_KEY_BYTES, BCM_MLDSA87_SIGNATURE_BYTES,
MLDSA87_generate_key, MLDSA87_sign, MLDSA87_parse_public_key,
MLDSA87_verify, MLDSA87_private_key_from_seed,
- MLDSA87_parse_private_key, BCM_mldsa87_private_key,
+ BCM_mldsa87_private_key, BCM_mldsa87_parse_private_key,
BCM_mldsa87_marshal_private_key>();
}
@@ -292,10 +287,10 @@
TEST(MLDSATest, InvalidPrivateKeyEncodingLength) {
std::vector<uint8_t> encoded_public_key(MLDSA65_PUBLIC_KEY_BYTES);
- auto priv = std::make_unique<MLDSA65_private_key>();
+ auto priv = std::make_unique<BCM_mldsa65_private_key>();
uint8_t seed[MLDSA_SEED_BYTES];
- EXPECT_TRUE(
- MLDSA65_generate_key(encoded_public_key.data(), seed, priv.get()));
+ EXPECT_TRUE(bcm_success(
+ BCM_mldsa65_generate_key(encoded_public_key.data(), seed, priv.get())));
CBB cbb;
std::vector<uint8_t> malformed_private_key(MLDSA65_PRIVATE_KEY_BYTES + 1, 0);
@@ -304,19 +299,22 @@
&cbb, reinterpret_cast<BCM_mldsa65_private_key *>(priv.get()))));
CBS cbs;
- auto parsed_priv = std::make_unique<MLDSA65_private_key>();
+ auto parsed_priv = std::make_unique<BCM_mldsa65_private_key>();
// Private key is 1 byte too short.
CBS_init(&cbs, malformed_private_key.data(), MLDSA65_PRIVATE_KEY_BYTES - 1);
- EXPECT_FALSE(MLDSA65_parse_private_key(parsed_priv.get(), &cbs));
+ EXPECT_FALSE(
+ bcm_success(BCM_mldsa65_parse_private_key(parsed_priv.get(), &cbs)));
// Private key has the correct length.
CBS_init(&cbs, malformed_private_key.data(), MLDSA65_PRIVATE_KEY_BYTES);
- EXPECT_TRUE(MLDSA65_parse_private_key(parsed_priv.get(), &cbs));
+ EXPECT_TRUE(
+ bcm_success(BCM_mldsa65_parse_private_key(parsed_priv.get(), &cbs)));
// Private key is 1 byte too long.
CBS_init(&cbs, malformed_private_key.data(), MLDSA65_PRIVATE_KEY_BYTES + 1);
- EXPECT_FALSE(MLDSA65_parse_private_key(parsed_priv.get(), &cbs));
+ EXPECT_FALSE(
+ bcm_success(BCM_mldsa65_parse_private_key(parsed_priv.get(), &cbs)));
}
template <typename PrivateKey, typename PublicKey, size_t SignatureBytes,
diff --git a/include/openssl/mldsa.h b/include/openssl/mldsa.h
index 134df0c..b57b354 100644
--- a/include/openssl/mldsa.h
+++ b/include/openssl/mldsa.h
@@ -122,12 +122,6 @@
OPENSSL_EXPORT int MLDSA65_parse_public_key(
struct MLDSA65_public_key *public_key, CBS *in);
-// MLDSA65_parse_private_key parses a private key, in the NIST format, from |in|
-// and writes the result to |out_private_key|. It returns 1 on success or 0 on
-// parse error or if there are trailing bytes in |in|.
-OPENSSL_EXPORT int MLDSA65_parse_private_key(
- struct MLDSA65_private_key *private_key, CBS *in);
-
#if defined(__cplusplus)
} // extern C