ECC (Elliptic curve crypto)
Elliptic curve cryptography: curves, points, keys, ECDH, ECDSA, and supporting bignum API.
Types
ecc_curve_params_t
Opaque ECC curve parameters (prime, order, generator, etc.). Initialized with noxtls_ecc_curve_init, freed with noxtls_ecc_curve_free. Pass to point and key operations.
ecc_point_t
ECC point (affine x, y or equivalent). Used for public keys and intermediate results. Initialized with noxtls_ecc_point_init.
ecc_key_t
ECC key pair (private scalar and public point). Initialized with noxtls_ecc_key_init, generated with noxtls_ecc_key_generate, freed with noxtls_ecc_key_free.
ecc_curve_t
Enumeration of supported ECC curves (e.g. SECP256R1, SECP384R1). Used when initializing ecc_curve_params_t or ecc_key_t.
ecdsa_signature_t
ECDSA signature (r, s). Initialized with noxtls_ecdsa_signature_init, freed with noxtls_ecdsa_signature_free.
API
noxtls_ecc_curve_init
noxtls_return_t noxtls_ecc_curve_init(ecc_curve_params_t *curve, ecc_curve_t curve_type);
Initialize ECC curve parameters
Parameters:
curve— ecc_curve_params_t to initializecurve_type— ecc_curve_t: curve identifier
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success, NOXTLS_RETURN_NULL if curve is NULL
noxtls_ecc_curve_free
noxtls_return_t noxtls_ecc_curve_free(ecc_curve_params_t *curve);
Free ECC curve parameters
Parameters:
curve— ecc_curve_params_t to free
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success, NOXTLS_RETURN_NULL if curve is NULL
noxtls_ecc_point_init
noxtls_return_t noxtls_ecc_point_init(ecc_point_t *point, uint32_t size);
Initialize ECC point
Parameters:
point— ecc_point_t to initializesize— Size of the point (coordinate size in bytes)
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success, NOXTLS_RETURN_NULL if point is NULL
noxtls_ecc_key_init
noxtls_return_t noxtls_ecc_key_init(ecc_key_t *key, ecc_curve_t curve_type);
Initialize ECC key
Parameters:
key— ecc_key_t to initializecurve_type— ecc_curve_t
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success, NOXTLS_RETURN_NULL if key is NULL
noxtls_ecc_key_generate
noxtls_return_t noxtls_ecc_key_generate(ecc_key_t *key, ecc_curve_t curve_type);
Generate ECC key pair Generates a random private key d in range [1, n-1] using DRBG, then computes the public key Q = d G
Parameters:
key— ecc_key_t to initializecurve_type— ecc_curve_t
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success, NOXTLS_RETURN_NULL if key is NULL
noxtls_ecc_key_free
noxtls_return_t noxtls_ecc_key_free(ecc_key_t *key);
Free ECC key
Parameters:
key— ecc_key_t to free
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success, NOXTLS_RETURN_NULL if key is NULL
noxtls_ecdh_compute_shared_secret
noxtls_return_t noxtls_ecdh_compute_shared_secret(ecc_key_t *private_key, const ecc_point_t *peer_public_key, uint8_t *shared_secret, uint32_t *shared_secret_len);
ECDH Compute Shared Secret Computes the shared secret from our private key and peer's public key. Shared secret = d Q_peer, where d is our private key and Q_peer is peer's public point.
Parameters:
private_key— Our private keypeer_public_key— Peer's public key pointshared_secret— Output buffer for shared secretshared_secret_len— Input: buffer size, Output: actual shared secret length
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success
noxtls_ecdsa_signature_init
noxtls_return_t noxtls_ecdsa_signature_init(ecdsa_signature_t *sig, uint32_t size);
Initialize ECDSA signature structure
Parameters:
sig— ecdsa_signature_tsize— Size of the signature
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success, NOXTLS_RETURN_NULL if sig is NULL
noxtls_ecdsa_signature_free
noxtls_return_t noxtls_ecdsa_signature_free(ecdsa_signature_t *sig);
Free ECDSA signature structure
Parameters:
sig— ecdsa_signature_t
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success, NOXTLS_RETURN_NULL if sig is NULL
noxtls_ecdsa_signature_parse_der
noxtls_return_t noxtls_ecdsa_signature_parse_der(const uint8_t *der, uint32_t der_len, ecdsa_signature_t *out, uint32_t coord_size);
Parse DER-encoded ECDSA signature (SEQUENCE of two INTEGERs r, s) into ecdsa_signature_t
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success.
noxtls_ecdsa_sign
noxtls_return_t noxtls_ecdsa_sign(ecc_key_t *key, const uint8_t *message, uint32_t message_len, ecdsa_signature_t *signature, noxtls_hash_algos_t hash_algo);
ECDSA Signature Generation Algorithm: 1. Hash the message: h = HASH(message) 2. Generate random nonce k in [1, n-1] 3. Compute (x, y) = k G 4. r = x mod n (if r == 0, go to step 2) 5. s = k^-1 (h + r d) mod n (if s == 0, go to step 2) 6. Signature is (r, s)
Parameters:
key— ecc_key_tmessage— Message to signmessage_len— Length of the messagesignature— ecdsa_signature_thash_algo— noxtls_hash_algos_t
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success, NOXTLS_RETURN_NULL if key is NULL
noxtls_ecdsa_verify
noxtls_return_t noxtls_ecdsa_verify(ecc_key_t *key, const uint8_t *message, uint32_t message_len, const ecdsa_signature_t *signature, noxtls_hash_algos_t hash_algo);
ECDSA Signature Verification Algorithm: 1. Verify r and s are in [1, n-1] 2. Hash the message: h = HASH(message) 3. u1 = s^-1 h mod n 4. u2 = s^-1 r mod n 5. Compute (x, y) = u1 G + u2 Q 6. v = x mod n 7. Accept if v == r
Parameters:
key— ecc_key_tmessage— Message to verifymessage_len— Length of the messagesignature— ecdsa_signature_thash_algo— noxtls_hash_algos_t
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success, NOXTLS_RETURN_NULL if key is NULL
Bignum (for ECC)
Low-level big-integer helpers used by ECC operations. Big-endian byte arrays.
noxtls_bn_cmp
int noxtls_bn_cmp(const uint8_t *a, const uint8_t *b, uint32_t len);
Compare two big integers (byte arrays, big-endian)
Parameters:
a— First big integerb— Second big integerlen— Length of the big integers
Returns: int 1 if a > b, -1 if a < b, 0 if a == b
noxtls_bn_is_zero
int noxtls_bn_is_zero(const uint8_t *a, uint32_t len);
Check if big integer is zero
Parameters:
a— Big integerlen— Length of the big integer
Returns: int 1 if the big integer is zero, 0 otherwise
noxtls_bn_is_one
int noxtls_bn_is_one(const uint8_t *a, uint32_t len);
Check if big integer is one
Parameters:
a— Big integerlen— Length of the big integer
Returns: int 1 if the big integer is one, 0 otherwise
noxtls_bn_copy
noxtls_return_t noxtls_bn_copy(uint8_t *dst, const uint8_t *src, uint32_t len);
Copy big integer
Parameters:
dst— Destination big integersrc— Source big integerlen— Length of the big integer
noxtls_bn_add
noxtls_return_t noxtls_bn_add(uint8_t *result, const uint8_t *a, const uint8_t *b, uint32_t len);
Add two big integers: result = a + b
Parameters:
result— Result big integera— First big integerb— Second big integerlen— Length of the big integers
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success.
noxtls_bn_sub
noxtls_return_t noxtls_bn_sub(uint8_t *result, const uint8_t *a, const uint8_t *b, uint32_t len);
Subtract two big integers: result = a - b (assumes a >= b)
Parameters:
result— Result big integera— First big integerb— Second big integerlen— Length of the big integers
noxtls_bn_mul
noxtls_return_t noxtls_bn_mul(uint8_t *result, const uint8_t *a, uint32_t a_len, const uint8_t *b, uint32_t b_len);
Multiply two big integers: result = a b (limb-based schoolbook) Uses 32-bit limbs and 64-bit multiply-accumulate (MULADDC-style). Converts BE bytes to LE limbs, runs one pass per limb of b (multiply a by b[i], add into result at offset i), then converts result limbs back to BE bytes.
Parameters:
result— Result big integer (a_len + b_len bytes, big-endian)a— First big integer (big-endian)a_len— Length of the first big integerb— Second big integer (big-endian)b_len— Length of the second big integer
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success.
noxtls_bn_rshift1
noxtls_return_t noxtls_bn_rshift1(uint8_t *a, uint32_t len);
Right shift big integer by one bit (divide by 2)
Parameters:
a— Big integerlen— Length of the big integer
noxtls_bn_mod
noxtls_return_t noxtls_bn_mod(uint8_t *result, const uint8_t *a, uint32_t a_len, const uint8_t *mod, uint32_t mod_len);
Modulus operation: result = a mod mod
Parameters:
result— Result big integera— First big integera_len— Length of the first big integermod— Modulus big integermod_len— Length of the modulus big integer
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success.
noxtls_bn_mod_exp
noxtls_return_t noxtls_bn_mod_exp(uint8_t *result, const uint8_t *base, const uint8_t *exp, uint32_t exp_len, const uint8_t *mod, uint32_t mod_len);
Modular exponentiation: result = base ^ exp mod mod
Parameters:
result— Result big integerbase— Base big integerexp— Exponent big integerexp_len— Length of the exponent big integermod— Modulus big integermod_len— Length of the modulus big integer
noxtls_bn_mod_inv
noxtls_return_t noxtls_bn_mod_inv(uint8_t *result, const uint8_t *a, uint32_t a_len, const uint8_t *m, uint32_t m_len);
Binary Extended Euclidean Algorithm: compute a^-1 mod m (much faster - no division!)
Parameters:
result— Result big integera— First big integera_len— Length of the first big integerm— Modulus big integerm_len— Length of the modulus big integer
Returns: noxtls_return_t: NOXTLS_RETURN_SUCCESS on success.