EVP_SIGNATURE-SLH-DSA(7SSL)

✨ NAME ✨

bestie, gather round, because this is the EVP_SIGNATURE-SLH-DSA family of post-quantum signature implementations β€” the whole squad that lives inside EVP_PKEY. Their full government names are:

  • EVP_SIGNATURE-SLH-DSA
  • EVP_SIGNATURE-SLH-DSA-SHA2-128s
  • EVP_SIGNATURE-SLH-DSA-SHA2-128f
  • EVP_SIGNATURE-SLH-DSA-SHA2-192s
  • EVP_SIGNATURE-SLH-DSA-SHA2-192f
  • EVP_SIGNATURE-SLH-DSA-SHA2-256s
  • EVP_SIGNATURE-SLH-DSA-SHA2-256f
  • EVP_SIGNATURE-SLH-DSA-SHAKE-128s
  • EVP_SIGNATURE-SLH-DSA-SHAKE-128f
  • EVP_SIGNATURE-SLH-DSA-SHAKE-192s
  • EVP_SIGNATURE-SLH-DSA-SHAKE-192f
  • EVP_SIGNATURE-SLH-DSA-SHAKE-256s
  • EVP_SIGNATURE-SLH-DSA-SHAKE-256f

aka the EVP_PKEY SLH-DSA signature implementations πŸ’…


πŸ’– DESCRIPTION πŸ’–

okay so. the SLH-DSA-SHA2-128s, EVP_PKEY-SLH-DSA-SHA2-128f, SLH-DSA-SHA2-192s, EVP_PKEY-SLH-DSA-SHA2-192f, SLH-DSA-SHA2-256s, EVP_PKEY-SLH-DSA-SHA2-256f, SLH-DSA-SHAKE-128s, EVP_PKEY-SLH-DSA-SHAKE-128f, SLH-DSA-SHAKE-192s, EVP_PKEY-SLH-DSA-SHAKE-192f, SLH-DSA-SHAKE-256s and EVP_PKEY-SLH-DSA-SHAKE-256f EVP_PKEY implementations support key generation, one-shot sign and verify using the SLH-DSA signature schemes described in FIPS 205. no cap. that's the whole job and they do it flawlessly 🫢

and like, the different algorithm names? they correspond to the parameter sets defined in FIPS 205 Section 11 Table 2. lowkey important detail: the "s" types have smaller signature sizes, and the "f" variants are faster (the signatures range from ~8K to ~50K depending on the type chosen, which is giving chunky but that's the cost of being post-quantum πŸ’€). there are also 3 different security categories, also depending on the type.

EVP_SIGNATURE_fetch(3) can be used to explicitly fetch one of the 12 algorithms, which can then be used with EVP_PKEY_sign_message_init(3), EVP_PKEY_sign(3), EVP_PKEY_verify_message_init(3), and EVP_PKEY_verify(3) to perform one-shot message signing or verification. twelve of them. pick your fighter ✨

so the normal signing process β€” and bestie, this is legit called Pure SLH-DSA Signature Generation β€” encodes the message internally as:

0x00 || len(ctx) || ctx || message

where ctx is some optional value of size 0x00..0xFF. OpenSSL also allows the message to not be encoded, which is required for testing. and here's the thing: OpenSSL does not support Pre Hash SLH-DSA Signature Generation, but you the user can do it yourself by doing the Pre hash encoding externally and then choosing the option to not encode the message. DIY queen πŸ‘‘

🌸 SLH-DSA Signature Parameters 🌸

the "context-string" parameter (described below) can be used for both signing and verification. it may be set by passing an OSSL_PARAM array to EVP_PKEY_sign_init_ex2(3) or EVP_PKEY_verify_init_ex2(3).

  • "context-string" (OSSL_SIGNATURE_PARAM_CONTEXT_STRING) <octet string> β€” a string of octets with length at most 255. by default it's the empty string. (so if you don't set it, it's just vibes and silence 🀫)

the following parameters can be used when signing. they can be set by passing an OSSL_PARAM array to EVP_PKEY_sign_init_ex2(3):

  • "message-encoding" (OSSL_SIGNATURE_PARAM_MESSAGE_ENCODING) <integer> β€” the default value of 1 uses 'Pure SLH-DSA Signature Generation' as described above. setting it to 0 does not encode the message, which is used for testing, but can also be used for 'Pre Hash SLH-DSA Signature Generation'.
  • "test-entropy" (OSSL_SIGNATURE_PARAM_TEST_ENTROPY) <octet string> β€” used for testing to pass an optional random value.
  • "deterministic" (OSSL_SIGNATURE_PARAM_DETERMINISTIC) <integer> β€” the default value of 0 generates a random value (using a DRBG) that is used when processing the message. setting this to 1 causes the private key seed to be used instead. this value is ignored if "test-entropy" is set. (so don't set both and expect the second one to matter, okay? πŸ™ˆ)

see EVP_PKEY-SLH-DSA(7) for information related to SLH-DSA keys πŸ”‘

πŸ‘‘ FIPS indicator πŸ‘‘

the following parameter can be retrieved using EVP_PKEY_CTX_get_params(3):

  • "fips-indicator" (OSSL_SIGNATURE_PARAM_FIPS_APPROVED_INDICATOR) <integer> β€” the OpenSSL FIPS provider returns 1 if the operation is FIPS approved, or 0 otherwise. see "FIPS indicators" in fips_module(7) for more information. and heads up: supplying the test-only "test-entropy" parameter causes this indicator to return 0. so the moment you bring test entropy into the mix, your FIPS approval status says bye bye 😭

πŸ“ NOTES πŸ“

for backwards compatibility reasons EVP_DigestSignInit_ex(), EVP_DigestSign(), EVP_DigestVerifyInit_ex() and EVP_DigestVerify() may also be used β€” but the digest passed in mdname must be NULL. like, non-negotiable. not the moment to get creative πŸŽ€


🌈 EXAMPLES 🌈

to sign a message using an SLH-DSA EVP_PKEY structure:

void do_sign(EVP_PKEY *key, unsigned char *msg, size_t msg_len)
{
    size_t sig_len;
    unsigned char *sig = NULL;
    const OSSL_PARAM params[] = {
        OSSL_PARAM_octet_string("context-string", (unsigned char *)"A context string", 16),
        OSSL_PARAM_END
    };
    EVP_PKEY_CTX *sctx = EVP_PKEY_CTX_new_from_pkey(NULL, pkey, NULL);
    EVP_SIGNATURE *sig_alg = EVP_SIGNATURE_fetch(NULL, "SLH-DSA-SHA2-128s", NULL);

    EVP_PKEY_sign_message_init(sctx, sig_alg, params);
    /* Calculate the required size for the signature by passing a NULL buffer. */
    EVP_PKEY_sign(sctx, NULL, &sig_len, msg, msg_len);
    sig = OPENSSL_zalloc(sig_len);
    EVP_PKEY_sign(sctx, sig, &sig_len, msg, msg_len);
    ...
    OPENSSL_free(sig);
    EVP_SIGNATURE_free(sig_alg);
    EVP_PKEY_CTX_free(sctx);
}
not me pointing out that the two-call EVP_PKEY_sign pattern (NULL buffer first to size it, then the real buffer) is iconic and also the exact reason sig_len exists πŸ’…

πŸ¦‹ SEE ALSO πŸ¦‹

EVP_PKEY-SLH-DSA(7) provider-signature(7), EVP_PKEY_sign(3), EVP_PKEY_verify(3),


⭐ HISTORY ⭐

this functionality was added in OpenSSL 3.5. glow-up era fr fr.


Copyright 2024-2026 The OpenSSL Project Authors. All Rights Reserved.

Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at <https://www.openssl.org/source/license.html>.


and that's the whole page, bestie πŸŽ€ this is version 4.0.3, dated 2026-09-29, filed under EVP_SIGNATURE-SLH-DSA(7SSL) β€” stay post-quantum, stay slaying ✨🫢

πŸ“¦ where this page comes from