in crypto/benches/paillier_benchmark.rs [79:136]
fn parallel_additive_shares(n: usize, c: &mut Criterion) {
c.bench_function(
format!("paillier parallel ser+des, size: {}", n).as_str(),
move |b| {
b.iter(|| {
let mut rng = rand::thread_rng();
let output_domain: BigUint = BigUint::one() << 64;
let range = Uniform::new(0_u64, 1 << 62);
let raw_text: Vec<u64> = (0..n).map(|_| rng.sample(&range)).collect();
let cipher = PaillierParallel::new();
let raw_text_enc = cipher.enc_serialise_u64(raw_text.as_ref());
let mask: Vec<BigUint> = (0..raw_text.len())
.map(|_| rng.gen_biguint_range(&BigUint::one(), &cipher.enc_key.n))
.collect();
let v_share1_enc = cipher.subtract_plaintext(raw_text_enc, &mask);
let share1 = cipher.decrypt_vec(v_share1_enc.clone());
let share2 = mask.clone();
share1
.into_par_iter()
.zip_eq(share2.into_par_iter())
.zip_eq(raw_text.into_par_iter())
.for_each(|(a, b)| {
// a.0 - party A shares
// a.1 - party B shares
// b - expected values
// DEC( ... ) - N mod 2^l
let party_a = {
let o_mod = output_domain.to_bigint().unwrap();
let t1 = a.0.to_bigint().unwrap() % &o_mod;
let t2 = cipher.enc_key.n.to_bigint().unwrap() % &o_mod;
let s = (t1 - t2 + &o_mod) % o_mod;
assert_eq!(s.is_negative(), false);
let (_, v) = s.to_u64_digits();
assert_eq!(v.len(), 1);
v[0]
};
let party_b = {
let t = (a.1 % &output_domain).to_u64_digits();
assert_eq!(t.len(), 1);
t[0]
};
let rec_output = (Wrapping(party_a) + Wrapping(party_b)).0;
assert_eq!(rec_output, b);
});
()
})
},
);
}