vyre 0.4.0

GPU compute intermediate representation with a standard operation library
Documentation
#![allow(clippy::expect_used)]
//! Catalog entry for `detect_base64_run`.

use crate::ops::security_detection::detector_support::{spans, DetectionError};

/// Embedded operation spec formerly stored in metadata/spec.toml.
pub const SPEC_TOML: &str = r#"schema_version = 1
id = "security_detection.detect_base64_run"
archetype = "match-bytes-pattern"
display_name = "Detect Base64 Run"
summary = "Returns offsets of base64-shaped byte runs using a config-encoded minimum length."
category = "C"

[intrinsic]
wgsl = "security_detection_detect_base64_run"

[signature]
inputs = ["Bytes", "Bytes"]
output = "Bytes"

laws = []
equivalence_classes = ["long_run", "short_run", "mixed_alphabet", "t47_cap"]
workgroup_size = [64, 1, 1]
tags = ["security-detection", "base64", "secret-scan", "t47"]
fixtures_dir = "fixtures/"
"#;

/// Embedded reference vectors formerly stored in fixtures/reference-vectors.toml.
pub const REFERENCE_VECTORS_TOML: &str = r#"[[case]]
name = "positive_secret_run"
input = "prefix QWxhZGRpbjpvcGVuIHNlc2FtZQ== suffix"
min_run_len = 16
expected_offsets = [7]

[[case]]
name = "negative_short_run"
input = "abc def ghi"
min_run_len = 8
expected_offsets = []
"#;

/// WGSL lowering source for this detector.
pub mod lowering {
    /// Return the detector-specific WGSL source.
    #[must_use]
    pub const fn source() -> &'static str {
        r#"fn is_base64(b: u32) -> bool {
    return (b >= 65u && b <= 90u) || (b >= 97u && b <= 122u) ||
           (b >= 48u && b <= 57u) || b == 43u || b == 47u || b == 61u;
}

@compute @workgroup_size(64)
pub fn detect_base64_run(@builtin(global_invocation_id) gid: vec3<u32>) {
    let i = gid.x;
    if (i >= input_len || !is_base64(input[i])) { return; }
    if (i > 0u && is_base64(input[i - 1u])) { return; }
    var j = i;
    loop {
        if (j >= input_len || !is_base64(input[j])) { break; }
        j = j + 1u;
    }
    if (j - i >= min_run_len) {
        let slot = atomicAdd(&out_count, 1u);
        offsets[slot] = i;
    }
}"#
    }
}

/// Return offsets of base64-shaped byte runs using a minimum length.
///
/// # Errors
///
/// Returns `Fix: ...` when input exceeds 64 MiB or offsets exceed the ABI.
pub fn detect_base64_run(input: &[u8], min_run_len: u32) -> Result<Vec<u32>, DetectionError> {
    spans::base64_run_offsets(input, min_run_len)
}

/// Parsed base64 run configuration.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct DetectBase64RunConfig {
    /// Minimum accepted run length.
    pub min_run_len: u32,
}

/// Decode the base64 run detector config from little-endian bytes.
///
/// # Errors
///
/// Returns `Fix: ...` when the config buffer is shorter than four bytes.
pub fn detect_base64_run_config(config: &[u8]) -> Result<DetectBase64RunConfig, DetectionError> {
    Ok(DetectBase64RunConfig {
        min_run_len: read_u32_config(config, "min_run_len")?,
    })
}

/// Read a little-endian u32 detector config field.
///
/// # Errors
///
/// Returns `Fix: ...` when the config buffer is shorter than four bytes.
pub fn read_u32_config(config: &[u8], field: &str) -> Result<u32, DetectionError> {
    let bytes: [u8; 4] = config
        .get(..4)
        .ok_or_else(|| format!("Fix: provide at least 4 config bytes for {field}"))?
        .try_into()
        .expect("slice length checked");
    Ok(u32::from_le_bytes(bytes))
}

/// Compatibility surface for the previous generated implementation module.
pub mod implementation {
    pub use super::detect_base64_run;
    pub use super::{detect_base64_run_config, read_u32_config, DetectBase64RunConfig};
    /// Compatibility module for callers that used the generated kernel path.
    pub mod kernel {
        pub use super::super::{
            detect_base64_run, detect_base64_run_config, read_u32_config, DetectBase64RunConfig,
        };
    }

    /// Compatibility module for callers that used the generated lowering path.
    pub mod lowering {
        /// Compatibility module for callers that used `implementation::lowering::wgsl`.
        pub mod wgsl {
            pub use super::super::super::lowering::source;
        }
    }
}