C API Reference

Complete API documentation for MetaMUI Crypto Primitives in C.

Installation

Using pkg-config

# Install the library
make install PREFIX=/usr/local

# Compile with pkg-config
gcc -o myapp myapp.c $(pkg-config --cflags --libs metamui-crypto)

Static Linking

gcc -o myapp myapp.c -lmetamui_crypto_static -lm -lpthread

Dynamic Linking

gcc -o myapp myapp.c -lmetamui_crypto -lm -lpthread

Quick Start

#include <metamui/crypto.h>
#include <stdio.h>
#include <string.h>

int main() {
    // Initialize library
    metamui_init();
    
    // Generate Ed25519 keypair
    metamui_ed25519_keypair_t keypair;
    metamui_ed25519_generate_keypair(&keypair);
    
    // Sign a message
    const uint8_t message[] = "Hello, World!";
    uint8_t signature[METAMUI_ED25519_SIGNATURE_SIZE];
    
    metamui_ed25519_sign(signature, message, sizeof(message) - 1, 
                         keypair.private_key);
    
    // Verify signature
    int valid = metamui_ed25519_verify(signature, message, sizeof(message) - 1,
                                       keypair.public_key);
    
    printf("Signature %s\n", valid ? "valid" : "invalid");
    
    // Cleanup
    metamui_cleanup();
    return 0;
}

API Documentation

For detailed API documentation, see:

Header Files

Core Headers

#include <metamui/crypto.h>        // Main header, includes all modules
#include <metamui/hash.h>          // Hash functions
#include <metamui/signature.h>     // Digital signatures
#include <metamui/encryption.h>    // Symmetric encryption
#include <metamui/kex.h>          // Key exchange
#include <metamui/kdf.h>          // Key derivation
#include <metamui/pqc.h>          // Post-quantum algorithms
#include <metamui/util.h>         // Utility functions

Memory Management

Stack Allocation

// Fixed-size buffers on stack
uint8_t hash[METAMUI_SHA256_HASH_SIZE];
uint8_t key[METAMUI_CHACHA20_KEY_SIZE];
uint8_t nonce[METAMUI_CHACHA20_NONCE_SIZE];

Heap Allocation

// Dynamic allocation
size_t ciphertext_len = plaintext_len + METAMUI_CHACHA20_POLY1305_TAG_SIZE;
uint8_t *ciphertext = malloc(ciphertext_len);

// Always check allocation
if (ciphertext == NULL) {
    return METAMUI_ERR_MEMORY;
}

// Always free when done
free(ciphertext);

Secure Memory

// Allocate secure memory (locked, non-swappable)
uint8_t *secret_key = metamui_secure_alloc(32);
if (secret_key == NULL) {
    return METAMUI_ERR_MEMORY;
}

// Use the key...

// Secure cleanup (overwrites memory before freeing)
metamui_secure_free(secret_key, 32);

Error Handling

Return Codes

typedef enum {
    METAMUI_OK = 0,
    METAMUI_ERR_INVALID_PARAM = -1,
    METAMUI_ERR_INVALID_KEY = -2,
    METAMUI_ERR_INVALID_SIGNATURE = -3,
    METAMUI_ERR_DECRYPT_FAILED = -4,
    METAMUI_ERR_MEMORY = -5,
    METAMUI_ERR_NOT_INITIALIZED = -6,
    METAMUI_ERR_UNKNOWN = -99
} metamui_error_t;

Error Checking

metamui_error_t result;

// Check function return
result = metamui_aes256_gcm_encrypt(ciphertext, &ciphertext_len,
                                    plaintext, plaintext_len,
                                    key, nonce, aad, aad_len);
if (result != METAMUI_OK) {
    fprintf(stderr, "Encryption failed: %s\n", 
            metamui_error_string(result));
    return -1;
}

Thread Safety

Thread-Safe Functions

Most functions are thread-safe and can be called concurrently:

// These can be called from multiple threads simultaneously
metamui_sha256_hash(hash1, data1, len1);  // Thread 1
metamui_sha256_hash(hash2, data2, len2);  // Thread 2

Thread-Local State

Some operations require thread-local state:

// Each thread needs its own context
metamui_blake3_ctx_t ctx;
metamui_blake3_init(&ctx);
metamui_blake3_update(&ctx, data, len);
metamui_blake3_final(&ctx, hash);

Synchronization

// Use mutexes for shared resources
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

pthread_mutex_lock(&lock);
// Access shared cryptographic state
pthread_mutex_unlock(&lock);

Hash Functions

SHA-256/512

uint8_t hash[METAMUI_SHA256_HASH_SIZE];
metamui_sha256_hash(hash, data, data_len);

uint8_t hash512[METAMUI_SHA512_HASH_SIZE];
metamui_sha512_hash(hash512, data, data_len);

BLAKE2b/2s

uint8_t hash[METAMUI_BLAKE2B_HASH_SIZE];
metamui_blake2b_hash(hash, sizeof(hash), data, data_len, NULL, 0);

uint8_t hash2s[METAMUI_BLAKE2S_HASH_SIZE];
metamui_blake2s_hash(hash2s, sizeof(hash2s), data, data_len, NULL, 0);

BLAKE3

uint8_t hash[METAMUI_BLAKE3_HASH_SIZE];
metamui_blake3_hash(hash, data, data_len);

// Keyed hashing
uint8_t keyed_hash[METAMUI_BLAKE3_HASH_SIZE];
metamui_blake3_keyed_hash(keyed_hash, data, data_len, key);

// Derive key
uint8_t derived_key[32];
metamui_blake3_derive_key(derived_key, sizeof(derived_key), 
                         "my-context", data, data_len);

Streaming Hash

metamui_sha256_ctx_t ctx;
metamui_sha256_init(&ctx);

// Process chunks
while (has_more_data()) {
    metamui_sha256_update(&ctx, chunk, chunk_len);
}

// Get final hash
uint8_t hash[METAMUI_SHA256_HASH_SIZE];
metamui_sha256_final(&ctx, hash);

Digital Signatures

Ed25519

// Generate keypair
metamui_ed25519_keypair_t keypair;
metamui_ed25519_generate_keypair(&keypair);

// Sign
uint8_t signature[METAMUI_ED25519_SIGNATURE_SIZE];
metamui_ed25519_sign(signature, message, message_len, 
                    keypair.private_key);

// Verify
int valid = metamui_ed25519_verify(signature, message, message_len,
                                  keypair.public_key);

Sr25519

// Generate keypair
metamui_sr25519_keypair_t keypair;
metamui_sr25519_generate_keypair(&keypair);

// Sign with context
uint8_t signature[METAMUI_SR25519_SIGNATURE_SIZE];
metamui_sr25519_sign_with_context(signature, message, message_len,
                                  keypair.private_key, 
                                  context, context_len);

// Verify with context
int valid = metamui_sr25519_verify_with_context(signature, 
                                               message, message_len,
                                               keypair.public_key,
                                               context, context_len);

Encryption

ChaCha20-Poly1305

// Generate key and nonce
uint8_t key[METAMUI_CHACHA20_KEY_SIZE];
uint8_t nonce[METAMUI_CHACHA20_POLY1305_NONCE_SIZE];
metamui_random_bytes(key, sizeof(key));
metamui_random_bytes(nonce, sizeof(nonce));

// Encrypt with associated data
uint8_t tag[METAMUI_POLY1305_TAG_SIZE];
size_t ciphertext_len = plaintext_len;
uint8_t *ciphertext = malloc(ciphertext_len);

metamui_chacha20_poly1305_encrypt(ciphertext, tag,
                                  plaintext, plaintext_len,
                                  aad, aad_len,
                                  key, nonce);

// Decrypt and verify
uint8_t *decrypted = malloc(ciphertext_len);
int result = metamui_chacha20_poly1305_decrypt(decrypted,
                                               ciphertext, ciphertext_len,
                                               tag, aad, aad_len,
                                               key, nonce);
if (result != METAMUI_OK) {
    // Authentication failed
}

AES-256-GCM

// Generate key and IV
uint8_t key[METAMUI_AES256_KEY_SIZE];
uint8_t iv[METAMUI_AES256_GCM_IV_SIZE];
metamui_random_bytes(key, sizeof(key));
metamui_random_bytes(iv, sizeof(iv));

// Encrypt
uint8_t tag[METAMUI_AES256_GCM_TAG_SIZE];
size_t ciphertext_len = plaintext_len;
uint8_t *ciphertext = malloc(ciphertext_len);

metamui_aes256_gcm_encrypt(ciphertext, tag,
                          plaintext, plaintext_len,
                          aad, aad_len,
                          key, iv);

// Decrypt
uint8_t *decrypted = malloc(ciphertext_len);
int result = metamui_aes256_gcm_decrypt(decrypted,
                                       ciphertext, ciphertext_len,
                                       tag, aad, aad_len,
                                       key, iv);

Key Exchange

X25519

// Generate keypairs
uint8_t alice_private[METAMUI_X25519_KEY_SIZE];
uint8_t alice_public[METAMUI_X25519_KEY_SIZE];
uint8_t bob_private[METAMUI_X25519_KEY_SIZE];
uint8_t bob_public[METAMUI_X25519_KEY_SIZE];

metamui_x25519_generate_keypair(alice_public, alice_private);
metamui_x25519_generate_keypair(bob_public, bob_private);

// Compute shared secrets
uint8_t alice_shared[METAMUI_X25519_KEY_SIZE];
uint8_t bob_shared[METAMUI_X25519_KEY_SIZE];

metamui_x25519_compute_shared(alice_shared, alice_private, bob_public);
metamui_x25519_compute_shared(bob_shared, bob_private, alice_public);

// alice_shared == bob_shared

Post-Quantum Algorithms

ML-KEM-768

// Generate keypair
metamui_mlkem768_keypair_t keypair;
metamui_mlkem768_generate_keypair(&keypair);

// Encapsulation (sender)
uint8_t ciphertext[METAMUI_MLKEM768_CIPHERTEXT_SIZE];
uint8_t shared_secret[METAMUI_MLKEM768_SHARED_SECRET_SIZE];

metamui_mlkem768_encapsulate(ciphertext, shared_secret, 
                            keypair.public_key);

// Decapsulation (receiver)
uint8_t shared_secret2[METAMUI_MLKEM768_SHARED_SECRET_SIZE];
metamui_mlkem768_decapsulate(shared_secret2, ciphertext, 
                            keypair.private_key);

// shared_secret == shared_secret2

Dilithium

// Generate keypair
metamui_dilithium3_keypair_t keypair;
metamui_dilithium3_generate_keypair(&keypair);

// Sign
size_t signature_len;
uint8_t signature[METAMUI_DILITHIUM3_MAX_SIGNATURE_SIZE];

metamui_dilithium3_sign(signature, &signature_len,
                       message, message_len,
                       keypair.private_key);

// Verify
int valid = metamui_dilithium3_verify(signature, signature_len,
                                     message, message_len,
                                     keypair.public_key);

Key Derivation

Argon2

// Generate salt
uint8_t salt[METAMUI_ARGON2_SALT_SIZE];
metamui_random_bytes(salt, sizeof(salt));

// Hash password
uint8_t hash[32];
metamui_argon2_hash(hash, sizeof(hash),
                   password, password_len,
                   salt, sizeof(salt),
                   3,      // iterations
                   4096,   // memory (KB)
                   1);     // parallelism

// Verify password
int valid = metamui_argon2_verify(hash, sizeof(hash),
                                 password, password_len,
                                 salt, sizeof(salt),
                                 3, 4096, 1);

PBKDF2

uint8_t salt[16];
metamui_random_bytes(salt, sizeof(salt));

uint8_t derived_key[32];
metamui_pbkdf2_sha256(derived_key, sizeof(derived_key),
                     password, password_len,
                     salt, sizeof(salt),
                     100000);  // iterations

HKDF

// Extract
uint8_t prk[METAMUI_SHA256_HASH_SIZE];
metamui_hkdf_sha256_extract(prk, salt, salt_len, ikm, ikm_len);

// Expand
uint8_t okm[42];  // Can be any length
metamui_hkdf_sha256_expand(okm, sizeof(okm), prk, info, info_len);

// Or one-shot
metamui_hkdf_sha256(okm, sizeof(okm),
                   ikm, ikm_len,
                   salt, salt_len,
                   info, info_len);

Utility Functions

Random Number Generation

// Generate random bytes
uint8_t random_data[32];
metamui_random_bytes(random_data, sizeof(random_data));

// Generate random 32-bit integer
uint32_t random_int = metamui_random_u32();

// Generate random number in range [0, max)
uint32_t random_range = metamui_random_uniform(max);

Constant-Time Operations

// Constant-time comparison
int equal = metamui_ct_compare(a, b, len);

// Constant-time conditional copy
metamui_ct_select(dest, src1, src2, len, condition);

// Constant-time memory clear
metamui_secure_zero(sensitive_data, sizeof(sensitive_data));

Encoding/Decoding

// Hex encoding
char hex[65];  // 32 bytes = 64 hex chars + null
metamui_to_hex(hex, data, 32);

// Hex decoding
uint8_t decoded[32];
metamui_from_hex(decoded, hex, 64);

// Base64 encoding
char base64[45];  // 32 bytes = 44 base64 chars + null
size_t base64_len;
metamui_to_base64(base64, &base64_len, data, 32);

// Base64 decoding
uint8_t decoded_b64[32];
size_t decoded_len;
metamui_from_base64(decoded_b64, &decoded_len, base64, base64_len);

Build System Integration

CMake

find_package(MetaMUICrypto REQUIRED)
target_link_libraries(myapp MetaMUI::Crypto)

Makefile

CFLAGS += $(shell pkg-config --cflags metamui-crypto)
LDFLAGS += $(shell pkg-config --libs metamui-crypto)

myapp: myapp.c
    $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)

Autotools

# In configure.ac
PKG_CHECK_MODULES([METAMUI], [metamui-crypto >= 3.0.0])

# In Makefile.am
myapp_CFLAGS = $(METAMUI_CFLAGS)
myapp_LDADD = $(METAMUI_LIBS)

Performance Optimization

SIMD Support

// Check for SIMD availability
if (metamui_has_avx2()) {
    // Use AVX2-optimized functions
    metamui_blake3_hash_avx2(hash, data, data_len);
} else if (metamui_has_sse41()) {
    // Use SSE4.1-optimized functions
    metamui_blake3_hash_sse41(hash, data, data_len);
} else {
    // Fall back to portable implementation
    metamui_blake3_hash(hash, data, data_len);
}

Batch Operations

// Batch signature verification
metamui_ed25519_batch_verify_result_t results[100];
metamui_ed25519_batch_verify(results, 
                            signatures, messages, message_lens,
                            public_keys, count);

for (int i = 0; i < count; i++) {
    if (results[i] == METAMUI_BATCH_VALID) {
        // Signature i is valid
    }
}

Memory Pools

// Create memory pool for repeated allocations
metamui_pool_t *pool = metamui_pool_create(1024 * 1024);  // 1MB pool

// Allocate from pool (fast, no fragmentation)
void *buffer1 = metamui_pool_alloc(pool, 256);
void *buffer2 = metamui_pool_alloc(pool, 512);

// Reset pool (frees all allocations at once)
metamui_pool_reset(pool);

// Destroy pool when done
metamui_pool_destroy(pool);

Security Notes

Best Practices

  1. Always check return values - Crypto operations can fail
  2. Use secure random sources - Never use rand() for crypto
  3. Clear sensitive memory - Use metamui_secure_zero()
  4. Validate input sizes - Check buffer bounds
  5. Use constant-time operations - For secret-dependent code

Common Pitfalls

// DON'T: Compare secrets with memcmp (not constant-time)
if (memcmp(computed_mac, expected_mac, 32) == 0) {  // BAD!
    // ...
}

// DO: Use constant-time comparison
if (metamui_ct_compare(computed_mac, expected_mac, 32)) {  // GOOD!
    // ...
}

// DON'T: Leave secrets in memory
uint8_t secret_key[32];
// ... use key ...
// Key remains in memory!  // BAD!

// DO: Clear sensitive data
uint8_t secret_key[32];
// ... use key ...
metamui_secure_zero(secret_key, sizeof(secret_key));  // GOOD!

Platform Security Features

// Enable platform security features
metamui_enable_secure_mode();

// Check if running in secure environment
if (metamui_is_secure_environment()) {
    // Use hardware security features
    metamui_use_hardware_rng();
    metamui_use_hardware_aes();
}

Examples

Complete Encryption Example

#include <metamui/crypto.h>
#include <stdio.h>
#include <string.h>

int encrypt_file(const char *input_file, const char *output_file,
                const uint8_t *key) {
    FILE *in = fopen(input_file, "rb");
    FILE *out = fopen(output_file, "wb");
    
    if (!in || !out) {
        return -1;
    }
    
    // Generate random nonce
    uint8_t nonce[METAMUI_CHACHA20_POLY1305_NONCE_SIZE];
    metamui_random_bytes(nonce, sizeof(nonce));
    
    // Write nonce to output
    fwrite(nonce, 1, sizeof(nonce), out);
    
    // Initialize encryption context
    metamui_chacha20_poly1305_ctx_t ctx;
    metamui_chacha20_poly1305_init(&ctx, key, nonce);
    
    // Encrypt file in chunks
    uint8_t buffer[4096];
    size_t bytes_read;
    
    while ((bytes_read = fread(buffer, 1, sizeof(buffer), in)) > 0) {
        metamui_chacha20_poly1305_update(&ctx, buffer, bytes_read);
        fwrite(buffer, 1, bytes_read, out);
    }
    
    // Write authentication tag
    uint8_t tag[METAMUI_POLY1305_TAG_SIZE];
    metamui_chacha20_poly1305_final(&ctx, tag);
    fwrite(tag, 1, sizeof(tag), out);
    
    fclose(in);
    fclose(out);
    return 0;
}

Secure Communication Protocol

typedef struct {
    metamui_mlkem768_keypair_t kem_keypair;
    metamui_ed25519_keypair_t sign_keypair;
} identity_t;

int establish_secure_channel(identity_t *alice, identity_t *bob,
                            uint8_t *shared_key) {
    // Alice: Create ephemeral shared secret
    uint8_t ciphertext[METAMUI_MLKEM768_CIPHERTEXT_SIZE];
    uint8_t alice_secret[METAMUI_MLKEM768_SHARED_SECRET_SIZE];
    
    metamui_mlkem768_encapsulate(ciphertext, alice_secret,
                                bob->kem_keypair.public_key);
    
    // Alice: Sign the ciphertext
    uint8_t signature[METAMUI_ED25519_SIGNATURE_SIZE];
    metamui_ed25519_sign(signature, ciphertext, sizeof(ciphertext),
                        alice->sign_keypair.private_key);
    
    // Bob: Verify signature
    if (!metamui_ed25519_verify(signature, ciphertext, sizeof(ciphertext),
                               alice->sign_keypair.public_key)) {
        return -1;  // Authentication failed
    }
    
    // Bob: Decapsulate to get shared secret
    uint8_t bob_secret[METAMUI_MLKEM768_SHARED_SECRET_SIZE];
    metamui_mlkem768_decapsulate(bob_secret, ciphertext,
                               bob->kem_keypair.private_key);
    
    // Derive session key from shared secret
    metamui_hkdf_sha256(shared_key, 32,
                       bob_secret, sizeof(bob_secret),
                       NULL, 0,
                       (uint8_t*)"session", 7);
    
    // Clear secrets
    metamui_secure_zero(alice_secret, sizeof(alice_secret));
    metamui_secure_zero(bob_secret, sizeof(bob_secret));
    
    return 0;
}

See Also