-
Notifications
You must be signed in to change notification settings - Fork 760
feat: support AEAD #324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: support AEAD #324
Conversation
|
补一条: 如果传入的不符合 BlockCrypt 或 cipher.AEAD 比如 nil 或者 其他内容 那就是无加密 ( |
|
@xtaci 注释和文档变更就交给你了,你先看,我去 rebase 一下 |
|
这个我得慢慢看了 |
fc90173 to
bcf7a48
Compare
|
行了,少了个 return 补上了 |
|
好的,这个我主要考虑必要性,因为AEAD一般是在上层封装消息的时候,对于UDP数据包的必要性,一个4B的crc32应该就够了,AEAD的tag在12-16,这个会增加overhead.
|
|
确实是会增加overhead, 对于 chacha20 的话 AES GCM 的 authTag 可以在12-16之间 不考虑 XChacha20 这个还是能接受的 |
|
GHASH 现在也有 CPU 硬解加速什么的, 可能会比 CRC32 快一些? |
|
这点速度是有GHASH的硬件看不上,没GHASH的硬件GCM更慢。 |
|
我先看看,暂时不合并这个,先留着。 |
是这样,可以考虑 Chacha20Poly1035 什么的 |
|
https://github.com/xtaci/kcptun/releases/tag/v20251210 |
|
晚点我加几个 Benchmark 看看吞吐 AEAD的 NonceSize 也能调 |
$ go.exe test -benchmem -run=^$ -bench "^Benchmark(CFB|AEAD)" .
2025/12/10 15:10:40 beginning tests, encryption:salsa20, fec:10/3
goos: windows
goarch: amd64
pkg: github.com/xtaci/kcp-go/v5
cpu: Intel(R) Xeon(R) CPU E5-2683 v4 @ 2.10GHz
BenchmarkCFB_AES_128_CRC32-32 320488 3453 ns/op 405.39 MB/s 0 B/op 0 allocs/op
BenchmarkAEAD_AES_128_GCM-32 602001 1994 ns/op 702.28 MB/s 3072 B/op 1 allocs/op
BenchmarkCFB_Salsa20_CRC32-32 554316 2113 ns/op 662.70 MB/s 0 B/op 0 allocs/op
BenchmarkAEAD_Chacha20_Poly1035-32 488388 2397 ns/op 584.07 MB/s 3072 B/op 1 allocs/op
PASS
ok github.com/xtaci/kcp-go/v5 4.788s有硬解的情况下 GCM 比 CFB 快多了 不过 Chacha20Poly1035 就不比 Salsa20 快了 (包里没有 Chacha20 的 BlockCrypt) 重用 AEAD 内存以后的结果 2025/12/10 15:16:23 beginning tests, encryption:salsa20, fec:10/3
goos: windows
goarch: amd64
pkg: github.com/xtaci/kcp-go/v5
cpu: Intel(R) Xeon(R) CPU E5-2683 v4 @ 2.10GHz
BenchmarkCFB_AES_128_CRC32-32 299253 3448 ns/op 406.06 MB/s 0 B/op 0 allocs/op
BenchmarkAEAD_AES_128_GCM-32 1555551 772.4 ns/op 1812.60 MB/s 0 B/op 0 allocs/op
BenchmarkCFB_Salsa20_CRC32-32 565623 2117 ns/op 661.20 MB/s 0 B/op 0 allocs/op
BenchmarkAEAD_Chacha20_Poly1035-32 959094 1254 ns/op 1116.54 MB/s 0 B/op 0 allocs/op
PASS
ok github.com/xtaci/kcp-go/v5 4.771s这下吊打了 |
88cca5e to
f36e133
Compare
|
或者说,有没有办法直接扩展BlockCrypt,让AEAD 是其中一种类型。这样改动最小。 |
|
我本来是想封装成aead的,但是吧authTag (CRC32) 写起来真的很难受( |
|
要么就是加个结构体,内部是any,调用必须通过函数构造私有结构体 但是不管是扩展还是改函数签名都会破坏兼容性 :( 可以考虑未知的cipher直接panic |
|
不过可以考虑这样子 type aeadCrypt struct {
cipher.AEAD
}
func (aeadCrypt) Encrypt(_, _ []byte) {
panic("called Encrypt on AEAD crypt")
}
func (aeadCrypt) Decrypt(_, _ []byte) {
panic("called Decrypt on AEAD crypt")
}然后内部断言 if block ok := l.block.(*aeadCrypt); ok {
block.Seal(...)
} |
|
可以尝试下 |
|
OK |
|
好了,我跑个测试去 |
|
看上去他工作,数据正常传输 |
|
好的,非加密情况的长度,就是case nil那里是确保是0对吧,测试过没 |
|
AEAD的工作,nil 的话 sess_test.go 里面应该有? |
|
OK,你要不直接PR |
|
我在外面 ( 对于 Open 的话 理论上 Open 不用检查, 因为 dst 重用 ciphertext 肯定是比 plaintext 大的 |
|
OK,我来 |
|
编辑了一下,Open不用检查, Seal 检查就行了 |
|
检查扔到seal前面,检查不通过连seal都不用 |
|
其实我的想法是直接在newUDPSession里面检查 NonceSize 和 Overhead 直接在 newUDPSession 就抛 ( |
这个也需要的,提前检查。但内部的assert也需要的,一个保险丝。 |
|
这个assert感觉永远碰不到倒是 |
避免其他的对kcp的改动碰到,当然正常碰不到,但需要。 |
|
这样的话 hmmmm 我想应该改成这样子 # Seal
if dst == nil || cap(dst)-len(dst) < len(plaintext) + s.aead.Overhead() {
panic("a new buffer allocated!")
}
# Open
if dst == nil || cap(dst)-len(dst) < len(ciphertext) - s.aead.Overhead() {
panic("unreachable")
}没有 dst 也会生成新 Buffer |
|
最好 UDPSession 里面调用一下 SetMTU 或者确保 headerSize + IKCP_MTU_DEF 不会超过 1500 我的倾向是调用一次 SetMTU(IKCP_MTU_DEF) |
if !sess.SetMTU(IKCP_MTU_DEF) {
panic("Overhead too large")
}修正一次 MTU |
|
应该没问题 你什么时候开一个 dev 分支或者临时分支的, |
OK,平时改动少。这次改动多了。 |
|
以后就用dev分支吧,我push上去了。 |
|
应该没啥问题了, Seal 那个应该也永远碰不到 我在想要不要把 Seal 那个检查扔到测试里面 |
你先想想,我先测试几天aesgcm的kcptun |
行,我回去加几个测试 |











CFB 加密格式
encrypt( [Nonce] [CRC32] [FEC] [KCP])
AEAD 加密格式
[Nonce] encrypt([FEC] [KCP]) [AEAD Tag]
要点如下:
Header 长度变更 (仅 Nonce), 尾部留空 (已经有了)
MTU 计算变更 Header + (AEAD Overhead)