Skip to main content

sqisign_verify/params/
mod.rs

1//!
2//! Defines the [`SecurityLevel`] trait and the marker structs [`Level1`],
3//! [`Level3`], [`Level5`] for NIST security levels I, III, V. Downstream
4//! crates are generic over `L: SecurityLevel` and the compiler
5//! monomorphizes one specialized copy per level from a single source.
6//!
7//! All three levels ([`Level1`], [`Level3`], [`Level5`]) have full
8//! `SecurityLevel` implementations.
9
10use hybrid_array::ArraySize;
11
12pub mod level1;
13pub mod level3;
14pub mod level5;
15
16/// Marker trait for SQIsign security levels (NIST I, III, V).
17///
18/// Associated types encode array/buffer sizes via `hybrid-array` typenum.
19/// Associated constants encode scalar parameters used in arithmetic and
20/// loop bounds.
21///
22/// # Design rules
23///
24/// - Only INDEPENDENT, per-level parameters belong here.
25/// - Derived sizes are computed in downstream crate impl blocks.
26/// - Do not add trait bounds beyond `Default + Clone + Debug + 'static`.
27pub trait SecurityLevel: Default + Clone + core::fmt::Debug + 'static {
28    /// Number of 64-bit limbs in a prime-field element `Fp`.
29    ///
30    /// For Level 1 this is `U5`: 5 unsaturated radix-2^51 limbs
31    /// (51 * 5 = 255 bits of storage for a 251-bit prime).
32    type FpLimbs: ArraySize;
33
34    /// Number of 64-bit limbs for `mp`-layer scalar/order intermediates.
35    /// This is `NWORDS_ORDER`, not the field width.
36    type MpLimbs: ArraySize;
37
38    /// Byte length of a serialized canonical `Fp` element.
39    type FpEncodedBytes: ArraySize;
40
41    /// Byte length of a serialized canonical `Fp2` element (`2 *
42    /// FpEncodedBytes`).
43    type Fp2EncodedBytes: ArraySize;
44
45    /// Byte length of a serialized public key.
46    type PkLen: ArraySize;
47
48    /// Byte length of a serialized standard signature.
49    type SigLen: ArraySize;
50
51    /// Byte length of a serialized expanded signature.
52    type ExpandedSigLen: ArraySize;
53
54    /// Byte length of a serialized compressed signature.
55    type CompressedSigLen: ArraySize;
56
57    /// Byte length of a serialized secret key.
58    type SkLen: ArraySize;
59
60    /// The prime `p` as a static byte slice (little-endian canonical
61    /// encoding, length `FP_ENCODED_BYTES`).
62    fn prime_le_bytes() -> &'static [u8];
63
64    /// Security parameter `lambda` in bits (128, 192, or 256).
65    const LAMBDA: u32;
66
67    /// Exponent `f` of the 2-power torsion available on the starting
68    /// curve E0. The full 2ᶠ-torsion E0\[2ᶠ\] ≅ (ℤ/2ᶠ)² is
69    /// rational over `Fp2`. Equal to [`TORSION_EVEN_POWER`](Self::TORSION_EVEN_POWER).
70    const F_CHR: u32;
71
72    /// Bit-length of the response isogeny degree `2^E_RSP`. The
73    /// response isogeny in the sigma protocol has degree exactly
74    /// `2^E_RSP`. Must satisfy `E_RSP < F_CHR`.
75    const E_RSP: u32;
76
77    /// Bit-length of the challenge space. The verifier's challenge
78    /// scalar is drawn from `{0, ..., 2^E_CHL - 1}`. Equal to
79    /// `LAMBDA` for standard security.
80    const E_CHL: u32;
81
82    /// Maximum number of hash-to-challenge iterations before aborting.
83    /// Each iteration squeezes from SHAKE256 and checks whether the
84    /// result falls in the valid challenge range.
85    const HASH_ITERATIONS: u32;
86
87    /// Number of 64-bit limbs for order/scalar arrays. Determines the
88    /// width of multi-precision scalar arithmetic in the EC layer.
89    /// Level 1 = 4 (256 bits), Level 3 = 6 (384 bits), Level 5 = 8
90    /// (512 bits).
91    const NWORDS_ORDER: usize;
92
93    /// The 2-adic valuation of `p + 1`, i.e. the largest `f` such that
94    /// 2ᶠ | (p + 1). This is the exponent of the available even
95    /// torsion on the supersingular curve E0 over `Fp2`.
96    const TORSION_EVEN_POWER: u32;
97
98    /// Bit-length of the odd cofactor `(p + 1) / 2^TORSION_EVEN_POWER`.
99    /// For Level 1: `(p+1)/2^248 = 5`, which has bit-length 3.
100    const P_COFACTOR_FOR_2F_BITLENGTH: usize;
101
102    /// Length (in bits) of the response isogeny in the sigma protocol.
103    /// Equal to [`E_RSP`](Self::E_RSP).
104    const SQISIGN_RESPONSE_LENGTH: u32;
105}
106
107/// NIST Security Level I (128-bit post-quantum security).
108///
109/// Prime: `p = 5 * 2^248 - 1`, encoded in 32 bytes.
110#[derive(Default, Clone, Debug)]
111pub struct Level1;
112
113/// NIST Security Level III (192-bit post-quantum security).
114///
115/// Prime: `p = 65 * 2^376 - 1`, encoded in 48 bytes.
116#[derive(Default, Clone, Debug)]
117pub struct Level3;
118
119/// NIST Security Level V (256-bit post-quantum security).
120///
121/// Prime: `p = 27 * 2^500 - 1`, encoded in 64 bytes.
122#[derive(Default, Clone, Debug)]
123pub struct Level5;