11use ark_bls12_381:: Bls12_381 ;
22use 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 } ;
57use criterion:: { criterion_group, criterion_main, BenchmarkId , Criterion } ;
8+ use simple_batched_threshold_encryption:: bte:: decryption:: { decrypt, decrypt_fft} ;
69use 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+
107175fn 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+
190276fn 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) ;
264351criterion_main ! ( benches) ;
0 commit comments