package  ecdhimport  (	"crypto/internal/edwards25519/field" 	"crypto/internal/randutil" 	"errors" 	"io" )var  (	x25519PublicKeySize     = 32 	x25519PrivateKeySize    = 32 	x25519SharedSecretSize  = 32 )func  X25519 Curve  { return  x25519  }var  x25519  = &x25519Curve {}type  x25519Curve  struct {}func  (c  *x25519Curve ) String string  {	return  "X25519" }func  (c  *x25519Curve ) GenerateKey rand  io .Reader ) (*PrivateKey , error ) {	key  := make ([]byte , x25519PrivateKeySize )	randutil .MaybeReadByte (rand )	if  _ , err  := io .ReadFull (rand , key ); err  != nil  {		return  nil , err 	}	return  c .NewPrivateKey (key )}func  (c  *x25519Curve ) NewPrivateKey key  []byte ) (*PrivateKey , error ) {	if  len (key ) != x25519PrivateKeySize  {		return  nil , errors .New ("crypto/ecdh: invalid private key size" )	}	return  &PrivateKey {		curve :      c ,		privateKey : append ([]byte {}, key ...),	}, nil }func  (c  *x25519Curve ) privateKeyToPublicKey key  *PrivateKey ) *PublicKey  {	if  key .curve  != c  {		panic ("crypto/ecdh: internal error: converting the wrong key type" )	}	k  := &PublicKey {		curve :     key .curve ,		publicKey : make ([]byte , x25519PublicKeySize ),	}	x25519Basepoint  := [32 ]byte {9 }	x25519ScalarMult (k .publicKey , key .privateKey , x25519Basepoint [:])	return  k }func  (c  *x25519Curve ) NewPublicKey key  []byte ) (*PublicKey , error ) {	if  len (key ) != x25519PublicKeySize  {		return  nil , errors .New ("crypto/ecdh: invalid public key" )	}	return  &PublicKey {		curve :     c ,		publicKey : append ([]byte {}, key ...),	}, nil }func  (c  *x25519Curve ) ecdh local  *PrivateKey , remote  *PublicKey ) ([]byte , error ) {	out  := make ([]byte , x25519SharedSecretSize )	x25519ScalarMult (out , local .privateKey , remote .publicKey )	if  isZero (out ) {		return  nil , errors .New ("crypto/ecdh: bad X25519 remote ECDH input: low order point" )	}	return  out , nil }func  x25519ScalarMult dst , scalar , point  []byte ) {	var  e  [32 ]byte 	copy (e [:], scalar [:])	e [0 ] &= 248 	e [31 ] &= 127 	e [31 ] |= 64 	var  x1 , x2 , z2 , x3 , z3 , tmp0 , tmp1  field .Element 	x1 .SetBytes (point [:])	x2 .One ()	x3 .Set (&x1 )	z3 .One ()	swap  := 0 	for  pos  := 254 ; pos  >= 0 ; pos -- {		b  := e [pos /8 ] >> uint (pos &7 )		b  &= 1 		swap  ^= int (b )		x2 .Swap (&x3 , swap )		z2 .Swap (&z3 , swap )		swap  = int (b )		tmp0 .Subtract (&x3 , &z3 )		tmp1 .Subtract (&x2 , &z2 )		x2 .Add (&x2 , &z2 )		z2 .Add (&x3 , &z3 )		z3 .Multiply (&tmp0 , &x2 )		z2 .Multiply (&z2 , &tmp1 )		tmp0 .Square (&tmp1 )		tmp1 .Square (&x2 )		x3 .Add (&z3 , &z2 )		z2 .Subtract (&z3 , &z2 )		x2 .Multiply (&tmp1 , &tmp0 )		tmp1 .Subtract (&tmp1 , &tmp0 )		z2 .Square (&z2 )		z3 .Mult32 (&tmp1 , 121666 )		x3 .Square (&x3 )		tmp0 .Add (&tmp0 , &z3 )		z3 .Multiply (&x1 , &z2 )		z2 .Multiply (&tmp1 , &tmp0 )	}	x2 .Swap (&x3 , swap )	z2 .Swap (&z3 , swap )	z2 .Invert (&z2 )	x2 .Multiply (&x2 , &z2 )	copy (dst [:], x2 .Bytes ())} The pages are generated with Golds v0.7.6 . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .