DSA
Digital Signature Algorithm (DSA) per FIPS 186-4: key management, signing, and verification.
Algorithm overview
DSA is a discrete-logarithm signature scheme over finite fields. It signs messages by combining a per-signature nonce with the private key and verifies signatures with the corresponding public key and domain parameters.
Pros and cons
Pros
- Historically standardized and supported in older compliance-oriented stacks.
- Signature-only model can be straightforward in narrowly scoped systems.
- Mature and well-analyzed in its intended parameter ranges.
Cons
- Legacy compared with newer signature schemes (Ed25519/ECDSA in many modern deployments).
- Strongly sensitive to nonce quality/reuse; nonce failures can leak private keys.
- Generally less attractive for new systems due to ecosystem and performance trade-offs.
When to use
- Use mainly for interoperability with systems that explicitly require DSA.
- Ensure robust randomness for nonces and strict parameter validation.
- For new deployments, prefer Ed25519 or ECDSA unless policy dictates DSA.
Types
dsa_key_t
DSA domain parameters and key. Holds prime modulus p, prime order q, generator g, public key y, and optional private key x. Initialized with noxtls_dsa_key_init, freed with noxtls_dsa_key_free. For verification-only, x may be left unset (or set to zero); y must be set with noxtls_dsa_key_set_public.
dsa_signature_t
DSA signature (r, s). r and s are each q_len bytes (big-endian). Initialized with noxtls_dsa_signature_init, cleared with noxtls_dsa_signature_free.
Constants
- DSA_MAX_Q_BYTES — Maximum length of q (and of r, s) in bytes (32 for 256-bit q).
- DSA_MAX_P_BYTES — Maximum length of p (and g, y) in bytes (384 for 3072-bit p).
API
noxtls_dsa_key_init
noxtls_return_t noxtls_dsa_key_init(dsa_key_t *key, const uint8_t *p, uint32_t p_len, const uint8_t *q, uint32_t q_len, const uint8_t *g, uint32_t g_len);
Initialize DSA key with domain parameters p, q, g (all big-endian). Copies parameters into key and allocates storage for y and x. g_len must equal p_len.
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success.
noxtls_dsa_key_set_public
noxtls_return_t noxtls_dsa_key_set_public(dsa_key_t *key, const uint8_t *y);
Set the public key y (p_len bytes, big-endian). Use for verification-only keys.
noxtls_dsa_key_set_private
noxtls_return_t noxtls_dsa_key_set_private(dsa_key_t *key, const uint8_t *x);
Set the private key x (q_len bytes, big-endian). Required for signing.
noxtls_dsa_key_generate
noxtls_return_t noxtls_dsa_key_generate(dsa_key_t *key);
Generate a random private key x in [1, q−1] and compute y = g^x mod p. Domain parameters p, q, g must already be set (e.g. via noxtls_dsa_key_init).
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success.
noxtls_dsa_key_free
noxtls_return_t noxtls_dsa_key_free(dsa_key_t *key);
Free storage held by key. key is a dsa_key_t.
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success.
noxtls_dsa_signature_init
noxtls_return_t noxtls_dsa_signature_init(dsa_signature_t *sig, uint32_t q_len);
Initialize signature structure for the given q_len (subgroup size in bytes).
noxtls_dsa_signature_free
noxtls_return_t noxtls_dsa_signature_free(dsa_signature_t *sig);
Clear sensitive fields of sig.
noxtls_dsa_sign
noxtls_return_t noxtls_dsa_sign(const dsa_key_t *key, const uint8_t *message, uint32_t message_len, dsa_signature_t *signature, noxtls_hash_algos_t hash_algo);
Compute DSA signature (r, s) of message using key (must have private x) and hash_algo. Supported hashes: MD5, SHA-1, SHA-224, SHA-256, SHA-384, SHA-512. The hash is truncated to q_len bytes (leftmost bits) per FIPS 186-4.
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success.
noxtls_dsa_verify
noxtls_return_t noxtls_dsa_verify(const dsa_key_t *key, const uint8_t *message, uint32_t message_len, const dsa_signature_t *signature, noxtls_hash_algos_t hash_algo);
Verify DSA signature over message using key (must have public y) and hash_algo.
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS if the signature is valid, NOXTLS_RETURN_FAILED otherwise.