Skip to main content

ferritls_core/
sign.rs

1//! 数字签名:ECDSA(P-256/P-384,RFC 6979 确定性 nonce)、Ed25519
2//! (RFC 8032)、RSA(PKCS#1 v1.5 / PSS,M4b 落地)。
3//!
4//! 批准状态:ECDSA P-256/384 与 RSA 为 FIPS 批准;**Ed25519 非批准**
5//! (FIPS 186-5 不含 EdDSA)。
6//!
7//! 签名 API:`sign` 接收**未哈希**消息,内部按算法完成哈希(与 rustls
8//! `Signer::sign` 约定一致)。
9//!
10//! 向量:RFC 6979 A.2.5(P-256 "sample")、RFC 8032 §7.1(Ed25519
11//! TEST 1/2),人工录入并与官方原文核对;RSA 向量在 M4b。
12//!
13//! 安全:
14//! - ECDSA nonce 一律 RFC 6979 确定性生成(FIPS 186-5 允许);标量乘
15//!   经 ecdh 模块统一盲化;
16//! - 验证路径一切失败归一化为同一错误,不泄露失败阶段;
17//! - 私钥材料 ZeroizeOnDrop。
18
19use crate::fields::{Fp256Scalar, Fp384Scalar, Fp25519};
20use crate::sha2::Sha512;
21
22/// 最小长度 BE 整数的 DER INTEGER 编码。
23fn der_integer(value_be: &[u8]) -> Vec<u8> {
24    let mut m = value_be;
25    while m.len() > 1 && m[0] == 0 {
26        m = &m[1..];
27    }
28    let mut content = Vec::with_capacity(m.len() + 1);
29    if m[0] & 0x80 != 0 {
30        content.push(0x00);
31    }
32    content.extend_from_slice(m);
33    let mut out = Vec::with_capacity(content.len() + 2);
34    out.push(0x02);
35    out.push(content.len() as u8);
36    out.extend_from_slice(&content);
37    out
38}
39
40/// 编码 ECDSA-Sig-Value ::= SEQUENCE { r INTEGER, s INTEGER }。
41pub fn encode_der_sig(r_be: &[u8], s_be: &[u8]) -> Vec<u8> {
42    let r = der_integer(r_be);
43    let s = der_integer(s_be);
44    let mut out = Vec::with_capacity(r.len() + s.len() + 5);
45    out.push(0x30);
46    out.push((r.len() + s.len()) as u8);
47    out.extend_from_slice(&r);
48    out.extend_from_slice(&s);
49    out
50}
51
52/// 生成一条曲线的 ECDSA 模块。
53macro_rules! ecdsa_curve {
54    ($modname:ident, $curve:ident, $sfield:ident, $coordlen:expr, $hash:ident, $hmac:ident, $doc:expr) => {
55        #[doc = $doc]
56        pub mod $modname {
57            use super::*;
58            use crate::ecdh::$curve as crv;
59            use crate::hmac::$hmac;
60            use crate::sha2::$hash;
61
62            type S = $sfield;
63
64            const SEED_LEN: usize = $coordlen;
65            const HLEN: usize = $hmac::OUTPUT_LEN;
66
67            /// 私钥(模 n 规范标量,`ZeroizeOnDrop`)。
68            #[derive(Clone)]
69            pub struct SigningKey {
70                d: [u64; S::LIMBS],
71            }
72
73            impl SigningKey {
74                /// 本算法在 FIPS 140-3 下的批准状态。
75                pub const APPROVAL: crate::Approval = crate::Approval::Approved;
76
77                /// 由种子确定性构造(int2octets(x),mod n 归约)。
78                pub fn from_seed(seed: [u8; SEED_LEN]) -> Self {
79                    let d = S::from_bytes_be_mod(&seed);
80                    Self { d: d.to_raw() }
81                }
82
83                /// 公钥(未压缩 SEC1:0x04 || X || Y)。
84                pub fn public_key_sec1(&self) -> [u8; 1 + 2 * SEED_LEN] {
85                    let (x, y) = crv::mul_base(&self.d);
86                    let mut out = [0u8; 1 + 2 * SEED_LEN];
87                    out[0] = 0x04;
88                    out[1..1 + SEED_LEN].copy_from_slice(&x.to_bytes_be());
89                    out[1 + SEED_LEN..].copy_from_slice(&y.to_bytes_be());
90                    out
91                }
92
93                /// 对消息签名:返回 DER 编码的 ECDSA-Sig-Value。
94                /// nonce 按 RFC 6979 确定性生成。
95                pub fn sign(&self, message: &[u8]) -> Result<Vec<u8>, crate::Error> {
96                    let digest = $hash::one_shot(message);
97                    let z = S::from_bytes_be_mod(&digest);
98                    let d_m = S::from_raw(self.d);
99                    let x_oct = S::from_raw(self.d).to_bytes_be();
100                    let z_oct = z.to_bytes_be();
101
102                    // RFC 6979 §3.2 步骤 b–g:V = 0x01^hlen,K = 0x00^hlen;
103                    // K = HMAC_K(V || {0x00,0x01} || int2octets(x) || bits2octets(h1)),
104                    // 每次 K 更新后先 V = HMAC_K(V)。两次输入仅分隔字节不同,复用 buf。
105                    let mut v = [0x01u8; HLEN];
106                    let mut k = [0u8; HLEN];
107                    let mut buf = [0u8; HLEN + 1 + 2 * SEED_LEN];
108                    buf[..HLEN].copy_from_slice(&v);
109                    buf[HLEN] = 0x00;
110                    buf[HLEN + 1..HLEN + 1 + SEED_LEN].copy_from_slice(&x_oct);
111                    buf[HLEN + 1 + SEED_LEN..].copy_from_slice(&z_oct);
112                    k = $hmac::one_shot(&k, &buf); // d
113                    v = $hmac::one_shot(&k, &v); // e
114                    buf[..HLEN].copy_from_slice(&v); // f 必须用更新后的 V
115                    buf[HLEN] = 0x01;
116                    k = $hmac::one_shot(&k, &buf); // f
117                    v = $hmac::one_shot(&k, &v); // g
118
119                    loop {
120                        // h:V = HMAC_K(V);候选 k = bits2int(V)——按 RFC 与 q
121                        // 比较拒绝(不取模);k = 0(V 全零)同样拒绝。
122                        v = $hmac::one_shot(&k, &v);
123                        let n_be = n_bytes_be();
124                        let mut ge_n = false;
125                        for i in 0..SEED_LEN {
126                            if v[i] < n_be[i] {
127                                break;
128                            }
129                            if v[i] > n_be[i] {
130                                ge_n = true;
131                                break;
132                            }
133                        }
134                        let mut nonzero = false;
135                        for &b in &v {
136                            if b != 0 {
137                                nonzero = true;
138                                break;
139                            }
140                        }
141                        let k_s = S::from_bytes_be_mod(&v); // v < n 时无损
142                        let (x, _) = crv::mul_base(&k_s.to_raw());
143                        let r_s = S::from_bytes_be_mod(&x.to_bytes_be());
144                        let s = k_s.invert().mul(&z.add(&r_s.mul(&d_m)));
145                        if nonzero && !ge_n && !r_s.is_zero() && !s.is_zero() {
146                            let r_be = r_s.to_bytes_be();
147                            let s_be = s.to_bytes_be();
148                            return Ok(encode_der_sig(&r_be, &s_be));
149                        }
150                        // h.5 重试:K = HMAC_K(V || 0x00);V = HMAC_K(V)
151                        let mut b2 = [0u8; HLEN + 1];
152                        b2[..HLEN].copy_from_slice(&v);
153                        b2[HLEN] = 0x00;
154                        k = $hmac::one_shot(&k, &b2);
155                        v = $hmac::one_shot(&k, &v);
156                    }
157                }
158            }
159
160            /// 模数 n 的规范 BE 字节(S::P 即 n 的普通形式 limbs;
161            /// 严禁经 from_raw/to_raw 转换——模数在 mod n 下映射为 0)。
162            fn n_bytes_be() -> [u8; SEED_LEN] {
163                let mut out = [0u8; SEED_LEN];
164                for j in 0..S::LIMBS {
165                    out[(S::LIMBS - 1 - j) * 8..(S::LIMBS - j) * 8]
166                        .copy_from_slice(&S::P[j].to_be_bytes());
167                }
168                out
169            }
170
171            /// 解析 DER 签名并返回 (r, s) 的定长 BE 形式。
172            fn parse_sig(
173                signature_der: &[u8],
174            ) -> Result<([u8; SEED_LEN], [u8; SEED_LEN]), crate::Error> {
175                let (rs_body, rest) = crate::der::sequence(signature_der)?;
176                if !rest.is_empty() {
177                    return Err(crate::Error::InvalidInput);
178                }
179                let (r_bytes, rest) = crate::der::integer(rs_body)?;
180                let (s_bytes, rest2) = crate::der::integer(rest)?;
181                if !rest2.is_empty() || r_bytes.len() > SEED_LEN || s_bytes.len() > SEED_LEN {
182                    return Err(crate::Error::VerificationFailed);
183                }
184                let mut rb = [0u8; SEED_LEN];
185                rb[SEED_LEN - r_bytes.len()..].copy_from_slice(r_bytes);
186                let mut sb = [0u8; SEED_LEN];
187                sb[SEED_LEN - s_bytes.len()..].copy_from_slice(s_bytes);
188                // r、s 必须严格小于 n:与 n 的规范 BE 字节逐字节比较
189                let n_bytes = n_bytes_be();
190                for i in 0..SEED_LEN {
191                    if rb[i] < n_bytes[i] {
192                        break;
193                    }
194                    if rb[i] > n_bytes[i] {
195                        return Err(crate::Error::VerificationFailed);
196                    }
197                }
198                for i in 0..SEED_LEN {
199                    if sb[i] < n_bytes[i] {
200                        break;
201                    }
202                    if sb[i] > n_bytes[i] {
203                        return Err(crate::Error::VerificationFailed);
204                    }
205                }
206                if rb == [0u8; SEED_LEN] || sb == [0u8; SEED_LEN] {
207                    return Err(crate::Error::VerificationFailed);
208                }
209                Ok((rb, sb))
210            }
211
212            /// ECDSA 验证公钥。
213            ///
214            /// 唯一构造路径 [`VerifyKey::from_sec1_point`]:输入必须是
215            /// **未压缩 SEC1 点**(`0x04 ‖ X ‖ Y`,RFC 5480),不含
216            /// SPKI/AlgorithmIdentifier 包装——X.509 剥离由调用方完成
217            /// (rustls 适配层直接透传 webpki 的 `key_value`)。
218            pub struct VerifyKey {
219                qx: crv::F,
220                qy: crv::F,
221            }
222
223            impl VerifyKey {
224                /// 解析未压缩 SEC1 点(含规范性与在曲线校验)。
225                pub fn from_sec1_point(bytes: &[u8]) -> Result<Self, crate::Error> {
226                    let (qx, qy) = crv::parse_public(bytes)?;
227                    Ok(Self { qx, qy })
228                }
229
230                /// 验证 DER 编码的 ECDSA 签名。
231                pub fn verify(
232                    &self,
233                    message: &[u8],
234                    signature_der: &[u8],
235                ) -> Result<(), crate::Error> {
236                    let (rb, sb) = parse_sig(signature_der)?;
237                    let digest = $hash::one_shot(message);
238                    let z = S::from_bytes_be_mod(&digest);
239                    let r_s = S::from_bytes_be_mod(&rb);
240                    let s_s = S::from_bytes_be_mod(&sb);
241
242                    let w = s_s.invert();
243                    let u1 = z.mul(&w);
244                    let u2 = r_s.mul(&w);
245
246                    let g = (crv::gx(), crv::gy());
247                    let p1 = crv::mul_point_pub(&u1.to_raw(), &g.0, &g.1);
248                    if p1.is_infinity() {
249                        return Err(crate::Error::VerificationFailed);
250                    }
251                    let p2 = crv::mul_point_pub(&u2.to_raw(), &self.qx, &self.qy);
252                    if p2.is_infinity() {
253                        return Err(crate::Error::VerificationFailed);
254                    }
255                    let (x, _) = crv::add_points_affine_pub(
256                        &crv::to_affine_pub(&p1),
257                        &crv::to_affine_pub(&p2),
258                    )?;
259                    let r_prime = S::from_bytes_be_mod(&x.to_bytes_be());
260                    if r_prime == r_s {
261                        Ok(())
262                    } else {
263                        Err(crate::Error::VerificationFailed)
264                    }
265                }
266            }
267        }
268    };
269}
270
271pub mod ecdsa {
272    // 宏展开在模块作用域内需要可见的项
273    use super::{Fp256Scalar, Fp384Scalar, encode_der_sig};
274
275    ecdsa_curve!(
276        p256,
277        p256,
278        Fp256Scalar,
279        32,
280        Sha256,
281        HmacSha256,
282        "P-256 ECDSA(SHA-256,RFC 6979 确定性 nonce)。"
283    );
284
285    ecdsa_curve!(
286        p384,
287        p384,
288        Fp384Scalar,
289        48,
290        Sha384,
291        HmacSha384,
292        "P-384 ECDSA(SHA-384,RFC 6979 确定性 nonce)。"
293    );
294}
295
296// ---------------------------------------------------------------------------
297// Ed25519(RFC 8032)——FIPS 非批准
298// ---------------------------------------------------------------------------
299
300/// Ed25519 命名空间。
301pub mod ed25519 {
302    use super::*;
303    use crate::fields::Fp25519ScalarL as ScL;
304
305    /// 私钥种子字节数。
306    pub const SEED_LEN: usize = 32;
307    /// 公钥字节数。
308    pub const PUBLIC_KEY_LEN: usize = 32;
309    /// 签名字节数。
310    pub const SIGNATURE_LEN: usize = 64;
311
312    /// 基点压缩编码(RFC 8032:y = 4/5,x 为偶)。
313    pub(crate) const G_COMPRESSED: [u8; 32] = [
314        0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
315        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
316        0x66, 0x66,
317    ];
318
319    /// 扭曲 Edwards 曲线参数 d(= −121665/121666),每次调用时计算。
320    pub(crate) fn curve_d() -> Fp25519 {
321        let um = Fp25519::from_raw([121665, 0, 0, 0]);
322        let vm = Fp25519::from_raw([121666, 0, 0, 0]);
323        um.neg().mul(&vm.invert())
324    }
325
326    /// 扩展坐标点 (X : Y : Z : T),恒等元 = (0, 1, 1, 0)。
327    #[derive(Clone, Copy)]
328    pub(crate) struct Point {
329        pub(crate) x: Fp25519,
330        pub(crate) y: Fp25519,
331        pub(crate) z: Fp25519,
332        pub(crate) t: Fp25519,
333    }
334
335    impl Point {
336        pub(crate) fn identity() -> Self {
337            Self {
338                x: Fp25519::zero(),
339                y: Fp25519::one(),
340                z: Fp25519::one(),
341                t: Fp25519::zero(),
342            }
343        }
344
345        /// 统一加法(add-2008-hwcd-3,a = −1)。
346        pub(crate) fn add(&self, other: &Self) -> Self {
347            let dd = curve_d().add(&curve_d());
348            let a = self.y.sub(&self.x).mul(&other.y.sub(&other.x));
349            let b = self.y.add(&self.x).mul(&other.y.add(&other.x));
350            let c = self.t.mul(&other.t).mul(&dd);
351            let d = self.z.add(&self.z).mul(&other.z);
352            let e = b.sub(&a);
353            let f = d.sub(&c);
354            let g = d.add(&c);
355            let h = b.add(&a);
356            Self {
357                x: e.mul(&f),
358                y: g.mul(&h),
359                z: f.mul(&g),
360                t: e.mul(&h),
361            }
362        }
363
364        fn double(&self) -> Self {
365            self.add(self)
366        }
367
368        /// 压缩编码。
369        pub(crate) fn compress(&self) -> [u8; 32] {
370            // 扩展坐标仿射转换:x = X/Z,y = Y/Z(不是 Jacobian 的 Z²/Z³)
371            let zinv = self.z.invert();
372            let x = self.x.mul(&zinv);
373            let y = self.y.mul(&zinv);
374            let mut out = y.to_bytes_le();
375            // 符号位 = 仿射 x(规范普通形式)的奇偶;必须先转出 Montgomery 形式
376            out[31] |= ((x.to_raw()[0] & 1) as u8) << 7;
377            out
378        }
379    }
380
381    /// 从 32 字节压缩编码恢复点(含在曲线校验)。
382    pub(crate) fn decompress(bytes: &[u8; 32]) -> Result<Point, crate::Error> {
383        let mut y_bytes = *bytes;
384        let sign = y_bytes[31] >> 7;
385        y_bytes[31] &= 127;
386        let y = {
387            let mut limbs = [0u64; 4];
388            for j in 0..4 {
389                let mut w = [0u8; 8];
390                w.copy_from_slice(&y_bytes[j * 8..j * 8 + 8]);
391                limbs[j] = u64::from_le_bytes(w);
392            }
393            // 非规范编码拒绝(RFC 8032 §5.1.3 步骤 2/3;与 dalek 严格
394            // 模式一致):y ∈ [p, 2^255) 不是合法编码,宽容归约会给同一
395            // 签名/公钥留下第二种编码(malleability 面)。
396            if Fp25519::geq_canonical(&limbs) {
397                return Err(crate::Error::VerificationFailed);
398            }
399            // 统一转换到 Montgomery 形式(后续运算均为 Montgomery 域)
400            Fp25519::from_raw(limbs)
401        };
402        // x² = (y² − 1) / (d·y² + 1),RFC 8032 §5.1.3 恢复配方
403        let d = curve_d();
404        let y2 = y.square();
405        let u = y2.sub(&Fp25519::one());
406        let v = d.mul(&y2).add(&Fp25519::one());
407        let v3 = v.square().mul(&v);
408        let v7 = v3.square().mul(&v);
409        let uv7 = u.mul(&v7);
410        let e = [
411            0xfffffffffffffffd,
412            0xffffffffffffffff,
413            0xffffffffffffffff,
414            0x0fffffffffffffff,
415        ]; // (q−5)/8
416        let pow_e = uv7.pow(&e);
417        let mut x = u.mul(&v3).mul(&pow_e);
418        let vx2 = v.mul(&x.square());
419        if vx2 == u {
420            // 有效
421        } else if vx2 == u.neg() {
422            // x *= 2^((q−1)/4)
423            let e2 = [
424                0xfffffffffffffffb,
425                0xffffffffffffffff,
426                0xffffffffffffffff,
427                0x1fffffffffffffff,
428            ]; // (q−1)/4 = 2^253 − 5
429            x = x.mul(&Fp25519::from_raw([2, 0, 0, 0]).pow(&e2));
430        } else {
431            return Err(crate::Error::VerificationFailed);
432        }
433        // 符号修正:比较仿射 x 的规范奇偶(to_raw 先出 Montgomery 形式)。
434        // RFC 8032 §5.1.3:奇偶必须与符号位一致——x=0 且 sign=1 无法通过
435        // 取负满足(-0 = 0,奇偶仍为 0),必须拒绝解码。
436        let neg = ((x.to_raw()[0] ^ u64::from(sign)) & 1).wrapping_neg();
437        x = Fp25519::select(neg, &x.neg(), &x);
438        if (x.to_raw()[0] ^ u64::from(sign)) & 1 == 1 {
439            return Err(crate::Error::VerificationFailed);
440        }
441        Ok(Point {
442            x,
443            y,
444            z: Fp25519::one(),
445            t: x.mul(&y),
446        })
447    }
448
449    /// 标量乘(倍加 + 统一加法,天然处理所有例外输入)。
450    pub(crate) fn scalar_mult(k_bytes: &[u8; 32], base: &Point) -> Point {
451        let mut acc = Point::identity();
452        for i in (0..256).rev() {
453            acc = acc.double();
454            let bit = ((k_bytes[i / 8] >> (i % 8)) & 1) as u64;
455            let bit_mask = bit.wrapping_neg();
456            let sum = acc.add(base);
457            acc = Point {
458                x: Fp25519::select(bit_mask, &sum.x, &acc.x),
459                y: Fp25519::select(bit_mask, &sum.y, &acc.y),
460                z: Fp25519::select(bit_mask, &sum.z, &acc.z),
461                t: Fp25519::select(bit_mask, &sum.t, &acc.t),
462            };
463        }
464        acc
465    }
466
467    pub(crate) fn base_point() -> Point {
468        decompress(&G_COMPRESSED).expect("standard base point")
469    }
470
471    /// 私钥种子(`ZeroizeOnDrop`)。
472    #[derive(Clone)]
473    pub struct SigningKey {
474        seed: [u8; 32],
475    }
476
477    impl SigningKey {
478        /// 本算法在 FIPS 140-3 下的批准状态。
479        pub const APPROVAL: crate::Approval = crate::Approval::NonApproved;
480
481        /// 生成新密钥(OS 熵直读;M5 起批准模式走边界内 CTR-DRBG)。
482        pub fn generate() -> Result<Self, crate::Error> {
483            let mut seed = [0u8; 32];
484            crate::entropy::fill(&mut seed)?;
485            Ok(Self { seed })
486        }
487
488        /// 由种子构造(测试/向量入口)。
489        pub fn from_seed(seed: [u8; 32]) -> Self {
490            Self { seed }
491        }
492
493        /// 公钥(32 字节压缩)。
494        pub fn public_key(&self) -> [u8; 32] {
495            let h = Sha512::one_shot(&self.seed);
496            let mut a = [0u8; 32];
497            a.copy_from_slice(&h[..32]);
498            a[0] &= 248;
499            a[31] &= 127;
500            a[31] |= 64;
501            scalar_mult(&a, &base_point()).compress()
502        }
503
504        /// 对消息签名(PureEdDSA,64 字节:R || S)。
505        pub fn sign(&self, message: &[u8]) -> [u8; 64] {
506            let h = Sha512::one_shot(&self.seed);
507            let mut a = [0u8; 32];
508            a.copy_from_slice(&h[..32]);
509            a[0] &= 248;
510            a[31] &= 127;
511            a[31] |= 64;
512            let a_s = ScL::from_bytes_le_mod(&a);
513            let prefix = &h[32..64];
514
515            // r = H(prefix || M) mod L
516            let mut rh = Sha512::new();
517            rh.update(prefix);
518            rh.update(message);
519            let r_digest = rh.finalize();
520            let r = ScL::from_bytes_le_mod(&r_digest);
521            let big_r = scalar_mult(&r.to_bytes_le(), &base_point()).compress();
522
523            // k = H(R || A || M) mod L
524            let mut kh = Sha512::new();
525            kh.update(&big_r);
526            kh.update(&self.public_key());
527            kh.update(message);
528            let k_digest = kh.finalize();
529            let k = ScL::from_bytes_le_mod(&k_digest);
530
531            // S = (r + k·a) mod L
532            let s = r.add(&k.mul(&a_s));
533            let s_le = s.to_bytes_le();
534
535            let mut sig = [0u8; 64];
536            sig[..32].copy_from_slice(&big_r);
537            sig[32..].copy_from_slice(&s_le);
538            sig
539        }
540    }
541
542    impl Drop for SigningKey {
543        fn drop(&mut self) {
544            self.seed.fill(0);
545        }
546    }
547
548    impl std::fmt::Debug for SigningKey {
549        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
550            f.write_str("ed25519::SigningKey")
551        }
552    }
553
554    /// Ed25519 验证公钥。
555    ///
556    /// 唯一构造路径 [`VerifyKey::from_raw_bytes`]:输入是 32 字节
557    /// 压缩编码(RFC 8032 §5.1.5,含规范性与在曲线校验)。
558    #[derive(Clone, Copy)]
559    pub struct VerifyKey {
560        bytes: [u8; 32],
561    }
562
563    impl std::fmt::Debug for VerifyKey {
564        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
565            f.write_str("ed25519::VerifyKey")
566        }
567    }
568
569    impl VerifyKey {
570        /// 解析 32 字节压缩公钥编码。
571        pub fn from_raw_bytes(public_key: &[u8]) -> Result<Self, crate::Error> {
572            if public_key.len() != PUBLIC_KEY_LEN {
573                return Err(crate::Error::InvalidInput);
574            }
575            let mut bytes = [0u8; PUBLIC_KEY_LEN];
576            bytes.copy_from_slice(public_key);
577            // 构造期校验规范性与在曲线(验证期 decompress 确定性地成功)
578            decompress(&bytes)?;
579            Ok(Self { bytes })
580        }
581
582        /// 验证 64 字节 Ed25519 签名。
583        pub fn verify(&self, message: &[u8], signature: &[u8]) -> Result<(), crate::Error> {
584            if signature.len() != SIGNATURE_LEN {
585                return Err(crate::Error::InvalidInput);
586            }
587            let a_bytes = self.bytes;
588            let a_pt = decompress(&a_bytes)?;
589
590            let mut r_bytes = [0u8; 32];
591            r_bytes.copy_from_slice(&signature[..32]);
592            let r_pt = decompress(&r_bytes)?;
593
594            // S 必须规范(0 ≤ S < L):LE 字节自最高位比较;全部相等(S == L)也拒绝
595            let l_bytes: [u8; 32] = [
596                0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9,
597                0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10,
598            ];
599            let mut s_lt_l = false;
600            for i in (0..32).rev() {
601                if signature[32 + i] < l_bytes[i] {
602                    s_lt_l = true;
603                    break;
604                }
605                if signature[32 + i] > l_bytes[i] {
606                    return Err(crate::Error::VerificationFailed);
607                }
608            }
609            if !s_lt_l {
610                return Err(crate::Error::VerificationFailed);
611            }
612            let mut s_bytes = [0u8; 32];
613            s_bytes.copy_from_slice(&signature[32..]);
614            let s_s = ScL::from_bytes_le_mod(&s_bytes);
615
616            let mut kh = Sha512::new();
617            kh.update(&signature[..32]);
618            kh.update(&a_bytes);
619            kh.update(message);
620            let k_digest = kh.finalize();
621            let k = ScL::from_bytes_le_mod(&k_digest);
622
623            // [S]G == R + [k]A
624            let lhs = scalar_mult(&s_s.to_bytes_le(), &base_point());
625            let ka = scalar_mult(&k.to_bytes_le(), &a_pt);
626            let rhs = r_pt.add(&ka);
627            if lhs.compress() == rhs.compress() {
628                Ok(())
629            } else {
630                Err(crate::Error::VerificationFailed)
631            }
632        }
633    }
634}
635
636// ---------------------------------------------------------------------------
637// RSA(M4b/M4c:固定宽度大数模幂 + CRT + 盲化 + PKCS#1 v1.5/PSS,RFC 8017)
638// ---------------------------------------------------------------------------
639
640/// RSA 签名/验证(RSASSA-PKCS1-v1_5 与 RSASSA-PSS,RFC 8017)。
641///
642/// 批准状态:FIPS 批准(FIPS 186-5 RSASSA;TLS 1.3 首选 PSS)。
643///
644/// 安全:
645/// - 私钥运算走 CRT(p/q 各自模幂,Garner 重组),指数位经掩码选择,
646///   对秘密指数常数时间(见 `rsabig` 模块);Garner 回绕修正为
647///   常数时间掩码选择;
648/// - 乘法盲化(Kocher,M4c):每次签名取单次使用随机 r ∈ [1, n)
649///   (OS 熵 + 拒绝采样),先算 EM′ = EM·rᵉ mod n 的 CRT 私钥运算,
650///   再乘 r⁻¹ 去盲——CRT 内全部中间值随 r 随机化,秘密与观测
651///   时序/访存解耦;r⁻¹ 经变量时间 binary xgcd 求得,输入为单次
652///   随机值与公开模数,时序不泄露可利用信息(Go/OpenSSL 同实践,
653///   见 `rsabig::mod_inverse_odd`);r 与盲化中间值退出前零化;
654/// - 验证 padding 检查严格,一切失败归一化为
655///   [`Error::VerificationFailed`](crate::Error::VerificationFailed);
656/// - 模长 < 2048 位拒绝([`crate::sign::rsa::MIN_MODULUS_LEN`]),
657///   > 4096 位拒绝(受 `rsabig::MAX_LIMBS` 限制);
658/// - 密钥装载做结构校验:p·q = n、q·qInv ≡ 1 (mod p)、dp < p、
659///   dq < q、qInv < p、n/p/q 为奇数、e ≥ 3 且为奇数;不做素性检测
660///   (密钥来源为本机信任输入,素性由密钥生成方保证)。
661pub mod rsa {
662    use crate::ct::zeroize::Zeroize;
663    use crate::rsabig;
664    use crate::sha2::{Sha256, Sha384, Sha512};
665
666    /// 盲化因子采样/求逆的最大尝试次数。每轮拒绝概率 ≤ 1/2
667    /// (n 顶位为 1),128 轮全部失败概率 ≤ 2⁻¹²⁸,视为熵源异常。
668    const BLIND_ATTEMPTS: usize = 128;
669
670    /// 最短允许的模长字节数(2048 位)。
671    pub const MIN_MODULUS_LEN: usize = 256;
672    /// 最长支持的模长字节数(4096 位)。
673    pub const MAX_MODULUS_LEN: usize = rsabig::MAX_LIMBS * 8;
674
675    /// RSA 私钥(CRT 参数;`Drop` 零化秘密分量)。
676    #[derive(Clone)]
677    pub struct SigningKey {
678        n_len: usize,
679        n_bytes: usize,
680        em_mask: u8,
681        // 公开参数(盲化的预乘 rᵉ 与去盲 r⁻¹ 在 mod n 下进行)
682        n: Vec<u64>,
683        e: Vec<u64>,
684        e_bits: usize,
685        n0_n: u64,
686        r2_n: Vec<u64>,
687        // 秘密参数(CRT)
688        p: Vec<u64>,
689        q: Vec<u64>,
690        dp: Vec<u64>,
691        dq: Vec<u64>,
692        qinv: Vec<u64>,
693        n0_p: u64,
694        r2_p: Vec<u64>,
695        n0_q: u64,
696        r2_q: Vec<u64>,
697        pl: usize,
698    }
699
700    impl SigningKey {
701        /// 本算法在 FIPS 140-3 下的批准状态。
702        pub const APPROVAL: crate::Approval = crate::Approval::Approved;
703
704        /// 从 PKCS#8 DER(内层 PKCS#1 RSAPrivateKey)解析。模长 < 2048 位
705        /// 返回 [`Error::Unsupported`](crate::Error::Unsupported)。
706        pub fn from_pkcs8_der(der: &[u8]) -> Result<Self, crate::Error> {
707            match crate::der::parse_pkcs8_private_key(der)? {
708                crate::der::ParsedPrivateKey::RsaPkcs1(pkcs1) => Self::from_pkcs1_der(&pkcs1),
709                _ => Err(crate::Error::InvalidInput),
710            }
711        }
712
713        /// 解析 PKCS#1 RSAPrivateKey DER 并做结构一致性校验
714        ///(rustls KeyProvider 的 PKCS#1 入口)。
715        pub fn from_pkcs1_der(der: &[u8]) -> Result<Self, crate::Error> {
716            let (seq, rest) = crate::der::sequence(der)?;
717            if !rest.is_empty() {
718                return Err(crate::Error::InvalidInput);
719            }
720            let (version, rest) = crate::der::integer(seq)?;
721            if version.len() != 1 || version[0] != 0 {
722                return Err(crate::Error::InvalidInput);
723            }
724            // RSAPrivateKey ::= SEQUENCE { version, n, e, d, p, q,
725            //   d mod p-1, d mod q-1, qInv, otherPrimeInfos [0] OPTIONAL }
726            let (n_b, rest) = crate::der::integer(rest)?;
727            let (e_b, rest) = crate::der::integer(rest)?;
728            let (_d_b, rest) = crate::der::integer(rest)?; // CRT 路径不使用 d
729            let (p_b, rest) = crate::der::integer(rest)?;
730            let (q_b, rest) = crate::der::integer(rest)?;
731            let (dp_b, rest) = crate::der::integer(rest)?;
732            let (dq_b, rest) = crate::der::integer(rest)?;
733            let (qinv_b, rest) = crate::der::integer(rest)?;
734            // 多素数扩展不支持
735            if !rest.is_empty() {
736                return Err(crate::Error::InvalidInput);
737            }
738
739            // 模长范围
740            let n_bytes = n_b.len();
741            if n_bytes < MIN_MODULUS_LEN {
742                return Err(crate::Error::Unsupported);
743            }
744            if n_bytes > MAX_MODULUS_LEN {
745                return Err(crate::Error::InvalidInput);
746            }
747            let n_len = n_bytes.div_ceil(8);
748            let pl = n_len.div_ceil(2);
749            // EM 左端必须清零的位数 = 8·emLen − emBits(emBits = modBits − 1)
750            let n_bitlen = 8 * n_bytes - n_b[0].leading_zeros() as usize;
751            let em_left_bits = 8 * n_bytes + 1 - n_bitlen;
752            let em_mask: u8 = (0xffu32 >> em_left_bits) as u8;
753
754            let mut n = vec![0u64; n_len];
755            rsabig::os2ip_be(n_b, &mut n);
756            if n[0] & 1 == 0 {
757                return Err(crate::Error::InvalidInput); // n 必须为奇
758            }
759
760            // e:≤ 8 字节、奇数且 ≥ 3
761            if e_b.is_empty() || e_b.len() > 8 {
762                return Err(crate::Error::InvalidInput);
763            }
764            let mut e = vec![0u64; 1];
765            rsabig::os2ip_be(e_b, &mut e);
766            if e[0] < 3 || e[0] & 1 == 0 {
767                return Err(crate::Error::InvalidInput);
768            }
769
770            // p、q:≤ pl limbs、奇数
771            if p_b.len() > pl * 8 || q_b.len() > pl * 8 {
772                return Err(crate::Error::InvalidInput);
773            }
774            let mut p = vec![0u64; pl];
775            let mut q = vec![0u64; pl];
776            rsabig::os2ip_be(p_b, &mut p);
777            rsabig::os2ip_be(q_b, &mut q);
778            if p[0] & 1 == 0
779                || q[0] & 1 == 0
780                || p.iter().all(|&x| x == 0)
781                || q.iter().all(|&x| x == 0)
782            {
783                return Err(crate::Error::InvalidInput);
784            }
785
786            // dp < p、dq < q、qInv < p
787            if dp_b.len() > pl * 8 || dq_b.len() > pl * 8 || qinv_b.len() > pl * 8 {
788                return Err(crate::Error::InvalidInput);
789            }
790            let mut dp = vec![0u64; pl];
791            let mut dq = vec![0u64; pl];
792            let mut qinv = vec![0u64; pl];
793            rsabig::os2ip_be(dp_b, &mut dp);
794            rsabig::os2ip_be(dq_b, &mut dq);
795            rsabig::os2ip_be(qinv_b, &mut qinv);
796            if rsabig::geq(&dp, &p) || rsabig::geq(&dq, &q) || rsabig::geq(&qinv, &p) {
797                return Err(crate::Error::InvalidInput);
798            }
799
800            // p·q = n
801            let pq = rsabig::mul_full(&p, &q);
802            if pq[..n_len] != n[..] || pq[n_len..].iter().any(|&x| x != 0) {
803                return Err(crate::Error::InvalidInput);
804            }
805
806            // Montgomery 常数(CRT 侧 + 盲化用的 n 侧)
807            let n0_p = rsabig::n0_inv(p[0]);
808            let n0_q = rsabig::n0_inv(q[0]);
809            let r2_p = rsabig::compute_r2(&p);
810            let r2_q = rsabig::compute_r2(&q);
811            let n0_n = rsabig::n0_inv(n[0]);
812            let r2_n = rsabig::compute_r2(&n);
813            let e_bits = 64 - e[0].leading_zeros() as usize;
814
815            // q·qInv ≡ 1 (mod p)
816            let mut mq = vec![0u64; pl];
817            let mut mqinv = vec![0u64; pl];
818            rsabig::to_mont(&q, &r2_p, &p, n0_p, &mut mq);
819            rsabig::to_mont(&qinv, &r2_p, &p, n0_p, &mut mqinv);
820            let mut chk = vec![0u64; pl];
821            rsabig::mont_mul(&mq, &mqinv, &p, n0_p, &mut chk);
822            rsabig::from_mont(&mut chk, &p, n0_p);
823            if chk[0] != 1 || chk[1..].iter().any(|&x| x != 0) {
824                return Err(crate::Error::InvalidInput);
825            }
826
827            Ok(Self {
828                n_len,
829                n_bytes,
830                em_mask,
831                n,
832                e,
833                e_bits,
834                n0_n,
835                r2_n,
836                p,
837                q,
838                dp,
839                dq,
840                qinv,
841                n0_p,
842                r2_p,
843                n0_q,
844                r2_q,
845                pl,
846            })
847        }
848
849        /// 均匀采样 r ∈ [1, n):OS 熵 + 拒绝采样(n 顶位为 1,每轮
850        /// 拒绝概率 ≤ 1/2)。任何失败路径上 `out` 与采样缓冲均已零化。
851        fn sample_blinding_factor(&self, out: &mut [u64]) -> Result<(), crate::Error> {
852            debug_assert_eq!(out.len(), self.n_len);
853            let mut buf = vec![0u8; self.n_bytes];
854            for _ in 0..BLIND_ATTEMPTS {
855                if let Err(e) = crate::entropy::fill(&mut buf) {
856                    buf.zeroize();
857                    out.zeroize();
858                    return Err(e);
859                }
860                rsabig::os2ip_be(&buf, out);
861                let zero = out.iter().all(|&w| w == 0);
862                if !zero && !rsabig::geq(out, &self.n) {
863                    buf.zeroize();
864                    return Ok(());
865                }
866            }
867            buf.zeroize();
868            out.zeroize();
869            Err(crate::Error::EntropyFailed)
870        }
871
872        /// CRT 私钥运算:m^d mod n(m 为普通形式 limbs 且 m < n,
873        /// 返回 n_len limbs)。本函数的输入应为**盲化后**的值——
874        /// 内部中间值(mp/mq/sp/sq/h 等)随盲化因子随机化;
875        /// 秘密中间缓冲退出前零化。
876        fn crt(&self, m: &[u64]) -> Vec<u64> {
877            let l = self.pl;
878            let nl = self.n_len;
879
880            let mut mp = vec![0u64; l];
881            rsabig::reduce_limbs(m, &self.p, &mut mp);
882            let mut mq = vec![0u64; l];
883            rsabig::reduce_limbs(m, &self.q, &mut mq);
884
885            // sp = m^dp mod p、sq = m^dq mod q(Montgomery 域内完成)
886            let mut sp = vec![0u64; l];
887            let mut sq = vec![0u64; l];
888            {
889                let mut base = vec![0u64; l];
890                let mut res = vec![0u64; l];
891                rsabig::to_mont(&mp, &self.r2_p, &self.p, self.n0_p, &mut base);
892                rsabig::mont_exp(
893                    &base,
894                    &self.dp,
895                    64 * l,
896                    &self.p,
897                    self.n0_p,
898                    &self.r2_p,
899                    &mut res,
900                );
901                rsabig::from_mont(&mut res, &self.p, self.n0_p);
902                sp.copy_from_slice(&res);
903                rsabig::to_mont(&mq, &self.r2_q, &self.q, self.n0_q, &mut base);
904                rsabig::mont_exp(
905                    &base,
906                    &self.dq,
907                    64 * l,
908                    &self.q,
909                    self.n0_q,
910                    &self.r2_q,
911                    &mut res,
912                );
913                rsabig::from_mont(&mut res, &self.q, self.n0_q);
914                sq.copy_from_slice(&res);
915                base.zeroize();
916                res.zeroize();
917            }
918
919            // Garner(qInv = q⁻¹ mod p):h = (sp − sq)·qInv mod p;
920            // s′ = sq + q·h ≤ (q−1) + q(p−1) = n − 1 < n。
921            // 回绕修正无条件计算 diff + p,按借位掩码选取(常数时间;
922            // 借位为 1 时加法跨过 2^(64l) 恰一次,进位按同余定义丢弃,
923            // 结果落在 [0, p))。
924            let mut diff = vec![0u64; l];
925            let borrow = rsabig::sub_limbs(&sp, &sq, &mut diff);
926            let mut sum = vec![0u64; l];
927            {
928                let mut carry = 0u64;
929                for ((dv, pv), sv) in diff.iter().zip(self.p.iter()).zip(sum.iter_mut()) {
930                    let (v, c1) = dv.overflowing_add(*pv);
931                    let (v, c2) = v.overflowing_add(carry);
932                    *sv = v;
933                    carry = (c1 as u64) | (c2 as u64);
934                }
935            }
936            let mut fixed = vec![0u64; l];
937            rsabig::select(borrow.wrapping_neg(), &sum, &diff, &mut fixed);
938            sum.zeroize();
939            diff.copy_from_slice(&fixed); // 修正后的 (sp − sq) mod p
940            fixed.zeroize();
941            // h = diff·qInv mod p:diff 先入 Montgomery 域,与 raw qInv 相乘
942            // 的结果即为 raw(mont(diff)·qInv·R⁻¹ = diff·qInv)
943            let mut hm = vec![0u64; l];
944            rsabig::to_mont(&diff, &self.r2_p, &self.p, self.n0_p, &mut hm);
945            let mut h = vec![0u64; l];
946            rsabig::mont_mul(&hm, &self.qinv, &self.p, self.n0_p, &mut h);
947
948            let mut qh = rsabig::mul_full(&self.q, &h); // 2l limbs
949            qh.truncate(nl);
950            let mut sqx = vec![0u64; nl];
951            sqx[..l].copy_from_slice(&sq);
952            let mut sres = vec![0u64; nl];
953            rsabig::add_limbs(&sqx, &qh, &mut sres); // < n,无进位
954
955            for v in [
956                &mut mp, &mut mq, &mut sp, &mut sq, &mut diff, &mut hm, &mut h, &mut qh, &mut sqx,
957            ] {
958                v.zeroize();
959            }
960            sres
961        }
962
963        /// 对消息代表元 EM 私钥运算(乘法盲化 + CRT + Garner 重组),
964        /// 返回定长签名。
965        ///
966        /// 盲化(M4c):单次随机 r ∈ [1, n),s = (EM·rᵉ)^d·r⁻¹ mod n
967        /// ——盲化在数学上精确抵消,签名结果与无盲化实现逐字节一致
968        /// (PKCS#1 v1.5 的 openssl 逐字节锚定与 selftest KAT 即为
969        /// 盲化正确性的回归门)。
970        fn sign_em(&self, em: &[u8]) -> Result<Vec<u8>, crate::Error> {
971            debug_assert_eq!(em.len(), self.n_bytes);
972            let nl = self.n_len;
973
974            let mut m = vec![0u64; nl];
975            rsabig::os2ip_be(em, &mut m);
976
977            let mut r = vec![0u64; nl];
978            let mut rinv = vec![0u64; nl];
979            let mut re = vec![0u64; nl]; // rᵉ(Montgomery 域)
980            let mut t = vec![0u64; nl];
981            let mut t2 = vec![0u64; nl];
982            let mut sig = vec![0u64; nl];
983            let mut ok = false;
984            let mut err = None;
985            'blind: for _ in 0..BLIND_ATTEMPTS {
986                if let Err(e) = self.sample_blinding_factor(&mut r) {
987                    err = Some(e);
988                    break 'blind;
989                }
990                // gcd(r, n) ≠ 1:合法密钥(n = p·q,p/q 为大素数)下
991                // 概率 ~2⁻¹⁰²³;换 r 重试
992                match rsabig::mod_inverse_odd(&r, &self.n) {
993                    Some(inv) => rinv.copy_from_slice(&inv),
994                    None => continue,
995                }
996                // re = rᵉ mod n(e 为公开指数,mont_exp 对其常数时间)
997                rsabig::to_mont(&r, &self.r2_n, &self.n, self.n0_n, &mut t);
998                rsabig::mont_exp(
999                    &t,
1000                    &self.e,
1001                    self.e_bits,
1002                    &self.n,
1003                    self.n0_n,
1004                    &self.r2_n,
1005                    &mut re,
1006                );
1007                // m′ = m·rᵉ mod n
1008                rsabig::to_mont(&m, &self.r2_n, &self.n, self.n0_n, &mut t);
1009                rsabig::mont_mul(&t, &re, &self.n, self.n0_n, &mut t2);
1010                rsabig::from_mont(&mut t2, &self.n, self.n0_n);
1011                // s′ = CRT(m′);s = s′·r⁻¹ mod n(去盲)
1012                let mut s_blind = self.crt(&t2);
1013                rsabig::to_mont(&s_blind, &self.r2_n, &self.n, self.n0_n, &mut t);
1014                rsabig::to_mont(&rinv, &self.r2_n, &self.n, self.n0_n, &mut t2);
1015                rsabig::mont_mul(&t, &t2, &self.n, self.n0_n, &mut sig);
1016                rsabig::from_mont(&mut sig, &self.n, self.n0_n);
1017                s_blind.zeroize();
1018                ok = true;
1019                break 'blind;
1020            }
1021            // 零化盲化因子与中间值(成功/失败路径统一覆盖)
1022            for v in [&mut m, &mut r, &mut rinv, &mut re, &mut t, &mut t2] {
1023                v.zeroize();
1024            }
1025            if let Some(e) = err {
1026                return Err(e);
1027            }
1028            if !ok {
1029                // 全部尝试的 r 均与 n 不互素:模数不是半素数(结构异常)
1030                return Err(crate::Error::Unsupported);
1031            }
1032            let mut out = vec![0u8; self.n_bytes];
1033            rsabig::i2osp_be(&sig, &mut out);
1034            sig.zeroize();
1035            Ok(out)
1036        }
1037
1038        /// RSA-PSS 签名(salt 长度 = 哈希长度;TLS 1.3 使用)。
1039        pub fn sign_pss(&self, hash_bits: u16, message: &[u8]) -> Result<Vec<u8>, crate::Error> {
1040            let mhash = hash_msg(hash_bits, message)?;
1041            let hlen = mhash.len();
1042            let emlen = self.n_bytes;
1043            // emLen ≥ hLen + sLen + 2(sLen = hLen)
1044            if emlen < 2 * hlen + 2 {
1045                return Err(crate::Error::InvalidInput);
1046            }
1047            let mut salt = vec![0u8; hlen];
1048            crate::entropy::fill(&mut salt)?;
1049            // M' = 0x00 × 8 || mHash || salt
1050            let mut mprime = vec![0u8; 8 + 2 * hlen];
1051            mprime[8..8 + hlen].copy_from_slice(&mhash);
1052            mprime[8 + hlen..].copy_from_slice(&salt);
1053            let h = hash_msg(hash_bits, &mprime)?;
1054            // DB = PS(0x00 × (emLen − hLen − sLen − 2)) || 0x01 || salt
1055            let dblen = emlen - hlen - 1;
1056            let mut db = vec![0u8; dblen];
1057            db[dblen - hlen - 1] = 0x01;
1058            db[dblen - hlen..].copy_from_slice(&salt);
1059            let mut dbmask = vec![0u8; dblen];
1060            mgf1(hash_bits, &h, &mut dbmask)?;
1061            for i in 0..dblen {
1062                db[i] ^= dbmask[i];
1063            }
1064            db[0] &= self.em_mask;
1065            let mut em = Vec::with_capacity(emlen);
1066            em.extend_from_slice(&db);
1067            em.extend_from_slice(&h);
1068            em.push(0xbc);
1069            self.sign_em(&em)
1070        }
1071
1072        /// RSA PKCS#1 v1.5 签名(TLS 1.2 遗留套件与证书链验证使用)。
1073        pub fn sign_pkcs1v15(
1074            &self,
1075            hash_bits: u16,
1076            message: &[u8],
1077        ) -> Result<Vec<u8>, crate::Error> {
1078            let mhash = hash_msg(hash_bits, message)?;
1079            let prefix = digestinfo_prefix(hash_bits)?;
1080            let tlen = prefix.len() + mhash.len();
1081            let emlen = self.n_bytes;
1082            if emlen < tlen + 11 {
1083                return Err(crate::Error::InvalidInput);
1084            }
1085            let mut em = vec![0u8; emlen];
1086            em[0] = 0x00;
1087            em[1] = 0x01;
1088            for b in em[2..emlen - tlen - 1].iter_mut() {
1089                *b = 0xff;
1090            }
1091            em[emlen - tlen - 1] = 0x00;
1092            em[emlen - tlen..emlen - mhash.len()].copy_from_slice(prefix);
1093            em[emlen - mhash.len()..].copy_from_slice(&mhash);
1094            self.sign_em(&em)
1095        }
1096    }
1097
1098    impl Drop for SigningKey {
1099        fn drop(&mut self) {
1100            // n/e 及其 Montgomery 常数(n0_n/r2_n)是公开钥分量,不零化;
1101            // r2_p/r2_q/n0_p/n0_q 派生自秘密素数,随秘密一并零化。
1102            for v in [
1103                &mut self.p,
1104                &mut self.q,
1105                &mut self.dp,
1106                &mut self.dq,
1107                &mut self.qinv,
1108                &mut self.r2_p,
1109                &mut self.r2_q,
1110            ] {
1111                for w in v.iter_mut() {
1112                    *w = 0;
1113                }
1114            }
1115            self.n0_p = 0;
1116            self.n0_q = 0;
1117        }
1118    }
1119
1120    impl std::fmt::Debug for SigningKey {
1121        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1122            f.write_str("rsa::SigningKey")
1123        }
1124    }
1125
1126    /// RSA 验证公钥(RSASSA-PKCS1-v1_5 / RSASSA-PSS,RFC 8017)。
1127    ///
1128    /// 两条显式命名的构造路径,名字即契约:
1129    /// - [`VerifyKey::from_rsapublickey_der`]:**裸 `RSAPublicKey` DER**
1130    ///   (`SEQUENCE { INTEGER n, INTEGER e }`)——X.509 之下的密钥本体;
1131    /// - [`VerifyKey::from_spki_der`]:完整 SPKI(`SEQUENCE { AlgId,
1132    ///   BIT STRING }`)——X.509 公钥包装,便利入口。
1133    ///
1134    /// X.509 剥离由调用方选择;rustls 适配层直接透传 webpki 的
1135    /// `key_value`(裸格式),见 `ferritls-rustls::verify`。
1136    #[derive(Clone)]
1137    pub struct VerifyKey {
1138        n: Vec<u64>,
1139        e: Vec<u64>,
1140        n0_n: u64,
1141        r2_n: Vec<u64>,
1142        n_len: usize,
1143        n_bytes: usize,
1144        e_len: usize,
1145        em_mask: u8,
1146    }
1147
1148    impl std::fmt::Debug for VerifyKey {
1149        fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1150            f.write_str("rsa::VerifyKey")
1151        }
1152    }
1153
1154    impl VerifyKey {
1155        /// 解析裸 `RSAPublicKey` DER(`SEQUENCE { INTEGER n, INTEGER e }`,
1156        /// RFC 8017)。结构校验:外层 SEQUENCE 无尾字节、模长 2048–4096
1157        /// 位、n 奇、e ≥ 3 且为奇。
1158        pub fn from_rsapublickey_der(der: &[u8]) -> Result<Self, crate::Error> {
1159            let (keyseq, krest) = crate::der::sequence(der)?;
1160            if !krest.is_empty() {
1161                return Err(crate::Error::InvalidInput);
1162            }
1163            let (n_b, r) = crate::der::integer(keyseq)?;
1164            let (e_b, erest) = crate::der::integer(r)?;
1165            if !erest.is_empty() {
1166                return Err(crate::Error::InvalidInput);
1167            }
1168            if n_b.len() < MIN_MODULUS_LEN || n_b.len() > MAX_MODULUS_LEN {
1169                return Err(crate::Error::Unsupported);
1170            }
1171            if e_b.is_empty() || e_b.len() > 8 {
1172                return Err(crate::Error::InvalidInput);
1173            }
1174            let n_len = n_b.len().div_ceil(8);
1175            let n_bitlen = 8 * n_b.len() - n_b[0].leading_zeros() as usize;
1176            let em_left_bits = 8 * n_b.len() + 1 - n_bitlen;
1177            let mut n = vec![0u64; n_len];
1178            rsabig::os2ip_be(n_b, &mut n);
1179            if n[0] & 1 == 0 {
1180                return Err(crate::Error::InvalidInput);
1181            }
1182            let mut e = vec![0u64; 1];
1183            rsabig::os2ip_be(e_b, &mut e);
1184            if e[0] < 3 || e[0] & 1 == 0 {
1185                return Err(crate::Error::InvalidInput);
1186            }
1187            let n0_n = rsabig::n0_inv(n[0]);
1188            let r2_n = rsabig::compute_r2(&n);
1189            Ok(Self {
1190                n,
1191                e,
1192                n0_n,
1193                r2_n,
1194                n_len,
1195                n_bytes: n_b.len(),
1196                e_len: 1,
1197                em_mask: (0xffu32 >> em_left_bits) as u8,
1198            })
1199        }
1200
1201        /// 解析完整 SPKI(SubjectPublicKeyInfo,`SEQUENCE { AlgId,
1202        /// BIT STRING }`):校验 AlgorithmIdentifier 为 rsaEncryption,
1203        /// 再按裸 `RSAPublicKey` 解析 BIT STRING 内容。便利入口——
1204        /// 已持有 X.509 公钥包装的调用方(如自检 KAT 向量)可直用。
1205        pub fn from_spki_der(spki: &[u8]) -> Result<Self, crate::Error> {
1206            let (seq, rest) = crate::der::sequence(spki)?;
1207            if !rest.is_empty() {
1208                return Err(crate::Error::InvalidInput);
1209            }
1210            let (alg, rest) = crate::der::sequence(seq)?;
1211            let (oid, _params) = crate::der::object_identifier(alg)?;
1212            if oid != crate::der::oid::RSA_ENCRYPTION {
1213                return Err(crate::Error::InvalidInput);
1214            }
1215            let (keybits, rest) = crate::der::bit_string(rest)?;
1216            if !rest.is_empty() {
1217                return Err(crate::Error::InvalidInput);
1218            }
1219            Self::from_rsapublickey_der(keybits)
1220        }
1221
1222        /// s^e mod n,返回 I2OSP 定长编码(含签名长度与 s < n 校验)。
1223        fn public_exponentiate(&self, signature: &[u8]) -> Result<Vec<u8>, crate::Error> {
1224            if signature.len() != self.n_bytes {
1225                return Err(crate::Error::InvalidInput);
1226            }
1227            let mut s = vec![0u64; self.n_len];
1228            rsabig::os2ip_be(signature, &mut s);
1229            if rsabig::geq(&s, &self.n) {
1230                return Err(crate::Error::VerificationFailed);
1231            }
1232            let mut base = vec![0u64; self.n_len];
1233            rsabig::to_mont(&s, &self.r2_n, &self.n, self.n0_n, &mut base);
1234            let mut m = vec![0u64; self.n_len];
1235            rsabig::mont_exp(
1236                &base,
1237                &self.e,
1238                64 * self.e_len,
1239                &self.n,
1240                self.n0_n,
1241                &self.r2_n,
1242                &mut m,
1243            );
1244            rsabig::from_mont(&mut m, &self.n, self.n0_n);
1245            let mut out = vec![0u8; self.n_bytes];
1246            rsabig::i2osp_be(&m, &mut out);
1247            Ok(out)
1248        }
1249    }
1250
1251    fn hash_msg(hash_bits: u16, message: &[u8]) -> Result<Vec<u8>, crate::Error> {
1252        match hash_bits {
1253            256 => Ok(Sha256::one_shot(message).to_vec()),
1254            384 => Ok(Sha384::one_shot(message).to_vec()),
1255            512 => Ok(Sha512::one_shot(message).to_vec()),
1256            _ => Err(crate::Error::Unsupported),
1257        }
1258    }
1259
1260    /// DigestInfo 前缀(RFC 8017 §9.2 注 1)。
1261    fn digestinfo_prefix(hash_bits: u16) -> Result<&'static [u8], crate::Error> {
1262        match hash_bits {
1263            256 => Ok(&[
1264                0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
1265                0x01, 0x05, 0x00, 0x04, 0x20,
1266            ]),
1267            384 => Ok(&[
1268                0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
1269                0x02, 0x05, 0x00, 0x04, 0x30,
1270            ]),
1271            512 => Ok(&[
1272                0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
1273                0x03, 0x05, 0x00, 0x04, 0x40,
1274            ]),
1275            _ => Err(crate::Error::Unsupported),
1276        }
1277    }
1278
1279    /// MGF1(RFC 8017 附录 B.2.1)。
1280    fn mgf1(hash_bits: u16, seed: &[u8], mask: &mut [u8]) -> Result<(), crate::Error> {
1281        let mut counter = 0u32;
1282        let mut filled = 0usize;
1283        while filled < mask.len() {
1284            let mut input = Vec::with_capacity(seed.len() + 4);
1285            input.extend_from_slice(seed);
1286            input.extend_from_slice(&counter.to_be_bytes());
1287            let h = hash_msg(hash_bits, &input)?;
1288            let take = core::cmp::min(h.len(), mask.len() - filled);
1289            mask[filled..filled + take].copy_from_slice(&h[..take]);
1290            filled += take;
1291            counter += 1;
1292        }
1293        Ok(())
1294    }
1295
1296    impl VerifyKey {
1297        /// 验证 RSA-PSS 签名(RFC 8017 §9.1,salt 长度 = 哈希长度)。
1298        /// 重复验证同一把公钥时应复用 `VerifyKey`,模幂前的解析开销均摊。
1299        pub fn verify_pss(
1300            &self,
1301            hash_bits: u16,
1302            message: &[u8],
1303            signature: &[u8],
1304        ) -> Result<(), crate::Error> {
1305            let em = self.public_exponentiate(signature)?;
1306            let mhash = hash_msg(hash_bits, message)?;
1307            let hlen = mhash.len();
1308            let emlen = em.len();
1309            // 一切 padding 失败归一化为同一错误(不泄露失败阶段)
1310            if emlen < 2 * hlen + 2 || em[emlen - 1] != 0xbc {
1311                return Err(crate::Error::VerificationFailed);
1312            }
1313            if em[0] & !self.em_mask != 0 {
1314                return Err(crate::Error::VerificationFailed);
1315            }
1316            let h = &em[emlen - hlen - 1..emlen - 1];
1317            let dblen = emlen - hlen - 1;
1318            let mut db = em[..dblen].to_vec();
1319            let mut dbmask = vec![0u8; dblen];
1320            mgf1(hash_bits, h, &mut dbmask)?;
1321            for i in 0..dblen {
1322                db[i] ^= dbmask[i];
1323            }
1324            db[0] &= self.em_mask;
1325            let ps_len = dblen - hlen - 1;
1326            if db[..ps_len].iter().any(|&b| b != 0) || db[ps_len] != 0x01 {
1327                return Err(crate::Error::VerificationFailed);
1328            }
1329            let salt = &db[ps_len + 1..];
1330            let mut mprime = vec![0u8; 8 + 2 * hlen];
1331            mprime[8..8 + hlen].copy_from_slice(&mhash);
1332            mprime[8 + hlen..].copy_from_slice(salt);
1333            let h2 = hash_msg(hash_bits, &mprime)?;
1334            if h2[..] != *h {
1335                return Err(crate::Error::VerificationFailed);
1336            }
1337            Ok(())
1338        }
1339
1340        /// 验证 RSA PKCS#1 v1.5 签名(严格 padding 检查,防 Bleichenbacher)。
1341        pub fn verify_pkcs1v15(
1342            &self,
1343            hash_bits: u16,
1344            message: &[u8],
1345            signature: &[u8],
1346        ) -> Result<(), crate::Error> {
1347            let em = self.public_exponentiate(signature)?;
1348            let mhash = hash_msg(hash_bits, message)?;
1349            let prefix = digestinfo_prefix(hash_bits)?;
1350            let tlen = prefix.len() + mhash.len();
1351            let emlen = em.len();
1352            if emlen < tlen + 11 {
1353                return Err(crate::Error::VerificationFailed);
1354            }
1355            // 逐字节重构期望 EM 并全等比较(拒绝非规范 0xFF 串等一切变体)
1356            let mut expected = vec![0u8; emlen];
1357            expected[0] = 0x00;
1358            expected[1] = 0x01;
1359            for b in expected[2..emlen - tlen - 1].iter_mut() {
1360                *b = 0xff;
1361            }
1362            expected[emlen - tlen - 1] = 0x00;
1363            expected[emlen - tlen..emlen - mhash.len()].copy_from_slice(prefix);
1364            expected[emlen - mhash.len()..].copy_from_slice(&mhash);
1365            if em != expected {
1366                return Err(crate::Error::VerificationFailed);
1367            }
1368            Ok(())
1369        }
1370    }
1371}
1372
1373#[cfg(test)]
1374mod tests {
1375    use super::*;
1376
1377    /// 非规范压缩编码必须拒绝(RFC 8032 §5.1.3):y ∈ [p, 2^255) 的
1378    /// 32 字节编码不是合法点编码。此前实现会对 y 条件减 p 后静默接受,
1379    /// 给同一验证结果留下第二种签名/公钥编码(malleability 面)。
1380    #[test]
1381    fn ed25519_decompress_rejects_noncanonical_y() {
1382        // y' = p(2^255 − 19):LE 字节 = ed ff…ff 7f
1383        let mut b = [0xffu8; 32];
1384        b[0] = 0xed;
1385        b[31] = 0x7f;
1386        assert!(
1387            matches!(
1388                ed25519::decompress(&b),
1389                Err(crate::Error::VerificationFailed)
1390            ),
1391            "y == p must be rejected"
1392        );
1393        // y' = p + 18 = 2^255 − 1(该区间最大值)
1394        let mut b2 = [0xffu8; 32];
1395        b2[31] = 0x7f;
1396        assert!(ed25519::decompress(&b2).is_err());
1397        // 区间内其余值同样拒绝
1398        let mut b3 = [0xffu8; 32];
1399        b3[0] = 0xf0;
1400        b3[31] = 0x7f;
1401        assert!(ed25519::decompress(&b3).is_err());
1402    }
1403
1404    /// 严格化不得误伤:恒等元 (0,1) 的规范编码(y=1,x 偶)必须仍可
1405    /// 解码——验证方程允许 R = 恒等元。
1406    #[test]
1407    fn ed25519_decompress_accepts_canonical_identity() {
1408        let mut id = [0u8; 32];
1409        id[0] = 0x01;
1410        let p = ed25519::decompress(&id).expect("canonical identity decodes");
1411        // t = x·y = 0、z = 1
1412        assert!(p.x.is_zero());
1413        assert_eq!(p.compress(), id, "identity round-trips");
1414    }
1415
1416    /// 基点压缩编码往返(decompress 严格化后的规范路径回归)。
1417    #[test]
1418    fn ed25519_base_point_round_trip() {
1419        let g = ed25519::base_point();
1420        let enc = g.compress();
1421        assert_eq!(enc, ed25519::G_COMPRESSED);
1422        let back = ed25519::decompress(&enc).expect("base point decodes");
1423        assert_eq!(back.compress(), enc);
1424    }
1425}