#![deny(missing_docs)]
#![deny(rustdoc::broken_intra_doc_links)]
mod array;
mod error;
mod keys;
mod metadata;
mod run;
mod runtime;
mod serialization;
use std::sync::Arc;
pub use crate::error::*;
pub use crate::keys::*;
pub use crate::metadata::*;
pub use run::*;
pub use runtime::*;
pub use serialization::WithContext;
use seal_fhe::{Ciphertext as SealCiphertext, Plaintext as SealPlaintext};
use serde::{Deserialize, Serialize};
use sunscreen_zkp_backend::BigInt;
#[derive(Debug, Clone, PartialEq, Hash, Serialize, Deserialize, Eq)]
pub enum InnerPlaintext {
Seal(Vec<WithContext<SealPlaintext>>),
}
impl InnerPlaintext {
pub fn len(&self) -> usize {
match self {
Self::Seal(d) => d.len(),
}
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn scatter(&self) -> Vec<InnerPlaintext> {
match self {
Self::Seal(d) => d.iter().map(|p| Self::Seal(vec![p.clone()])).collect(),
}
}
pub fn to_bytes(&self) -> Result<Vec<u8>> {
Ok(bincode::serialize(&self)?)
}
pub fn from_bytes(data: &[u8]) -> Result<Self> {
Ok(bincode::deserialize(data)?)
}
pub fn as_seal_plaintext(&self) -> Result<&[WithContext<SealPlaintext>]> {
match self {
Self::Seal(d) => Ok(d),
}
}
}
#[derive(Clone)]
pub enum SealData {
Ciphertext(SealCiphertext),
Plaintext(SealPlaintext),
}
impl From<SealCiphertext> for SealData {
fn from(val: SealCiphertext) -> Self {
Self::Ciphertext(val)
}
}
impl From<SealPlaintext> for SealData {
fn from(val: SealPlaintext) -> Self {
Self::Plaintext(val)
}
}
#[derive(Clone, Serialize, Deserialize)]
pub struct Plaintext {
pub data_type: Type,
pub inner: InnerPlaintext,
}
impl Plaintext {
pub fn inner_as_seal_plaintext(&self) -> Result<&[WithContext<SealPlaintext>]> {
self.inner.as_seal_plaintext()
}
}
#[derive(Clone, Deserialize, Serialize)]
pub enum InnerCiphertext {
Seal(Vec<WithContext<SealCiphertext>>),
}
#[derive(Clone, Deserialize, Serialize)]
pub struct Ciphertext {
pub data_type: Type,
pub inner: InnerCiphertext,
}
pub trait FheProgramInputTrait: TryIntoPlaintext + TypeNameInstance {}
pub enum FheProgramInput {
Ciphertext(Ciphertext),
Plaintext(Box<dyn FheProgramInputTrait>),
}
pub trait ZkpProgramInputTrait: ToNativeFields + TypeNameInstance {}
impl<T: ToNativeFields + TypeNameInstance> ZkpProgramInputTrait for T {}
#[derive(Clone)]
pub struct ZkpProgramInput(pub Arc<dyn ZkpProgramInputTrait>);
impl<T> From<T> for ZkpProgramInput
where
T: ZkpProgramInputTrait + 'static,
{
fn from(val: T) -> Self {
Self(Arc::new(val))
}
}
impl TypeNameInstance for FheProgramInput {
fn type_name_instance(&self) -> Type {
match self {
Self::Ciphertext(c) => c.data_type.clone(),
Self::Plaintext(p) => p.type_name_instance(),
}
}
}
impl From<Ciphertext> for FheProgramInput {
fn from(val: Ciphertext) -> Self {
Self::Ciphertext(val)
}
}
impl<T> From<T> for FheProgramInput
where
T: FheProgramInputTrait + 'static,
{
fn from(val: T) -> Self {
Self::Plaintext(Box::new(val))
}
}
pub trait TryIntoPlaintext {
fn try_into_plaintext(&self, params: &Params) -> Result<Plaintext>;
}
pub trait ToNativeFields {
fn to_native_fields(&self) -> Vec<BigInt>;
}
impl<T, const N: usize> ToNativeFields for [T; N]
where
T: ToNativeFields,
{
fn to_native_fields(&self) -> Vec<sunscreen_zkp_backend::BigInt> {
self.iter().flat_map(|x| x.to_native_fields()).collect()
}
}
pub trait TryFromPlaintext
where
Self: Sized,
{
fn try_from_plaintext(plaintext: &Plaintext, params: &Params) -> Result<Self>;
}
pub trait NumCiphertexts {
const NUM_CIPHERTEXTS: usize;
}
pub trait FheType:
TypeNameInstance + TryIntoPlaintext + TryFromPlaintext + FheProgramInputTrait + NumCiphertexts
{
}
pub trait BfvType: FheType {}
pub trait TypeNameInstance {
fn type_name_instance(&self) -> Type;
}