pub struct Enc<C, T> {
    owner: C,
    data: EncData<T>,
}
pub struct EncData<T> {
    #[init_len = n_arcis_values as T]
    data: [ArcisCiphertext],
    phantom: [T; 0],
}

impl<C, T> Enc<C, T> {
    #[arcis_circuit = "to_arcis"]
    pub fn __arcis_inner(cipher: C, data: EncData<T>) -> T {}

    pub fn to_arcis(&self) -> T {
        Self::__arcis_inner(self.owner, self.data)
    }

    fn new_inner(owner: C, a: T, data: [ArcisCiphertext; T::n_values()]) -> Self {
        let phantom = [a; 0];
        let data = EncData { data, phantom };
        Self { owner, data }
    }
}

impl Shared {
    #[arcis_circuit = "client_encrypt"]
    fn from_arcis_inner<T>(self, a: T) -> [ArcisCiphertext; T::n_values()] {}
    pub fn from_arcis<T>(mut self, a: T) -> Enc<Self, T> {
        self.nonce = self.nonce.wrapping_add(1);
        Enc::new_inner(self, a, self.from_arcis_inner(a))
    }
}
impl Mxe {
    #[arcis_circuit = "mxe_encrypt"]
    fn from_arcis_inner<T>(self, a: T) -> [ArcisCiphertext; T::n_values()] {}
    pub fn from_arcis<T>(mut self, a: T) -> Enc<Self, T> {
        self.nonce = self.nonce.wrapping_add(1);
        Enc::new_inner(self, a, self.from_arcis_inner(a))
    }
}
