Skip to main content

cggmp24/
security_level.rs

1//! Security level of CGGMP protocol
2//!
3//! Security level is defined as set of parameters in the CGGMP paper. Higher security level gives more
4//! security but makes protocol execution slower.
5//!
6//! We provide a predefined default [SecurityLevel128].
7//!
8//! You can define your own security level using macro [define_security_level]. Be sure that you properly
9//! analyzed the CGGMP paper and you understand implications. Inconsistent security level may cause unexpected
10//! unverbose runtime error or reduced security of the protocol.
11
12use crate::backend::Integer;
13
14/// Security level of CGGMP24 DKG protocol
15pub use cggmp24_keygen::security_level::SecurityLevel as KeygenSecurityLevel;
16
17/// Hardcoded value for parameter $m$ of security level
18///
19/// Currently, security parameter $m$ is hardcoded to this constant. We're going to fix that
20/// once `feature(generic_const_exprs)` is stable.
21pub const M: usize = 128;
22
23/// Security level of the CGGMP24 protocol
24///
25/// You should not implement this trait manually. Use [define_security_level] macro instead.
26pub trait SecurityLevel: KeygenSecurityLevel {
27    /// Length of RSA prime that matches the security level
28    const RSA_PRIME_BITLEN: u32;
29    /// Minimal length of RSA public key (bi-prime $N = pq$) that matches the
30    /// security level
31    const RSA_PUBKEY_BITLEN: u32;
32
33    /// $\varepsilon$ bits
34    const EPSILON: usize;
35
36    /// $\ell$ parameter
37    const ELL: usize;
38    /// $\ell'$ parameter
39    const ELL_PRIME: usize;
40}
41
42/// Determines max size of exponents
43///
44/// During the CGGMP24 protocol, we often calculate $s^x t^y \mod N$. Given the security level
45/// we can determine max size of $x$ and $y$ in bits.
46///
47/// Size of exponents can be used to build a [multiexp table](paillier_zk::multiexp).
48///
49/// Returns `(x_bits, y_bits)`
50pub fn max_exponents_size<L: SecurityLevel>() -> (u32, u32) {
51    use std::cmp;
52
53    let x_bits = cmp::max(
54        L::ELL as u32 + L::EPSILON as u32 + L::RSA_PRIME_BITLEN,
55        (L::ELL_PRIME + L::EPSILON) as _,
56    );
57    let y_bits = (L::ELL + L::EPSILON) as u32 + (L::RSA_PUBKEY_BITLEN + 4);
58
59    (x_bits, y_bits)
60}
61
62/// Internal module that's powers `define_security_level` macro
63#[doc(hidden)]
64pub mod _internal {
65
66    pub use crate::backend::Integer;
67    pub use cggmp24_keygen::security_level::{
68        define_security_level as define_keygen_security_level, SecurityLevel as KeygenSecurityLevel,
69    };
70}
71
72/// Defines security level
73///
74/// ## Example
75///
76/// This code defines security level corresponding to $\kappa=1024$, RSA prime bitlen = 256,
77/// RSA public key bitlen = 511, $\varepsilon=128$, $\ell = \ell' = 1024$, and $m = 128$ (note:
78/// choice of parameters is random, it does not correspond to meaningful security level):
79/// ```rust
80/// use cggmp24::security_level::define_security_level;
81///
82/// #[derive(Clone)]
83/// pub struct MyLevel;
84/// define_security_level!(MyLevel {
85///     kappa_bits: 1024,
86///     rsa_prime_bitlen: 256,
87///     rsa_pubkey_bitlen: 511,
88///     epsilon: 128,
89///     ell: 1024,
90///     ell_prime: 1024,
91///     m: 128,
92/// });
93/// ```
94///
95/// **Note:** currently, security parameter $m$ is hardcoded to the [`M = 128`](M) due to compiler limitations.
96/// Setting any other value of $m$ results into compilation error. We're going to fix that once `generic_const_exprs`
97/// feature is stable.
98#[macro_export]
99macro_rules! define_security_level {
100    ($struct_name:ident {
101        kappa_bits: $k:expr,
102        rsa_prime_bitlen: $rsa_prime_bitlen:expr,
103        rsa_pubkey_bitlen: $rsa_pubkey_bitlen:expr,
104        epsilon: $e:expr,
105        ell: $ell:expr,
106        ell_prime: $ell_prime:expr,
107        m: $m:tt,
108    }) => {
109        $crate::define_security_level! {
110            $struct_name {
111                rsa_prime_bitlen: $rsa_prime_bitlen,
112                rsa_pubkey_bitlen: $rsa_pubkey_bitlen,
113                epsilon: $e,
114                ell: $ell,
115                ell_prime: $ell_prime,
116                m: $m,
117            }
118        }
119        $crate::security_level::_internal::define_keygen_security_level! {
120            $struct_name {
121                kappa_bits: $k,
122            }
123        }
124    };
125    ($struct_name:ident {
126        rsa_prime_bitlen: $rsa_prime_bitlen:expr,
127        rsa_pubkey_bitlen: $rsa_pubkey_bitlen:expr,
128        epsilon: $e:expr,
129        ell: $ell:expr,
130        ell_prime: $ell_prime:expr,
131        m: 128,
132    }) => {
133        impl $crate::security_level::SecurityLevel for $struct_name {
134            const RSA_PRIME_BITLEN: u32 = $rsa_prime_bitlen;
135            const RSA_PUBKEY_BITLEN: u32 = $rsa_pubkey_bitlen;
136            const EPSILON: usize = $e;
137            const ELL: usize = $ell;
138            const ELL_PRIME: usize = $ell_prime;
139        }
140    };
141    ($struct_name:ident {
142        rsa_prime_bitlen: $rsa_prime_bitlen:expr,
143        rsa_pubkey_bitlen: $rsa_pubkey_bitlen:expr,
144        epsilon: $e:expr,
145        ell: $ell:expr,
146        ell_prime: $ell_prime:expr,
147        m: $m:tt,
148    }) => {
149        compile_error!(concat!("Currently, we can not set security parameter M to anything but 128 (you set m=", stringify!($m), ")"));
150    };
151}
152
153#[doc(inline)]
154pub use define_security_level;
155
156#[doc(inline)]
157pub use cggmp24_keygen::security_level::SecurityLevel128;
158define_security_level!(SecurityLevel128 {
159    rsa_prime_bitlen: 1536,
160    rsa_pubkey_bitlen: 3071,
161    epsilon: 256 * 2,
162    ell: 256,
163    ell_prime: 256 * 5,
164    m: 128,
165});
166
167#[doc(inline)]
168pub use cggmp24_keygen::security_level::SecurityLevel192;
169define_security_level!(SecurityLevel192 {
170    rsa_prime_bitlen: 7680 / 2,
171    rsa_pubkey_bitlen: 7679,
172    epsilon: Self::KAPPA_BITS as usize * 2,
173    ell: Self::KAPPA_BITS as usize,
174    ell_prime: Self::KAPPA_BITS as usize * 5,
175    m: 128,
176});
177
178/// Checks that public paillier key meets security level constraints
179pub(crate) fn validate_public_paillier_key_size<L: SecurityLevel>(N: &Integer) -> bool {
180    N.significant_bits() >= u64::from(L::RSA_PUBKEY_BITLEN)
181}
182
183/// Checks that a prime, that is a part of secret paillier key, meets security level constraints
184pub(crate) fn validate_secret_paillier_prime_size<L: SecurityLevel>(prime: &Integer) -> bool {
185    prime.significant_bits() >= u64::from(L::RSA_PRIME_BITLEN)
186}