arcis 0.10.4

A standard library of types and functions for writing MPC circuits with the Arcis framework.
Documentation
use crate::ArcisMath;

impl ArcisMath {
    /// Fast Euclidean division between an unsigned integer and an unsigned integer whose value is
    /// known by the interpreter.
    /// Returns the division, remainder and whether it was successful.
    /// Fails for b <= 0 and with < 2^-64 probability for 1 <= b < 256 and 0 <= x < 2^128.
    /// b > 255 is currently unsupported
    ///
    /// Example:
    /// ```
    /// use arcis::*;
    /// #[encrypted]
    /// mod circuits {
    ///     use arcis::*;
    ///     #[instruction]
    ///     fn slow_modulo_u128_3() -> u8 {
    ///         let input = ArcisRNG::gen_uniform::<u128>();
    ///         let res = (input % 3) as u8;
    ///         res.reveal()
    ///     }
    ///     #[instruction]
    ///     fn fast_modulo_u128_3() -> u8 {
    ///         let input = ArcisRNG::gen_uniform::<u128>();
    ///         let res = ArcisMath::fast_euclidean_division_by_known(input, 3).1;
    ///         res.reveal()
    ///     }
    /// }
    /// ```
    /// * slow_modulo_u128_3 uses 273063636 ACUs
    /// * fast_modulo_u128_3 uses 13936434 ACUs (95% reduction)
    pub fn fast_euclidean_division_by_known<
        T: Into<u128> + TryFrom<u128>,
        U: Into<i128> + TryFrom<i128>, // i128 so that it works for literals coerced to i32
    >(
        a: T,
        b: U,
    ) -> (T, U, bool) {
        let a = a.into();
        let b = b.into();
        if b == 0 {
            return (
                T::try_from(0).map_err(|_| "0 not a T ???").unwrap(),
                U::try_from(0).map_err(|_| "0 not a U ???").unwrap(),
                false,
            );
        }
        let b_128 = b as u128;
        let (q, r, success) = (a / b_128, a % b_128, true);
        (
            T::try_from(q)
                .map_err(|_| "division result not a T ???")
                .unwrap(),
            U::try_from(r as i128)
                .map_err(|_| "division result not a U ???")
                .unwrap(),
            success,
        )
    }
}