High-performance cryptographic operations are essential for modern enterprise systems that must balance security requirements with performance demands. This comprehensive guide explores advanced techniques for implementing cryptographic algorithms efficiently while maintaining security against sophisticated attacks, covering everything from low-level optimizations to hardware acceleration and protocol design.

Cryptographic Fundamentals and Performance Considerations

Understanding the mathematical foundations and performance characteristics of cryptographic algorithms is crucial for building efficient implementations that maintain security properties.

Symmetric Encryption: Advanced AES Implementation

#include <stdint.h>
#include <string.h>
#include <immintrin.h> // For AES-NI instructions
#include <openssl/aes.h>
#include <openssl/rand.h>

// AES-NI optimized implementation
typedef struct {
    __m128i round_keys[15]; // Maximum rounds for AES-256
    int num_rounds;
    size_t key_length;
    
    // Performance counters
    uint64_t blocks_encrypted;
    uint64_t blocks_decrypted;
    uint64_t total_bytes;
    
    // Security features
    bool constant_time_enabled;
    bool side_channel_protection;
} aes_context_t;

// AES key schedule using AES-NI instructions
static void aes_key_schedule_ni(aes_context_t *ctx, const uint8_t *key, size_t key_len)
{
    ctx->key_length = key_len;
    
    switch (key_len) {
        case 16: // AES-128
            ctx->num_rounds = 10;
            break;
        case 24: // AES-192
            ctx->num_rounds = 12;
            break;
        case 32: // AES-256
            ctx->num_rounds = 14;
            break;
        default:
            return; // Invalid key length
    }
    
    // Load initial key
    ctx->round_keys[0] = _mm_loadu_si128((__m128i*)key);
    
    if (key_len == 16) {
        // AES-128 key expansion
        __m128i temp1, temp2;
        __m128i *round_key = ctx->round_keys;
        
        temp1 = round_key[0];
        
        // Round 1
        temp2 = _mm_aeskeygenassist_si128(temp1, 0x01);
        temp1 = aes_128_key_expansion(temp1, temp2);
        round_key[1] = temp1;
        
        // Round 2
        temp2 = _mm_aeskeygenassist_si128(temp1, 0x02);
        temp1 = aes_128_key_expansion(temp1, temp2);
        round_key[2] = temp1;
        
        // Continue for all rounds...
        // (Simplified for brevity - real implementation would include all rounds)
    }
    // Similar implementations for AES-192 and AES-256
}

// AES-128 key expansion helper function
static __m128i aes_128_key_expansion(__m128i key, __m128i keygened)
{
    keygened = _mm_shuffle_epi32(keygened, _MM_SHUFFLE(3,3,3,3));
    key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
    key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
    key = _mm_xor_si128(key, _mm_slli_si128(key, 4));
    return _mm_xor_si128(key, keygened);
}

// High-performance AES encryption using AES-NI
static void aes_encrypt_block_ni(const aes_context_t *ctx, 
                                const uint8_t *plaintext, 
                                uint8_t *ciphertext)
{
    __m128i block = _mm_loadu_si128((__m128i*)plaintext);
    
    // Initial round
    block = _mm_xor_si128(block, ctx->round_keys[0]);
    
    // Main rounds
    for (int round = 1; round < ctx->num_rounds; round++) {
        block = _mm_aesenc_si128(block, ctx->round_keys[round]);
    }
    
    // Final round
    block = _mm_aesenclast_si128(block, ctx->round_keys[ctx->num_rounds]);
    
    _mm_storeu_si128((__m128i*)ciphertext, block);
}

// Vectorized AES encryption for multiple blocks
static void aes_encrypt_blocks_parallel(const aes_context_t *ctx,
                                       const uint8_t *plaintext,
                                       uint8_t *ciphertext,
                                       size_t num_blocks)
{
    const size_t parallel_blocks = 8; // Process 8 blocks in parallel
    
    for (size_t i = 0; i < num_blocks; i += parallel_blocks) {
        size_t blocks_to_process = (num_blocks - i < parallel_blocks) ? 
                                  num_blocks - i : parallel_blocks;
        
        __m128i blocks[8];
        
        // Load blocks
        for (size_t j = 0; j < blocks_to_process; j++) {
            blocks[j] = _mm_loadu_si128((__m128i*)(plaintext + (i + j) * 16));
        }
        
        // Initial round
        for (size_t j = 0; j < blocks_to_process; j++) {
            blocks[j] = _mm_xor_si128(blocks[j], ctx->round_keys[0]);
        }
        
        // Main rounds
        for (int round = 1; round < ctx->num_rounds; round++) {
            for (size_t j = 0; j < blocks_to_process; j++) {
                blocks[j] = _mm_aesenc_si128(blocks[j], ctx->round_keys[round]);
            }
        }
        
        // Final round
        for (size_t j = 0; j < blocks_to_process; j++) {
            blocks[j] = _mm_aesenclast_si128(blocks[j], ctx->round_keys[ctx->num_rounds]);
        }
        
        // Store results
        for (size_t j = 0; j < blocks_to_process; j++) {
            _mm_storeu_si128((__m128i*)(ciphertext + (i + j) * 16), blocks[j]);
        }
    }
}

// AES-GCM implementation with authentication
typedef struct {
    aes_context_t aes_ctx;
    __m128i auth_key;
    __m128i ghash_key;
    uint64_t total_aad_len;
    uint64_t total_plaintext_len;
} aes_gcm_context_t;

// GHASH function for AES-GCM authentication
static __m128i ghash_multiply(__m128i a, __m128i b)
{
    __m128i tmp0, tmp1, tmp2, tmp3;
    __m128i zero = _mm_setzero_si128();
    
    tmp0 = _mm_clmulepi64_si128(a, b, 0x00);
    tmp1 = _mm_clmulepi64_si128(a, b, 0x01);
    tmp2 = _mm_clmulepi64_si128(a, b, 0x10);
    tmp3 = _mm_clmulepi64_si128(a, b, 0x11);
    
    tmp1 = _mm_xor_si128(tmp1, tmp2);
    tmp2 = _mm_slli_si128(tmp1, 8);
    tmp1 = _mm_srli_si128(tmp1, 8);
    
    tmp0 = _mm_xor_si128(tmp0, tmp2);
    tmp3 = _mm_xor_si128(tmp3, tmp1);
    
    // Reduction
    __m128i poly = _mm_setr_epi32(0x1, 0, 0, 0xc2000000);
    tmp1 = _mm_clmulepi64_si128(tmp3, poly, 0x01);
    tmp2 = _mm_shuffle_epi32(tmp3, 0x4e);
    tmp3 = _mm_xor_si128(tmp1, tmp2);
    
    tmp1 = _mm_clmulepi64_si128(tmp3, poly, 0x00);
    tmp3 = _mm_shuffle_epi32(tmp3, 0x4e);
    tmp3 = _mm_xor_si128(tmp1, tmp3);
    
    return _mm_xor_si128(tmp0, tmp3);
}

// AES-GCM encryption with authentication
static int aes_gcm_encrypt(aes_gcm_context_t *ctx,
                          const uint8_t *plaintext, size_t plaintext_len,
                          const uint8_t *aad, size_t aad_len,
                          const uint8_t *iv, size_t iv_len,
                          uint8_t *ciphertext, uint8_t *tag, size_t tag_len)
{
    if (tag_len > 16) return -1;
    
    __m128i counter, auth_block;
    __m128i ghash_state = _mm_setzero_si128();
    
    // Process IV
    if (iv_len == 12) {
        counter = _mm_loadu_si128((__m128i*)iv);
        counter = _mm_insert_epi32(counter, 0x01000000, 3); // Big-endian 1
    } else {
        // GHASH the IV if it's not 96 bits
        // (Implementation details omitted for brevity)
    }
    
    // Generate authentication key
    __m128i zero_block = _mm_setzero_si128();
    aes_encrypt_block_ni(&ctx->aes_ctx, (uint8_t*)&zero_block, (uint8_t*)&ctx->auth_key);
    
    // Process AAD
    if (aad_len > 0) {
        size_t aad_blocks = (aad_len + 15) / 16;
        for (size_t i = 0; i < aad_blocks; i++) {
            __m128i aad_block = _mm_setzero_si128();
            size_t block_len = (i == aad_blocks - 1 && aad_len % 16) ? 
                              aad_len % 16 : 16;
            memcpy(&aad_block, aad + i * 16, block_len);
            
            ghash_state = _mm_xor_si128(ghash_state, aad_block);
            ghash_state = ghash_multiply(ghash_state, ctx->auth_key);
        }
    }
    
    // Encrypt plaintext and update GHASH
    size_t plaintext_blocks = (plaintext_len + 15) / 16;
    for (size_t i = 0; i < plaintext_blocks; i++) {
        // Increment counter
        counter = _mm_add_epi32(counter, _mm_setr_epi32(0, 0, 0, 0x01000000));
        
        // Encrypt counter
        __m128i keystream_block;
        aes_encrypt_block_ni(&ctx->aes_ctx, (uint8_t*)&counter, (uint8_t*)&keystream_block);
        
        // XOR with plaintext
        __m128i plaintext_block = _mm_setzero_si128();
        size_t block_len = (i == plaintext_blocks - 1 && plaintext_len % 16) ?
                          plaintext_len % 16 : 16;
        memcpy(&plaintext_block, plaintext + i * 16, block_len);
        
        __m128i ciphertext_block = _mm_xor_si128(plaintext_block, keystream_block);
        memcpy(ciphertext + i * 16, &ciphertext_block, block_len);
        
        // Update GHASH
        ghash_state = _mm_xor_si128(ghash_state, ciphertext_block);
        ghash_state = ghash_multiply(ghash_state, ctx->auth_key);
    }
    
    // Final GHASH with lengths
    __m128i length_block = _mm_setr_epi64x(aad_len * 8, plaintext_len * 8);
    ghash_state = _mm_xor_si128(ghash_state, length_block);
    ghash_state = ghash_multiply(ghash_state, ctx->auth_key);
    
    // Generate authentication tag
    __m128i tag_mask;
    counter = _mm_loadu_si128((__m128i*)iv);
    counter = _mm_insert_epi32(counter, 0x01000000, 3);
    aes_encrypt_block_ni(&ctx->aes_ctx, (uint8_t*)&counter, (uint8_t*)&tag_mask);
    
    __m128i auth_tag = _mm_xor_si128(ghash_state, tag_mask);
    memcpy(tag, &auth_tag, tag_len);
    
    return 0;
}

Asymmetric Cryptography: RSA and Elliptic Curve Optimizations

Asymmetric cryptography requires careful optimization of big integer arithmetic and curve operations.

High-Performance RSA Implementation

#include <gmp.h> // GNU Multiple Precision Arithmetic Library

typedef struct {
    mpz_t n; // Modulus
    mpz_t e; // Public exponent
    mpz_t d; // Private exponent
    mpz_t p; // Prime factor 1
    mpz_t q; // Prime factor 2
    
    // CRT components for fast decryption
    mpz_t dp; // d mod (p-1)
    mpz_t dq; // d mod (q-1)
    mpz_t qinv; // q^-1 mod p
    
    size_t key_size; // In bits
    bool crt_enabled;
    
    // Performance counters
    uint64_t encryptions;
    uint64_t decryptions;
    uint64_t signatures;
    uint64_t verifications;
} rsa_key_t;

// Initialize RSA key structure
static void rsa_key_init(rsa_key_t *key)
{
    mpz_init(key->n);
    mpz_init(key->e);
    mpz_init(key->d);
    mpz_init(key->p);
    mpz_init(key->q);
    mpz_init(key->dp);
    mpz_init(key->dq);
    mpz_init(key->qinv);
    
    key->crt_enabled = true;
    key->encryptions = 0;
    key->decryptions = 0;
    key->signatures = 0;
    key->verifications = 0;
}

// Generate RSA key pair with secure random primes
static int rsa_generate_key(rsa_key_t *key, size_t key_size)
{
    if (key_size < 2048 || key_size % 8 != 0) {
        return -1; // Minimum 2048 bits, multiple of 8
    }
    
    key->key_size = key_size;
    size_t prime_bits = key_size / 2;
    
    gmp_randstate_t rstate;
    gmp_randinit_default(rstate);
    
    // Seed with secure random data
    unsigned char seed[32];
    if (RAND_bytes(seed, sizeof(seed)) != 1) {
        return -1;
    }
    gmp_randseed(rstate, *(mpz_t*)seed);
    
    mpz_t phi_n, gcd_temp, p_minus_1, q_minus_1;
    mpz_init(phi_n);
    mpz_init(gcd_temp);
    mpz_init(p_minus_1);
    mpz_init(q_minus_1);
    
    // Generate prime p
    do {
        mpz_urandomb(key->p, rstate, prime_bits);
        mpz_setbit(key->p, prime_bits - 1); // Ensure high bit is set
        mpz_setbit(key->p, 0); // Ensure odd
        
        // Miller-Rabin primality test
    } while (mpz_probab_prime_p(key->p, 50) == 0);
    
    // Generate prime q (different from p)
    do {
        mpz_urandomb(key->q, rstate, prime_bits);
        mpz_setbit(key->q, prime_bits - 1);
        mpz_setbit(key->q, 0);
        
        // Ensure q != p and |p - q| is large enough
        mpz_sub(gcd_temp, key->p, key->q);
        mpz_abs(gcd_temp, gcd_temp);
        
    } while (mpz_probab_prime_p(key->q, 50) == 0 || 
             mpz_cmp(key->p, key->q) == 0 ||
             mpz_sizeinbase(gcd_temp, 2) < prime_bits - 100);
    
    // Calculate n = p * q
    mpz_mul(key->n, key->p, key->q);
    
    // Calculate phi(n) = (p-1)(q-1)
    mpz_sub_ui(p_minus_1, key->p, 1);
    mpz_sub_ui(q_minus_1, key->q, 1);
    mpz_mul(phi_n, p_minus_1, q_minus_1);
    
    // Choose public exponent e = 65537
    mpz_set_ui(key->e, 65537);
    
    // Verify gcd(e, phi(n)) = 1
    mpz_gcd(gcd_temp, key->e, phi_n);
    if (mpz_cmp_ui(gcd_temp, 1) != 0) {
        // This should be extremely rare with e = 65537
        return -1;
    }
    
    // Calculate private exponent d = e^-1 mod phi(n)
    if (mpz_invert(key->d, key->e, phi_n) == 0) {
        return -1;
    }
    
    // Calculate CRT components for fast decryption
    mpz_mod(key->dp, key->d, p_minus_1);
    mpz_mod(key->dq, key->d, q_minus_1);
    mpz_invert(key->qinv, key->q, key->p);
    
    // Cleanup
    mpz_clear(phi_n);
    mpz_clear(gcd_temp);
    mpz_clear(p_minus_1);
    mpz_clear(q_minus_1);
    gmp_randclear(rstate);
    
    return 0;
}

// RSA encryption (public key operation)
static int rsa_encrypt(const rsa_key_t *key, const mpz_t plaintext, mpz_t ciphertext)
{
    // Verify plaintext < n
    if (mpz_cmp(plaintext, key->n) >= 0) {
        return -1;
    }
    
    // c = m^e mod n
    mpz_powm(ciphertext, plaintext, key->e, key->n);
    
    ((rsa_key_t*)key)->encryptions++;
    
    return 0;
}

// RSA decryption using Chinese Remainder Theorem
static int rsa_decrypt_crt(const rsa_key_t *key, const mpz_t ciphertext, mpz_t plaintext)
{
    if (!key->crt_enabled) {
        // Fallback to standard decryption
        mpz_powm(plaintext, ciphertext, key->d, key->n);
        ((rsa_key_t*)key)->decryptions++;
        return 0;
    }
    
    mpz_t m1, m2, h, temp;
    mpz_init(m1);
    mpz_init(m2);
    mpz_init(h);
    mpz_init(temp);
    
    // m1 = c^dp mod p
    mpz_powm(m1, ciphertext, key->dp, key->p);
    
    // m2 = c^dq mod q
    mpz_powm(m2, ciphertext, key->dq, key->q);
    
    // h = qinv * (m1 - m2) mod p
    mpz_sub(temp, m1, m2);
    mpz_mul(temp, temp, key->qinv);
    mpz_mod(h, temp, key->p);
    
    // m = m2 + h * q
    mpz_mul(temp, h, key->q);
    mpz_add(plaintext, m2, temp);
    
    // Cleanup
    mpz_clear(m1);
    mpz_clear(m2);
    mpz_clear(h);
    mpz_clear(temp);
    
    ((rsa_key_t*)key)->decryptions++;
    
    return 0;
}

// Constant-time RSA operations for side-channel resistance
static int rsa_decrypt_constant_time(const rsa_key_t *key, 
                                    const mpz_t ciphertext, 
                                    mpz_t plaintext)
{
    // Montgomery ladder for constant-time exponentiation
    mpz_t r0, r1, temp;
    mpz_init_set_ui(r0, 1);
    mpz_init_set(r1, ciphertext);
    mpz_init(temp);
    
    size_t d_bits = mpz_sizeinbase(key->d, 2);
    
    for (long i = d_bits - 2; i >= 0; i--) {
        int bit = mpz_tstbit(key->d, i);
        
        if (bit == 0) {
            // r1 = r0 * r1 mod n, r0 = r0^2 mod n
            mpz_mul(temp, r0, r1);
            mpz_mod(r1, temp, key->n);
            mpz_mul(temp, r0, r0);
            mpz_mod(r0, temp, key->n);
        } else {
            // r0 = r0 * r1 mod n, r1 = r1^2 mod n
            mpz_mul(temp, r0, r1);
            mpz_mod(r0, temp, key->n);
            mpz_mul(temp, r1, r1);
            mpz_mod(r1, temp, key->n);
        }
    }
    
    mpz_set(plaintext, r0);
    
    mpz_clear(r0);
    mpz_clear(r1);
    mpz_clear(temp);
    
    return 0;
}

Elliptic Curve Cryptography Implementation

// Elliptic curve point structure (Jacobian coordinates)
typedef struct {
    mpz_t x, y, z;
    bool is_infinity;
} ec_point_t;

// Elliptic curve parameters
typedef struct {
    mpz_t p; // Prime modulus
    mpz_t a, b; // Curve parameters y^2 = x^3 + ax + b
    ec_point_t G; // Generator point
    mpz_t n; // Order of generator
    size_t bit_length;
    
    // Precomputed values for optimization
    ec_point_t *precomputed_G; // Precomputed multiples of G
    size_t precomputed_count;
    
    // Montgomery curve parameters (if applicable)
    mpz_t A24; // (A + 2) / 4 for Montgomery ladder
} ec_curve_t;

// Initialize elliptic curve point
static void ec_point_init(ec_point_t *point)
{
    mpz_init(point->x);
    mpz_init(point->y);
    mpz_init(point->z);
    point->is_infinity = true;
}

// Set point to infinity
static void ec_point_set_infinity(ec_point_t *point)
{
    mpz_set_ui(point->x, 1);
    mpz_set_ui(point->y, 1);
    mpz_set_ui(point->z, 0);
    point->is_infinity = true;
}

// Convert from affine to Jacobian coordinates
static void ec_point_affine_to_jacobian(ec_point_t *jac, 
                                       const mpz_t x, const mpz_t y)
{
    mpz_set(jac->x, x);
    mpz_set(jac->y, y);
    mpz_set_ui(jac->z, 1);
    jac->is_infinity = false;
}

// Point doubling in Jacobian coordinates
static void ec_point_double(const ec_curve_t *curve, 
                           const ec_point_t *P, 
                           ec_point_t *result)
{
    if (P->is_infinity) {
        ec_point_set_infinity(result);
        return;
    }
    
    mpz_t A, B, C, D, E, F, temp;
    mpz_init(A); mpz_init(B); mpz_init(C); mpz_init(D);
    mpz_init(E); mpz_init(F); mpz_init(temp);
    
    // A = X1^2
    mpz_mul(A, P->x, P->x);
    mpz_mod(A, A, curve->p);
    
    // B = Y1^2
    mpz_mul(B, P->y, P->y);
    mpz_mod(B, B, curve->p);
    
    // C = B^2
    mpz_mul(C, B, B);
    mpz_mod(C, C, curve->p);
    
    // D = 2*((X1+B)^2-A-C)
    mpz_add(temp, P->x, B);
    mpz_mul(temp, temp, temp);
    mpz_sub(temp, temp, A);
    mpz_sub(temp, temp, C);
    mpz_mul_ui(D, temp, 2);
    mpz_mod(D, D, curve->p);
    
    // E = 3*A
    mpz_mul_ui(E, A, 3);
    mpz_mod(E, E, curve->p);
    
    // F = E^2
    mpz_mul(F, E, E);
    mpz_mod(F, F, curve->p);
    
    // X3 = F - 2*D
    mpz_mul_ui(temp, D, 2);
    mpz_sub(result->x, F, temp);
    mpz_mod(result->x, result->x, curve->p);
    
    // Y3 = E*(D-X3) - 8*C
    mpz_sub(temp, D, result->x);
    mpz_mul(temp, E, temp);
    mpz_mul_ui(C, C, 8);
    mpz_sub(result->y, temp, C);
    mpz_mod(result->y, result->y, curve->p);
    
    // Z3 = 2*Y1*Z1
    mpz_mul(result->z, P->y, P->z);
    mpz_mul_ui(result->z, result->z, 2);
    mpz_mod(result->z, result->z, curve->p);
    
    result->is_infinity = false;
    
    // Cleanup
    mpz_clear(A); mpz_clear(B); mpz_clear(C); mpz_clear(D);
    mpz_clear(E); mpz_clear(F); mpz_clear(temp);
}

// Point addition in Jacobian coordinates
static void ec_point_add(const ec_curve_t *curve,
                        const ec_point_t *P, const ec_point_t *Q,
                        ec_point_t *result)
{
    if (P->is_infinity) {
        mpz_set(result->x, Q->x);
        mpz_set(result->y, Q->y);
        mpz_set(result->z, Q->z);
        result->is_infinity = Q->is_infinity;
        return;
    }
    
    if (Q->is_infinity) {
        mpz_set(result->x, P->x);
        mpz_set(result->y, P->y);
        mpz_set(result->z, P->z);
        result->is_infinity = P->is_infinity;
        return;
    }
    
    mpz_t U1, U2, S1, S2, H, r, temp1, temp2;
    mpz_init(U1); mpz_init(U2); mpz_init(S1); mpz_init(S2);
    mpz_init(H); mpz_init(r); mpz_init(temp1); mpz_init(temp2);
    
    // U1 = X1*Z2^2
    mpz_mul(temp1, Q->z, Q->z);
    mpz_mod(temp1, temp1, curve->p);
    mpz_mul(U1, P->x, temp1);
    mpz_mod(U1, U1, curve->p);
    
    // U2 = X2*Z1^2
    mpz_mul(temp1, P->z, P->z);
    mpz_mod(temp1, temp1, curve->p);
    mpz_mul(U2, Q->x, temp1);
    mpz_mod(U2, U2, curve->p);
    
    // S1 = Y1*Z2^3
    mpz_mul(temp1, Q->z, Q->z);
    mpz_mul(temp1, temp1, Q->z);
    mpz_mod(temp1, temp1, curve->p);
    mpz_mul(S1, P->y, temp1);
    mpz_mod(S1, S1, curve->p);
    
    // S2 = Y2*Z1^3
    mpz_mul(temp1, P->z, P->z);
    mpz_mul(temp1, temp1, P->z);
    mpz_mod(temp1, temp1, curve->p);
    mpz_mul(S2, Q->y, temp1);
    mpz_mod(S2, S2, curve->p);
    
    // Check if points are equal
    if (mpz_cmp(U1, U2) == 0) {
        if (mpz_cmp(S1, S2) == 0) {
            // Points are equal, perform doubling
            ec_point_double(curve, P, result);
        } else {
            // Points are additive inverses
            ec_point_set_infinity(result);
        }
        goto cleanup;
    }
    
    // H = U2 - U1
    mpz_sub(H, U2, U1);
    mpz_mod(H, H, curve->p);
    
    // r = S2 - S1
    mpz_sub(r, S2, S1);
    mpz_mod(r, r, curve->p);
    
    // X3 = r^2 - H^3 - 2*U1*H^2
    mpz_mul(temp1, r, r);
    mpz_mul(temp2, H, H);
    mpz_mul(temp2, temp2, H); // H^3
    mpz_sub(result->x, temp1, temp2);
    
    mpz_mul(temp1, H, H); // H^2
    mpz_mul(temp1, temp1, U1);
    mpz_mul_ui(temp1, temp1, 2);
    mpz_sub(result->x, result->x, temp1);
    mpz_mod(result->x, result->x, curve->p);
    
    // Y3 = r*(U1*H^2 - X3) - S1*H^3
    mpz_mul(temp1, H, H);
    mpz_mul(temp1, temp1, U1);
    mpz_sub(temp1, temp1, result->x);
    mpz_mul(temp1, r, temp1);
    
    mpz_mul(temp2, H, H);
    mpz_mul(temp2, temp2, H);
    mpz_mul(temp2, temp2, S1);
    
    mpz_sub(result->y, temp1, temp2);
    mpz_mod(result->y, result->y, curve->p);
    
    // Z3 = Z1*Z2*H
    mpz_mul(result->z, P->z, Q->z);
    mpz_mul(result->z, result->z, H);
    mpz_mod(result->z, result->z, curve->p);
    
    result->is_infinity = false;

cleanup:
    mpz_clear(U1); mpz_clear(U2); mpz_clear(S1); mpz_clear(S2);
    mpz_clear(H); mpz_clear(r); mpz_clear(temp1); mpz_clear(temp2);
}

// Scalar multiplication using windowed NAF method
static void ec_point_mul(const ec_curve_t *curve, 
                        const mpz_t scalar, 
                        const ec_point_t *point,
                        ec_point_t *result)
{
    if (mpz_cmp_ui(scalar, 0) == 0) {
        ec_point_set_infinity(result);
        return;
    }
    
    // Precompute odd multiples: P, 3P, 5P, ..., (2^w-1)P
    const int window_size = 4;
    const int precomp_size = 1 << (window_size - 1);
    
    ec_point_t precomp[precomp_size];
    for (int i = 0; i < precomp_size; i++) {
        ec_point_init(&precomp[i]);
    }
    
    // precomp[0] = P
    mpz_set(precomp[0].x, point->x);
    mpz_set(precomp[0].y, point->y);
    mpz_set(precomp[0].z, point->z);
    precomp[0].is_infinity = point->is_infinity;
    
    // precomp[1] = 2P
    ec_point_t double_P;
    ec_point_init(&double_P);
    ec_point_double(curve, point, &double_P);
    
    // Compute remaining odd multiples
    for (int i = 1; i < precomp_size; i++) {
        ec_point_add(curve, &precomp[i-1], &double_P, &precomp[i]);
    }
    
    // Convert scalar to NAF representation
    // (Implementation simplified for brevity)
    
    // Perform scalar multiplication using precomputed values
    ec_point_set_infinity(result);
    
    size_t scalar_bits = mpz_sizeinbase(scalar, 2);
    for (long i = scalar_bits - 1; i >= 0; i--) {
        ec_point_double(curve, result, result);
        
        if (mpz_tstbit(scalar, i)) {
            ec_point_add(curve, result, point, result);
        }
    }
    
    // Cleanup
    for (int i = 0; i < precomp_size; i++) {
        mpz_clear(precomp[i].x);
        mpz_clear(precomp[i].y);
        mpz_clear(precomp[i].z);
    }
    ec_point_init(&double_P);
}

Hardware Acceleration and Optimization

Modern processors provide specialized instructions and hardware modules for cryptographic operations.

Intel AES-NI and Other Hardware Features

#include <cpuid.h>

// CPU feature detection
typedef struct {
    bool aes_ni;
    bool pclmulqdq;
    bool rdrand;
    bool rdseed;
    bool sha_extensions;
    bool avx;
    bool avx2;
    bool avx512f;
} cpu_features_t;

// Detect available CPU cryptographic features
static cpu_features_t detect_crypto_features(void)
{
    cpu_features_t features = {0};
    unsigned int eax, ebx, ecx, edx;
    
    // Check if CPUID is available
    if (__get_cpuid_max(0, NULL) < 1) {
        return features;
    }
    
    // Get feature flags from CPUID
    __cpuid_count(1, 0, eax, ebx, ecx, edx);
    
    features.aes_ni = (ecx & bit_AES) != 0;
    features.pclmulqdq = (ecx & bit_PCLMUL) != 0;
    features.rdrand = (ecx & bit_RDRND) != 0;
    features.avx = (ecx & bit_AVX) != 0;
    
    // Check extended features
    if (__get_cpuid_max(0, NULL) >= 7) {
        __cpuid_count(7, 0, eax, ebx, ecx, edx);
        
        features.rdseed = (ebx & bit_RDSEED) != 0;
        features.sha_extensions = (ebx & bit_SHA) != 0;
        features.avx2 = (ebx & bit_AVX2) != 0;
        features.avx512f = (ebx & bit_AVX512F) != 0;
    }
    
    return features;
}

// Hardware random number generation
static int hardware_random_bytes(uint8_t *buffer, size_t length)
{
    cpu_features_t features = detect_crypto_features();
    
    if (features.rdseed) {
        // Use RDSEED instruction for cryptographic randomness
        size_t generated = 0;
        while (generated < length) {
            uint64_t random_val;
            int success = 0;
            
            // Try RDSEED with retry loop
            for (int retry = 0; retry < 10; retry++) {
                if (_rdseed64_step(&random_val)) {
                    success = 1;
                    break;
                }
                _mm_pause(); // Pause instruction for better performance
            }
            
            if (!success) {
                return -1; // RDSEED failed
            }
            
            size_t copy_bytes = (length - generated < sizeof(random_val)) ?
                               length - generated : sizeof(random_val);
            memcpy(buffer + generated, &random_val, copy_bytes);
            generated += copy_bytes;
        }
        return 0;
    } else if (features.rdrand) {
        // Fallback to RDRAND
        size_t generated = 0;
        while (generated < length) {
            uint64_t random_val;
            int success = 0;
            
            for (int retry = 0; retry < 10; retry++) {
                if (_rdrand64_step(&random_val)) {
                    success = 1;
                    break;
                }
                _mm_pause();
            }
            
            if (!success) {
                return -1;
            }
            
            size_t copy_bytes = (length - generated < sizeof(random_val)) ?
                               length - generated : sizeof(random_val);
            memcpy(buffer + generated, &random_val, copy_bytes);
            generated += copy_bytes;
        }
        return 0;
    }
    
    return -1; // No hardware random available
}

// SHA-256 using Intel SHA extensions
static void sha256_ni_transform(uint32_t *state, const uint8_t *data)
{
    __m128i STATE0, STATE1;
    __m128i MSG, TMP;
    __m128i MSG0, MSG1, MSG2, MSG3;
    __m128i ABEF_SAVE, CDGH_SAVE;
    
    // Load initial hash values
    TMP = _mm_loadu_si128((__m128i*)(state + 0));
    STATE1 = _mm_loadu_si128((__m128i*)(state + 4));
    
    TMP = _mm_shuffle_epi32(TMP, 0xB1);
    STATE1 = _mm_shuffle_epi32(STATE1, 0x1B);
    STATE0 = _mm_alignr_epi8(TMP, STATE1, 8);
    STATE1 = _mm_blend_epi16(STATE1, TMP, 0xF0);
    
    // Save current state
    ABEF_SAVE = STATE0;
    CDGH_SAVE = STATE1;
    
    // Load message data
    MSG0 = _mm_loadu_si128((__m128i*)(data + 0));
    MSG1 = _mm_loadu_si128((__m128i*)(data + 16));
    MSG2 = _mm_loadu_si128((__m128i*)(data + 32));
    MSG3 = _mm_loadu_si128((__m128i*)(data + 48));
    
    // Byte swap for little-endian
    MSG0 = _mm_shuffle_epi8(MSG0, _mm_set_epi64x(0x0c0d0e0f08090a0b, 0x0405060700010203));
    MSG1 = _mm_shuffle_epi8(MSG1, _mm_set_epi64x(0x0c0d0e0f08090a0b, 0x0405060700010203));
    MSG2 = _mm_shuffle_epi8(MSG2, _mm_set_epi64x(0x0c0d0e0f08090a0b, 0x0405060700010203));
    MSG3 = _mm_shuffle_epi8(MSG3, _mm_set_epi64x(0x0c0d0e0f08090a0b, 0x0405060700010203));
    
    // Rounds 0-3
    MSG = _mm_add_epi32(MSG0, _mm_set_epi64x(0xE9B5DBA5B5C0FBCF, 0x71374491428A2F98));
    STATE1 = _mm_sha256rnds2_epu32(STATE1, STATE0, MSG);
    MSG = _mm_shuffle_epi32(MSG, 0x0E);
    STATE0 = _mm_sha256rnds2_epu32(STATE0, STATE1, MSG);
    
    // Continue for all 64 rounds (simplified here)
    // ... (remaining rounds follow similar pattern)
    
    // Add back to state
    STATE0 = _mm_add_epi32(STATE0, ABEF_SAVE);
    STATE1 = _mm_add_epi32(STATE1, CDGH_SAVE);
    
    // Store results back
    TMP = _mm_shuffle_epi32(STATE0, 0x1B);
    STATE1 = _mm_shuffle_epi32(STATE1, 0xB1);
    STATE0 = _mm_blend_epi16(TMP, STATE1, 0xF0);
    STATE1 = _mm_alignr_epi8(STATE1, TMP, 8);
    
    _mm_storeu_si128((__m128i*)(state + 0), STATE0);
    _mm_storeu_si128((__m128i*)(state + 4), STATE1);
}

// Optimized ChaCha20 implementation using AVX2
static void chacha20_block_avx2(uint32_t *output, 
                               const uint32_t *input, 
                               size_t blocks)
{
    if (blocks >= 8) {
        // Process 8 blocks in parallel using AVX2
        __m256i s0, s1, s2, s3, s4, s5, s6, s7;
        __m256i s8, s9, s10, s11, s12, s13, s14, s15;
        
        // Load state
        s0 = _mm256_broadcastd_epi32(_mm_loadu_si128((__m128i*)(input + 0)));
        s1 = _mm256_broadcastd_epi32(_mm_loadu_si128((__m128i*)(input + 1)));
        // ... (load remaining state elements)
        
        // Set up counters for 8 parallel blocks
        s12 = _mm256_add_epi32(s12, _mm256_set_epi32(7, 6, 5, 4, 3, 2, 1, 0));
        
        // Perform 20 rounds (10 double rounds)
        for (int round = 0; round < 10; round++) {
            // Quarter round on columns
            s0 = _mm256_add_epi32(s0, s4);
            s12 = _mm256_xor_si256(s12, s0);
            s12 = _mm256_or_si256(_mm256_slli_epi32(s12, 16), _mm256_srli_epi32(s12, 16));
            
            s8 = _mm256_add_epi32(s8, s12);
            s4 = _mm256_xor_si256(s4, s8);
            s4 = _mm256_or_si256(_mm256_slli_epi32(s4, 12), _mm256_srli_epi32(s4, 20));
            
            // Continue quarter round...
            // (Full implementation would include all operations)
        }
        
        // Add original state back
        s0 = _mm256_add_epi32(s0, _mm256_broadcastd_epi32(_mm_loadu_si128((__m128i*)(input + 0))));
        // ... (add remaining state elements)
        
        // Store results
        _mm256_storeu_si256((__m256i*)(output + 0), s0);
        // ... (store remaining output)
    } else {
        // Fallback to scalar implementation for small block counts
        // (Implementation omitted for brevity)
    }
}

Side-Channel Attack Mitigation

Protecting against side-channel attacks requires careful implementation techniques to prevent information leakage through timing, power consumption, or electromagnetic emanations.

Constant-Time Implementations

// Constant-time conditional selection
static void ct_select_u32(uint32_t *result, uint32_t a, uint32_t b, uint32_t condition)
{
    // condition must be 0 or 1
    uint32_t mask = -condition; // 0 becomes 0x00000000, 1 becomes 0xFFFFFFFF
    *result = (a & mask) | (b & ~mask);
}

// Constant-time memory comparison
static int ct_memcmp(const void *a, const void *b, size_t len)
{
    const uint8_t *pa = (const uint8_t*)a;
    const uint8_t *pb = (const uint8_t*)b;
    uint8_t result = 0;
    
    for (size_t i = 0; i < len; i++) {
        result |= pa[i] ^ pb[i];
    }
    
    return (int)result;
}

// Constant-time conditional copy
static void ct_copy(void *dst, const void *src, size_t len, uint32_t condition)
{
    uint8_t *pdst = (uint8_t*)dst;
    const uint8_t *psrc = (const uint8_t*)src;
    uint8_t mask = -condition; // 0x00 or 0xFF
    
    for (size_t i = 0; i < len; i++) {
        pdst[i] = (pdst[i] & ~mask) | (psrc[i] & mask);
    }
}

// Secure memory clearing to prevent compiler optimization
static void secure_memzero(void *ptr, size_t len)
{
    volatile uint8_t *vptr = (volatile uint8_t*)ptr;
    for (size_t i = 0; i < len; i++) {
        vptr[i] = 0;
    }
}

// Constant-time modular exponentiation
static void ct_mod_exp(mpz_t result, const mpz_t base, const mpz_t exponent, const mpz_t modulus)
{
    mpz_t temp, acc;
    mpz_init_set_ui(acc, 1);
    mpz_init_set(temp, base);
    
    size_t exp_bits = mpz_sizeinbase(exponent, 2);
    
    for (size_t i = 0; i < exp_bits; i++) {
        int bit = mpz_tstbit(exponent, i);
        
        // Always perform both operations to maintain constant time
        mpz_t mult_result, square_result;
        mpz_init(mult_result);
        mpz_init(square_result);
        
        mpz_mul(mult_result, acc, temp);
        mpz_mod(mult_result, mult_result, modulus);
        
        mpz_mul(square_result, temp, temp);
        mpz_mod(square_result, square_result, modulus);
        
        // Conditional selection based on bit value
        if (bit) {
            mpz_set(acc, mult_result);
        }
        mpz_set(temp, square_result);
        
        mpz_clear(mult_result);
        mpz_clear(square_result);
    }
    
    mpz_set(result, acc);
    mpz_clear(acc);
    mpz_clear(temp);
}

// Blinding techniques for RSA operations
typedef struct {
    mpz_t blinding_factor;
    mpz_t unblinding_factor;
    bool valid;
} rsa_blinding_t;

static int generate_rsa_blinding(rsa_blinding_t *blinding, const rsa_key_t *key)
{
    mpz_init(blinding->blinding_factor);
    mpz_init(blinding->unblinding_factor);
    
    gmp_randstate_t rstate;
    gmp_randinit_default(rstate);
    
    // Generate random blinding factor r
    do {
        mpz_urandomm(blinding->blinding_factor, rstate, key->n);
    } while (mpz_cmp_ui(blinding->blinding_factor, 1) <= 0);
    
    // Compute r^e mod n
    mpz_powm(blinding->unblinding_factor, blinding->blinding_factor, key->e, key->n);
    
    // Compute r^(-1) mod n for unblinding
    if (mpz_invert(blinding->blinding_factor, blinding->blinding_factor, key->n) == 0) {
        mpz_clear(blinding->blinding_factor);
        mpz_clear(blinding->unblinding_factor);
        gmp_randclear(rstate);
        return -1;
    }
    
    blinding->valid = true;
    gmp_randclear(rstate);
    return 0;
}

static int rsa_decrypt_blinded(const rsa_key_t *key, 
                              const mpz_t ciphertext, 
                              mpz_t plaintext)
{
    rsa_blinding_t blinding;
    if (generate_rsa_blinding(&blinding, key) != 0) {
        return -1;
    }
    
    mpz_t blinded_ciphertext, blinded_plaintext;
    mpz_init(blinded_ciphertext);
    mpz_init(blinded_plaintext);
    
    // Blind the ciphertext: c' = c * r^e mod n
    mpz_mul(blinded_ciphertext, ciphertext, blinding.unblinding_factor);
    mpz_mod(blinded_ciphertext, blinded_ciphertext, key->n);
    
    // Perform blinded decryption
    rsa_decrypt_crt(key, blinded_ciphertext, blinded_plaintext);
    
    // Unblind the result: m = m' * r^(-1) mod n
    mpz_mul(plaintext, blinded_plaintext, blinding.blinding_factor);
    mpz_mod(plaintext, plaintext, key->n);
    
    // Cleanup
    mpz_clear(blinded_ciphertext);
    mpz_clear(blinded_plaintext);
    mpz_clear(blinding.blinding_factor);
    mpz_clear(blinding.unblinding_factor);
    
    return 0;
}

Cryptographic Protocol Implementation

Building secure protocols requires careful attention to authentication, key exchange, and message integrity.

Authenticated Encryption with Associated Data (AEAD)

// AEAD context structure
typedef struct {
    aes_gcm_context_t gcm_ctx;
    uint8_t session_key[32];
    uint8_t iv_base[12];
    uint64_t message_counter;
    
    // Protocol state
    bool initialized;
    bool key_established;
    
    // Security parameters
    size_t key_size;
    size_t iv_size;
    size_t tag_size;
} aead_context_t;

// Initialize AEAD context
static int aead_init(aead_context_t *ctx, const uint8_t *key, size_t key_len)
{
    if (key_len != 32) return -1; // Only AES-256 supported
    
    memcpy(ctx->session_key, key, key_len);
    ctx->key_size = key_len;
    ctx->iv_size = 12;
    ctx->tag_size = 16;
    ctx->message_counter = 0;
    
    // Initialize AES-GCM context
    aes_key_schedule_ni(&ctx->gcm_ctx.aes_ctx, key, key_len);
    
    // Generate random IV base
    if (hardware_random_bytes(ctx->iv_base, sizeof(ctx->iv_base)) != 0) {
        return -1;
    }
    
    ctx->initialized = true;
    ctx->key_established = true;
    
    return 0;
}

// AEAD encryption
static int aead_encrypt(aead_context_t *ctx,
                       const uint8_t *plaintext, size_t plaintext_len,
                       const uint8_t *aad, size_t aad_len,
                       uint8_t *ciphertext, uint8_t *tag)
{
    if (!ctx->initialized || !ctx->key_established) {
        return -1;
    }
    
    // Construct IV: base || counter
    uint8_t iv[12];
    memcpy(iv, ctx->iv_base, sizeof(ctx->iv_base));
    
    // Encode counter in big-endian format
    uint64_t counter = ++ctx->message_counter;
    for (int i = 7; i >= 0; i--) {
        iv[4 + i] = counter & 0xFF;
        counter >>= 8;
    }
    
    // Perform AES-GCM encryption
    return aes_gcm_encrypt(&ctx->gcm_ctx, plaintext, plaintext_len,
                          aad, aad_len, iv, sizeof(iv),
                          ciphertext, tag, ctx->tag_size);
}

// AEAD decryption with authentication
static int aead_decrypt(aead_context_t *ctx,
                       const uint8_t *ciphertext, size_t ciphertext_len,
                       const uint8_t *aad, size_t aad_len,
                       const uint8_t *iv, const uint8_t *tag,
                       uint8_t *plaintext)
{
    if (!ctx->initialized || !ctx->key_established) {
        return -1;
    }
    
    // Verify IV format and extract counter
    if (memcmp(iv, ctx->iv_base, 4) != 0) {
        return -1; // Invalid IV base
    }
    
    uint64_t message_counter = 0;
    for (int i = 0; i < 8; i++) {
        message_counter = (message_counter << 8) | iv[4 + i];
    }
    
    // Check for replay attacks
    if (message_counter <= ctx->message_counter) {
        return -1; // Replay attack detected
    }
    
    // Perform AES-GCM decryption (implementation would include verification)
    // ... (simplified for brevity)
    
    ctx->message_counter = message_counter;
    return 0;
}

Conclusion

High-performance cryptographic operations require a deep understanding of both mathematical foundations and system-level optimizations. The techniques presented in this guide demonstrate how to implement cryptographic algorithms efficiently while maintaining security against sophisticated attacks, from basic side-channel resistance to advanced hardware acceleration.

Key principles for successful cryptographic implementation include constant-time execution, proper use of hardware features, comprehensive testing against known attack vectors, and careful attention to protocol design. By combining mathematical rigor with performance optimization and security awareness, developers can create cryptographic systems that meet the demanding requirements of modern enterprise environments.

The implementations shown here provide the foundation for building sophisticated cryptographic libraries and protocols that can protect sensitive data while delivering the performance required for high-throughput applications. Understanding these fundamentals enables the development of secure systems that can withstand both current and emerging cryptographic threats.