#ifndef ZERIN_CRYPTO_H #define ZERIN_CRYPTO_H #include #include #define CRYPTO_KEY_SIZE 32 #define CRYPTO_NONCE_SIZE 12 #define CRYPTO_TAG_SIZE 16 #define CRYPTO_SHA256_SIZE 32 #define CRYPTO_X25519_KEY 32 // ============================================================================ // Random // ============================================================================ int crypto_random_bytes(uint8_t *buf, size_t len); double crypto_random_float(void); // [0.0, 1.0) // ============================================================================ // SHA-256 // ============================================================================ typedef struct { uint32_t state[8]; uint64_t bitcount; uint8_t buffer[64]; uint32_t buflen; } sha256_ctx_t; void sha256_init(sha256_ctx_t *ctx); void sha256_update(sha256_ctx_t *ctx, const uint8_t *data, size_t len); void sha256_final(sha256_ctx_t *ctx, uint8_t out[32]); void sha256(const uint8_t *data, size_t len, uint8_t out[32]); // HMAC-SHA256 void hmac_sha256(const uint8_t *key, size_t key_len, const uint8_t *data, size_t data_len, uint8_t out[32]); // ============================================================================ // HKDF (RFC 5869) // ============================================================================ int hkdf_extract(const uint8_t *salt, size_t salt_len, const uint8_t *ikm, size_t ikm_len, uint8_t prk[32]); int hkdf_expand(const uint8_t prk[32], const uint8_t *info, size_t info_len, uint8_t *okm, size_t okm_len); int hkdf_derive(const uint8_t *salt, size_t salt_len, const uint8_t *ikm, size_t ikm_len, const uint8_t *info, size_t info_len, uint8_t *okm, size_t okm_len); // ============================================================================ // X25519 (RFC 7748) // ============================================================================ void x25519_clamp(uint8_t key[32]); int x25519_keygen(uint8_t privkey[32], uint8_t pubkey[32]); int x25519_shared_secret(const uint8_t privkey[32], const uint8_t peer_pubkey[32], uint8_t shared[32]); // ============================================================================ // ChaCha20 (RFC 8439) // ============================================================================ typedef struct { uint32_t state[16]; } chacha20_ctx_t; void chacha20_init(chacha20_ctx_t *ctx, const uint8_t key[32], const uint8_t nonce[12], uint32_t counter); void chacha20_encrypt(chacha20_ctx_t *ctx, const uint8_t *in, uint8_t *out, size_t len); // ============================================================================ // Poly1305 (RFC 8439) // ============================================================================ typedef struct { uint32_t r[5]; uint32_t h[5]; uint32_t pad[4]; uint8_t buffer[16]; size_t buflen; size_t total; } poly1305_ctx_t; void poly1305_init(poly1305_ctx_t *ctx, const uint8_t key[32]); void poly1305_update(poly1305_ctx_t *ctx, const uint8_t *data, size_t len); void poly1305_final(poly1305_ctx_t *ctx, uint8_t tag[16]); // ============================================================================ // ChaCha20-Poly1305 AEAD (RFC 8439) // ============================================================================ // Encrypt: returns ciphertext_len (plaintext_len + 16 for tag) // out must have room for plaintext_len + CRYPTO_TAG_SIZE int aead_encrypt(const uint8_t key[32], const uint8_t nonce[12], const uint8_t *aad, size_t aad_len, const uint8_t *plaintext, size_t plaintext_len, uint8_t *out); // Decrypt: returns 0 on success, -1 on auth failure // out must have room for ciphertext_len - CRYPTO_TAG_SIZE int aead_decrypt(const uint8_t key[32], const uint8_t nonce[12], const uint8_t *aad, size_t aad_len, const uint8_t *ciphertext, size_t ciphertext_len, uint8_t *out); // ============================================================================ // Key Exchange // ============================================================================ typedef struct { uint8_t agent_pubkey_hash[32]; // SHA256(agent_pubkey) uint8_t ephemeral_pubkey[32]; uint8_t ephemeral_privkey[32]; // NOT sent uint8_t session_key[32]; } key_exchange_t; int key_exchange_init(key_exchange_t *kx, const uint8_t agent_pubkey[32]); int key_exchange_derive(key_exchange_t *kx, const uint8_t server_pubkey[32]); // ============================================================================ // Utility // ============================================================================ void secure_zero(void *ptr, size_t len); int constant_time_compare(const uint8_t *a, const uint8_t *b, size_t len); #endif // ZERIN_CRYPTO_H