use static_assertions::const_assert;
use crate::Type;
use sunscreen_zkp_backend::Error as ZkpError;
#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
pub enum Error {
#[error("The FHE program is malformed: {0}")]
IRError(#[from] sunscreen_fhe_program::Error),
#[error("SEAL encountered an error {0}")]
SealError(#[from] seal_fhe::Error),
#[error("Relinearization keys were required, but not present")]
MissingRelinearizationKeys,
#[error("Galois keys were required, but not present")]
MissingGaloisKeys,
#[error("An incorrect number of ciphertexts were given to the FHE program")]
IncorrectCiphertextCount,
#[error("The given value is incompatible with the context.")]
ParameterMismatch,
#[error("Expected arguments {:#?}, got {:#?}", self.unwrap_argument_mismatch_data().0, self.unwrap_argument_mismatch_data().1)]
ArgumentMismatch(Box<(Vec<Type>, Vec<Type>)>),
#[error("Type mismatch, expected {:#?} found {:#?}", self.unwrap_type_mismatch_data().0, self.unwrap_type_mismatch_data().1)]
TypeMismatch(Box<(Type, Type)>),
#[error("Data returned from FHE program doesn't match return signature")]
ReturnTypeMetadataError,
#[error("Too much noise")]
TooMuchNoise,
#[error("Running FHE program failed {0}")]
FheProgramRunError(#[from] crate::run::FheProgramRunFailure),
#[error("Type encoding error: {0}")]
FheTypeError(Box<String>),
#[error("Failed to deserialize parameters")]
ParamDeserializationError,
#[error("Plaintext has no data")]
NoPlaintextData,
#[error("Plaintext is malformed")]
MalformedPlaintext,
#[error("Bincode serialization failed: {0}")]
BincodeError(Box<String>),
#[error("Not a SEAL plaintext")]
NotASealPlaintext,
#[error("ZKP error: {0}")]
ZkpError(#[from] ZkpError),
#[error("ZKP builder error: {0}")]
ZkpBuilderError(Box<String>),
}
const_assert!(std::mem::size_of::<Error>() <= 24);
impl Error {
pub fn argument_mismatch(expected: &[Type], actual: &[Type]) -> Self {
Self::ArgumentMismatch(Box::new((expected.to_owned(), actual.to_owned())))
}
pub fn type_mismatch(expected: &Type, actual: &Type) -> Self {
Self::TypeMismatch(Box::new((expected.clone(), actual.clone())))
}
pub fn fhe_type_error(msg: &str) -> Self {
Self::FheTypeError(Box::new(msg.to_owned()))
}
pub fn zkp_builder_error(msg: &str) -> Self {
Self::ZkpBuilderError(Box::new(msg.to_owned()))
}
fn unwrap_argument_mismatch_data(&self) -> &(Vec<Type>, Vec<Type>) {
match self {
Self::ArgumentMismatch(d) => d,
_ => panic!("Not an argument mismatch"),
}
}
fn unwrap_type_mismatch_data(&self) -> &(Type, Type) {
match self {
Self::TypeMismatch(d) => d,
_ => panic!("Not a type mismatch"),
}
}
}
impl From<bincode::Error> for Error {
fn from(err: bincode::Error) -> Self {
Self::BincodeError(Box::new(format!("{}", err)))
}
}
pub type Result<T> = std::result::Result<T, Error>;