diff --git a/main/commands/all/commands.go b/main/commands/all/commands.go index 9f8270f9..fba3a4b8 100644 --- a/main/commands/all/commands.go +++ b/main/commands/all/commands.go @@ -18,5 +18,6 @@ func init() { cmdWG, cmdMLDSA65, cmdMLKEM768, + cmdVLESSEnc, ) } diff --git a/main/commands/all/curve25519.go b/main/commands/all/curve25519.go index 16ca8c7c..6729439a 100644 --- a/main/commands/all/curve25519.go +++ b/main/commands/all/curve25519.go @@ -25,6 +25,21 @@ func Curve25519Genkey(StdEncoding bool, input_base64 string) { return } } + privateKey, password, hash32, err := genCurve25519(privateKey) + if err != nil { + fmt.Println(err) + return + } + fmt.Printf("PrivateKey: %v\nPassword: %v\nHash32: %v\n", + encoding.EncodeToString(privateKey), + encoding.EncodeToString(password), + encoding.EncodeToString(hash32[:])) +} + +func genCurve25519(inputPrivateKey []byte) (privateKey []byte, password []byte, hash32 [32]byte, returnErr error) { + if len(inputPrivateKey) > 0 { + privateKey = inputPrivateKey + } if privateKey == nil { privateKey = make([]byte, 32) rand.Read(privateKey) @@ -39,13 +54,10 @@ func Curve25519Genkey(StdEncoding bool, input_base64 string) { key, err := ecdh.X25519().NewPrivateKey(privateKey) if err != nil { - fmt.Println(err.Error()) + returnErr = err return } - password := key.PublicKey().Bytes() - hash32 := blake3.Sum256(password) - fmt.Printf("PrivateKey: %v\nPassword: %v\nHash32: %v", - encoding.EncodeToString(privateKey), - encoding.EncodeToString(password), - encoding.EncodeToString(hash32[:])) + password = key.PublicKey().Bytes() + hash32 = blake3.Sum256(password) + return } diff --git a/main/commands/all/mldsa65.go b/main/commands/all/mldsa65.go index 495fb088..2c90d975 100644 --- a/main/commands/all/mldsa65.go +++ b/main/commands/all/mldsa65.go @@ -40,7 +40,7 @@ func executeMLDSA65(cmd *base.Command, args []string) { rand.Read(seed[:]) } pub, _ := mldsa65.NewKeyFromSeed(&seed) - fmt.Printf("Seed: %v\nVerify: %v", + fmt.Printf("Seed: %v\nVerify: %v\n", base64.RawURLEncoding.EncodeToString(seed[:]), base64.RawURLEncoding.EncodeToString(pub.Bytes())) } diff --git a/main/commands/all/mlkem768.go b/main/commands/all/mlkem768.go index 0f6e707b..05c62c14 100644 --- a/main/commands/all/mlkem768.go +++ b/main/commands/all/mlkem768.go @@ -12,9 +12,9 @@ import ( var cmdMLKEM768 = &base.Command{ UsageLine: `{{.Exec}} mlkem768 [-i "seed (base64.RawURLEncoding)"]`, - Short: `Generate key pair for ML-KEM-768 post-quantum key exchange (VLESS)`, + Short: `Generate key pair for ML-KEM-768 post-quantum key exchange (VLESS Encryption)`, Long: ` -Generate key pair for ML-KEM-768 post-quantum key exchange (VLESS). +Generate key pair for ML-KEM-768 post-quantum key exchange (VLESS Encryption). Random: {{.Exec}} mlkem768 @@ -40,11 +40,21 @@ func executeMLKEM768(cmd *base.Command, args []string) { } else { rand.Read(seed[:]) } - key, _ := mlkem.NewDecapsulationKey768(seed[:]) - client := key.EncapsulationKey().Bytes() - hash32 := blake3.Sum256(client) - fmt.Printf("Seed: %v\nClient: %v\nHash32: %v", + seed, client, hash32 := genMLKEM768(&seed) + fmt.Printf("Seed: %v\nClient: %v\nHash32: %v\n", base64.RawURLEncoding.EncodeToString(seed[:]), base64.RawURLEncoding.EncodeToString(client), base64.RawURLEncoding.EncodeToString(hash32[:])) } + +func genMLKEM768(inputSeed *[64]byte) (seed [64]byte, client []byte, hash32 [32]byte) { + if inputSeed == nil { + rand.Read(seed[:]) + } else { + seed = *inputSeed + } + key, _ := mlkem.NewDecapsulationKey768(seed[:]) + client = key.EncapsulationKey().Bytes() + hash32 = blake3.Sum256(client) + return +} diff --git a/main/commands/all/vlessenc.go b/main/commands/all/vlessenc.go new file mode 100644 index 00000000..fae416f2 --- /dev/null +++ b/main/commands/all/vlessenc.go @@ -0,0 +1,41 @@ +package all + +import ( + "encoding/base64" + "fmt" + "strings" + + "github.com/xtls/xray-core/main/commands/base" +) + +var cmdVLESSEnc = &base.Command{ + UsageLine: `{{.Exec}} vlessenc`, + Short: `Generate decryption/encryption json pair (VLESS Encryption)`, + Long: ` +Generate decryption/encryption json pair (VLESS Encryption). +`, +} + +func init() { + cmdVLESSEnc.Run = executeVLESSEnc // break init loop +} + +func executeVLESSEnc(cmd *base.Command, args []string) { + privateKey, password, _, _ := genCurve25519(nil) + serverKey := base64.RawURLEncoding.EncodeToString(privateKey) + clientKey := base64.RawURLEncoding.EncodeToString(password) + decryption := generateDotConfig("mlkem768x25519plus", "native", "600s", serverKey) + encryption := generateDotConfig("mlkem768x25519plus", "native", "0rtt", clientKey) + seed, client, _ := genMLKEM768(nil) + serverKeyPQ := base64.RawURLEncoding.EncodeToString(seed[:]) + clientKeyPQ := base64.RawURLEncoding.EncodeToString(client) + decryptionPQ := generateDotConfig("mlkem768x25519plus", "native", "600s", serverKeyPQ) + encryptionPQ := generateDotConfig("mlkem768x25519plus", "native", "0rtt", clientKeyPQ) + fmt.Printf("Choose one Authentication to use, do not mix them. Ephemeral key exchange is Post-Quantum safe anyway.\n\n") + fmt.Printf("Authentication: X25519, not Post-Quantum\n\"decryption\": \"%v\"\n\"encryption\": \"%v\"\n\n", decryption, encryption) + fmt.Printf("Authentication: ML-KEM-768, Post-Quantum\n\"decryption\": \"%v\"\n\"encryption\": \"%v\"\n", decryptionPQ, encryptionPQ) +} + +func generateDotConfig(fields ...string) string { + return strings.Join(fields, ".") +} diff --git a/main/commands/all/x25519.go b/main/commands/all/x25519.go index 7ef23f03..784a1790 100644 --- a/main/commands/all/x25519.go +++ b/main/commands/all/x25519.go @@ -6,9 +6,9 @@ import ( var cmdX25519 = &base.Command{ UsageLine: `{{.Exec}} x25519 [-i "private key (base64.RawURLEncoding)"] [--std-encoding]`, - Short: `Generate key pair for X25519 key exchange (VLESS, REALITY)`, + Short: `Generate key pair for X25519 key exchange (REALITY, VLESS Encryption)`, Long: ` -Generate key pair for X25519 key exchange (VLESS, REALITY). +Generate key pair for X25519 key exchange (REALITY, VLESS Encryption). Random: {{.Exec}} x25519