x25519.go 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package all
  2. import (
  3. "crypto/rand"
  4. "encoding/base64"
  5. "fmt"
  6. "io"
  7. "github.com/xtls/xray-core/main/commands/base"
  8. "golang.org/x/crypto/curve25519"
  9. )
  10. var cmdX25519 = &base.Command{
  11. UsageLine: `{{.Exec}} x25519 [-i "private key (base64.RawURLEncoding)"]`,
  12. Short: `Generate key pair for x25519 key exchange`,
  13. Long: `
  14. Generate key pair for x25519 key exchange.
  15. Random: {{.Exec}} x25519
  16. From private key: {{.Exec}} x25519 -i "private key (base64.RawURLEncoding)"
  17. `,
  18. }
  19. func init() {
  20. cmdX25519.Run = executeX25519 // break init loop
  21. }
  22. var input_base64 = cmdX25519.Flag.String("i", "", "")
  23. func executeX25519(cmd *base.Command, args []string) {
  24. var output string
  25. var err error
  26. var privateKey []byte
  27. var publicKey []byte
  28. if len(*input_base64) > 0 {
  29. privateKey, err = base64.RawURLEncoding.DecodeString(*input_base64)
  30. if err != nil {
  31. output = err.Error()
  32. goto out
  33. }
  34. if len(privateKey) != curve25519.ScalarSize {
  35. output = "Invalid length of private key."
  36. goto out
  37. }
  38. }
  39. if privateKey == nil {
  40. privateKey = make([]byte, curve25519.ScalarSize)
  41. if _, err = io.ReadFull(rand.Reader, privateKey); err != nil {
  42. output = err.Error()
  43. goto out
  44. }
  45. }
  46. if publicKey, err = curve25519.X25519(privateKey, curve25519.Basepoint); err != nil {
  47. output = err.Error()
  48. goto out
  49. }
  50. output = fmt.Sprintf("Private key: %v\nPublic key: %v",
  51. base64.RawURLEncoding.EncodeToString(privateKey),
  52. base64.RawURLEncoding.EncodeToString(publicKey))
  53. out:
  54. fmt.Println(output)
  55. }