github.com/xtls/xray-core@v1.8.12-0.20240518155711-3168d27b0bdb/main/commands/all/curve25519.go (about)

     1  package all
     2  
     3  import (
     4  	"crypto/rand"
     5  	"encoding/base64"
     6  	"fmt"
     7  
     8  	"golang.org/x/crypto/curve25519"
     9  )
    10  
    11  func Curve25519Genkey(StdEncoding bool, input_base64 string) {
    12  	var output string
    13  	var err error
    14  	var privateKey, publicKey []byte
    15  	var encoding *base64.Encoding
    16  	if *input_stdEncoding || StdEncoding {
    17  		encoding = base64.StdEncoding
    18  	} else {
    19  		encoding = base64.RawURLEncoding
    20  	}
    21  
    22  	if len(input_base64) > 0 {
    23  		privateKey, err = encoding.DecodeString(input_base64)
    24  		if err != nil {
    25  			output = err.Error()
    26  			goto out
    27  		}
    28  		if len(privateKey) != curve25519.ScalarSize {
    29  			output = "Invalid length of private key."
    30  			goto out
    31  		}
    32  	}
    33  
    34  	if privateKey == nil {
    35  		privateKey = make([]byte, curve25519.ScalarSize)
    36  		if _, err = rand.Read(privateKey); err != nil {
    37  			output = err.Error()
    38  			goto out
    39  		}
    40  	}
    41  
    42  	// Modify random bytes using algorithm described at:
    43  	// https://cr.yp.to/ecdh.html.
    44  	privateKey[0] &= 248
    45  	privateKey[31] &= 127 | 64
    46  
    47  	if publicKey, err = curve25519.X25519(privateKey, curve25519.Basepoint); err != nil {
    48  		output = err.Error()
    49  		goto out
    50  	}
    51  
    52  	output = fmt.Sprintf("Private key: %v\nPublic key: %v",
    53  		encoding.EncodeToString(privateKey),
    54  		encoding.EncodeToString(publicKey))
    55  out:
    56  	fmt.Println(output)
    57  }