aigis-enc-binding 0.1.0

Rust bindings for the AIGIS-ENC KEM/TKEM implementation from PQMagic
Documentation
use cc::Build;
use std::env;
use std::fs;
use std::path::PathBuf;

fn main() {
    let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
    let source_root = manifest_dir.join("vendor").join("pqmagic");
    assert!(
        source_root.exists(),
        "Missing vendored source directory: {}",
        source_root.display()
    );

    let kem_path = source_root.join("kem").join("aigis-enc").join("std");
    let utils_path = source_root.join("utils");
    let include_path = source_root.join("include");
    let sm3_path = source_root.join("hash").join("sm3");
    let sm3_x86_path = sm3_path.join("x86-64");

    let params = if cfg!(feature = "params-1") {
        "1"
    } else if cfg!(feature = "params-2") {
        "2"
    } else if cfg!(feature = "params-3") {
        "3"
    } else if cfg!(feature = "params-4") {
        "4"
    } else {
        "2"
    };

    println!("cargo:rustc-env=AIGIS_ENC_PARAMS={}", params);

    let constants_code = match params {
        "1" => r#"pub const PARAMS: usize = 1;
pub const CRYPTO_PUBLICKEYBYTES: usize = 672;
pub const CRYPTO_SECRETKEYBYTES: usize = 1568;
pub const CRYPTO_CIPHERTEXTBYTES: usize = 736;
pub const CRYPTO_BYTES: usize = 32;"#,
        "2" => r#"pub const PARAMS: usize = 2;
pub const CRYPTO_PUBLICKEYBYTES: usize = 896;
pub const CRYPTO_SECRETKEYBYTES: usize = 2208;
pub const CRYPTO_CIPHERTEXTBYTES: usize = 992;
pub const CRYPTO_BYTES: usize = 32;"#,
        "3" => r#"pub const PARAMS: usize = 3;
pub const CRYPTO_PUBLICKEYBYTES: usize = 992;
pub const CRYPTO_SECRETKEYBYTES: usize = 2304;
pub const CRYPTO_CIPHERTEXTBYTES: usize = 1056;
pub const CRYPTO_BYTES: usize = 32;"#,
        "4" => r#"pub const PARAMS: usize = 4;
pub const CRYPTO_PUBLICKEYBYTES: usize = 1440;
pub const CRYPTO_SECRETKEYBYTES: usize = 2752;
pub const CRYPTO_CIPHERTEXTBYTES: usize = 1472;
pub const CRYPTO_BYTES: usize = 32;"#,
        _ => r#"pub const PARAMS: usize = 2;
pub const CRYPTO_PUBLICKEYBYTES: usize = 896;
pub const CRYPTO_SECRETKEYBYTES: usize = 2208;
pub const CRYPTO_CIPHERTEXTBYTES: usize = 992;
pub const CRYPTO_BYTES: usize = 32;"#,
    };

    let out_dir = env::var("OUT_DIR").unwrap();
    let constants_path = PathBuf::from(&out_dir).join("constants.rs");
    fs::write(&constants_path, constants_code).expect("Failed to write constants file");

    println!("cargo:rerun-if-changed=build.rs");
    println!("cargo:rerun-if-changed={}", kem_path.display());
    println!("cargo:rerun-if-changed={}", utils_path.display());
    println!("cargo:rerun-if-changed={}", include_path.display());
    println!("cargo:rerun-if-changed={}", sm3_path.display());

    let mut builder = Build::new();
    builder
        .include(&source_root)
        .include(&kem_path)
        .include(&utils_path)
        .include(&include_path)
        .include(&sm3_path)
        .include(&sm3_x86_path)
        .file(kem_path.join("kem.c"))
        .file(kem_path.join("cbd.c"))
        .file(kem_path.join("genmatrix.c"))
        .file(kem_path.join("hashkdf.c"))
        .file(kem_path.join("ntt.c"))
        .file(kem_path.join("owcpa.c"))
        .file(kem_path.join("poly.c"))
        .file(kem_path.join("polyvec.c"))
        .file(kem_path.join("reduce.c"))
        .file(kem_path.join("sm3kdf.c"))
        .file(kem_path.join("verify.c"))
        .file(utils_path.join("randombytes.c"))
        .file(sm3_path.join("sm3_extended.c"))
        .file(sm3_path.join("mgf_sm3.c"))
        .file(sm3_x86_path.join("sm3.c"))
        .define("AIGIS_ENC_MODE", params)
        .flag("-Wno-unused-parameter");

    builder.compile("aigis_enc_c");

    if cfg!(target_os = "windows") {
        println!("cargo:rustc-link-lib=advapi32");
    }
}