-
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
6 changed files
with
299 additions
and
3 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,198 @@ | ||
//! Benchmarks for ciphertext operations | ||
use ark_mpc::algebra::Scalar; | ||
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion, Throughput}; | ||
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 mut keypair = BGVKeypair::gen(¶ms); | ||
|
||
let plaintext = Plaintext::new(¶ms); | ||
let slots = plaintext.num_slots(); | ||
|
||
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 mut plaintext = Plaintext::new(¶ms); | ||
|
||
for i in 0..(slots as usize) { | ||
plaintext.set_element(i, Scalar::random(&mut rng)); | ||
} | ||
|
||
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 keypair = BGVKeypair::gen(¶ms); | ||
|
||
let plaintext = Plaintext::new(¶ms); | ||
let slots = plaintext.num_slots(); | ||
|
||
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 plaintext1 = Plaintext::new(¶ms); | ||
let mut plaintext2 = Plaintext::new(¶ms); | ||
|
||
for i in 0..(slots as usize) { | ||
plaintext1.set_element(i, Scalar::random(&mut rng)); | ||
plaintext2.set_element(i, Scalar::random(&mut rng)); | ||
} | ||
|
||
let ciphertext = keypair.encrypt(&plaintext1); | ||
|
||
let start = std::time::Instant::now(); | ||
let _ = &ciphertext + &plaintext2; | ||
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 keypair = BGVKeypair::gen(¶ms); | ||
|
||
let plaintext = Plaintext::new(¶ms); | ||
let slots = plaintext.num_slots(); | ||
|
||
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 plaintext1 = Plaintext::new(¶ms); | ||
let mut plaintext2 = Plaintext::new(¶ms); | ||
|
||
for i in 0..(slots as usize) { | ||
plaintext1.set_element(i, Scalar::random(&mut rng)); | ||
plaintext2.set_element(i, Scalar::random(&mut rng)); | ||
} | ||
|
||
let ciphertext = keypair.encrypt(&plaintext1); | ||
|
||
let start = std::time::Instant::now(); | ||
let _ = &ciphertext * &plaintext2; | ||
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 keypair = BGVKeypair::gen(¶ms); | ||
|
||
let plaintext = Plaintext::new(¶ms); | ||
let slots = plaintext.num_slots(); | ||
|
||
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 mut plaintext1 = Plaintext::new(¶ms); | ||
let mut plaintext2 = Plaintext::new(¶ms); | ||
|
||
for i in 0..(slots as usize) { | ||
plaintext1.set_element(i, Scalar::random(&mut rng)); | ||
plaintext2.set_element(i, Scalar::random(&mut rng)); | ||
} | ||
|
||
let ciphertext1 = keypair.encrypt(&plaintext1); | ||
let ciphertext2 = keypair.encrypt(&plaintext2); | ||
|
||
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 keypair = BGVKeypair::gen(¶ms); | ||
|
||
let plaintext = Plaintext::new(¶ms); | ||
let slots = plaintext.num_slots(); | ||
|
||
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 mut plaintext1 = Plaintext::new(¶ms); | ||
let mut plaintext2 = Plaintext::new(¶ms); | ||
|
||
for i in 0..(slots as usize) { | ||
plaintext1.set_element(i, Scalar::random(&mut rng)); | ||
plaintext2.set_element(i, Scalar::random(&mut rng)); | ||
} | ||
|
||
let ciphertext1 = keypair.encrypt(&plaintext1); | ||
let ciphertext2 = keypair.encrypt(&plaintext2); | ||
|
||
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,80 @@ | ||
use std::time::{Duration, Instant}; | ||
|
||
use ark_mpc::algebra::Scalar; | ||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion}; | ||
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 plaintext = Plaintext::new(¶ms); | ||
let slots = plaintext.num_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 = Plaintext::new(¶ms); | ||
let mut plaintext2 = Plaintext::new(¶ms); | ||
|
||
for i in 0..(slots as usize) { | ||
plaintext1.set_element(i, Scalar::random(&mut rng)); | ||
plaintext2.set_element(i, Scalar::random(&mut rng)); | ||
} | ||
|
||
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 plaintext = Plaintext::new(¶ms); | ||
let slots = plaintext.num_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 mut plaintext1 = Plaintext::new(¶ms); | ||
let mut plaintext2 = Plaintext::new(¶ms); | ||
|
||
for i in 0..(slots as usize) { | ||
plaintext1.set_element(i, Scalar::random(&mut rng)); | ||
plaintext2.set_element(i, Scalar::random(&mut rng)); | ||
} | ||
|
||
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