Skip to content

Commit a482106

Browse files
adds naive batch verify benchmarks
1 parent bbc3180 commit a482106

3 files changed

Lines changed: 102 additions & 10 deletions

File tree

benches/bte_bench.rs

Lines changed: 97 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
use ark_bls12_381::Bls12_381;
22
use ark_ec::pairing::{Pairing, PairingOutput};
3-
use ark_ec::PrimeGroup;
4-
use ark_std::{test_rng, UniformRand};
3+
use ark_ec::{AffineRepr, CurveGroup, PrimeGroup, VariableBaseMSM};
4+
use ark_ff::Zero;
5+
use ark_poly::EvaluationDomain;
6+
use ark_std::{rand::Rng, test_rng, UniformRand};
57
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
8+
use simple_batched_threshold_encryption::bte::decryption::{decrypt, decrypt_fft};
69
use simple_batched_threshold_encryption::bte::{
710
crs::setup,
811
decryption::{combine, finalize_decrypt, partial_decrypt, predecrypt_fft, verify},
@@ -104,6 +107,71 @@ fn make_fo_context(batch_size: usize, num_parties: usize, threshold: usize) -> F
104107
}
105108
}
106109

110+
fn naive_s_fft_kernel(ctx: &BenchContext) -> Vec<<E as Pairing>::G2> {
111+
let b = ctx.dk.batch_size;
112+
let n = ctx.dk.fft_size;
113+
114+
// h_vec[d] = h_{B+1+d}, encoded modulo n, so convolution with r gives
115+
// S_ell = sum_i r_i * h_{ell+B+1-i} for every ell.
116+
let mut h_vec = vec![<E as Pairing>::G2::zero(); n];
117+
h_vec[0] = ctx.dk.powers_of_h_affine[b + 1].into_group();
118+
for d in 1..b {
119+
h_vec[d] = ctx.dk.powers_of_h_affine[b + 1 + d].into_group();
120+
h_vec[n - d] = ctx.dk.powers_of_h_affine[b + 1 - d].into_group();
121+
}
122+
123+
ctx.dk.fft_domain.fft_in_place(&mut h_vec);
124+
h_vec
125+
}
126+
127+
fn compute_naive_s_fft(
128+
dk: &DecryptionKey<E>,
129+
h_hat: &[<E as Pairing>::G2],
130+
r: &[Fr],
131+
) -> Vec<<E as Pairing>::G2Affine> {
132+
let b = dk.batch_size;
133+
let n = dk.fft_size;
134+
assert_eq!(r.len(), b);
135+
136+
let mut r_hat = r.to_vec();
137+
r_hat.resize(n, Fr::zero());
138+
dk.fft_domain.fft_in_place(&mut r_hat);
139+
140+
let mut s_hat = h_hat.to_vec();
141+
for (s, r_i) in s_hat.iter_mut().zip(r_hat) {
142+
*s *= r_i;
143+
}
144+
145+
dk.fft_domain.ifft_in_place(&mut s_hat);
146+
147+
<E as Pairing>::G2::normalize_batch(&s_hat[..b])
148+
}
149+
150+
fn naive_batch_verify_decryption(
151+
ctx: &BenchContext,
152+
h_hat: &[<E as Pairing>::G2],
153+
rng: &mut impl Rng,
154+
) -> bool {
155+
let b = ctx.cts.len();
156+
157+
let r: Vec<Fr> = (0..b).map(|_| Fr::rand(rng)).collect();
158+
159+
let mut lhs = PairingOutput::<E>::zero();
160+
for i in 0..b {
161+
lhs += (ctx.cts[i].ct2 - ctx.messages[i]) * r[i];
162+
}
163+
164+
let pd_bases: Vec<_> = (0..b).map(|i| ctx.dk.powers_of_h_affine[b - i]).collect();
165+
let pd_term_g2 = <E as Pairing>::G2::msm(&pd_bases, &r).unwrap();
166+
let pd_term = E::pairing(ctx.combined_pd, pd_term_g2.into_affine());
167+
168+
let s_values = compute_naive_s_fft(&ctx.dk, h_hat, &r);
169+
170+
let cross = E::multi_pairing(ctx.cts.iter().map(|ct| ct.ct1), s_values);
171+
172+
lhs == pd_term - cross
173+
}
174+
107175
fn bench_encrypt(c: &mut Criterion) {
108176
let mut group = c.benchmark_group("encrypt");
109177
group.sample_size(10);
@@ -165,15 +233,15 @@ fn bench_decrypt_naive_vs_fft(c: &mut Criterion) {
165233
for &b in &[8, 32, 128, 512, 2048] {
166234
let ctx = make_context(b, 100, 50);
167235

168-
// group.bench_with_input(BenchmarkId::new("naive", b), &b, |bench, _| {
169-
// let mut rng = test_rng();
170-
// bench.iter(|| decrypt(&ctx.dk, &ctx.combined_pd, &ctx.cts, &mut rng));
171-
// });
236+
group.bench_with_input(BenchmarkId::new("naive", b), &b, |bench, _| {
237+
let mut rng = test_rng();
238+
bench.iter(|| decrypt(&ctx.dk, &ctx.combined_pd, &ctx.cts, &mut rng));
239+
});
172240

173-
// group.bench_with_input(BenchmarkId::new("fft", b), &b, |bench, _| {
174-
// let mut rng = test_rng();
175-
// bench.iter(|| decrypt_fft(&ctx.dk, &ctx.combined_pd, &ctx.cts, &mut rng));
176-
// });
241+
group.bench_with_input(BenchmarkId::new("fft", b), &b, |bench, _| {
242+
let mut rng = test_rng();
243+
bench.iter(|| decrypt_fft(&ctx.dk, &ctx.combined_pd, &ctx.cts, &mut rng));
244+
});
177245

178246
group.bench_with_input(BenchmarkId::new("predecrypt", b), &b, |bench, _| {
179247
bench.iter(|| predecrypt_fft(&ctx.dk, &ctx.cts));
@@ -187,6 +255,24 @@ fn bench_decrypt_naive_vs_fft(c: &mut Criterion) {
187255
group.finish();
188256
}
189257

258+
fn bench_naive_batch_verify_decryption(c: &mut Criterion) {
259+
let mut group = c.benchmark_group("naive_batch_verify_decryption");
260+
group.sample_size(10);
261+
262+
for &b in &[8, 32, 128, 512, 2048] {
263+
let ctx = make_context(b, 100, 50);
264+
let h_hat = naive_s_fft_kernel(&ctx);
265+
266+
group.bench_with_input(BenchmarkId::from_parameter(b), &b, |bench, _| {
267+
let mut rng = test_rng();
268+
bench.iter(|| {
269+
assert!(naive_batch_verify_decryption(&ctx, &h_hat, &mut rng));
270+
});
271+
});
272+
}
273+
group.finish();
274+
}
275+
190276
fn bench_fo_encrypt(c: &mut Criterion) {
191277
let mut group = c.benchmark_group("fo_encrypt");
192278
group.sample_size(10);
@@ -260,5 +346,6 @@ criterion_group!(
260346
bench_fo_helper_decrypt,
261347
bench_fo_batch_verify,
262348
bench_fo_batch_verify_bandwidth_optimized,
349+
bench_naive_batch_verify_decryption,
263350
);
264351
criterion_main!(benches);

src/bte/crs.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ pub fn setup<E: Pairing>(
104104
batch_size: b,
105105
num_parties,
106106
threshold,
107+
powers_of_h_affine: h_affine,
107108
powers_of_h,
108109
verification_keys,
109110
fft_size,

src/bte/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ pub struct DecryptionKey<E: Pairing> {
2222
pub batch_size: usize,
2323
pub num_parties: usize,
2424
pub threshold: usize,
25+
/// powers_of_h_affine[j] is [tau^j]_2 for j = 0, ..., 2B.
26+
/// Slot B+1 is the identity. Stored before pairing preparation so callers
27+
/// can perform G2 MSMs/FFTs without recomputing setup material.
28+
pub powers_of_h_affine: Vec<E::G2Affine>,
2529
/// powers_of_h[j] is the prepared form of [tau^j]_2 for j = 0, ..., 2B.
2630
/// Slot B+1 is the identity.
2731
pub powers_of_h: Vec<E::G2Prepared>,

0 commit comments

Comments
 (0)