libsodium offers a small, opinionated set of primitives behind hard-to-misuse functions, and it is bundled into PHP, used by many language bindings and embedded in messaging apps. Signatures are Ed25519 only: the headers of 1.0.22 (checked on the Alpine 3.24.2 package) declare no ECDSA function, so anything that speaks ES256 or secp256k1 needs another library.
Ed25519 signing is deterministic, as RFC 8032 specifies — two signatures of the same message were identical — and crypto_sign_*_ph functions implement Ed25519ph, whose signatures are not interchangeable with plain Ed25519: the plain verifier rejected one in the check. The secret key is 64 bytes, the 32-byte seed followed by the public key, while most other libraries store only the seed; crypto_sign_ed25519_sk_to_seed and crypto_sign_seed_keypair convert between the two, as the sample shows.
Verification is strict where other implementations differ. A signature with S replaced by S + L — the same value modulo the group order, forbidden by RFC 8032 — was rejected, and so was a signature checked against the small-order identity point as public key. Libraries that accept those inputs disagree with libsodium on edge cases, which matters for consensus systems that must agree on validity. crypto_sign_verify_detached takes no signature length and reads exactly 64 bytes, so check the length before calling it.
Post-quantum support in 1.0.22 is key encapsulation only: crypto_kem_mlkem768_* (1184-byte public keys, 1088-byte ciphertexts) and the hybrid X-Wing (crypto_kem_xwing_*, 1216 and 1120 bytes), which is also what the generic crypto_kem_* functions use by default. There is no ML-DSA or other post-quantum signature. Keys are raw bytes throughout — 32-byte public keys and seeds — with no PEM, DER or JWK support. Compare KEM sizes in the post-quantum KEM playground.