stoffelcrypto 0.1.0

Asynchronous HoneyBadgerMPC protocols, preprocessing, and arithmetic for Stoffel.
Documentation
use std::collections::HashMap;

use ark_ff::FftField;
use ark_serialize::SerializationError;
use bincode::ErrorKind;
use serde::{Deserialize, Serialize};
use stoffelnet::network_utils::NetworkError;
use thiserror::Error;
use tokio::sync::oneshot::{channel, Receiver, Sender};

use crate::{
    common::{rbc::RbcError, share::ShareError},
    honeybadger::{
        robust_interpolate::{robust_interpolate::RobustShare, InterpolateError},
        SessionId,
    },
};

pub mod share_gen;

/// Error type for the Random Single Share (RanSha) protocol.
#[derive(Debug, Error)]
pub enum RanShaError {
    #[error("there was an error in the network: {0:?}")]
    NetworkError(#[from] NetworkError),
    #[error("error while serializing an arkworks object: {0:?}")]
    ArkSerialization(#[from] SerializationError),
    #[error("error while serializing an arkworks object: {0:?}")]
    ArkDeserialization(SerializationError),
    #[error("error while serializing the object into bytes: {0:?}")]
    SerializationError(#[from] Box<ErrorKind>),
    #[error("inner error: {0:?}")]
    InterpolateError(#[from] InterpolateError),
    #[error("Rbc error: {0:?}")]
    RbcError(#[from] RbcError),
    #[error("Share error: {0:?}")]
    ShareError(#[from] ShareError),
    #[error("error sending the result: {0:?}")]
    SendError(SessionId),
    #[error("error receiving the result: {0:?}")]
    ReceiveError(SessionId),
    #[error("received abort signal")]
    Abort,
    #[error("Party Id is out of bounds")]
    InvalidPartyId,
    #[error("session ID {0:?} malformed")]
    SessionIdError(SessionId),
    #[error("limit reached")]
    LimitError,
    #[error("no such session ID exists: {0:?}")]
    NoSuchSessionId(SessionId),
    #[error("result already received: {0:?}")]
    ResultAlreadyReceived(SessionId),
    #[error("multiplication {0:?} did not complete in time")]
    Timeout(SessionId),
    #[error("no calling protocol in the session ID")]
    NoCallingProtocol,
}

#[derive(Debug)]
pub struct RanShaStore<F: FftField> {
    pub initial_shares: HashMap<usize, Vec<RobustShare<F>>>,
    pub reception_tracker: Vec<bool>,
    pub received_r_shares: HashMap<usize, Vec<RobustShare<F>>>,
    pub computed_r_shares: Vec<RobustShare<F>>,
    pub received_ok_msg: Vec<usize>,
    pub batch_size: usize,
    pub state: RanShaState,
    pub protocol_output: Vec<RobustShare<F>>,
    pub output_sender: Option<Sender<Vec<RobustShare<F>>>>,
    pub output_receiver: Option<Receiver<Vec<RobustShare<F>>>>,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RanShaState {
    Initialized,
    FinishedInitialSharing,
    Reconstruction,
    Finished,
}

impl<F: FftField> RanShaStore<F> {
    pub fn empty(n_parties: usize) -> Self {
        let (output_sender, output_receiver) = channel();
        Self {
            initial_shares: HashMap::new(),
            reception_tracker: vec![false; n_parties],
            received_r_shares: HashMap::new(),
            computed_r_shares: Vec::new(),
            received_ok_msg: Vec::new(),
            batch_size: 1,
            state: RanShaState::Initialized,
            protocol_output: Vec::new(),
            output_sender: Some(output_sender),
            output_receiver: Some(output_receiver),
        }
    }
}

/// Types for all the possible messages sent during the Random Single Sharing protocol.
#[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
pub enum RanShaMessageType {
    //Initial shares generated by each parties that could be faulty
    ShareMessage,
    /// Tag for the message received by the reconstruction handler.
    ReconstructMessage,
    /// Tag for the message received by the output handler.
    OutputMessage,
}

#[derive(Clone, Serialize, Deserialize, Debug)]
pub enum RanShaPayload {
    Share(Vec<u8>),
    SharesBatch(Vec<u8>),
    /// Contains the share of r sent during reconstruction.
    Reconstruct(Vec<u8>),
    ReconstructSharesBatch(Vec<u8>),
    /// Output message confirming reconstruction success or failure.
    Output(bool),
}

/// Message sent in the Random Single Sharing protocol.
#[derive(Clone, Serialize, Deserialize, Debug)]
pub struct RanShaMessage {
    /// ID of the sender of the message.
    pub sender_id: usize,
    /// Type of the message according to the handler.
    pub msg_type: RanShaMessageType,
    /// Session ID of the execution.
    pub session_id: SessionId,
    /// Contents of the message.
    pub payload: RanShaPayload,
}

impl RanShaMessage {
    pub fn new(
        sender_id: usize,
        msg_type: RanShaMessageType,
        session_id: SessionId,
        payload: RanShaPayload,
    ) -> Self {
        Self {
            sender_id,
            msg_type,
            session_id,
            payload,
        }
    }
}