shurlinet/go-clatter

GitHub: shurlinet/go-clatter

为 Go 语言提供后量子 Noise 协议框架,支持 ML-KEM 密钥交换与 ML-DSA/SLH-DSA 签名,帮助开发者构建抗量子计算攻击的安全通信通道。

Stars: 2 | Forks: 0

# go-clatter 🔊 [![Go Reference](https://pkg.go.dev/badge/github.com/shurlinet/go-clatter.svg)](https://pkg.go.dev/github.com/shurlinet/go-clatter) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) 适用于 Go 的后量子 [Noise](https://noiseprotocol.org/noise.html) 握手。实现了 [PQNoise](https://doi.org/10.1145/3548606.3560577)([alt](https://sci-net.xyz/10.1145/3548606.3560577))扩展(ACM CCS 2022),该扩展用量子抗性的 KEM 替代了经典的 DH 密钥交换,同时保留了 Noise 的形式化安全保证。 移植自由 [Joni Lepisto](https://github.com/jmlepisto) 开发的 [Rust Clatter v2.2.0](https://github.com/jmlepisto/clatter),并与其进行了逐字节的验证。基于 Go 标准库 crypto(`crypto/mlkem`、`crypto/ecdh`)构建,并使用 `golang.org/x/crypto` 提供 ChaCha20-Poly1305 和 BLAKE2 支持。没有其他外部依赖。所有密钥材料都保存在固定大小的数组中,并具有显式的 `Destroy()` 清零功能。 ⚠️ **警告** ⚠️ * 本库尚未接受任何正式的安全审计 * 虽然我们使用了 Go 的标准库加密原语,但由 **您自己** 决定评估它们是否满足您的安全和完整性要求 * 后量子密码学尚未像经典密码学那样成熟。鼓励用户使用混合握手(`HybridHandshake`、`HybridDualLayerHandshake`),结合经典和后量子原语以实现纵深防御 * 此 Go 移植版是在 AI 辅助下([Claude](https://claude.ai))编写并由人类审查的。所有代码均与 Rust 参考实现进行了逐字节验证,并经过了 26,000+ 次握手、408 个跨实现向量、1,452 个 NIST/PQC-Suite-B 向量以及 11 个 Fuzz 目标的测试。AI 生成了代码;人类做出了每一项设计决策,审查了每一行代码,并对每一个 Bug 负责。 📖 **文档** 📖 * [`pkg.go.dev`](https://pkg.go.dev/github.com/shurlinet/go-clatter) - API 参考和类型文档 * [`examples/`](examples/) - 涵盖每种握手类型、观察者回调、ML-DSA-65 和 SLH-DSA 签名的可运行示例 ## Noise 协议 本库遵循 Noise 协议框架**第 34 版**。以下功能不受支持: * Curve 448 DH 支持 - 不存在合适的 Go 实现 * 延迟模式支持 - 可由用户自行实现 * 回退模式支持 - 可由用户自行实现 ### PSK 有效性规则 go-clatter 采用了与 Rust Clatter 相同的、针对后量子模式修改过的 PSK 有效性解释。 当使用 PQ 模式时,发送 `e` 或 `ekem` 令牌可提供所需的自选随机性,这等效于经典 Noise 模式中的 `e` 令牌。如果 `skem` 出现在消息模式中的任何 `psk` 令牌之前,它也满足此要求。 ## 握手类型 * **NQ** (`NqHandshake`) - 使用 X25519 的经典纯 DH 握手 * **PQ** (`PqHandshake`) - 使用 ML-KEM-768 或 ML-KEM-1024 的纯 KEM 握手 * **混合** (`HybridHandshake`) - 在单个对称状态中结合 DH 和 KEM 操作的真正混合握手 * **双层** (`DualLayerHandshake`) - 具有独立层的外部加密内部管道式握手 * **混合双层** (`HybridDualLayerHandshake`) - 层间带有加密绑定的外部加密内部管道式握手 90 种握手模式。4 种哈希函数。2 种 AEAD 密码。2 种 KEM 大小。 ## 后量子签名 * **ML-DSA-65** (`crypto/sign/mldsa65`) - FIPS 204 基于格的数字签名(NIST 级别 3,约 192 位安全性)。种子 = 32 B,公钥 = 1952 B,签名 = 3309 B。 * **SLH-DSA** (`crypto/sign/slhdsa`) - FIPS 205 基于哈希的数字签名。NIST 针对 ML-DSA 的备选方案。18 个参数集:12 个 FIPS(SHA2 + SHAKE)和 6 个非 FIPS 的 BLAKE3 变体。安全级别 1/3/5,具有快速签名和小签名权衡。已根据 1,260 个 NIST ACVP 向量和 192 个 PQC Suite B BLAKE3 向量进行了验证。 独立的签名模块。未集成到 Noise 握手中 - 这些是用于应用层通用目的的签名原语。 ## 加密原语 | 原语 | 实现 | 协议名称 | |-----------|---------------|---------------| | X25519 DH | `crypto/ecdh` | `25519` | | ML-KEM-768 | `crypto/mlkem` (FIPS 203) | `MLKEM768` | | ML-KEM-1024 | `crypto/mlkem` (FIPS 203) | `MLKEM1024` | | ChaCha20-Poly1305 | `golang.org/x/crypto` | `ChaChaPoly` | | AES-256-GCM | `crypto/aes` | `AESGCM` | | SHA-256 | `crypto/sha256` | `SHA256` | | SHA-512 | `crypto/sha512` | `SHA512` | | BLAKE2s | `golang.org/x/crypto/blake2s` | `BLAKE2s` | | BLAKE2b | `golang.org/x/crypto/blake2b` | `BLAKE2b` | | ML-DSA-65 | `filippo.io/mldsa` (FIPS 204) | - | | SLH-DSA (SHA2) | 内嵌 [Trail of Bits go-slh-dsa](https://github.com/trailofbits/go-slh-dsa) (FIPS 205) | - | | SLH-DSA (SHAKE) | 内嵌 Trail of Bits + `golang.org/x/crypto/sha3` | - | | SLH-DSA (BLAKE3) | 内嵌 Trail of Bits + `lukechampine.com/blake3` | - | ## 协议命名 go-clatter 使用与 Rust Clatter 相同的命名方案,以确保跨实现的兼容性: ``` Noise_NN_25519_ChaChaPoly_SHA256 (NQ) Noise_pqNN_MLKEM768_ChaChaPoly_SHA256 (PQ, same KEM) Noise_pqNN_MLKEM768+MLKEM1024_ChaChaPoly_SHA256 (PQ, different KEMs) Noise_hybridNN_25519+MLKEM768_ChaChaPoly_SHA256 (Hybrid) ``` ## 用法 ``` import ( clatter "github.com/shurlinet/go-clatter" "github.com/shurlinet/go-clatter/crypto/cipher" "github.com/shurlinet/go-clatter/crypto/dh" "github.com/shurlinet/go-clatter/crypto/hash" "github.com/shurlinet/go-clatter/crypto/kem" ) // NQ handshake (classical) suite := clatter.CipherSuite{ DH: dh.NewX25519(), Cipher: cipher.NewChaChaPoly(), Hash: hash.NewSha256(), } alice, _ := clatter.NewNqHandshake(clatter.PatternXX, true, suite, clatter.WithStaticKey(aliceKeys), clatter.WithPrologue([]byte("my-app/v1")), ) // Hybrid handshake (quantum-resistant) hybridSuite := clatter.CipherSuite{ DH: dh.NewX25519(), EKEM: kem.NewMlKem768(), SKEM: kem.NewMlKem768(), Cipher: cipher.NewChaChaPoly(), Hash: hash.NewSha256(), } alice, _ := clatter.NewHybridHandshake(clatter.PatternHybridXX, true, hybridSuite, clatter.WithStaticKey(aliceDHKeys), clatter.WithStaticKEMKey(aliceKEMKeys), clatter.WithPrologue([]byte("my-app/v1")), ) ``` ### ML-DSA-65 签名 ``` import "github.com/shurlinet/go-clatter/crypto/sign/mldsa65" // Generate a key pair. sk, _ := mldsa65.GenerateKey() defer sk.Destroy() // zeros seed on cleanup // Sign (hedged randomness - recommended for production). sig, _ := sk.Sign([]byte("message to sign")) // Verify. ok := sk.PublicKey().Verify([]byte("message to sign"), sig) // Context separation prevents cross-purpose replay. sig, _ = sk.SignWithContext([]byte("data"), "my-app/transfers/v1") ok = sk.PublicKey().VerifyWithContext([]byte("data"), sig, "my-app/transfers/v1") // Seed export/import for key persistence. seed, _ := sk.Seed() // 32 bytes - store securely sk2, _ := mldsa65.NewPrivateKeyFromSeed(seed) // reconstruct later defer sk2.Destroy() ``` ### SLH-DSA 签名 ``` import "github.com/shurlinet/go-clatter/crypto/sign/slhdsa" // Generate a key pair (SHA2-128f: fastest FIPS 205 param set). priv, _ := slhdsa.GenerateKey(slhdsa.SHA2_128f) defer priv.Destroy() // Sign (hedged randomness - recommended for production). sig, _ := priv.SignMessage([]byte("message")) // Verify. ok := priv.PublicKey().Verify([]byte("message"), sig) // BLAKE3 variant (non-FIPS, faster on x86 with SIMD). // Same API, just a different ParamSet constant. privB, _ := slhdsa.GenerateKey(slhdsa.BLAKE3_128f) defer privB.Destroy() sigB, _ := privB.SignMessage([]byte("blake3 message")) _ = privB.PublicKey().Verify([]byte("blake3 message"), sigB) // Pre-hash mode for large files (SHA2/SHAKE param sets only). largeFile := []byte("contents of a large file") sig, _ = priv.SignPreHash(largeFile, slhdsa.HashSHA2_256) ok = priv.PublicKey().VerifyPreHash(largeFile, sig, slhdsa.HashSHA2_256) ``` 提供 18 个参数集。有关完整的 API 和参数集指南,请参阅 [SLH-DSA godoc](https://pkg.go.dev/github.com/shurlinet/go-clatter/crypto/sign/slhdsa)。 ## 可观测性 将 `Observer` 附加到任何握手,以接收有关消息处理、密钥交换事件和错误的实时通知: ``` type myObserver struct{} func (o *myObserver) OnMessage(e clatter.HandshakeEvent) { fmt.Printf("[msg %d] %s type=%s payload=%d bytes\n", e.MessageIndex, e.Direction, e.HandshakeType, e.PayloadLen) } func (o *myObserver) OnError(e clatter.HandshakeErrorEvent) { fmt.Printf("[msg %d] ERROR: %v\n", e.MessageIndex, e.Err) } alice, _ := clatter.NewNqHandshake(clatter.PatternXX, true, suite, clatter.WithStaticKey(aliceKeys), clatter.WithObserver(&myObserver{}), ) ``` Observer 事件报告已获知的远程密钥(DH 和 KEM)、握手哈希、协议名称、阶段(用于双层)和完成状态。nil observer 零开销。Observer 回调中的 panic 会被恢复。请参阅 [`examples/observer/`](examples/observer/) 和 [Observer godoc](https://pkg.go.dev/github.com/shurlinet/go-clatter#Observer)。 ## 与 Rust Clatter 的差异 * **CipherSuite 结构体**代替了泛型类型参数 - Go 的类型系统倾向于运行时派发 * **所有 Rust panic 都转换成了 Go error** - go-clatter 绝不会因用户输入而 panic * **没有 ML-KEM-512** - Go 标准库 `crypto/mlkem` 仅提供 768 和 1024(NIST 安全裕度决策) * **没有跨厂商 KEM 测试** - Go 每个密钥大小只有一个 KEM 实现(标准库) * **后量子签名模块** - go-clatter 通过独立的 FIPS 204 (ML-DSA-65) 和 FIPS 205 (SLH-DSA) 签名原语扩展了握手之外的功能。Rust Clatter 不包含签名模块。这为 Go 用户提供了完整的 PQ 工具箱:抗量子密钥交换 (ML-KEM)、基于格的签名 (ML-DSA) 和基于哈希的签名 (SLH-DSA) 集于一体。 ## 验证 go-clatter 由以下方式验证: * 跨所有包的单元测试 * [冒烟测试](smoke_test.go) - 跨所有模式/密码/哈希/KEM 组合的 26,112 次握手 (NQ + PQ + Hybrid + DualLayer + HybridDualLayer) * [属性测试](maxmsglen_property_test.go) - 使用独立的负载开销计算器、每条消息的运行时交叉检查、实际写入字节数预言机、构造函数边界验证和传输强制执行来验证所有 90 种模式 * [Fuzz 测试](fuzz_test.go) - 9 个与 Rust Clatter 的 fuzz 套件相匹配的 Noise fuzz 目标 + 2 个 SLH-DSA fuzz 目标(签名-验证往返 + 加载器崩溃抗性) * [MaxMsgLen fuzz](maxmsglen_fuzz_test.go) - 跨 3 种模式 (NQ、PQ、Hybrid) 覆盖所有消息数量形态的边界清晰度验证 * [Cacophony](https://github.com/haskell-cryptography/cacophony) 和 [Snow](https://github.com/mcginty/snow) 测试向量 - 408 个已逐字节验证的跨实现向量 ([vectors/](vectors/)) * 10 个由 Rust Clatter 使用确定性 RNG 生成的 Rust 互操作性向量 * [NIST ACVP 向量](crypto/sign/slhdsa/testdata/acvp/) - 1,260 个跨所有 12 个 FIPS 205 参数集(包括 pre-hash 模式)的 SLH-DSA 测试向量(keygen + sigGen + sigVer) * [PQC Suite B BLAKE3 向量](crypto/sign/slhdsa/testdata/blake3/) - 针对所有 6 个 BLAKE3 参数集的 192 个跨实现向量 ``` go test -race -count=1 ./... ``` ## 未来工作 * **SM3 哈希函数支持** - [SM3](https://grokipedia.com/page/sm3_hash_function) 是中国国家密码散列函数(ISO/IEC 10118-3:2018,256 位,安全性与 SHA-256 相当)。SLH-DSA 与哈希无关的架构允许与 SHA2/SHAKE/BLAKE3 一起实例化基于 SM3 的参数集。Go 库:[`emmansun/gmsm`](https://github.com/emmansun/gmsm)。正在等待官方的 SLH-DSA-SM3 规范。 * **HQC KEM** - NIST 选定的备选 KEM(基于编码,数学原理与 ML-KEM 不同)。等待 NIST FIPS 最终确定(预计在 2026 年底 / 2027 年初)。 * **中国 NGCC 算法** - 中国的[下一代商用密码算法计划](https://www.niccs.org.cn/en/)(NGCC,于 2025 年 2 月启动)正在独立于 NIST 进行自己的 PQC 标准化,提交截止日期为 2026 年 6 月,预计将在 2027-2028 年选出算法。go-clatter 的模块化架构(CipherSuite,ParamSetFuncs 接口)旨在适应新的 KEM 和签名算法的标准化,不论其来源。 ## 依赖项 * Go 1.26+(`crypto/mlkem` 所需) * `golang.org/x/crypto` (ChaCha20-Poly1305, BLAKE2, SHA3/SHAKE) * [`filippo.io/mldsa`](https://pkg.go.dev/filippo.io/mldsa) (ML-DSA-65 签名) - Go 即将推出的 `crypto/mldsa` 标准库包的预发布版本,由 [Filippo Valsorda](https://filippo.io) 维护。当 `crypto/mldsa` 发布时,只需更改一次导入路径即可完成向标准库的迁移(提案 [#77626](https://github.com/golang/go/issues/77626) 已被接受)。 * [`lukechampine.com/blake3`](https://pkg.go.dev/lukechampine.com/blake3) (SLH-DSA BLAKE3 参数集) - 纯 Go 实现 + 针对 amd64/arm64 的 SIMD 汇编。 ## 致谢 特别感谢 [Joni Lepisto](https://github.com/jmlepisto) 创建了 [Rust Clatter](https://github.com/jmlepisto/clatter)。他整洁且经过充分测试的实现使这个 Go 移植版成为可能,他的测试基础设施(互操作向量、冒烟测试、fuzz 目标)为我们设定了验证标准。 还要感谢我们使用其测试向量数据集来验证正确性的项目: * [Cacophony](https://github.com/haskell-cryptography/cacophony)(Haskell Noise 实现)- 944 个测试向量 * [Snow](https://github.com/mcginty/snow)(Rust Noise 实现)- 408 个测试向量 以及感谢 PQNoise 论文的作者提供了本库所实现的基础研究。 感谢 [Filippo Valsorda](https://filippo.io) 提供 [`filippo.io/mldsa`](_URL_35/>) - 为我们的签名模块提供动力的 ML-DSA 实现。Filippo 维护着 Go 的密码学标准库,并将这个包设计为 `crypto/mldsa` 的直接前身。他的工作在标准库发布之前几年,就为 Go 生态系统提供了可用于生产环境的后量子签名。 感谢 [Trail of Bits](https://trailofbits.com) 提供 [go-slh-dsa](https://github.com/trailofbits/go-slh-dsa) - 嵌入在我们签名模块中的 SLH-DSA 引擎。他们的实现是纯 Go 的,具有抗侧信道攻击能力,并涵盖了所有 12 个 FIPS 205 参数集。 感谢 [JP Aumasson](https://aumasson.jp)、[Zooko Wilcox-O'Hearn](https://grokipedia.com/page/Zooko_Wilcox-O'Hearn) 和 Alex Pruden 提供 [PQC Suite B](https://github.com/PQC-Suite-B/) - 验证我们 BLAKE3 参数集的 BLAKE3 变体研究和测试向量。 感谢 [Luke Champine](https://github.com/lukechampine) 提供 [lukechampine.com/blake3](https://github.com/lukechampine/blake3) - 带有针对 amd64 和 arm64 的 SIMD 加速的 BLAKE3 实现。 ## 许可证 MIT - 与上游 Rust Clatter 许可证相匹配。
标签:ACVP, BLAKE2, BLAKE3, ChaCha20-Poly1305, CVE, DNS解析, ECDH, EVTX分析, FIPS 203, FIPS 204, FIPS 205, Fuzzing, Go语言, MIT许可, ML-DSA-65, ML-KEM, NIST, Noise协议, PQNoise, SHA2, SHAKE, SLH-DSA, 内核驱动, 双层层级握手, 后量子密码学, 安全通信, 密码学, 密钥封装, 开源项目, 手动系统调用, 抗量子计算, 数字签名, 日志审计, 混合加密, 点对点加密, 程序破解, 网络协议, 网络安全, 蓝队防御, 隐私保护