webgpu-groth16 0.1.1

Groth16 GPU prover aimed primarily at browser environments
Documentation
// src/shader/bls12_381/fr.wgsl

// ============================================================================
// SCALAR FIELD (F_r) - 256-bit arithmetic
// Used for NTT and polynomial evaluation.
// Limbs are stored in little-endian order (limbs[0] is least significant).
// ============================================================================

struct U256 {
    limbs: array<u32, 8>,
}

// Computes `a + b`, returning the 256-bit result (ignores overflow beyond 256 bits).
fn add_u256(a: U256, b: U256) -> U256 {
    var result: U256;
    var carry: u32 = 0u;

    for (var i: u32 = 0u; i < 8u; i = i + 1u) {
        let a_val = a.limbs[i];
        let b_val = b.limbs[i];
        
        // Manual carry tracking
        let sum1 = a_val + b_val;
        let carry1 = u32(sum1 < a_val);

        let sum2 = sum1 + carry;
        let carry2 = u32(sum2 < sum1);

        result.limbs[i] = sum2;
        carry = carry1 + carry2;
    }

    return result;
}

// Computes `a - b`, returning the 256-bit result.
fn sub_u256(a: U256, b: U256) -> U256 {
    var result: U256;
    var borrow: u32 = 0u;

    for (var i: u32 = 0u; i < 8u; i = i + 1u) {
        let a_val = a.limbs[i];
        let b_val = b.limbs[i];

        let diff1 = a_val - b_val;
        let borrow1 = u32(a_val < b_val);

        let diff2 = diff1 - borrow;
        let borrow2 = u32(diff1 < borrow);

        result.limbs[i] = diff2;
        borrow = borrow1 + borrow2;
    }

    return result;
}