spectral_vm 0.1.6

HYPERION: Production-ready zero-knowledge virtual machine with spectral analysis
Documentation
/*
 * ═══════════════════════════════════════════════════════════════════════════
 * TECHNICAL MANIFEST: Spectral Signals
 * SOVEREIGN SPECTRAL ROLE: Hypercube Data Representations
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * COMPLEXITY: O(n) for construction | O(n) for integrity verification
 * FIELD: Goldilocks (2^64 - 2^32 + 1) for spectral manifolds
 * DOMAIN: Time Domain (SpectralSignal) | Frequency Domain (SpectralManifold)
 *
 * ARCHITECTURAL INVARIANTS:
 * - Signal size MUST be power of two (FWHT requirement)
 * - SpectralSignal values MUST be in {0, 1} (Booleanity)
 * - SpectralManifold stores Goldilocks field elements
 *
 * SECURITY PROPERTIES:
 * - Integrity: verify_integrity() enforces Booleanity pre-verification
 * - Immutability: Signals are immutable after construction
 * ═══════════════════════════════════════════════════════════════════════════
 */

use crate::field::Goldilocks;

/// Time Domain Representation (Spectral Signal).
/// Stores the 'Execution Trace' data. Each value represents the signal
/// amplitude (0 or 1) at a corner of the boolean hypercube.
/// Stored as i64 to allow for negative intermediate values during spectral arithmetic.
#[derive(Clone, Debug, PartialEq)]
pub struct SpectralSignal {
    /// Number of variables defining the hypercube (n vars → 2^n corners).
    pub num_vars: usize,
    /// Values mapped across the hypercube.
    pub values: Vec<i64>,
}

impl SpectralSignal {
    /// Creates a new SpectralSignal (Time Domain Trace).
    /// CONSTRAINT: Size must be a power of two for FWHT algorithm.
    /// COMPLEXITY: O(n).
    pub fn new(values: Vec<i64>) -> Self {
        let len = values.len();
        assert!(len.is_power_of_two(), "Signal size must be a power of two.");
        let num_vars = len.trailing_zeros() as usize;
        Self { num_vars, values }
    }

    /// Constructs a time domain signal from a raw boolean sequence.
    /// COMPLEXITY: O(n).
    pub fn from_bools(bools: &[bool]) -> Self {
        let values = bools.iter().map(|&b| if b { 1 } else { 0 }).collect();
        Self::new(values)
    }

    /// Verifies signal integrity: all values ∈ {0, 1}.
    /// SOVEREIGN INVARIANT: Pre-condition for sound attestation.
    /// COMPLEXITY: O(n) time-domain check.
    pub fn verify_integrity(&self) -> bool {
        self.values.iter().all(|&v| v == 0 || v == 1)
    }

    /// Verifies signal integrity with explicit error reporting.
    /// Returns the first violating index and value if integrity check fails.
    pub fn verify_integrity_strict(&self) -> Result<(), (usize, i64)> {
        for (i, &v) in self.values.iter().enumerate() {
            if v != 0 && v != 1 {
                return Err((i, v));
            }
        }
        Ok(())
    }

    /// Pointwise multiplication.
    /// This operation in the time domain is equivalent to 'Dyadic Convolution'
    /// in the frequency domain.
    /// COMPLEXITY: O(n).
    pub fn mul(&self, other: &Self) -> Self {
        assert_eq!(self.values.len(), other.values.len());
        let new_vals = self
            .values
            .iter()
            .zip(other.values.iter())
            .map(|(a, b)| a * b)
            .collect();
        Self::new(new_vals)
    }

    /// Pointwise addition. The time domain projection of spectral addition.
    /// COMPLEXITY: O(n).
    pub fn add(&self, other: &Self) -> Self {
        assert_eq!(self.values.len(), other.values.len());
        let new_vals = self
            .values
            .iter()
            .zip(other.values.iter())
            .map(|(a, b)| a + b)
            .collect();
        Self::new(new_vals)
    }
}

/// Frequency Domain Representation (Spectral Manifold).
/// Stores the spectral coefficients of the boolean hypercube in the Goldilocks field.
/// This structure serves as the primary component for Spectral Constraints.
#[derive(Clone, Debug, PartialEq)]
pub struct SpectralManifold {
    pub values: Vec<Goldilocks>,
}

impl SpectralManifold {
    /// Creates a new Spectral Manifold.
    /// COMPLEXITY: O(n).
    pub fn new(values: Vec<Goldilocks>) -> Self {
        assert!(values.len().is_power_of_two());
        Self { values }
    }

    /// Pointwise multiplication in the spectral domain.
    /// Represents the frequency domain result of a 'Dyadic Convolution'
    /// performed in the time domain.
    /// COMPLEXITY: O(n).
    pub fn mul(&self, other: &Self) -> Self {
        assert_eq!(self.values.len(), other.values.len());
        let new_vals = self
            .values
            .iter()
            .zip(other.values.iter())
            .map(|(&a, &b)| a.mul(b))
            .collect();
        Self { values: new_vals }
    }

    /// Pointwise addition in the spectral domain.
    /// Due to linearity, the sum of spectral coefficients equals the spectrum
    /// of the sum in the time domain.
    /// COMPLEXITY: O(n).
    pub fn add(&self, other: &Self) -> Self {
        assert_eq!(self.values.len(), other.values.len());
        let new_vals = self
            .values
            .iter()
            .zip(other.values.iter())
            .map(|(&a, &b)| a.add(b))
            .collect();
        Self { values: new_vals }
    }
}

// Backward compatibility aliases (deprecated, will be removed in v2.0)
#[deprecated(note = "Use SpectralSignal instead")]
pub type BooleanTensor = SpectralSignal;
#[deprecated(note = "Use SpectralManifold instead")]
pub type SpectralTensor = SpectralManifold;