Skip to main content

ML-DSA usage

Use this example to generate and verify digital signatures via the Crypto Interface QS_* APIs.

Sign

MSTATUS status = OK;
QS_CTX *pCtx = NULL;
ubyte *pMsg = <points to message to be signed>;
ubyte4 msgLen = <length of pMsg in octets>;
ubyte *pPub = NULL;
ubyte4 pubLen = 0;
ubyte *pSig = NULL;
ubyte4 sigLen = 0;

/* Create a new context shell for a ML-DSA-44 key */
status = CRYPTO_INTERFACE_QS_newCtx(&pCtx, cid_PQC_MLDSA_44);
    if (OK != status)
        goto exit;

/* generate a new key pair */
status = CRYPTO_INTERFACE_QS_generateKeyPair(pCtx, RANDOM_rngFun, g_pRandomContext);
    if (OK != status)
        goto exit;

/* get the public key in order to send it to the other party */
status = CRYPTO_INTERFACE_QS_getPublicKeyAlloc(pCtx, &pPub, &pubLen);
if (OK != status)
    goto exit;

/* get the signature length and allocate a buffer for it */
status = CRYPTO_INTERFACE_QS_SIG_getSignatureLen(pCtx, &sigLen);
if (OK != status)
    goto exit;
status = MOC_MALLOC((void **) &pSig, sigLen);
if (OK != status)
    goto exit;

/* compute the signature */
status = CRYPTO_INTERFACE_QS_SIG_signMessage(pCtx, RANDOM_rngFun, g_pRandomContext,
    pMsg, msgLen, pSig, sigLen, &sigLen);
if (OK != status)
    goto exit;

/* transmit the public key and signature to the other party */
...

exit:
/* Cleanup the context and other buffers, zero sensitive data */
(void) CRYPTO_INTERFACE_QS_deleteCtx(&pCtx);
(void) MOC_MEMSET_FREE(&pPub, pubLen);
(void) MOC_MEMSET_FREE(&pSig, sigLen);
return status;

Verify

MSTATUS status = OK;
QS_CTX *pCtx = NULL;
ubyte *pMsg = <points to message to be signed>;
ubyte4 msgLen = <length of pMsg in octets>;
ubyte *pPub = NULL;
ubyte4 pubLen = 0;
ubyte *pSig = NULL;
ubyte4 sigLen = 0;
ubyte4 vStatus = 1;

/* Create a new context shell for a ML-DSA-44 key */
status = CRYPTO_INTERFACE_QS_newCtx(&pCtx, cid_PQC_MLDSA_44);
    if (OK != status)
        goto exit;

/* Receive the public key and signature from the other party */
...

/* Set the public key in the context */
status = CRYPTO_INTERFACE_QS_setPublicKey(pCtx, pPub, pubLen);
    if (OK != status)
        goto exit;

/* verify the signature, vStatus will be set to 0 for valid signatures,
   and 1 for invalid */
status = CRYPTO_INTERFACE_QS_SIG_verifyMessage(pCtx, pMsg, msgLen, pSig,
    sigLen, &vStatus);
if (OK != status)
    goto exit;
if (vStatus)
{ /* handle as an INVALID signature */… }
else
{ /* handle as a VALID signature */ … }
...
exit:
/* Cleanup the context and other buffers, zero sensitive data */
(void) CRYPTO_INTERFACE_QS_deleteCtx(&pCtx);
return status;