Pure ML-DSA signature verification

57 views
Skip to first unread message

Manish Patidar

unread,
Feb 24, 2026, 7:19:38 AM (5 days ago) Feb 24
to openss...@openssl.org
Hi

I am attempting to verify the Pure ML-DSA signature, but I have encountered an issue. OpenSSL does not support the Verify update operation, meaning the data to be verified must be provided in one instance. 
Is this a limitation of OpenSSL or the Pure ML-DSA algorithm?

Regards 
Manish

Christian Schmidt

unread,
Feb 24, 2026, 8:38:18 AM (5 days ago) Feb 24
to openss...@openssl.org
If it's like ED25519 signatures, it's a limitation of openssl. I need to
add a large patch with an init_ex function as this digest algorithms
requires the signature during the initialization, which the current API
does not support.

Looking at page 27 of FIPS 204 to me implies that in ML-DSA the
signature that is to be verified also is processed before the actual
message data, though I did not actually try to understand the algorithm
in detail. So ML-DSA would also need an init_ex function that can
receive the signature early.

As such, I'd say it's a limitation of openssl for ML-DSA, too.

Regards,
Christian

> Regards
> Manish
>
> --
> You received this message because you are subscribed to the Google
> Groups "openssl-users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to openssl-user...@openssl.org <mailto:openssl-
> users+un...@openssl.org>.
> To view this discussion visit https://groups.google.com/a/openssl.org/d/
> msgid/openssl-users/CAN6ajHKQXjhD-
> TxyVCtEamJq242q35cK%2BNqOffZAXM6_XeXAvw%40mail.gmail.com <https://
> groups.google.com/a/openssl.org/d/msgid/openssl-users/CAN6ajHKQXjhD-
> TxyVCtEamJq242q35cK%2BNqOffZAXM6_XeXAvw%40mail.gmail.com?
> utm_medium=email&utm_source=footer>.

Viktor Dukhovni

unread,
Feb 24, 2026, 8:40:52 AM (5 days ago) Feb 24
to openss...@openssl.org
Pure ML-DSA requires the entire message to be provided in one shot, or
that the caller pre-computes the external-μ value, and passes that,
indicating that the input is the μ value. See EVP_SIGNATURE-ML-DSA(7)
for details.

The upcoming OpenSSL 4.0 will include support for "ML-DSA-MU" as a
pseudo-digest, that you can use with EVP_DigestInit_ex(3) to compute the
external-μ value given the target public key and incremental chunks of
the message. See EVP_MD-ML-DSA-MU(7) (in the OpenSSL 4.0 source tree,
or installed image).

With OpenSSL 3.5 and 3.6 you can compute external-μ yourself, it is just
a 64-byte SHAKE256 digest of the message representative prefixed with a
couple of parameters as described FIPS204 (the public digest key `tr`,
the context string, a domain-separation byte and an optional OID for
HashML-DSA).

--
Viktor. 🇺🇦 Слава Україні!

Viktor Dukhovni

unread,
Feb 24, 2026, 8:43:05 AM (5 days ago) Feb 24
to openss...@openssl.org
On Tue, Feb 24, 2026 at 02:38:03PM +0100, Christian Schmidt wrote:

> Looking at page 27 of FIPS 204 to me implies that in ML-DSA the signature
> that is to be verified also is processed before the actual message data,
> though I did not actually try to understand the algorithm in detail. So
> ML-DSA would also need an init_ex function that can receive the signature
> early.
>
> As such, I'd say it's a limitation of openssl for ML-DSA, too.

Or you could just not make up the answer out of thin air. :-)

--
Viktor. 🇺🇦 Слава Україні!

Christian Schmidt

unread,
Feb 24, 2026, 8:55:55 AM (5 days ago) Feb 24
to openss...@openssl.org
You wrote it yourself - openssl is lacking a (simple) API that enables a
simple init - update - final verification for algorithms that process
the signature early (here: calculate the µ value), and people that just
want to work with a cryptographic library need to deep-dive into algorithms.

The lack of such an API, that could be easily generalized with an
init_ex function that accepts the signature to be verified, is as such a
limitation of openssl.

Regards,
Christian

PS: If you have an idea how to do the same for ED25519 I'd be highly
interested. Having to continuously port patches forward is kind of
annoying, and the core ED25519 functions are not exposed enough to be
called externally.

Alicja Kario

unread,
Feb 24, 2026, 9:09:21 AM (5 days ago) Feb 24
to Christian Schmidt, openss...@openssl.org
On Tuesday, 24 February 2026 14:55:44 CET, Christian Schmidt wrote:
> On 2/24/26 2:42 PM, Viktor Dukhovni wrote:
>> On Tue, Feb 24, 2026 at 02:38:03PM +0100, Christian Schmidt wrote:
>> ...
>
> You wrote it yourself - openssl is lacking a (simple) API that
> enables a simple init - update - final verification for
> algorithms that process the signature early (here: calculate the
> µ value), and people that just want to work with a cryptographic
> library need to deep-dive into algorithms.
>
> The lack of such an API, that could be easily generalized with
> an init_ex function that accepts the signature to be verified,
> is as such a limitation of openssl.
>
> Regards,
> Christian
>
> PS: If you have an idea how to do the same for ED25519 I'd be
> highly interested. Having to continuously port patches forward
> is kind of annoying, and the core ED25519 functions are not
> exposed enough to be called externally.

The big issue for EdDSA is that for signing, the message needs to be hashed
twice...
--
Regards,
Alicja Kario
Principal Quality Engineer, RHEL Crypto team
Web: www.cz.redhat.com
Red Hat Czech s.r.o., Purkyňova 115, 612 00, Brno, Czech Republic

Viktor Dukhovni

unread,
Feb 24, 2026, 9:11:58 AM (5 days ago) Feb 24
to openss...@openssl.org
On Wed, Feb 25, 2026 at 12:40:39AM +1100, Viktor Dukhovni wrote:

> > I am attempting to verify the Pure ML-DSA signature, but I have
> > encountered an issue. OpenSSL does not support the Verify update
> > operation, meaning the data to be verified must be provided in one
> > instance. Is this a limitation of OpenSSL or the Pure ML-DSA
> > algorithm?
>
> Pure ML-DSA requires the entire message to be provided in one shot, or
> that the caller pre-computes the external-μ value, and passes that,
> indicating that the input is the μ value. See EVP_SIGNATURE-ML-DSA(7)
> for details.

I should perhaps mention that this is for the EVP_DigestSignInit() and
EVP_DigestVerifyInit() APIs. OpenSSL also providers an API that is
specifically designed for incremental signing and verification for
algorithms like ML-DSA.

See EVP_PKEY_sign_message_init(3), EVP_PKEY_sign_message_update(3),
EVP_PKEY_sign_message_final(3), EVP_PKEY_verify_message_init(3),
EVP_PKEY_verify_message_update(3), EVP_PKEY_verify_message_final(3),

Support for incremental ML-DSA signing and verification via
EVP_PKEY_sign_message_update(3) and EVP_PKEY_verify_message_update(3)
was added in OpenSSL 3.6.

The CI code for this looks like:

if (!TEST_true(ml_dsa_create_keypair(&pkey, td->alg, td->priv, td->priv_len, NULL, 0, 1))
|| !TEST_ptr(sctx = EVP_PKEY_CTX_new_from_pkey(lib_ctx, pkey, NULL))
|| !TEST_ptr(sig_alg = EVP_SIGNATURE_fetch(lib_ctx, td->alg, NULL))
|| !TEST_int_eq(EVP_PKEY_sign_message_init(sctx, sig_alg, params), 1)
|| !TEST_int_eq(EVP_PKEY_sign_message_update(sctx, td->msg, 1), 1)
|| !TEST_int_eq(EVP_PKEY_sign_message_update(sctx, td->msg + 1, td->msg_len - 1), 1)
|| !TEST_int_eq(EVP_PKEY_sign_message_final(sctx, NULL, &psig_len), 1)
|| !TEST_ptr(psig = OPENSSL_zalloc(psig_len))
|| !TEST_int_eq(EVP_PKEY_sign_message_final(sctx, psig, &psig_len), 1))
...

Above the first byte of the message is processed separately from the
rest.

The advantage of the external-μ approach is that if the signer with the
private key is some sort of network HSM one really does not want to
transmit the entire message for signing, and then computing μ on the
client end is compelling. If the message data is local to the party
doing the ML-DSA computations, the EVP_PKEY_sign_message_* (IUF) API
is another option that avoids having to deal with external μ.

Also, if you're willing and able to compute μ for yourself, you can get
incremental ML-DSA message signing and verification with OpenSSL 3.5,
otherwise, you'll need 3.6 or (soon) 4.0.

--
Viktor. 🇺🇦 Слава Україні!

Viktor Dukhovni

unread,
Feb 24, 2026, 9:25:15 AM (5 days ago) Feb 24
to openss...@openssl.org
On Tue, Feb 24, 2026 at 02:55:44PM +0100, Christian Schmidt wrote:

> You wrote it yourself - openssl is lacking a (simple) API that enables a
> simple init - update - final verification for algorithms that process the
> signature early (here: calculate the µ value), and people that just want to
> work with a cryptographic library need to deep-dive into algorithms.

Actually, that API is also present, but the initial ML-DSA integration
into the OpenSSL 3.5 default provider did not have the requesite
handlers for EVP_PKEY_{sign,verify}_message_{update,final}(). These
were added in OpenSSL 3.6.

> The lack of such an API, that could be easily generalized with an
> init_ex function that accepts the signature to be verified, is as such
> a limitation of OpenSSL.

Good things come to those who wait... With EdDSA the limiation is
fundamental, and there's a "prehash" variant for those who must have
IUF. With ML-DSA IUF is possible, and now available in two different
ways. Just not through the EVP_Digest{Sign,Verify} APIs which are for
"traditional" signature algorithms that operate on precomputed message
digests with the aid of a separately specified digest algorithm.

--
Viktor. 🇺🇦 Слава Україні!
Reply all
Reply to author
Forward
0 new messages