use std::sync::Arc;
use crate::{
Ciphertext, Error, Ptr32, proc::DispatchIsaOp, tomasulo::tomasulo_processor::RetirementInfo,
};
use mux_circuits::convert_value_to_bits;
use parasol_concurrency::AtomicRefCell;
use parasol_runtime::{
CiphertextType, CompletionHandler, FheCircuit, FheOp, L1GlweCiphertext,
insert_ciphertext_conversion,
};
use petgraph::stable_graph::NodeIndex;
use super::fhe_processor::FheProcessor;
mod add;
mod and;
mod bitshift;
mod casting;
mod cmux;
mod comparisons;
mod dbg;
mod load;
mod loadi;
mod mov;
mod mul;
mod neg;
mod not;
mod or;
mod store;
mod sub;
mod xor;
pub fn insert_ciphertext_inputs(
graph: &mut FheCircuit,
input: &Ciphertext,
dst: CiphertextType,
) -> Vec<NodeIndex> {
match input {
Ciphertext::L0Lwe { data } => data
.iter()
.map(|x| {
let input_node = graph.add_node(FheOp::InputLwe0(x.clone()));
insert_ciphertext_conversion(
graph,
input_node,
CiphertextType::L0LweCiphertext,
dst,
)
})
.collect(),
Ciphertext::L1Ggsw { data } => data
.iter()
.map(|x| {
let input_node = graph.add_node(FheOp::InputGgsw1(x.clone()));
insert_ciphertext_conversion(
graph,
input_node,
CiphertextType::L1GgswCiphertext,
dst,
)
})
.collect(),
Ciphertext::L1Glwe { data } => data
.iter()
.map(|x| {
let input_node = graph.add_node(FheOp::InputGlwe1(x.clone()));
insert_ciphertext_conversion(
graph,
input_node,
CiphertextType::L1GlweCiphertext,
dst,
)
})
.collect(),
Ciphertext::L1Lwe { data } => data
.iter()
.map(|x| {
let input_node = graph.add_node(FheOp::InputLwe1(x.clone()));
insert_ciphertext_conversion(
graph,
input_node,
CiphertextType::L1LweCiphertext,
dst,
)
})
.collect(),
}
}
pub(crate) fn trivially_encrypt_value_l1glwe(
val: u128,
width: u32,
zero: &L1GlweCiphertext,
one: &L1GlweCiphertext,
) -> Vec<Arc<AtomicRefCell<L1GlweCiphertext>>> {
let bits = convert_value_to_bits(val, width);
bits.into_iter()
.map(|bit| {
let encrypted_bit = if bit { one.clone() } else { zero.clone() };
Arc::new(AtomicRefCell::new(encrypted_bit))
})
.collect()
}
pub fn make_parent_op(retirement_info: &RetirementInfo<DispatchIsaOp>) -> Arc<CompletionHandler> {
let retirement_info = retirement_info.clone();
Arc::new(CompletionHandler::new(move |err| {
let result = match err {
Some(e) => Err(Error::from(e)),
None => Ok(()),
};
FheProcessor::retire(&retirement_info, result)
}))
}
pub(crate) fn is_invalid_load_store_alignment(addr: Ptr32, num_bytes: u32) -> bool {
num_bytes == 0
|| !addr.0.is_multiple_of(num_bytes)
|| num_bytes > 16
|| !num_bytes.is_power_of_two()
}
#[macro_export]
#[doc(hidden)]
macro_rules! unwrap_registers {
((mut $reg:ident) $($rest:tt)*) => {
let mut $reg = $reg.entry_mut()?;
let $reg = std::ops::DerefMut::deref_mut(&mut *$reg);
unwrap_registers!($($rest)*);
};
(($reg:ident) $($rest:tt)*) => {
let $reg = $reg.entry();
let $reg = std::ops::Deref::deref(&*$reg);
unwrap_registers!($($rest)*);
};
() => {
};
}