curve

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 14, 2026 License: AGPL-3.0 Imports: 7 Imported by: 0

Documentation

Overview

Package curve implements the Curve25519 (Djb) key types used by the Signal protocol: X25519 key agreement and the 33-byte serialized public-key wire format.

It is a pure-Go port of rust/core/src/curve.rs. Serialization is wire-compatible with upstream libsignal: a public key is one type byte (0x05 for the Djb key type) followed by the 32-byte Montgomery-u coordinate; a private key is the 32-byte clamped scalar.

XEdDSA signing and verification (calculate_signature / verify_signature) are implemented separately in xeddsa.go.

Index

Constants

View Source
const (
	// PublicKeyLength is the length of the raw Montgomery-u public key.
	PublicKeyLength = 32
	// PrivateKeyLength is the length of the raw (clamped) private scalar.
	PrivateKeyLength = 32
	// AgreementLength is the length of an X25519 shared secret.
	AgreementLength = 32
	// SerializedPublicKeyLength is the length of the wire form of a public
	// key: one type byte followed by the raw public key.
	SerializedPublicKeyLength = 1 + PublicKeyLength
)
View Source
const SignatureLength = 64

SignatureLength is the length of an XEdDSA signature in bytes.

Variables

This section is empty.

Functions

This section is empty.

Types

type BadKeyLengthError

type BadKeyLengthError struct {
	KeyType KeyType
	Length  int
}

BadKeyLengthError is returned when a serialized key has the wrong length for its key type.

func (BadKeyLengthError) Error

func (e BadKeyLengthError) Error() string

type BadKeyTypeError

type BadKeyTypeError struct {
	Type byte
}

BadKeyTypeError is returned when a serialized key carries an unrecognized type byte.

func (BadKeyTypeError) Error

func (e BadKeyTypeError) Error() string

type ErrInvalidKeyAgreement

type ErrInvalidKeyAgreement struct{}

ErrInvalidKeyAgreement is returned when a key agreement produces the all-zero shared secret, which indicates a low-order or otherwise malicious peer public key.

func (ErrInvalidKeyAgreement) Error

type ErrNoKeyTypeIdentifier

type ErrNoKeyTypeIdentifier struct{}

ErrNoKeyTypeIdentifier is returned when deserializing a public key from an empty input that carries no type byte.

func (ErrNoKeyTypeIdentifier) Error

type KeyPair

type KeyPair struct {
	PublicKey  PublicKey
	PrivateKey PrivateKey
}

KeyPair is a Curve25519 public/private key pair.

func GenerateKeyPair

func GenerateKeyPair(rng io.Reader) (KeyPair, error)

GenerateKeyPair generates a new key pair, drawing 32 bytes of private-key entropy from rng. The scalar is clamped per X25519 and the public key is derived from it. rng must be a cryptographically secure source; passing a deterministic reader yields a deterministic key pair, which is used in tests.

func KeyPairFromPrivateKey

func KeyPairFromPrivateKey(privateKey PrivateKey) (KeyPair, error)

KeyPairFromPrivateKey derives the public key from privateKey and returns the resulting key pair.

func KeyPairFromPublicAndPrivate

func KeyPairFromPublicAndPrivate(publicKey, privateKey []byte) (KeyPair, error)

KeyPairFromPublicAndPrivate deserializes a key pair from the wire form of a public key and the raw bytes of a private key.

func NewKeyPair

func NewKeyPair(publicKey PublicKey, privateKey PrivateKey) KeyPair

NewKeyPair pairs an existing public and private key.

func (KeyPair) CalculateAgreement

func (kp KeyPair) CalculateAgreement(theirKey PublicKey) ([]byte, error)

CalculateAgreement performs the X25519 agreement between this key pair's private key and theirKey.

type KeyType

type KeyType uint8

KeyType identifies the elliptic curve a key belongs to. Only the Djb (Curve25519) type is defined.

const (
	// KeyTypeDjb is the Curve25519 key type; its serialized type byte is 0x05.
	KeyTypeDjb KeyType = 0x05
)

func (KeyType) String

func (k KeyType) String() string

String implements fmt.Stringer.

type PrivateKey

type PrivateKey struct {
	// contains filtered or unexported fields
}

PrivateKey is a Curve25519 private key (a clamped X25519 scalar).

func DeserializePrivateKey

func DeserializePrivateKey(value []byte) (PrivateKey, error)

DeserializePrivateKey parses a raw 32-byte private key. The scalar is clamped per X25519; clamping is not strictly necessary but is kept for backward compatibility, matching upstream.

func (PrivateKey) CalculateAgreement

func (p PrivateKey) CalculateAgreement(theirKey PublicKey) ([]byte, error)

CalculateAgreement performs an X25519 Diffie-Hellman with the peer's public key and returns the 32-byte shared secret. An all-zero shared secret (from a low-order peer key) is rejected with ErrInvalidKeyAgreement.

func (PrivateKey) CalculateSignature

func (p PrivateKey) CalculateSignature(rng io.Reader, message ...[]byte) ([]byte, error)

CalculateSignature produces an XEdDSA signature over message using this private key, drawing 64 bytes of randomness from rng (use crypto/rand.Reader in production; a deterministic reader yields a deterministic signature for tests). message may be supplied in multiple pieces, which are concatenated; passing no pieces signs the empty message.

The construction follows the XEdDSA spec (https://signal.org/docs/specifications/xeddsa/#curve25519) exactly as implemented in rust/core/src/curve/curve25519.rs: the Ed25519 public key's sign bit is carried in the otherwise-zero most significant bit of the signature (for compatibility with libsignal-protocol-java) rather than forced to 0 as in the original paper.

func (PrivateKey) Format

func (p PrivateKey) Format(f fmt.State, _ rune)

Format implements fmt.Formatter, redacting the secret key material under every verb so the scalar never leaks into logs.

func (PrivateKey) KeyType

func (p PrivateKey) KeyType() KeyType

KeyType reports the key type of the private key.

func (PrivateKey) PublicKey

func (p PrivateKey) PublicKey() (PublicKey, error)

PublicKey derives the public key corresponding to this private key.

func (PrivateKey) Serialize

func (p PrivateKey) Serialize() []byte

Serialize returns the raw 32-byte (clamped) private key.

func (PrivateKey) String

func (p PrivateKey) String() string

String implements fmt.Stringer, redacting the secret key material.

type PublicKey

type PublicKey struct {
	// contains filtered or unexported fields
}

PublicKey is a Curve25519 public key.

func DeserializePublicKey

func DeserializePublicKey(value []byte) (PublicKey, error)

DeserializePublicKey parses the wire form of a public key: a one-byte key type followed by the raw key. Trailing data after a Djb key is permitted for backward compatibility (matching upstream), but a key body shorter than 32 bytes is rejected.

func NewPublicKey

func NewPublicKey(bytes []byte) (PublicKey, error)

NewPublicKey constructs a Djb public key from its raw 32-byte Montgomery-u coordinate, rejecting inputs of the wrong length with a BadKeyLengthError.

func (PublicKey) Equal

func (p PublicKey) Equal(other PublicKey) bool

Equal reports whether two public keys are equal, comparing the key body in constant time once the key types match.

func (PublicKey) IsCanonical

func (p PublicKey) IsCanonical() bool

IsCanonical reports whether the public key is both torsion-free and in range, i.e. a well-formed prime-order Curve25519 point. Mirrors PublicKey::is_canonical in rust/core/src/curve.rs.

func (PublicKey) IsTorsionFree

func (p PublicKey) IsTorsionFree() bool

IsTorsionFree reports whether the public key, interpreted as a Montgomery point mapped to Edwards, lies in the prime-order subgroup (i.e. has no small-order torsion component). Mirrors PublicKey::is_torsion_free in rust/core/src/curve.rs. A point that does not map to a valid Edwards point is treated as not torsion-free.

func (PublicKey) KeyType

func (p PublicKey) KeyType() KeyType

KeyType reports the key type of the public key.

func (PublicKey) PublicKeyBytes

func (p PublicKey) PublicKeyBytes() []byte

PublicKeyBytes returns a copy of the raw 32-byte public key, without the type byte.

func (PublicKey) ScalarIsInRange

func (p PublicKey) ScalarIsInRange() bool

ScalarIsInRange reports whether the public key's 32-byte little-endian value is below 2^255 - 19. It rejects keys with the high bit set, and keys whose value lies in [2^255-19, 2^255-1] (the non-canonical "above the prime modulus" range). Mirrors PublicKey::scalar_is_in_range in rust/core/src/curve.rs, byte-for-byte.

func (PublicKey) Serialize

func (p PublicKey) Serialize() []byte

Serialize returns the wire form of the public key: the type byte followed by the raw public key.

func (PublicKey) VerifySignature

func (p PublicKey) VerifySignature(signature []byte, message ...[]byte) bool

VerifySignature reports whether signature is a valid XEdDSA signature by this public key over message (supplied in one or more pieces, concatenated). It never panics and returns false for any malformed input.

Mirrors rust/core/src/curve/curve25519.rs verify_signature.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL