use crate::custom_ops::run_instantiation_pass;
use crate::data_types::Type;
use crate::evaluators::Evaluator;
use crate::graphs::{Context, Operation};
use crate::random::PRNG;
use crate::errors::Result;
use crate::typed_value::TypedValue;
#[doc(hidden)]
pub fn get_evaluator_result<T: Evaluator>(
context: Context,
inputs: Vec<TypedValue>,
reveal_output: bool,
mut evaluator: T,
) -> Result<TypedValue> {
let context = run_instantiation_pass(context)?.get_context();
let mut input_types = vec![];
for node in context.get_main_graph()?.get_nodes() {
if let Operation::Input(t) = node.get_operation() {
input_types.push(t);
}
}
if inputs.len() != input_types.len() {
return Err(runtime_error!(
"Invalid number of inputs: {} expected, {} received",
input_types.len(),
inputs.len()
));
}
let mut input_values = vec![];
let mut prng = PRNG::new(None)?;
for i in 0..inputs.len() {
eprint!("Input {i}: ");
if inputs[i].value.check_type(input_types[i].clone())? {
eprintln!("Using as is");
input_values.push(inputs[i].value.clone());
} else {
let e = Err(runtime_error!("Invalid input value"));
let v = if let Type::Tuple(v) = input_types[i].clone() {
v
} else {
return e;
};
if v.len() == 3
&& v[0] == v[1]
&& v[0] == v[2]
&& inputs[i].value.check_type((*v[0]).clone())?
{
eprintln!("Secret-sharing");
input_values.push(
TypedValue::new((*v[0]).clone(), inputs[i].value.clone())?
.secret_share(&mut prng)?
.value,
);
} else {
return e;
}
}
}
evaluator.preprocess(context.clone())?;
let mut result = TypedValue::new(
context.get_main_graph()?.get_output_node()?.get_type()?,
evaluator.evaluate_graph(context.get_main_graph()?, input_values)?,
)?;
if reveal_output {
result = result.secret_share_reveal()?;
}
Ok(result)
}