Source code
Revision control
Copy as Markdown
Other Tools
#![cfg_attr(windows, allow(dead_code))]
use cfg_if::cfg_if;
use iai::black_box;
#[cfg(feature = "experimental")]
use prio::{
codec::{Decode, Encode, ParameterizedDecode},
field::{Field255, FieldElement, FieldPrio2},
idpf::{Idpf, IdpfInput, IdpfPublicShare, RingBufferCache},
vdaf::{
poplar1::Poplar1IdpfValue,
prio2::{Prio2, Prio2PrepareShare},
xof::Seed,
Aggregator, Share,
},
};
use prio::{
field::{random_vector, Field128, Field64},
vdaf::{
prio3::{Prio3, Prio3InputShare},
Client,
},
};
fn prng(size: usize) -> Vec<Field128> {
random_vector(size).unwrap()
}
fn prng_16() -> Vec<Field128> {
prng(16)
}
fn prng_256() -> Vec<Field128> {
prng(256)
}
fn prng_1024() -> Vec<Field128> {
prng(1024)
}
fn prng_4096() -> Vec<Field128> {
prng(4096)
}
#[cfg(feature = "experimental")]
fn prio2_client(size: usize) -> Vec<Share<FieldPrio2, 32>> {
let prio2 = Prio2::new(size).unwrap();
let input = vec![0u32; size];
let nonce = [0; 16];
prio2.shard(&black_box(input), &black_box(nonce)).unwrap().1
}
#[cfg(feature = "experimental")]
fn prio2_client_10() -> Vec<Share<FieldPrio2, 32>> {
prio2_client(10)
}
#[cfg(feature = "experimental")]
fn prio2_client_100() -> Vec<Share<FieldPrio2, 32>> {
prio2_client(100)
}
#[cfg(feature = "experimental")]
fn prio2_client_1000() -> Vec<Share<FieldPrio2, 32>> {
prio2_client(1000)
}
#[cfg(feature = "experimental")]
fn prio2_shard_and_prepare(size: usize) -> Prio2PrepareShare {
let prio2 = Prio2::new(size).unwrap();
let input = vec![0u32; size];
let nonce = [0; 16];
let (public_share, input_shares) = prio2.shard(&black_box(input), &black_box(nonce)).unwrap();
prio2
.prepare_init(&[0; 32], 0, &(), &nonce, &public_share, &input_shares[0])
.unwrap()
.1
}
#[cfg(feature = "experimental")]
fn prio2_shard_and_prepare_10() -> Prio2PrepareShare {
prio2_shard_and_prepare(10)
}
#[cfg(feature = "experimental")]
fn prio2_shard_and_prepare_100() -> Prio2PrepareShare {
prio2_shard_and_prepare(100)
}
#[cfg(feature = "experimental")]
fn prio2_shard_and_prepare_1000() -> Prio2PrepareShare {
prio2_shard_and_prepare(1000)
}
fn prio3_client_count() -> Vec<Prio3InputShare<Field64, 16>> {
let prio3 = Prio3::new_count(2).unwrap();
let measurement = true;
let nonce = [0; 16];
prio3
.shard(&black_box(measurement), &black_box(nonce))
.unwrap()
.1
}
fn prio3_client_histogram_10() -> Vec<Prio3InputShare<Field128, 16>> {
let prio3 = Prio3::new_histogram(2, 10, 3).unwrap();
let measurement = 9;
let nonce = [0; 16];
prio3
.shard(&black_box(measurement), &black_box(nonce))
.unwrap()
.1
}
fn prio3_client_sum_32() -> Vec<Prio3InputShare<Field128, 16>> {
let prio3 = Prio3::new_sum(2, 16).unwrap();
let measurement = 1337;
let nonce = [0; 16];
prio3
.shard(&black_box(measurement), &black_box(nonce))
.unwrap()
.1
}
fn prio3_client_count_vec_1000() -> Vec<Prio3InputShare<Field128, 16>> {
let len = 1000;
let prio3 = Prio3::new_sum_vec(2, 1, len, 31).unwrap();
let measurement = vec![0; len];
let nonce = [0; 16];
prio3
.shard(&black_box(measurement), &black_box(nonce))
.unwrap()
.1
}
#[cfg(feature = "multithreaded")]
fn prio3_client_count_vec_multithreaded_1000() -> Vec<Prio3InputShare<Field128, 16>> {
let len = 1000;
let prio3 = Prio3::new_sum_vec_multithreaded(2, 1, len, 31).unwrap();
let measurement = vec![0; len];
let nonce = [0; 16];
prio3
.shard(&black_box(measurement), &black_box(nonce))
.unwrap()
.1
}
#[cfg(feature = "experimental")]
fn idpf_poplar_gen(
input: &IdpfInput,
inner_values: Vec<Poplar1IdpfValue<Field64>>,
leaf_value: Poplar1IdpfValue<Field255>,
) {
let idpf = Idpf::new((), ());
idpf.gen(input, inner_values, leaf_value, &[0; 16]).unwrap();
}
#[cfg(feature = "experimental")]
fn idpf_poplar_gen_8() {
let input = IdpfInput::from_bytes(b"A");
let one = Field64::one();
idpf_poplar_gen(
&input,
vec![Poplar1IdpfValue::new([one, one]); 7],
Poplar1IdpfValue::new([Field255::one(), Field255::one()]),
);
}
#[cfg(feature = "experimental")]
fn idpf_poplar_gen_128() {
let input = IdpfInput::from_bytes(b"AAAAAAAAAAAAAAAA");
let one = Field64::one();
idpf_poplar_gen(
&input,
vec![Poplar1IdpfValue::new([one, one]); 127],
Poplar1IdpfValue::new([Field255::one(), Field255::one()]),
);
}
#[cfg(feature = "experimental")]
fn idpf_poplar_gen_2048() {
let input = IdpfInput::from_bytes(&[0x41; 256]);
let one = Field64::one();
idpf_poplar_gen(
&input,
vec![Poplar1IdpfValue::new([one, one]); 2047],
Poplar1IdpfValue::new([Field255::one(), Field255::one()]),
);
}
#[cfg(feature = "experimental")]
fn idpf_poplar_eval(
input: &IdpfInput,
public_share: &IdpfPublicShare<Poplar1IdpfValue<Field64>, Poplar1IdpfValue<Field255>>,
key: &Seed<16>,
) {
let mut cache = RingBufferCache::new(1);
let idpf = Idpf::new((), ());
idpf.eval(0, public_share, key, input, &[0; 16], &mut cache)
.unwrap();
}
#[cfg(feature = "experimental")]
fn idpf_poplar_eval_8() {
let input = IdpfInput::from_bytes(b"A");
let public_share = IdpfPublicShare::get_decoded_with_param(&8, &[0x7f; 306]).unwrap();
let key = Seed::get_decoded(&[0xff; 16]).unwrap();
idpf_poplar_eval(&input, &public_share, &key);
}
#[cfg(feature = "experimental")]
fn idpf_poplar_eval_128() {
let input = IdpfInput::from_bytes(b"AAAAAAAAAAAAAAAA");
let public_share = IdpfPublicShare::get_decoded_with_param(&128, &[0x7f; 4176]).unwrap();
let key = Seed::get_decoded(&[0xff; 16]).unwrap();
idpf_poplar_eval(&input, &public_share, &key);
}
#[cfg(feature = "experimental")]
fn idpf_poplar_eval_2048() {
let input = IdpfInput::from_bytes(&[0x41; 256]);
let public_share = IdpfPublicShare::get_decoded_with_param(&2048, &[0x7f; 66096]).unwrap();
let key = Seed::get_decoded(&[0xff; 16]).unwrap();
idpf_poplar_eval(&input, &public_share, &key);
}
#[cfg(feature = "experimental")]
fn idpf_codec() {
let data = hex::decode(concat!(
"9a",
"0000000000000000000000000000000000000000000000",
"01eb3a1bd6b5fa4a4500000000000000000000000000000000",
"ffffffff0000000022522c3fd5a33cac00000000000000000000000000000000",
"ffffffff0000000069f41eee46542b6900000000000000000000000000000000",
"00000000000000000000000000000000000000000000000000000000000000",
"017d1fd6df94280145a0dcc933ceb706e9219d50e7c4f92fd8ca9a0ffb7d819646",
))
.unwrap();
let bits = 4;
let public_share = IdpfPublicShare::<Poplar1IdpfValue<Field64>, Poplar1IdpfValue<Field255>>::get_decoded_with_param(&bits, &data).unwrap();
let encoded = public_share.get_encoded().unwrap();
let _ = black_box(encoded.len());
}
macro_rules! main_base {
( $( $func_name:ident ),* $(,)* ) => {
iai::main!(
prng_16,
prng_256,
prng_1024,
prng_4096,
prio3_client_count,
prio3_client_histogram_10,
prio3_client_sum_32,
prio3_client_count_vec_1000,
$( $func_name, )*
);
};
}
#[cfg(feature = "multithreaded")]
macro_rules! main_add_multithreaded {
( $( $func_name:ident ),* $(,)* ) => {
main_base!(
prio3_client_count_vec_multithreaded_1000,
$( $func_name, )*
);
};
}
#[cfg(not(feature = "multithreaded"))]
macro_rules! main_add_multithreaded {
( $( $func_name:ident ),* $(,)* ) => {
main_base!(
$( $func_name, )*
);
};
}
#[cfg(feature = "experimental")]
macro_rules! main_add_experimental {
( $( $func_name:ident ),* $(,)* ) => {
main_add_multithreaded!(
prio2_client_10,
prio2_client_100,
prio2_client_1000,
prio2_shard_and_prepare_10,
prio2_shard_and_prepare_100,
prio2_shard_and_prepare_1000,
idpf_codec,
idpf_poplar_gen_8,
idpf_poplar_gen_128,
idpf_poplar_gen_2048,
idpf_poplar_eval_8,
idpf_poplar_eval_128,
idpf_poplar_eval_2048,
$( $func_name, )*
);
};
}
#[cfg(not(feature = "experimental"))]
macro_rules! main_add_experimental {
( $( $func_name:ident ),* $(,)* ) => {
main_add_multithreaded!(
$( $func_name, )*
);
};
}
cfg_if! {
if #[cfg(windows)] {
fn main() {
eprintln!("Cycle count benchmarks are not supported on Windows.");
}
}
else {
main_add_experimental!();
}
}