provekit-common 0.1.3

Common types and utilities for the ProveKit proving system
Documentation
mod binops;
mod digits;
mod ram;
mod scheduling;
mod witness_builder;
mod witness_generator;

use {
    crate::{
        utils::{serde_ark, serde_ark_vec},
        FieldElement,
    },
    ark_ff::{BigInteger, One, PrimeField},
    serde::{Deserialize, Serialize},
    sha2::{Digest, Sha256},
};
pub use {
    binops::{BINOP_ATOMIC_BITS, BINOP_BITS, NUM_DIGITS},
    digits::{decompose_into_digits, DigitalDecompositionWitnesses},
    ram::{SpiceMemoryOperation, SpiceWitnesses},
    scheduling::{Layer, LayerType, LayeredWitnessBuilders, SplitError, SplitWitnessBuilders},
    witness_builder::{
        CombinedTableEntryInverseData, ConstantTerm, ProductLinearTerm, SumTerm, WitnessBuilder,
        WitnessCoefficient,
    },
    witness_generator::NoirWitnessGenerator,
};

/// The index of the constant 1 witness in the R1CS instance
pub const WITNESS_ONE_IDX: usize = 0;

/// Compute spread(val): interleave bits of val with zeros.
/// E.g., `0b1011` → `0b01_00_01_01`.
pub fn compute_spread(val: u64) -> u64 {
    let mut result = 0u64;
    for i in 0..32 {
        result |= ((val >> i) & 1) << (2 * i);
    }
    result
}

#[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq)]
pub enum ConstantOrR1CSWitness {
    Constant(#[serde(with = "serde_ark")] FieldElement),
    Witness(usize),
}

impl ConstantOrR1CSWitness {
    #[must_use]
    pub fn to_tuple(&self) -> (FieldElement, usize) {
        match self {
            ConstantOrR1CSWitness::Constant(c) => (*c, WITNESS_ONE_IDX),
            ConstantOrR1CSWitness::Witness(w) => (FieldElement::one(), *w),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct PublicInputs(#[serde(with = "serde_ark_vec")] pub Vec<FieldElement>);

impl PublicInputs {
    #[must_use]
    pub fn new() -> Self {
        Self(Vec::new())
    }

    #[must_use]
    pub fn from_vec(vec: Vec<FieldElement>) -> Self {
        Self(vec)
    }

    #[must_use]
    pub fn len(&self) -> usize {
        self.0.len()
    }

    #[must_use]
    pub fn is_empty(&self) -> bool {
        self.0.is_empty()
    }

    #[must_use]
    pub fn hash(&self) -> FieldElement {
        let mut hasher = Sha256::new();
        for elem in &self.0 {
            hasher.update(elem.into_bigint().to_bytes_le());
        }
        FieldElement::from_le_bytes_mod_order(&hasher.finalize())
    }

    #[must_use]
    pub fn hash_bytes(&self) -> [u8; 32] {
        let hash = self.hash();
        let bytes = hash.into_bigint().to_bytes_le();
        let mut result = [0u8; 32];
        let len = bytes.len().min(32);
        result[..len].copy_from_slice(&bytes[..len]);
        result
    }
}

impl Default for PublicInputs {
    fn default() -> Self {
        Self::new()
    }
}