gsw_rs/params.rs
1//! LWE/GSW parameter definitions.
2//!
3//! Parameters are chosen for correctness with conservative security levels.
4//! In production, use lattice estimators for proper security parameter selection.
5
6/// Security level in bits.
7#[derive(Clone, Copy, Debug, PartialEq, Eq)]
8pub enum SecurityLevel {
9 /// Toy parameters for testing (~32-bit security)
10 Toy,
11 /// Low security (~64-bit)
12 Low,
13 /// Medium security (~128-bit)
14 Medium,
15}
16
17/// LWE/GSW instance parameters.
18#[derive(Clone, Debug)]
19pub struct Params {
20 /// Modulus q (must be power of 2 for gadget)
21 pub q: u64,
22 /// Lattice dimension n
23 pub n: usize,
24 /// Number of bits to represent q: l = log2(q)
25 pub l: usize,
26 /// N = (n+1) * l - dimension of expanded gadget space
27 pub n_expanded: usize,
28 /// Number of LWE samples for public key (columns of A)
29 pub m: usize,
30 /// Error bound B for discrete uniform error distribution [-B, B]
31 pub error_bound: i64,
32}
33
34impl Params {
35 /// Create parameters for the given security level.
36 ///
37 /// Parameters are chosen so that correctness never fails:
38 /// - Error growth: mult multiplies error by ~N=(n+1)*l, add doubles it
39 /// - Requirement: N * sqrt(m) * B ≪ q/4 for one multiplication
40 pub fn new(level: SecurityLevel) -> Self {
41 let mut p = match level {
42 SecurityLevel::Toy => Self {
43 q: 1 << 20, // 1M - margin for correctness
44 n: 8,
45 m: 256,
46 error_bound: 1,
47 l: 0,
48 n_expanded: 0,
49 },
50 SecurityLevel::Low => Self {
51 q: 1 << 24,
52 n: 24,
53 m: 384,
54 error_bound: 2,
55 l: 0,
56 n_expanded: 0,
57 },
58 SecurityLevel::Medium => Self {
59 q: 1 << 26,
60 n: 48,
61 m: 768,
62 error_bound: 4,
63 l: 0,
64 n_expanded: 0,
65 },
66 };
67 p.with_derived();
68 p
69 }
70
71 /// Create toy parameters for quick testing.
72 pub fn toy() -> Self {
73 Self::new(SecurityLevel::Toy)
74 }
75
76 fn with_derived(&mut self) {
77 self.l = (self.q as f64).log2() as usize;
78 self.n_expanded = (self.n + 1) * self.l;
79 }
80}