#P-384 (secp384r1)
#define FIO_P384
#include "fio-stl.h"P-384 is the NIST secp384r1 curve. In this STL, it is a verifier: it checks ECDSA P-384 signatures, mainly for TLS 1.3 certificate chains and CA roots that use P-384.
There is no signing or key-generation API here. Just verification. Nice and focused.
Security note: this implementation has not been independently audited. It is meant for verification of public data; prefer a tested crypto library when certificate trust is central to your application.
#What It Provides
| Use | Function | Notes |
|---|---|---|
| Verify DER signature | fio_ecdsa_p384_verify |
Accepts SEQUENCE { r INTEGER, s INTEGER } and a 97-byte uncompressed public key. |
| Verify raw signature | fio_ecdsa_p384_verify_raw |
Accepts raw 48-byte r, s, x, and y values. |
Curve parameters from NIST FIPS 186-4:
p = 2^384 - 2^128 - 2^96 + 2^32 - 1n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973- curve equation:
y² = x³ - 3x + b (mod p) - coordinate size: 48 bytes
#Verification API
#fio_ecdsa_p384_verify
SFUNC int fio_ecdsa_p384_verify(const uint8_t *sig,
size_t sig_len,
const uint8_t *msg_hash,
const uint8_t *pubkey,
size_t pubkey_len);Verifies a DER-encoded ECDSA P-384 signature over a 48-byte SHA-384 hash.
sigis a DERSEQUENCE { r INTEGER, s INTEGER }.sig_lenis the signature length in bytes.msg_hashis the SHA-384 hash of the message, exactly 48 bytes.pubkeymust be an uncompressed public key:0x04 || x || y.pubkey_lenmust be97.- Returns
0for a valid signature,-1for invalid input or a bad signature.
The function validates the public-key wrapper, decodes r and s from DER, then calls fio_ecdsa_p384_verify_raw.
Compressed public keys are not accepted by this API.
#fio_ecdsa_p384_verify_raw
SFUNC int fio_ecdsa_p384_verify_raw(const uint8_t r[48],
const uint8_t s[48],
const uint8_t msg_hash[48],
const uint8_t pubkey_x[48],
const uint8_t pubkey_y[48]);Verifies an ECDSA P-384 signature when the signature and public key are already decoded.
All inputs are fixed-width big-endian values:
rands: 48-byte signature scalars.msg_hash: 48-byte SHA-384 hash.pubkey_xandpubkey_y: 48-byte public-key coordinates.
The verifier checks that r and s are in range, checks the public point is on the P-384 curve, computes the ECDSA verification equation, and returns 0 only when r == R.x mod n.
#Example
#define FIO_P384
#include "fio-stl.h"
int verify_cert_sig(const uint8_t *sig,
size_t sig_len,
const uint8_t hash[48],
const uint8_t pubkey[97]) {
if (fio_ecdsa_p384_verify(sig, sig_len, hash, pubkey, 97))
return -1;
return 0;
}#Implementation Notes
The implementation uses 6 × 64-bit limbs for field elements, Jacobian coordinates for point work, P-384-specific modular reduction, and a double-scalar multiplication path for ECDSA verification.
The scalar multiplication is for public verification data. Do not treat this header as a P-384 signing toolkit; there is no public signing API, and private-key use should go to an audited library.