arcium-primitives 0.6.0

Arcium primitives
Documentation
pub mod keys;
pub mod open_share;
pub mod share;

use std::any::{Any, TypeId};

pub use keys::*;
pub use open_share::*;
pub use share::*;

use crate::{
    algebra::field::{binary::Gf2_128, FieldElement, FieldExtension},
    random::{BaseRng, Random, RandomWith, Seed, SeedableRng},
};

/// A trait for secret shares that hold keys for pairwise authentication.
pub trait PairwiseAuthenticated {
    /// Global keys used to authenticate the shares of all other parties.
    type GlobalAuthKey: Random + Clone + Any;

    /// Get the global keys used to authenticate the shares of every other party.
    fn get_global_keys(&self) -> impl ExactSizeIterator<Item = Self::GlobalAuthKey>;

    /// Deal global keys used to authenticate the shares of all parties.
    fn deal_global_keys(
        n_parties: usize,
        seed: Seed,
        compatibility: bool,
    ) -> Vec<Vec<Self::GlobalAuthKey>> {
        let rng = if compatibility {
            BaseRng::from_seed(seed)
        } else {
            BaseRng::from_tagged_seed(seed, std::any::type_name::<Self::GlobalAuthKey>())
        };
        let mut alphas: Vec<Vec<Self::GlobalAuthKey>> =
            Vec::<Self::GlobalAuthKey>::random_n_with(rng, n_parties, n_parties - 1);
        if !compatibility {
            // DPF/SPFSS over binary global MAC keys requires the per-pair invariant
            //   lsb(Δ_ij) = 0 if i < j, else 1
            // where Δ_ij is the key party i holds for party j. This implies the
            // 2-party condition lsb(Δ_01 ⊕ Δ_10) = 1 and generalizes it for n > 2.
            if TypeId::of::<Self::GlobalAuthKey>() == TypeId::of::<GlobalFieldKey<Gf2_128>>() {
                for (i, alphas_i) in alphas.iter_mut().enumerate() {
                    for j in 0..n_parties {
                        if i == j {
                            continue;
                        }
                        let pos = if j < i { j } else { j - 1 };
                        let target_lsb = u8::from(i > j);
                        let key: &mut GlobalFieldKey<Gf2_128> = (&mut alphas_i[pos]
                            as &mut dyn Any)
                            .downcast_mut()
                            .expect("TypeId guarantees this cast");
                        let current = key.inner();
                        if current.to_le_bytes()[0] & 1 != target_lsb {
                            *key = GlobalFieldKey::<Gf2_128>::new(FieldElement::new(
                                current + Gf2_128::from(1u128),
                            ));
                        }
                    }
                }
            }
        }
        alphas
    }
}