Function seec::secret::low_depth_reduce
source · pub fn low_depth_reduce<F, Idx: GateIdx>(
shares: impl IntoIterator<Item = Secret<BooleanGmw, Idx>>,
f: F
) -> Option<Secret<BooleanGmw, Idx>>
Expand description
Reduce the slice of Secrets with the provided operation. The operation can be a closure
or simply one of the operations implemented on Secret
s, like BitAnd
.
The circuit will be constructed such that the depth is minimal.
let inputs = inputs::<DefaultIdx>(23);
low_depth_reduce(inputs, std::ops::BitAnd::bitand)
.unwrap()
.output();
// It is important that the Gate and Idx type of the circuit match up with those of the
// Secrets, as otherwise an empty circuit will be returned
let and_tree: Circuit<bool, BooleanGate, DefaultIdx> = CircuitBuilder::global_into_circuit();
assert_eq!(and_tree.interactive_count(), 22)
Examples found in repository?
More examples
crates/seec/examples/privmail_sc.rs (line 162)
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169
fn comparison_circuit(keyword: &[[Secret; 8]], target_text: &[[Secret; 8]]) -> Secret {
const CHARACTER_BIT_LEN: usize = 6; // Follows from the special PrivMail encoding
let splitted_keyword: Vec<_> = keyword
.iter()
.flat_map(|c| c.iter().take(CHARACTER_BIT_LEN).cloned())
.collect();
let splitted_text: Vec<_> = target_text
.iter()
.flat_map(|c| c.iter().take(CHARACTER_BIT_LEN).cloned())
.collect();
let res: Vec<_> = splitted_keyword
.into_iter()
.zip(splitted_text)
.map(|(k, t)| !(k ^ t))
.collect();
low_depth_reduce(res, ops::BitAnd::bitand).expect("Empty input")
}
#[sub_circuit]
fn or_sc(input: &[Secret]) -> Secret {
low_depth_reduce(input.to_owned(), ops::BitOr::bitor)
.unwrap_or_else(|| Secret::from_const(0, false))
}
crates/seec/examples/privmail.rs (line 143)
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
fn create_search_circuit(keyword: &[[Secret; 8]], target_text: &[[Secret; 8]]) -> Secret {
/*
* Calculate the number of positions we need to compare. E.g., if search_keyword
* is "key" and target_text is "target", we must do 4 comparison:
*
* target , target , target , target
* ^^^ ^^^ ^^^ ^^^
* key key key key
*/
let num_positions = target_text.len() - keyword.len() + 1;
let search_results_per_position: Vec<_> = (0..num_positions)
.map(|k| create_comparison_circuit(keyword, target_text, k))
.collect();
let result_bits = search_results_per_position.into_iter().map(|result| {
debug!("AND reduce for {} bits", result.len());
low_depth_reduce(result, ops::BitAnd::bitand).expect("Reduce returned None")
});
// Finally, use OR tree to get the final answer of whether any of the comparisons was a match
low_depth_reduce(result_bits, ops::BitOr::bitor).expect("Reduce returned None")
}