libzeropool 0.5.6

zk-SNARK circuit and cryptography for ZeroPool
Documentation
use crate::fawkes_crypto::circuit::{
    bitify::{c_into_bits_le, c_into_bits_le_strict, c_from_bits_le},
    bool::CBool,
    num::CNum,
};
use crate::fawkes_crypto::core::signal::Signal;
use crate::fawkes_crypto::ff_uint::{NumRepr, PrimeFieldParams};
use crate::fawkes_crypto::circuit::cs::{RCS, CS};
use crate::native::boundednum::BoundedNum;

#[derive(Clone)]
pub struct CBoundedNum<C:CS, const L: usize>(CNum<C>);

impl<C:CS, const L: usize> CBoundedNum<C, L> {
    pub fn new_unchecked(n:&CNum<C>) -> Self {
        Self(n.clone())
    }

    pub fn new_trimmed(n:CNum<C>) -> Self {
        match n.as_const() {
            Some(cn) => n.derive_const(&BoundedNum::new_trimmed(cn)),
            _ => {
                assert!((L as u32) < C::Fr::MODULUS_BITS);
                let bits = c_into_bits_le_strict(&n);
                let new_n = c_from_bits_le(&bits[0..L]);
                Self::new_unchecked(&new_n)
            }
        }
    }

    pub fn new(n:&CNum<C>) -> Self {
        assert!(L < C::Fr::MODULUS_BITS as usize);
        match n.as_const() {
            Some(cn) => {
                assert!(cn.to_uint() < (NumRepr::<<C::Fr as PrimeFieldParams>::Inner>::ONE << L as u32));
                Self::new_unchecked(n)
            },
            _ => {
                c_into_bits_le(n, L);
                Self::new_unchecked(n)
            }
        }
    }
    pub fn as_num(&self) -> &CNum<C> {
        &self.0
    }
}

impl<C:CS, const L: usize> Signal<C> for CBoundedNum<C, L> {
    type Value = BoundedNum<C::Fr,L>;

    fn as_const(&self) -> Option<Self::Value> {
        let n = self.0.as_const()?;
        Some(BoundedNum::new(n))
    }

    fn get_value(&self) -> Option<Self::Value> {
        let n = self.0.get_value()?;
        Some(BoundedNum::new(n))
    }


    fn from_const(cs: &RCS<C>, value: &Self::Value) -> Self {
        let n = Signal::from_const(cs, value.as_num());
        Self::new(&n)
    }

    fn get_cs(&self) -> &RCS<C> {
        self.0.get_cs()
    }

    fn alloc(cs: &RCS<C>, value: Option<&Self::Value>) -> Self {
        let n = Signal::alloc(cs, value.map(|v| v.as_num()));
        Self::new(&n)
        
    }

    fn switch(&self, bit: &CBool<C>, if_else: &Self) -> Self {
        let n = self.0.switch(bit, &if_else.0);
        Self::new_unchecked(&n)
    }

    fn assert_const(&self, value: &Self::Value) {
        self.0.assert_const(value.as_num());
    }

    fn assert_eq(&self, other: &Self) {
        self.0.assert_eq(&other.0);
    }

    fn is_eq(&self, other: &Self) -> CBool<C> {
        self.0.is_eq(&other.0)
    }

    fn inputize(&self) {
        self.0.inputize();
    }
}