Skip to main content

rune_ring/
params.rs

1//! Cryptographic parameter sets for Rune.
2
3use crate::math::MAX_N;
4
5/// System parameters for Rune ring signatures.
6///
7/// Construct via the provided constants [`RUNE_128`] or [`RUNE_256`].
8/// Custom parameter construction is intentionally not exposed: incorrect
9/// choices can silently reduce security or cause signing to fail.
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct Params {
12    n: usize,
13    q: i64,
14    eta: u8,
15    kappa: usize,
16    gamma: i64,
17    beta: i64,
18    omega: usize,
19    max_attempts: usize,
20}
21
22impl Params {
23    /// Creates a validated parameter set.
24    ///
25    /// # Panics
26    ///
27    /// Panics if the parameters are internally inconsistent.
28    #[must_use]
29    #[allow(clippy::too_many_arguments)]
30    pub(crate) const fn new(
31        n: usize,
32        q: i64,
33        eta: u8,
34        kappa: usize,
35        gamma: i64,
36        beta: i64,
37        omega: usize,
38        max_attempts: usize,
39    ) -> Self {
40        assert!(n > 0 && n <= MAX_N);
41        assert!(q > 2 && q % 2 == 1);
42        assert!(eta > 0);
43        assert!(kappa > 0 && kappa < n);
44        assert!(gamma > 0);
45        assert!(beta > 0 && beta < gamma);
46        assert!(omega > 0);
47        assert!(max_attempts > 0);
48
49        Self {
50            n,
51            q,
52            eta,
53            kappa,
54            gamma,
55            beta,
56            omega,
57            max_attempts,
58        }
59    }
60
61    /// Polynomial degree.
62    #[must_use]
63    pub const fn n(&self) -> usize {
64        self.n
65    }
66
67    /// Coefficient modulus.
68    #[must_use]
69    pub const fn q(&self) -> i64 {
70        self.q
71    }
72
73    /// Centered binomial sampling parameter.
74    #[must_use]
75    pub const fn eta(&self) -> u8 {
76        self.eta
77    }
78
79    /// Challenge Hamming weight.
80    #[must_use]
81    pub const fn kappa(&self) -> usize {
82        self.kappa
83    }
84
85    /// Masking range.
86    #[must_use]
87    pub const fn gamma(&self) -> i64 {
88        self.gamma
89    }
90
91    /// Rejection margin.
92    #[must_use]
93    pub const fn beta(&self) -> i64 {
94        self.beta
95    }
96
97    /// Response norm bound used during rejection sampling.
98    #[must_use]
99    pub const fn response_bound(&self) -> i64 {
100        self.gamma - self.beta
101    }
102
103    /// Maximum hint weight for parameter sets with hints.
104    #[must_use]
105    pub const fn omega(&self) -> usize {
106        self.omega
107    }
108
109    /// Maximum signing attempt count.
110    #[must_use]
111    pub const fn max_attempts(&self) -> usize {
112        self.max_attempts
113    }
114}
115
116/// Demonstration parameters only. Security is approximately 10 bits. Use
117/// `RUNE_256` for any real deployment.
118pub const RUNE_128: Params = Params::new(256, 998_244_353, 2, 60, 249_561_088, 120, 60, 256);
119
120/// Default parameter set. Provides approximately 128 bits of classical
121/// security. Suitable for production use pending independent cryptographic
122/// audit. Uses q=8380417, which supports NTT-based polynomial multiplication
123/// (q ≡ 1 mod 2n). The current implementation uses schoolbook multiplication;
124/// NTT acceleration is planned for a future release.
125pub const RUNE_256: Params = Params::new(512, 8_380_417, 3, 60, 524_288, 180, 120, 256);
126
127#[cfg(test)]
128mod param_tests {
129    use super::*;
130
131    #[test]
132    fn params_constants_are_valid() {
133        let _ = RUNE_128.n();
134        let _ = RUNE_256.n();
135    }
136}