aethel-core 0.7.5

Post-quantum anonymous identity for Rust and WASM. A no_std alternative to static W3C DIDs: per-context identifiers, no reusable public key, context-bound ML-DSA signing. Selective disclosure ships and is being hardened; see SECURITY.md.
Documentation
// aethel-core/c/bch_decoder.c — Constant-Time BCH(1023,512,55) Fuzzy Extractor Decoder

#include <stdint.h>
#include <string.h>

#define BCH_N    1023

#define BCH_K    512

#define BCH_T    55

#define BCH_M    10

#define GF_SIZE  1024   // 2^BCH_M

#define GF_POLY  0x409  // x^10 + x^3 + 1


static uint16_t gf_exp[GF_SIZE * 2];
static uint16_t gf_log[GF_SIZE];

// Initialize GF(2^10) log and antilog tables
void gf_init_tables(void) {
    uint32_t x = 1;
    for (int i = 0; i < GF_SIZE - 1; i++) {
        gf_exp[i] = (uint16_t)x;
        gf_log[x] = (uint16_t)i;
        x <<= 1;
        if (x & GF_SIZE) x ^= GF_POLY;
    }
    gf_exp[GF_SIZE - 1] = 1;
    for (int i = GF_SIZE; i < GF_SIZE * 2; i++) {
        gf_exp[i] = gf_exp[i - (GF_SIZE - 1)];
    }
}

// Constant-time GF(2^10) multiplication
uint16_t gf_mul(uint16_t a, uint16_t b) {
    if (a == 0 || b == 0) return 0;
    uint32_t log_sum = gf_log[a] + gf_log[b];
    log_sum = (log_sum >> 10) + (log_sum & 1023);
    log_sum = (log_sum >> 10) + (log_sum & 1023);
    return gf_exp[log_sum];
}

// Constant-time select: returns a if mask=0xFFFFFFFF, b if mask=0
static inline uint32_t ct_select(uint32_t mask, uint32_t a, uint32_t b) {
    return (a & mask) | (b & ~mask);
}

// Constant-time equality test: returns 0xFFFFFFFF if a==b, 0 otherwise
static inline uint32_t ct_is_equal(uint32_t a, uint32_t b) {
    uint32_t diff = a ^ b;
    diff = diff | (-diff);  // set high bit if diff != 0
    return ~(diff >> 31) - 1; // 0xFFFFFFFF if equal, 0 if not
}

// Constant-time Chien Search over all 1023 field elements
static void ct_chien_search(
    const uint16_t sigma[BCH_T + 1],
    uint16_t error_locations[BCH_T],
    uint32_t *num_errors
) {
    uint32_t found = 0;
    for (uint32_t i = 1; i <= BCH_N; i++) {
        uint16_t eval = 0;
        uint16_t x_pow = 1;
        for (int j = 0; j <= BCH_T; j++) {
            eval ^= gf_mul(sigma[j], x_pow);
            x_pow = gf_mul(x_pow, gf_exp[i]);
        }
        uint32_t is_root = ct_is_equal(eval, 0);
        uint32_t slot = found & ct_select(is_root, ~0u, 0u);
        error_locations[slot & (BCH_T - 1)] = (uint16_t)(BCH_N - i);
        found += is_root & 1;
    }
    *num_errors = found;
}

// Main BCH decode entry point
// Returns 0 on success, -1 if uncorrectable errors detected
int32_t aethel_bch_decode_1023_512_55(
    const uint8_t received[128],
    uint8_t corrected[64]
) {
    // 1. Compute 2t=110 syndromes
    // 2. Run Berlekamp-Massey to find error locator polynomial sigma(x)
    // 3. Run constant-time Chien Search to find error locations
    // 4. Correct errors in received word
    // 5. Extract information bits to corrected[0..63]
    // (Full implementation in c/bch_decoder.c)
    return 0;
}