-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mp-spdz-rs: benches: Add benchmarks for FHE operations
- Loading branch information
Showing
7 changed files
with
277 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,155 @@ | ||
//! Benchmarks for ciphertext operations | ||
use ark_mpc::algebra::Scalar; | ||
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; | ||
use mp_spdz_rs::benchmark_helpers::random_plaintext; | ||
use mp_spdz_rs::fhe::{keys::BGVKeypair, params::BGVParams, plaintext::Plaintext}; | ||
use mp_spdz_rs::TestCurve; | ||
|
||
/// Benchmark the time to encrypt and decrypt a plaintext | ||
fn bench_ciphertext_encrypt_decrypt(c: &mut Criterion) { | ||
let mut group = c.benchmark_group("ciphertext-ops"); | ||
let params = BGVParams::<TestCurve>::new_no_mults(); | ||
let slots = params.plaintext_slots(); | ||
let mut keypair = BGVKeypair::gen(¶ms); | ||
|
||
group.throughput(Throughput::Elements(slots as u64)); | ||
group.bench_function(BenchmarkId::new("encrypt-decrypt", ""), |b| { | ||
b.iter_custom(|n_iters| { | ||
let mut total_time = std::time::Duration::default(); | ||
let mut rng = rand::thread_rng(); | ||
|
||
for _ in 0..n_iters { | ||
let plaintext = random_plaintext(¶ms); | ||
|
||
let start = std::time::Instant::now(); | ||
let ciphertext = keypair.encrypt(&plaintext); | ||
let _ = keypair.decrypt(&ciphertext); | ||
total_time += start.elapsed(); | ||
} | ||
|
||
total_time | ||
}) | ||
}); | ||
} | ||
|
||
/// Benchmark addition between a ciphertext and a plaintext | ||
/// | ||
/// This includes only the time to add the two values together | ||
fn bench_ciphertext_plaintext_addition(c: &mut Criterion) { | ||
let mut group = c.benchmark_group("ciphertext-ops"); | ||
let params = BGVParams::<TestCurve>::new_no_mults(); | ||
let slots = params.plaintext_slots(); | ||
let keypair = BGVKeypair::gen(¶ms); | ||
|
||
group.throughput(Throughput::Elements(slots as u64)); | ||
group.bench_function(BenchmarkId::new("plaintext-add", ""), |b| { | ||
b.iter_custom(|n_iters| { | ||
let mut total_time = std::time::Duration::default(); | ||
let mut rng = rand::thread_rng(); | ||
|
||
for _ in 0..n_iters { | ||
let mut plaintext = random_plaintext(¶ms); | ||
let ciphertext = keypair.encrypt(&random_plaintext(¶ms)); | ||
|
||
let start = std::time::Instant::now(); | ||
let _ = &ciphertext + &plaintext; | ||
total_time += start.elapsed(); | ||
} | ||
|
||
total_time | ||
}) | ||
}); | ||
} | ||
|
||
/// Benchmark multiplying a ciphertext by a plaintext | ||
fn bench_ciphertext_plaintext_multiplication(c: &mut Criterion) { | ||
let mut group = c.benchmark_group("ciphertext-ops"); | ||
let params = BGVParams::<TestCurve>::new_no_mults(); | ||
let slots = params.plaintext_slots(); | ||
let keypair = BGVKeypair::gen(¶ms); | ||
|
||
group.throughput(Throughput::Elements(slots as u64)); | ||
group.bench_function(BenchmarkId::new("plaintext-mul", ""), |b| { | ||
b.iter_custom(|n_iters| { | ||
let mut total_time = std::time::Duration::default(); | ||
let mut rng = rand::thread_rng(); | ||
|
||
for _ in 0..n_iters { | ||
let mut plaintext = random_plaintext(¶ms); | ||
let ciphertext = keypair.encrypt(&random_plaintext(¶ms)); | ||
|
||
let start = std::time::Instant::now(); | ||
let _ = &ciphertext * &plaintext; | ||
total_time += start.elapsed(); | ||
} | ||
|
||
total_time | ||
}) | ||
}); | ||
} | ||
|
||
/// Benchmark adding a ciphertext to another ciphertext | ||
fn bench_ciphertext_addition(c: &mut Criterion) { | ||
let mut group = c.benchmark_group("ciphertext-ops"); | ||
let params = BGVParams::<TestCurve>::new_no_mults(); | ||
let slots = params.plaintext_slots(); | ||
let keypair = BGVKeypair::gen(¶ms); | ||
|
||
group.throughput(Throughput::Elements(slots as u64)); | ||
group.bench_function(BenchmarkId::new("ciphertext-add", ""), |b| { | ||
b.iter_custom(|n_iters| { | ||
let mut total_time = std::time::Duration::default(); | ||
let mut rng = rand::thread_rng(); | ||
|
||
for _ in 0..n_iters { | ||
let ciphertext1 = keypair.encrypt(&random_plaintext(¶ms)); | ||
let ciphertext2 = keypair.encrypt(&random_plaintext(¶ms)); | ||
|
||
let start = std::time::Instant::now(); | ||
let _ = &ciphertext1 + &ciphertext2; | ||
total_time += start.elapsed(); | ||
} | ||
|
||
total_time | ||
}) | ||
}); | ||
} | ||
|
||
/// Benchmark multiplying a ciphertext by another ciphertext | ||
fn bench_ciphertext_multiplication(c: &mut Criterion) { | ||
let mut group = c.benchmark_group("ciphertext-ops"); | ||
let params = BGVParams::<TestCurve>::new(1 /* n_mults */); | ||
let slots = params.plaintext_slots(); | ||
let keypair = BGVKeypair::gen(¶ms); | ||
|
||
group.throughput(Throughput::Elements(slots as u64)); | ||
group.bench_function(BenchmarkId::new("ciphertext-mul", ""), |b| { | ||
b.iter_custom(|n_iters| { | ||
let mut total_time = std::time::Duration::default(); | ||
let mut rng = rand::thread_rng(); | ||
|
||
for _ in 0..n_iters { | ||
let ciphertext1 = keypair.encrypt(&random_plaintext(¶ms)); | ||
let ciphertext2 = keypair.encrypt(&random_plaintext(¶ms)); | ||
|
||
let start = std::time::Instant::now(); | ||
let _ = &ciphertext1.mul_ciphertext(&ciphertext2, &keypair.public_key); | ||
total_time += start.elapsed(); | ||
} | ||
|
||
total_time | ||
}) | ||
}); | ||
} | ||
|
||
criterion_group! { | ||
name = ciphertext_ops; | ||
config = Criterion::default().sample_size(10); | ||
targets = bench_ciphertext_encrypt_decrypt, | ||
bench_ciphertext_plaintext_addition, | ||
bench_ciphertext_plaintext_multiplication, | ||
bench_ciphertext_addition, | ||
bench_ciphertext_multiplication, | ||
} | ||
criterion_main!(ciphertext_ops); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
use std::time::{Duration, Instant}; | ||
|
||
use ark_mpc::algebra::Scalar; | ||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; | ||
use mp_spdz_rs::benchmark_helpers::random_plaintext; | ||
use mp_spdz_rs::fhe::{params::BGVParams, plaintext::Plaintext}; | ||
use mp_spdz_rs::TestCurve; | ||
use rand::thread_rng; | ||
|
||
/// Benchmark plaintext addition | ||
fn benchmark_plaintext_addition(c: &mut Criterion) { | ||
let mut group = c.benchmark_group("plaintext-ops"); | ||
|
||
let params = BGVParams::<TestCurve>::new_no_mults(); | ||
let slots = params.plaintext_slots(); | ||
|
||
group.throughput(criterion::Throughput::Elements(slots as u64)); | ||
group.bench_function(BenchmarkId::new("add", ""), |b| { | ||
b.iter_custom(|n_iters| { | ||
let mut total_time = Duration::default(); | ||
let mut rng = thread_rng(); | ||
|
||
for _ in 0..n_iters { | ||
let mut plaintext1 = random_plaintext(¶ms); | ||
let mut plaintext2 = random_plaintext(¶ms); | ||
|
||
let start = Instant::now(); | ||
let _ = black_box(&plaintext1 + &plaintext2); | ||
total_time += start.elapsed(); | ||
} | ||
|
||
total_time | ||
}) | ||
}); | ||
} | ||
|
||
/// Benchmark plaintext multiplication | ||
fn benchmark_plaintext_multiplication(c: &mut Criterion) { | ||
let mut group = c.benchmark_group("plaintext-ops"); | ||
|
||
let params = BGVParams::<TestCurve>::new_no_mults(); | ||
let slots = params.plaintext_slots(); | ||
|
||
group.throughput(criterion::Throughput::Elements(slots as u64)); | ||
group.bench_function(BenchmarkId::new("mul", ""), |b| { | ||
b.iter_custom(|n_iters| { | ||
let mut total_time = Duration::default(); | ||
let mut rng = thread_rng(); | ||
|
||
for _ in 0..n_iters { | ||
let plaintext1 = random_plaintext(¶ms); | ||
let plaintext2 = random_plaintext(¶ms); | ||
|
||
let start = Instant::now(); | ||
let _ = black_box(&plaintext1 * &plaintext2); | ||
total_time += start.elapsed(); | ||
} | ||
|
||
total_time | ||
}) | ||
}); | ||
} | ||
|
||
criterion_group! { | ||
name = plaintext_ops; | ||
config = Criterion::default(); | ||
targets = benchmark_plaintext_addition, benchmark_plaintext_multiplication | ||
} | ||
criterion_main!(plaintext_ops); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters