Skip to main content

encryption/manager/
asymmetric.rs

1// Copyright (c) 2026 erik <erik@erik.xyz> — https://erik.xyz
2
3//! 非对称能力门面:签名([`SignatureManager`])与密钥协商([`KeyAgreementManager`])。
4//!
5//! 与 [`super`] 里其余六个门面同构,同样由 `manager_facade!` 宏生成;单独成文件
6//! 只是按用途分组——签名与协商属于非对称能力,与 [`super`] 的加密 / 哈希 / 派生
7//! 门面分开放更好翻。两个调用点写在 `manager.rs` 的宏定义之后:`macro_rules!`
8//! 是文本作用域,先定义后调用的顺序不是排版随意。
9
10manager_facade! {
11    /// 签名门面。
12    SignatureManager, crate::contract::Signer, "signer",
13    /// 返回十六进制签名。
14    sign with sign_with(message: &[u8], private_key_hex: &str)
15        -> crate::error::Result<String>,
16    verify with verify_with(message: &[u8], signature_hex: &str, public_key_hex: &str)
17        -> crate::error::Result<()>,
18}
19
20manager_facade! {
21    /// 密钥协商门面。
22    KeyAgreementManager, crate::contract::KeyAgreement, "key agreement",
23    /// 返回定长共享秘密的十六进制。
24    agree with agree_with(private_key_hex: &str, peer_public_key_hex: &str)
25        -> crate::error::Result<String>,
26}
27
28#[cfg(test)]
29mod tests {
30    use super::*;
31    use crate::asymmetric::ed25519::Ed25519Signer;
32    use crate::asymmetric::x25519::X25519Agreement;
33    use crate::contract::{KeyAgreement, Signer};
34    use crate::error::Error;
35    use crate::registry::Registry;
36
37    /// 签名门面是纯转发:签一次、验一次通过,被改过的消息验签失败。
38    #[test]
39    fn signature_manager_round_trips_and_rejects_tampering() {
40        let mut registry: Registry<Box<dyn Signer>> = Registry::new("signer");
41        registry.register(Box::new(Ed25519Signer::new()));
42        let mut manager = SignatureManager::new(registry, Ed25519Signer::IDENTIFIER).unwrap();
43
44        let pair = Ed25519Signer::generate_key_pair_hex().unwrap();
45        let signature = manager.sign(b"message", &pair.private_key_hex).unwrap();
46        manager
47            .verify(b"message", &signature, &pair.public_key_hex)
48            .unwrap();
49        assert!(
50            manager
51                .verify(b"tampered", &signature, &pair.public_key_hex)
52                .is_err()
53        );
54
55        // 默认标识改不动:`set_default_identifier` 与 `new` 用同一个 kind 文案
56        //(宏里 `$kind` 的第二处展开)。
57        assert_eq!(
58            manager.set_default_identifier("missing").unwrap_err(),
59            Error::UnknownIdentifier {
60                kind: "signer",
61                identifier: "missing".to_string(),
62            }
63        );
64
65        // 门面的 Debug 由 derive 给出,注册表只打印能力名与标识列表:私钥不出现。
66        let text = format!("{manager:?}");
67        assert!(text.contains("Registry"), "{text}");
68        assert!(!text.contains(&pair.private_key_hex), "{text}");
69    }
70
71    /// 协商门面同样是纯转发:两端各用自己的私钥与对方公钥,导出同一个共享秘密。
72    #[test]
73    fn key_agreement_manager_agrees_on_the_same_secret() {
74        let mut registry: Registry<Box<dyn KeyAgreement>> = Registry::new("key agreement");
75        registry.register(Box::new(X25519Agreement::new()));
76        let manager = KeyAgreementManager::new(registry, X25519Agreement::IDENTIFIER).unwrap();
77
78        let alice = X25519Agreement::generate_key_pair_hex().unwrap();
79        let bob = X25519Agreement::generate_key_pair_hex().unwrap();
80
81        let from_alice = manager
82            .agree(&alice.private_key_hex, &bob.public_key_hex)
83            .unwrap();
84        let from_bob = manager
85            .agree(&bob.private_key_hex, &alice.public_key_hex)
86            .unwrap();
87        assert_eq!(from_alice, from_bob);
88    }
89}