package ecdh
import (
)
var (
x25519PublicKeySize = 32
x25519PrivateKeySize = 32
x25519SharedSecretSize = 32
)
func () Curve { return x25519 }
var x25519 = &x25519Curve{}
type x25519Curve struct{}
func ( *x25519Curve) () string {
return "X25519"
}
func ( *x25519Curve) ( io.Reader) (*PrivateKey, error) {
if fips140only.Enabled {
return nil, errors.New("crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode")
}
:= make([]byte, x25519PrivateKeySize)
randutil.MaybeReadByte()
if , := io.ReadFull(, ); != nil {
return nil,
}
return .NewPrivateKey()
}
func ( *x25519Curve) ( []byte) (*PrivateKey, error) {
if fips140only.Enabled {
return nil, errors.New("crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode")
}
if len() != x25519PrivateKeySize {
return nil, errors.New("crypto/ecdh: invalid private key size")
}
:= make([]byte, x25519PublicKeySize)
:= [32]byte{9}
x25519ScalarMult(, , [:])
return &PrivateKey{
curve: ,
privateKey: bytes.Clone(),
publicKey: &PublicKey{curve: , publicKey: },
}, nil
}
func ( *x25519Curve) ( []byte) (*PublicKey, error) {
if fips140only.Enabled {
return nil, errors.New("crypto/ecdh: use of X25519 is not allowed in FIPS 140-only mode")
}
if len() != x25519PublicKeySize {
return nil, errors.New("crypto/ecdh: invalid public key")
}
return &PublicKey{
curve: ,
publicKey: bytes.Clone(),
}, nil
}
func ( *x25519Curve) ( *PrivateKey, *PublicKey) ([]byte, error) {
:= make([]byte, x25519SharedSecretSize)
x25519ScalarMult(, .privateKey, .publicKey)
if isZero() {
return nil, errors.New("crypto/ecdh: bad X25519 remote ECDH input: low order point")
}
return , nil
}
func (, , []byte) {
var [32]byte
copy([:], [:])
[0] &= 248
[31] &= 127
[31] |= 64
var , , , , , , field.Element
.SetBytes([:])
.One()
.Set(&)
.One()
:= 0
for := 254; >= 0; -- {
:= [/8] >> uint(&7)
&= 1
^= int()
.Swap(&, )
.Swap(&, )
= int()
.Subtract(&, &)
.Subtract(&, &)
.Add(&, &)
.Add(&, &)
.Multiply(&, &)
.Multiply(&, &)
.Square(&)
.Square(&)
.Add(&, &)
.Subtract(&, &)
.Multiply(&, &)
.Subtract(&, &)
.Square(&)
.Mult32(&, 121666)
.Square(&)
.Add(&, &)
.Multiply(&, &)
.Multiply(&, &)
}
.Swap(&, )
.Swap(&, )
.Invert(&)
.Multiply(&, &)
copy([:], .Bytes())
}
func ( []byte) bool {
var byte
for , := range {
|=
}
return == 0
}