Skip to main content

tecdsa_core/
params.rs

1//! Security parameters (spec §5). Every size used by the protocols comes from here.
2
3/// Identifier of a parameter profile, carried in the message envelope.
4#[derive(Clone, Copy, Debug, PartialEq, Eq)]
5#[repr(u8)]
6pub enum ParamsId {
7    P128 = 128,
8    P112 = 112,
9}
10
11/// Parameter profile. All sizes are in bits unless noted.
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
13pub struct Params {
14    pub id: ParamsId,
15    /// Group order size κ.
16    pub kappa: u32,
17    /// Soundness ℓ.
18    pub ell: u32,
19    /// Statistical noise ν.
20    pub nu: u32,
21    /// Noise against subgroup leakage ν_leak.
22    pub nu_leak: u32,
23    /// Paillier / DF modulus size of the server.
24    pub n_rsa: u32,
25    /// Ephemeral DF modulus size of the client.
26    pub n_client: u32,
27    /// Repetitions of Π_mod.
28    pub r_mod: u32,
29    /// Repetitions of Π_df.
30    pub r_df: u32,
31    /// Repetitions of Π_df*.
32    pub r_df_star: u32,
33    /// Challenge size of Π_df* in bits (open question, spec §5).
34    pub ell0: u32,
35    /// Randomness range of a DF commitment, n_tρ.
36    pub n_t_rho: u32,
37    /// Number of small primes in (p−1)/2 for tough primes.
38    pub tough_count: u32,
39    /// Bit size of each small prime in tough primes.
40    pub tough_bits: u32,
41}
42
43impl Params {
44    /// Slack ε = ℓ + ν.
45    pub const fn eps(&self) -> u32 {
46        self.ell + self.nu
47    }
48    /// Range of x₂′: κ + ν_leak.
49    pub const fn n_x(&self) -> u32 {
50        self.kappa + self.nu_leak
51    }
52    /// Range of β: 2ℓ + ν_leak.
53    pub const fn n_lambda(&self) -> u32 {
54        2 * self.ell + self.nu_leak
55    }
56    /// Range of v: κ + ℓ + ν.
57    pub const fn n_b(&self) -> u32 {
58        self.kappa + self.ell + self.nu
59    }
60    /// Range of u: n_x + ε + n_b + ν.
61    pub const fn n_a(&self) -> u32 {
62        self.n_x() + self.eps() + self.n_b() + self.nu
63    }
64    /// Range of λ₀: n_λ + ε + n_b + ν.
65    pub const fn n_lambda0(&self) -> u32 {
66        self.n_lambda() + self.eps() + self.n_b() + self.nu
67    }
68
69    /// Checks internal consistency of a profile.
70    pub const fn is_consistent(&self) -> bool {
71        self.kappa == 256
72            && self.ell > 0
73            && self.r_df == self.ell
74            && self.r_mod == self.ell / 2
75            && self.r_df_star * self.ell0 >= self.ell
76            && self.n_rsa % 8 == 0
77            && self.n_client % 8 == 0
78    }
79}
80
81/// Main profile: 128-bit security.
82pub const PARAMS_128: Params = Params {
83    id: ParamsId::P128,
84    kappa: 256,
85    ell: 128,
86    nu: 64,
87    nu_leak: 64,
88    n_rsa: 3072,
89    n_client: 2048,
90    r_mod: 64,
91    r_df: 128,
92    r_df_star: 16,
93    ell0: 8,
94    n_t_rho: 1408,
95    tough_count: 6,
96    tough_bits: 256,
97};
98
99/// Benchmark-only profile: 112-bit security.
100// Tough primes are 1024 bits here (n_rsa / 2), so the factors of (p−1)/2 are sized to fit:
101// 5 factors of about 205 bits (the 128-bit profile uses 6 × 256 = 1536).
102pub const PARAMS_112: Params = Params {
103    id: ParamsId::P112,
104    kappa: 256,
105    ell: 112,
106    nu: 64,
107    nu_leak: 64,
108    n_rsa: 2048,
109    n_client: 2048,
110    r_mod: 56,
111    r_df: 112,
112    r_df_star: 16,
113    ell0: 8,
114    n_t_rho: 1344,
115    tough_count: 5,
116    tough_bits: 205,
117};
118
119const _: () = assert!(PARAMS_128.is_consistent());
120const _: () = assert!(PARAMS_112.is_consistent());
121const _: () = assert!(PARAMS_128.eps() == 192 && PARAMS_112.eps() == 176);
122const _: () = assert!(PARAMS_128.n_x() == 320 && PARAMS_112.n_x() == 320);
123const _: () = assert!(PARAMS_128.n_lambda() == 320 && PARAMS_112.n_lambda() == 288);
124const _: () = assert!(PARAMS_128.n_b() == 448 && PARAMS_112.n_b() == 432);
125const _: () = assert!(PARAMS_128.n_a() == 1024 && PARAMS_112.n_a() == 992);
126const _: () = assert!(PARAMS_128.n_lambda0() == 1024 && PARAMS_112.n_lambda0() == 960);