chore: sync vless encryption code
Some checks failed
Test / test (1.20, macos-13) (push) Has been cancelled
Test / test (1.20, macos-latest) (push) Has been cancelled
Test / test (1.20, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.20, ubuntu-latest) (push) Has been cancelled
Test / test (1.20, windows-latest) (push) Has been cancelled
Test / test (1.21, macos-13) (push) Has been cancelled
Test / test (1.21, macos-latest) (push) Has been cancelled
Test / test (1.21, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.21, ubuntu-latest) (push) Has been cancelled
Test / test (1.21, windows-latest) (push) Has been cancelled
Test / test (1.22, macos-13) (push) Has been cancelled
Test / test (1.22, macos-latest) (push) Has been cancelled
Test / test (1.22, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.22, ubuntu-latest) (push) Has been cancelled
Test / test (1.22, windows-latest) (push) Has been cancelled
Test / test (1.23, macos-13) (push) Has been cancelled
Test / test (1.23, macos-latest) (push) Has been cancelled
Test / test (1.23, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.23, ubuntu-latest) (push) Has been cancelled
Test / test (1.23, windows-latest) (push) Has been cancelled
Test / test (1.24, macos-13) (push) Has been cancelled
Test / test (1.24, macos-latest) (push) Has been cancelled
Test / test (1.24, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.24, ubuntu-latest) (push) Has been cancelled
Test / test (1.24, windows-latest) (push) Has been cancelled
Test / test (1.25, macos-13) (push) Has been cancelled
Test / test (1.25, macos-latest) (push) Has been cancelled
Test / test (1.25, ubuntu-24.04-arm) (push) Has been cancelled
Test / test (1.25, ubuntu-latest) (push) Has been cancelled
Test / test (1.25, windows-latest) (push) Has been cancelled
Trigger CMFA Update / trigger-CMFA-update (push) Has been cancelled

This commit is contained in:
wwqgtxx 2025-08-31 19:43:14 +08:00
parent c98f5f44b7
commit 33cde6592e
6 changed files with 46 additions and 34 deletions

View File

@ -642,11 +642,11 @@ proxies: # socks5
# native/xorpub 的 XTLS Vision 可以 Splice。只使用 1-RTT 模式 / 若服务端发的 ticket 中秒数不为零则 0-RTT 复用) # native/xorpub 的 XTLS Vision 可以 Splice。只使用 1-RTT 模式 / 若服务端发的 ticket 中秒数不为零则 0-RTT 复用)
# / 是只能选一个,后面 base64 至少一个,无限串联,使用 mihomo generate vless-x25519 和 mihomo generate vless-mlkem768 生成,替换值时需去掉括号 # / 是只能选一个,后面 base64 至少一个,无限串联,使用 mihomo generate vless-x25519 和 mihomo generate vless-mlkem768 生成,替换值时需去掉括号
# #
# Padding 是可选的参数,仅作用于 1-RTT 以消除握手的长度特征,双端默认值均为 "111-1111.111--66.3333--1234",它的含义是 # Padding 是可选的参数,仅作用于 1-RTT 以消除握手的长度特征,双端默认值均为 "100-111-1111.75-0-111.50-0-3333"
# 在 1-RTT client/server hello 后粘上随机 111 到 1111 字节的 padding # 在 1-RTT client/server hello 后以 100% 的概率粘上随机 111 到 1111 字节的 padding
# 等待随机 111 到负 66 毫秒,若随机到了负值则不等待 # 以 75% 的概率等待随机 0 到 111 毫秒("probability-from-to"
# 再次发送随机 3333 到负 1234 字节的 padding若随机到了负值则不发送 # 再次以 50% 的概率发送随机 0 到 3333 字节的 padding若为 0 则不 Write()
# 服务端、客户端可以设置不同的 padding 参数,正数写在左边,按 len、gap 的顺序无限串联,第一个 padding 需大于 16 字节 # 服务端、客户端可以设置不同的 padding 参数,按 len、gap 的顺序无限串联,第一个 padding 需概率 100%、至少 35 字节
# ------------------------- # -------------------------
encryption: "mlkem768x25519plus.native/xorpub/random.1rtt/0rtt.(padding len).(padding gap).(X25519 Password).(ML-KEM-768 Client)..." encryption: "mlkem768x25519plus.native/xorpub/random.1rtt/0rtt.(padding len).(padding gap).(X25519 Password).(ML-KEM-768 Client)..."
tls: false #可以不开启tls tls: false #可以不开启tls
@ -1373,11 +1373,11 @@ listeners:
# (原生外观 / 只 XOR 公钥 / 全随机数。只允许 1-RTT 模式 / 同时允许 1-RTT 模式与 600 秒复用的 0-RTT 模式) # (原生外观 / 只 XOR 公钥 / 全随机数。只允许 1-RTT 模式 / 同时允许 1-RTT 模式与 600 秒复用的 0-RTT 模式)
# / 是只能选一个,后面 base64 至少一个,无限串联,使用 mihomo generate vless-x25519 和 mihomo generate vless-mlkem768 生成,替换值时需去掉括号 # / 是只能选一个,后面 base64 至少一个,无限串联,使用 mihomo generate vless-x25519 和 mihomo generate vless-mlkem768 生成,替换值时需去掉括号
# #
# Padding 是可选的参数,仅作用于 1-RTT 以消除握手的长度特征,双端默认值均为 "111-1111.111--66.3333--1234",它的含义是 # Padding 是可选的参数,仅作用于 1-RTT 以消除握手的长度特征,双端默认值均为 "100-111-1111.75-0-111.50-0-3333"
# 在 1-RTT client/server hello 后粘上随机 111 到 1111 字节的 padding # 在 1-RTT client/server hello 后以 100% 的概率粘上随机 111 到 1111 字节的 padding
# 等待随机 111 到负 66 毫秒,若随机到了负值则不等待 # 以 75% 的概率等待随机 0 到 111 毫秒("probability-from-to"
# 再次发送随机 3333 到负 1234 字节的 padding若随机到了负值则不发送 # 再次以 50% 的概率发送随机 0 到 3333 字节的 padding若为 0 则不 Write()
# 服务端、客户端可以设置不同的 padding 参数,正数写在左边,按 len、gap 的顺序无限串联,第一个 padding 需大于 16 字节 # 服务端、客户端可以设置不同的 padding 参数,按 len、gap 的顺序无限串联,第一个 padding 需概率 100%、至少 35 字节
# ------------------------- # -------------------------
# decryption: "mlkem768x25519plus.native/xorpub/random.1rtt/600s.(padding len).(padding gap).(X25519 PrivateKey).(ML-KEM-768 Seed)..." # decryption: "mlkem768x25519plus.native/xorpub/random.1rtt/600s.(padding len).(padding gap).(X25519 PrivateKey).(ML-KEM-768 Seed)..."
# 下面两项如果填写则开启 tls需要同时填写 # 下面两项如果填写则开启 tls需要同时填写

View File

@ -104,9 +104,9 @@ func TestInboundVless_Encryption(t *testing.T) {
data string data string
}{ }{
{"unconfigured-padding", ""}, {"unconfigured-padding", ""},
{"default-padding", "111-1111.111--66.3333--1234."}, {"default-padding", "100-111-1111.75-0-111.50-0-3333."},
{"old-padding", "100-1000."}, // Xray-core v25.8.29 {"old-padding", "100-100-1000."}, // Xray-core v25.8.29
{"custom-padding", "7890-1234.1111--999.6666--3333.777--777."}, {"custom-padding", "100-1234-7890.33-0-1111.66-0-6666.55-111-777."},
} }
var modes = []string{ var modes = []string{
"native", "native",

View File

@ -33,8 +33,8 @@ type ClientInstance struct {
RelaysLength int RelaysLength int
XorMode uint32 XorMode uint32
Seconds uint32 Seconds uint32
PaddingLens [][2]int PaddingLens [][3]int
PaddingGaps [][2]int PaddingGaps [][3]int
RWLock sync.RWMutex RWLock sync.RWMutex
Expire time.Time Expire time.Time

View File

@ -217,50 +217,61 @@ func DecodeHeader(h []byte) (l int, err error) {
return return
} }
func ParsePadding(padding string, paddingLens, paddingGaps *[][2]int) (err error) { func ParsePadding(padding string, paddingLens, paddingGaps *[][3]int) (err error) {
if padding == "" { if padding == "" {
return return
} }
maxLen := 0 maxLen := 0
for i, s := range strings.Split(padding, ".") { for i, s := range strings.Split(padding, ".") {
x := strings.SplitN(s, "-", 2) x := strings.Split(s, "-")
if len(x) != 2 || x[0] == "" || x[1] == "" { if len(x) < 3 || x[0] == "" || x[1] == "" || x[2] == "" {
return errors.New("invalid padding lenth/gap parameter: " + s) return errors.New("invalid padding lenth/gap parameter: " + s)
} }
y := [2]int{} y := [3]int{}
if y[0], err = strconv.Atoi(x[0]); err != nil { if y[0], err = strconv.Atoi(x[0]); err != nil {
return return
} }
if y[1], err = strconv.Atoi(x[1]); err != nil { if y[1], err = strconv.Atoi(x[1]); err != nil {
return return
} }
if i == 0 && (y[0] < 17 || y[1] < 17) { if y[2], err = strconv.Atoi(x[2]); err != nil {
return errors.New("first padding length must be larger than 16") return
}
if i == 0 && (y[0] < 100 || y[1] < 18+17 || y[2] < 18+17) {
return errors.New("first padding length must not be smaller than 35")
} }
if i%2 == 0 { if i%2 == 0 {
*paddingLens = append(*paddingLens, y) *paddingLens = append(*paddingLens, y)
maxLen += max(y[0], y[1]) maxLen += max(y[1], y[2])
} else { } else {
*paddingGaps = append(*paddingGaps, y) *paddingGaps = append(*paddingGaps, y)
} }
} }
if maxLen > 65535 { if maxLen > 18+65535 {
return errors.New("total padding length must be smaller than 65536") return errors.New("total padding length must not be larger than 65553")
} }
return return
} }
func CreatPadding(paddingLens, paddingGaps [][2]int) (length int, lens []int, gaps []time.Duration) { func CreatPadding(paddingLens, paddingGaps [][3]int) (length int, lens []int, gaps []time.Duration) {
if len(paddingLens) == 0 { if len(paddingLens) == 0 {
paddingLens = [][2]int{{111, 1111}, {3333, -1234}} paddingLens = [][3]int{{100, 111, 1111}, {50, 0, 3333}}
paddingGaps = [][2]int{{111, -66}} paddingGaps = [][3]int{{75, 0, 111}}
} }
for _, l := range paddingLens { for _, y := range paddingLens {
lens = append(lens, int(max(0, randBetween(int64(l[0]), int64(l[1]))))) l := 0
length += lens[len(lens)-1] if y[0] >= int(randBetween(0, 100)) {
l = int(randBetween(int64(y[1]), int64(y[2])))
}
lens = append(lens, l)
length += l
} }
for _, g := range paddingGaps { for _, y := range paddingGaps {
gaps = append(gaps, time.Duration(max(0, randBetween(int64(g[0]), int64(g[1]))))*time.Millisecond) g := 0
if y[0] >= int(randBetween(0, 100)) {
g = int(randBetween(int64(y[1]), int64(y[2])))
}
gaps = append(gaps, time.Duration(g)*time.Millisecond)
} }
return return
} }

View File

@ -23,4 +23,5 @@
// https://github.com/XTLS/Xray-core/commit/b0b220985c9c1bc832665458d5fd6e0c287b67ae // https://github.com/XTLS/Xray-core/commit/b0b220985c9c1bc832665458d5fd6e0c287b67ae
// https://github.com/XTLS/Xray-core/commit/82ea7a3cc5ff23280b87e3052f0f83b04f0267fa // https://github.com/XTLS/Xray-core/commit/82ea7a3cc5ff23280b87e3052f0f83b04f0267fa
// https://github.com/XTLS/Xray-core/commit/e8b02cd6649f14889841e8ab8ee6b2acca71dbe6 // https://github.com/XTLS/Xray-core/commit/e8b02cd6649f14889841e8ab8ee6b2acca71dbe6
// https://github.com/XTLS/Xray-core/commit/6768a22f676c9121cfc9dc4f51181a8a07837c8d
package encryption package encryption

View File

@ -29,8 +29,8 @@ type ServerInstance struct {
RelaysLength int RelaysLength int
XorMode uint32 XorMode uint32
Seconds uint32 Seconds uint32
PaddingLens [][2]int PaddingLens [][3]int
PaddingGaps [][2]int PaddingGaps [][3]int
RWLock sync.RWMutex RWLock sync.RWMutex
Sessions map[[16]byte]*ServerSession Sessions map[[16]byte]*ServerSession