reality: Add support_x25519mlkem768 option

This commit is contained in:
Shtorm
2026-09-20 22:01:43 +03:00
parent 311d9b51eb
commit aae5f7ff02
3 changed files with 38 additions and 22 deletions
+22 -18
View File
@@ -45,10 +45,11 @@ import (
var _ ConfigCompat = (*RealityClientConfig)(nil)
type RealityClientConfig struct {
ctx context.Context
uClient *UTLSClientConfig
publicKey []byte
shortID [8]byte
ctx context.Context
uClient *UTLSClientConfig
publicKey []byte
shortID [8]byte
supportX25519MLKEM768 bool
}
func NewRealityClient(ctx context.Context, logger logger.ContextLogger, serverAddress string, options option.OutboundTLSOptions) (Config, error) {
@@ -84,7 +85,7 @@ func newRealityClient(ctx context.Context, logger logger.ContextLogger, serverAd
return nil, E.New("invalid short_id")
}
var config Config = &RealityClientConfig{ctx, uClient.(*UTLSClientConfig), publicKey, shortID}
var config Config = &RealityClientConfig{ctx, uClient.(*UTLSClientConfig), publicKey, shortID, options.Reality.SupportX25519MLKEM768}
if options.KernelRx || options.KernelTx {
if !C.IsLinux {
return nil, E.New("kTLS is only supported on Linux")
@@ -145,22 +146,24 @@ func (e *RealityClientConfig) ClientHandshake(ctx context.Context, conn net.Conn
if err != nil {
return nil, err
}
for _, extension := range uConn.Extensions {
if ce, ok := extension.(*utls.SupportedCurvesExtension); ok {
ce.Curves = common.Filter(ce.Curves, func(curveID utls.CurveID) bool {
return curveID != utls.X25519MLKEM768
})
if !e.supportX25519MLKEM768 {
for _, extension := range uConn.Extensions {
if ce, ok := extension.(*utls.SupportedCurvesExtension); ok {
ce.Curves = common.Filter(ce.Curves, func(curveID utls.CurveID) bool {
return curveID != utls.X25519MLKEM768
})
}
if ks, ok := extension.(*utls.KeyShareExtension); ok {
ks.KeyShares = common.Filter(ks.KeyShares, func(share utls.KeyShare) bool {
return share.Group != utls.X25519MLKEM768
})
}
}
if ks, ok := extension.(*utls.KeyShareExtension); ok {
ks.KeyShares = common.Filter(ks.KeyShares, func(share utls.KeyShare) bool {
return share.Group != utls.X25519MLKEM768
})
err = uConn.BuildHandshakeState()
if err != nil {
return nil, err
}
}
err = uConn.BuildHandshakeState()
if err != nil {
return nil, err
}
if len(uConfig.NextProtos) > 0 {
for _, extension := range uConn.Extensions {
@@ -271,6 +274,7 @@ func (e *RealityClientConfig) Clone() Config {
e.uClient.Clone().(*UTLSClientConfig),
e.publicKey,
e.shortID,
e.supportX25519MLKEM768,
}
}
+12 -1
View File
@@ -152,7 +152,8 @@ icon: material/new-box
"reality": {
"enabled": false,
"public_key": "jNXHt1yRo0vDuchQlIP6Z0ZvjT3KtzVI-T4E7RoLJS0",
"short_id": "0123456789abcdef"
"short_id": "0123456789abcdef",
"support_x25519mlkem768": false
}
}
```
@@ -825,6 +826,16 @@ Public key, generated by `sing-box generate reality-keypair`.
A hexadecimal string with zero to eight digits.
#### support_x25519mlkem768
==Client only==
Keep the `X25519MLKEM768` post-quantum hybrid key share in the ClientHello instead of stripping it.
Required by REALITY servers running `xtls/reality` built after 2026-09-08 (Xray-core >= v26.9.8), which reject
ClientHellos that don't offer it before any plain `X25519` share. Older REALITY servers may fail the handshake
if this key share is present, so it is disabled by default.
#### max_time_difference
==Server only==
+4 -3
View File
@@ -250,7 +250,8 @@ type OutboundUTLSOptions struct {
}
type OutboundRealityOptions struct {
Enabled bool `json:"enabled,omitempty"`
PublicKey string `json:"public_key,omitempty"`
ShortID string `json:"short_id,omitempty"`
Enabled bool `json:"enabled,omitempty"`
PublicKey string `json:"public_key,omitempty"`
ShortID string `json:"short_id,omitempty"`
SupportX25519MLKEM768 bool `json:"support_x25519mlkem768,omitempty"`
}