#Ed25519 & X25519
#define FIO_ED25519
#include "fio-stl.h"Elliptic-curve cryptography over Curve25519: Ed25519 for signatures and X25519 for key exchange. Both provide 128-bit security with compact 32-byte keys.
Security note: this implementation has not been independently audited. Use at your own risk, and prefer a tested cryptographic library when available.
#Ed25519 Digital Signatures
- Secret key: 32 bytes
- Public key: 32 bytes
- Signature: 64 bytes
#fio_ed25519_keypair
SFUNC void fio_ed25519_keypair(uint8_t secret_key[32], uint8_t public_key[32]);Generates a new random Ed25519 key pair.
#fio_ed25519_public_key
SFUNC void fio_ed25519_public_key(uint8_t public_key[32],
const uint8_t secret_key[32]);Derives the public key from a secret key.
#fio_ed25519_sign
SFUNC int fio_ed25519_sign(uint8_t signature[64],
const void *message,
size_t len,
const uint8_t secret_key[32],
const uint8_t public_key[32]);Signs a message. Returns 0 on success, -1 on failure. The signature is deterministic.
#fio_ed25519_verify
SFUNC int fio_ed25519_verify(const uint8_t signature[64],
const void *message,
size_t len,
const uint8_t public_key[32]);Verifies a signature. Returns 0 on success, -1 on failure.
#X25519 Key Exchange
- Secret key: 32 bytes
- Public key: 32 bytes
- Shared secret: 32 bytes
#fio_x25519_keypair
SFUNC void fio_x25519_keypair(uint8_t secret_key[32], uint8_t public_key[32]);Generates a new random X25519 key pair.
#fio_x25519_public_key
SFUNC void fio_x25519_public_key(uint8_t public_key[32],
const uint8_t secret_key[32]);Derives the public key from a secret key.
#fio_x25519_shared_secret
SFUNC int fio_x25519_shared_secret(uint8_t shared_secret[32],
const uint8_t secret_key[32],
const uint8_t their_public_key[32]);Computes a shared secret. Returns 0 on success, -1 if the result is the all-zero point.
Note: pass the shared secret through a KDF such as HKDF before using it as an encryption key.
#Key Conversion
#fio_ed25519_sk_to_x25519
SFUNC void fio_ed25519_sk_to_x25519(uint8_t x_secret_key[32],
const uint8_t ed_secret_key[32]);Converts an Ed25519 secret key to an X25519 secret key.
#fio_ed25519_pk_to_x25519
SFUNC void fio_ed25519_pk_to_x25519(uint8_t x_public_key[32],
const uint8_t ed_public_key[32]);Converts an Ed25519 public key to an X25519 public key.
#ECIES Public-Key Encryption
#FIO_X25519_CIPHERTEXT_LEN
#define FIO_X25519_CIPHERTEXT_LEN(message_len) ((message_len) + 48)Plaintext plus 32-byte ephemeral public key and 16-byte MAC.
#FIO_X25519_PLAINTEXT_LEN
#define FIO_X25519_PLAINTEXT_LEN(ciphertext_len) \
((ciphertext_len) > 48 ? ((ciphertext_len)-48) : 0)Reverses FIO_X25519_CIPHERTEXT_LEN. Returns 0 for invalid ciphertext.
#fio_x25519_encrypt
SFUNC int fio_x25519_encrypt(uint8_t *ciphertext,
const void *message,
size_t message_len,
fio_crypto_enc_fn encryption_function,
const uint8_t recipient_pk[32]);Encrypts a message to an X25519 public key. Ciphertext format: ephemeral_pk || mac || encrypted_data.
Parameters:
ciphertext— output buffer (message_len + 48bytes).message— plaintext.message_len— plaintext length.encryption_function— e.g.,fio_chacha20_poly1305_enc.recipient_pk— recipient's 32-byte X25519 public key.
Returns: 0 on success, -1 on failure.
#fio_x25519_decrypt
SFUNC int fio_x25519_decrypt(uint8_t *plaintext,
const uint8_t *ciphertext,
size_t ciphertext_len,
fio_crypto_dec_fn decryption_function,
const uint8_t recipient_sk[32]);Decrypts a message using the recipient's X25519 secret key.
Parameters:
plaintext— output buffer (ciphertext_len - 48bytes).ciphertext— ciphertext fromfio_x25519_encrypt.ciphertext_len— total ciphertext length (must be at least 48).decryption_function— e.g.,fio_chacha20_poly1305_dec.recipient_sk— recipient's 32-byte X25519 secret key.
Returns: 0 on success, -1 on failure.
#Example
#define FIO_ED25519
#include "fio-stl.h"
int main(void) {
uint8_t sk[32], pk[32], sig[64];
fio_ed25519_keypair(sk, pk);
const char *msg = "hello, ed25519";
fio_ed25519_sign(sig, msg, strlen(msg), sk, pk);
if (fio_ed25519_verify(sig, msg, strlen(msg), pk)) {
printf("bad signature\n");
return 1;
}
return 0;
}