Skip to content

Commit 211bbd7

Browse files
authored
Merge pull request #60 from qfall/psf_perturbation
PSF with Perturbation Sampling
2 parents 4c7e7a6 + 3215d9f commit 211bbd7

6 files changed

Lines changed: 827 additions & 139 deletions

File tree

benches/benchmarks.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use criterion::criterion_main;
1111

1212
pub mod pfdh;
13+
pub mod psf;
1314
pub mod regev;
1415

15-
criterion_main! {regev::benches, pfdh::benches}
16+
criterion_main! {regev::benches, pfdh::benches, psf::benches}

benches/psf.rs

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// Copyright © 2025 Niklas Siemer
2+
//
3+
// This file is part of qFALL-crypto.
4+
//
5+
// qFALL-crypto is free software: you can redistribute it and/or modify it under
6+
// the terms of the Mozilla Public License Version 2.0 as published by the
7+
// Mozilla Foundation. See <https://mozilla.org/en-US/MPL/2.0/>.
8+
9+
use criterion::{criterion_group, Criterion};
10+
use qfall_crypto::{
11+
primitive::psf::{PSFPerturbation, PSF, PSFGPV},
12+
sample::g_trapdoor::gadget_parameters::GadgetParameters,
13+
};
14+
use qfall_math::{integer_mod_q::MatZq, rational::Q};
15+
16+
/// Benchmark [bench_psf] with `n = 8`.
17+
///
18+
/// This benchmark can be run with for example:
19+
/// - `cargo criterion PSF\ GPV\ n=8`
20+
/// - `cargo bench --bench benchmarks PSF\ GPV\ n=8`
21+
/// - `cargo flamegraph --bench benchmarks -- --bench PSF\ GPV\ n=8`
22+
///
23+
/// Shorter variants or regex expressions can also be used to specify the
24+
/// benchmark name. The `\ ` is used to escape the space, alternatively,
25+
/// quotation marks can be used.
26+
fn bench_psf(c: &mut Criterion) {
27+
let (n, q) = (8, 128);
28+
29+
let psf = PSFGPV {
30+
gp: GadgetParameters::init_default(n, q),
31+
// multiply with the rounding parameter from next test to have the same samplign parameter
32+
s: Q::from(30) * Q::from(n).log(2).unwrap(),
33+
};
34+
35+
let target = MatZq::sample_uniform(n, 1, q);
36+
let (a, r) = psf.trap_gen();
37+
38+
c.bench_function("PSF GPV n=8", |b| b.iter(|| psf.samp_p(&a, &r, &target)));
39+
}
40+
41+
/// Benchmark [bench_psf_perturbation] with `n = 8`.
42+
///
43+
/// This benchmark can be run with for example:
44+
/// - `cargo criterion PSF\ Perturbation\ n=8`
45+
/// - `cargo bench --bench benchmarks PSF\ Perturbation\ n=8`
46+
/// - `cargo flamegraph --bench benchmarks -- --bench PSF\ Perturbation\ n=8`
47+
///
48+
/// Shorter variants or regex expressions can also be used to specify the
49+
/// benchmark name. The `\ ` is used to escape the space, alternatively,
50+
/// quotation marks can be used.
51+
fn bench_psf_perturbation(c: &mut Criterion) {
52+
let (n, q) = (8, 128);
53+
54+
let psf = PSFPerturbation {
55+
gp: GadgetParameters::init_default(n, q),
56+
s: Q::from(30),
57+
r: Q::from(n).log(2).unwrap(),
58+
};
59+
60+
let target = MatZq::sample_uniform(n, 1, q);
61+
let (a, r) = psf.trap_gen();
62+
63+
c.bench_function("PSF Perturbation n=8", |b| {
64+
b.iter(|| psf.samp_p(&a, &r, &target))
65+
});
66+
}
67+
68+
/// Benchmark [bench_psf_perturbation] with `n = 64`.
69+
///
70+
/// This benchmark can be run with for example:
71+
/// - `cargo criterion PSF\ Perturbation\ n=64`
72+
/// - `cargo bench --bench benchmarks PSF\ Perturbation\ n=64`
73+
/// - `cargo flamegraph --bench benchmarks -- --bench PSF\ Perturbation\ n=64`
74+
///
75+
/// Shorter variants or regex expressions can also be used to specify the
76+
/// benchmark name. The `\ ` is used to escape the space, alternatively,
77+
/// quotation marks can be used.
78+
fn bench_psf_perturbation_larger(c: &mut Criterion) {
79+
let (n, q) = (64, 128);
80+
81+
let psf = PSFPerturbation {
82+
gp: GadgetParameters::init_default(n, q),
83+
s: Q::from(100),
84+
r: Q::from(n).log(2).unwrap(),
85+
};
86+
87+
let target = MatZq::sample_uniform(n, 1, q);
88+
let (a, r) = psf.trap_gen();
89+
90+
c.bench_function("PSF Perturbation n=64", |b| {
91+
b.iter(|| psf.samp_p(&a, &r, &target))
92+
});
93+
}
94+
95+
criterion_group!(
96+
benches,
97+
bench_psf,
98+
bench_psf_perturbation,
99+
bench_psf_perturbation_larger,
100+
);

src/primitive/psf.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,18 @@
2020
//! January. Implementation and evaluation of improved Gaussian sampling for lattice
2121
//! trapdoors. In Proceedings of the 6th Workshop on Encrypted Computing & Applied
2222
//! Homomorphic Cryptography (pp. 61-71). <https://dl.acm.org/doi/pdf/10.1145/3267973.3267975>
23+
//! - \[3\] Peikert, Chris.
24+
//! An efficient and parallel Gaussian sampler for lattices.
25+
//! In: Annual Cryptology Conference - CRYPTO 2010.
26+
//! Springer, Berlin, Heidelberg. <https://doi.org/10.1007/978-3-642-14623-7_5>
2327
2428
mod gpv;
2529
mod gpv_ring;
30+
mod mp_perturbation;
2631

2732
pub use gpv::PSFGPV;
2833
pub use gpv_ring::PSFGPVRing;
34+
pub use mp_perturbation::PSFPerturbation;
2935

3036
/// This trait should be implemented by all constructions that are
3137
/// actual implementations of a preimage sampleable function.

0 commit comments

Comments
 (0)