arcium-primitives 0.4.5

Arcium primitives
Documentation
use std::mem::MaybeUninit;

use serde::{de::DeserializeOwned, Deserialize, Serialize};
use wincode::{
    io::{Reader, Writer},
    ReadResult,
    SchemaRead,
    SchemaWrite,
    WriteResult,
};

use crate::{
    algebra::{
        elliptic_curve::{BaseField, Point, ScalarField},
        field::{binary::Gf2_128, FieldElement, SubfieldElement},
    },
    types::heap_array::{CurvePoints, FieldElements, SubfieldElements},
};

/// Generic opening of a [`PairwiseAuthShare`]: the value and the corresponding MAC,
/// shared towards a remote peer for verification.
///
/// All four concrete opening types are type aliases of this struct:
/// - [`OpenFieldShare<F>`]     = `PairwiseAuthOpenShare<SubfieldElement<F>,   FieldElement<F>>`
/// - [`OpenFieldShares<F, M>`] = `PairwiseAuthOpenShare<SubfieldElements<F,M>,FieldElements<F,M>>`
/// - [`OpenPointShare<C>`]     = `PairwiseAuthOpenShare<Point<C>,             Point<C>>`
/// - [`OpenPointShares<C, M>`] = `PairwiseAuthOpenShare<CurvePoints<C,M>,     CurvePoints<C,M>>`
#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
#[serde(bound = "V: Serialize + DeserializeOwned, Mac: Serialize + DeserializeOwned")]
#[repr(C)]
pub struct PairwiseAuthOpenShare<V, Mac> {
    pub value: V,
    pub mac: Mac,
}

impl<V, Mac> SchemaWrite for PairwiseAuthOpenShare<V, Mac>
where
    V: SchemaWrite<Src = V>,
    Mac: SchemaWrite<Src = Mac>,
{
    type Src = Self;

    fn size_of(src: &Self) -> WriteResult<usize> {
        Ok(V::size_of(&src.value)? + Mac::size_of(&src.mac)?)
    }

    fn write(writer: &mut impl Writer, src: &Self) -> WriteResult<()> {
        V::write(writer, &src.value)?;
        Mac::write(writer, &src.mac)
    }
}

impl<'de, V, Mac> SchemaRead<'de> for PairwiseAuthOpenShare<V, Mac>
where
    V: SchemaRead<'de, Dst = V>,
    Mac: SchemaRead<'de, Dst = Mac>,
{
    type Dst = Self;

    fn read(reader: &mut impl Reader<'de>, dst: &mut MaybeUninit<Self>) -> ReadResult<()> {
        let mut value = MaybeUninit::<V>::uninit();
        let mut mac = MaybeUninit::<Mac>::uninit();
        V::read(reader, &mut value)?;
        Mac::read(reader, &mut mac)?;
        // SAFETY: all fields were initialised by the reads above
        let value = unsafe { value.assume_init() };
        let mac = unsafe { mac.assume_init() };
        dst.write(PairwiseAuthOpenShare { value, mac });
        Ok(())
    }
}

impl<V, Mac> PairwiseAuthOpenShare<V, Mac> {
    pub fn new(value: V, mac: Mac) -> Self {
        Self { value, mac }
    }

    pub fn get_value(&self) -> &V {
        &self.value
    }

    pub fn get_mac(&self) -> &Mac {
        &self.mac
    }
}

// --- Aliases --- //

// Single-element

/// Opening of a single authenticated field share.
/// Alias for [`PairwiseAuthOpenShare<SubfieldElement<F>, FieldElement<F>>`].
pub type OpenFieldShare<F> = PairwiseAuthOpenShare<SubfieldElement<F>, FieldElement<F>>;
/// Opening of a single authenticated curve-point share.
/// Alias for [`PairwiseAuthOpenShare<Point<C>, Point<C>>`].
pub type OpenPointShare<C> = PairwiseAuthOpenShare<Point<C>, Point<C>>;
/// Opening of a single authenticated share of a scalar field element (`ScalarField<C>`).
pub type OpenScalarShare<C> = OpenFieldShare<ScalarField<C>>;
/// Opening of a single authenticated share of a base field element (`BaseField<C>`).
pub type OpenBaseFieldShare<C> = OpenFieldShare<BaseField<C>>;
/// Opening of a single authenticated share of a GF(2^128) bit.
pub type OpenBitShare = OpenFieldShare<Gf2_128>;
/// Opening of a batch of `M` authenticated field shares.
/// Alias for [`PairwiseAuthOpenShare<SubfieldElements<F,M>, FieldElements<F,M>>`].
pub type OpenFieldShares<F, M> = PairwiseAuthOpenShare<SubfieldElements<F, M>, FieldElements<F, M>>;

// Batched

/// Opening of a batch of `M` authenticated curve-point shares.
/// Alias for [`PairwiseAuthOpenShare<CurvePoints<C,M>, CurvePoints<C,M>>`].
pub type OpenPointShares<C, M> = PairwiseAuthOpenShare<CurvePoints<C, M>, CurvePoints<C, M>>;
/// Opening of a batch of authenticated scalar field shares. See [`PairwiseAuthOpenShare`].
pub type OpenScalarShares<C, M> = OpenFieldShares<ScalarField<C>, M>;
/// Opening of a batch of authenticated base field shares. See [`PairwiseAuthOpenShare`].
pub type OpenBaseFieldShares<C, M> = OpenFieldShares<BaseField<C>, M>;