63 lines
1.6 KiB
Go
63 lines
1.6 KiB
Go
package xraykeys
|
||
|
||
import (
|
||
"crypto/rand"
|
||
"encoding/base64"
|
||
"encoding/hex"
|
||
"fmt"
|
||
|
||
"golang.org/x/crypto/curve25519"
|
||
)
|
||
|
||
// GenerateRealityKeyPair returns Xray-compatible Reality private/public keys
|
||
// (raw URL-safe base64 without padding, same as `xray x25519`).
|
||
func GenerateRealityKeyPair() (privateKey, publicKey string, err error) {
|
||
var priv [32]byte
|
||
if _, err = rand.Read(priv[:]); err != nil {
|
||
return "", "", err
|
||
}
|
||
priv[0] &= 248
|
||
priv[31] &= 127
|
||
priv[31] |= 64
|
||
|
||
var pub [32]byte
|
||
curve25519.ScalarBaseMult(&pub, &priv)
|
||
|
||
privateKey = base64.RawURLEncoding.EncodeToString(priv[:])
|
||
publicKey = base64.RawURLEncoding.EncodeToString(pub[:])
|
||
return privateKey, publicKey, nil
|
||
}
|
||
|
||
// GenerateShortID returns a random Reality shortId (1–16 hex chars).
|
||
func GenerateShortID() (string, error) {
|
||
b := make([]byte, 4)
|
||
if _, err := rand.Read(b); err != nil {
|
||
return "", err
|
||
}
|
||
return hex.EncodeToString(b), nil
|
||
}
|
||
|
||
// EnsureReality fills missing Reality keys/shortId on an inbound-like struct.
|
||
func EnsureReality(privateKey, publicKey, shortID, dest, serverNames string) (priv, pub, sid, d, names string, err error) {
|
||
priv, pub, sid, d, names = privateKey, publicKey, shortID, dest, serverNames
|
||
if d == "" {
|
||
d = "www.microsoft.com:443"
|
||
}
|
||
if names == "" {
|
||
names = "www.microsoft.com"
|
||
}
|
||
if priv == "" || pub == "" {
|
||
priv, pub, err = GenerateRealityKeyPair()
|
||
if err != nil {
|
||
return "", "", "", "", "", fmt.Errorf("reality keys: %w", err)
|
||
}
|
||
}
|
||
if sid == "" {
|
||
sid, err = GenerateShortID()
|
||
if err != nil {
|
||
return "", "", "", "", "", fmt.Errorf("reality short id: %w", err)
|
||
}
|
||
}
|
||
return priv, pub, sid, d, names, nil
|
||
}
|