#![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 { random_vector(size).unwrap() } fn prng_16() -> Vec { prng(16) } fn prng_256() -> Vec { prng(256) } fn prng_1024() -> Vec { prng(1024) } fn prng_4096() -> Vec { prng(4096) } #[cfg(feature = "experimental")] fn prio2_client(size: usize) -> Vec> { 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> { prio2_client(10) } #[cfg(feature = "experimental")] fn prio2_client_100() -> Vec> { prio2_client(100) } #[cfg(feature = "experimental")] fn prio2_client_1000() -> Vec> { 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> { 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> { 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> { 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> { 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> { 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>, leaf_value: Poplar1IdpfValue, ) { 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>, 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>::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!(); } }