ecdsa

package module
v1.1.0 Latest Latest
Warning

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

Go to latest
Published: Jul 12, 2026 License: MIT Imports: 10 Imported by: 0

README

Generic ecdsa for golang

Golang native implementation of Elliptic Curves - including secp256k1.


Features

  • Based on the now-deprecated native crypto/elliptic package, no external dependency at all
  • Support for any Weierstrass curve y² = x³ + ax + b including secp256k1, P224, P256, P384, and P521
  • Suitable for use with tinygo without any hardware acceleration

Motivation

Golang's crypto/elliptic and crypto/ecdsa has been deprecated for all but NIST-recommended curves (P224, P256, P384, P521), and lacks implementation of y² = x³ + ax + b curves where a != -3.

For a general curve like the popular secp256k1, one would have to rely on external packages, or deprecated codepaths in case of a = 3. This package aims to provide a general implementation of short-form Weierstrass curves without introducing further dependencies or build constraints.[^1] [^1]: This package does depend on golang.org/x repositories, which are part of the Go Project but are outside the main Go tree.

Note that this package uses math/big, which does not provide any timing guarantees, therefore it is not suitable for use when timing attacks are possible.

Quoting the go standard library:

[This package ...] is not guaranteed to provide any security property

Credits

Majority of the ECDSA implementation is directly reused from the Go Standard Library. Support for a != -3 curves is based on the work of dustinxie. Packing and maintenance is done by herczegzsolt.

Documentation

Overview

Package ecdsa implements the Elliptic Curve Digital Signature Algorithm, as defined in FIPS 186-3.

This implementation derives the nonce from a ChaCha8 stream chiper seeded by the user-provided csprng.

Package randutil contains internal randomness utilities for various crypto packages.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Marshal

func Marshal(curve Curve, x, y *big.Int) []byte

Marshal converts a point on the curve into the uncompressed form specified in SEC 1, Version 2.0, Section 2.3.3. If the point is not on the curve, this function will panic. The conventional point at (0,0) is encoded as []byte{0x00} unlike in the standard library.

func MarshalCompressed

func MarshalCompressed(curve Curve, x, y *big.Int) []byte

MarshalCompressed converts a point on the curve into the compressed form specified in SEC 1, Version 2.0, Section 2.3.3. If the point is not on the curve this function will panic. The conventional point at (0,0) is encoded as []byte{0x00} unlike in the standard library.

func Sign

func Sign(csprng io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error)

Sign signs a hash (which should be the result of hashing a larger message) using the private key, priv. If the hash is longer than the bit-length of the private key's curve order, the hash will be truncated to that length. It returns the signature as a pair of integers. Most applications should use SignASN1 instead of dealing directly with r, s.

func SignASN1

func SignASN1(csprng io.Reader, priv *PrivateKey, hash []byte) ([]byte, error)

SignASN1 signs a hash (which should be the result of hashing a larger message) using the private key, priv. If the hash is longer than the bit-length of the private key's curve order, the hash will be truncated to that length. It returns the ASN.1 encoded signature. The security of the private key depends on the entropy of csprng.

func Unmarshal

func Unmarshal(curve Curve, data []byte) (x, y *big.Int)

Unmarshal converts a point, serialized by Marshal, into an x, y pair. It is an error if the point is not in uncompressed form, or is not on the curve. On error, x, y = nil, nil.

func UnmarshalCompressed

func UnmarshalCompressed(curve Curve, data []byte) (x, y *big.Int)

UnmarshalCompressed converts a point, serialized by MarshalCompressed, into an x, y pair. It is an error if the point is not in compressed form or is not on the curve. On error, x, y = nil, nil.

func Verify

func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool

Verify verifies the signature in r, s of hash using the public key, pub. Its return value records whether the signature is valid. Most applications should use VerifyASN1 instead of dealing directly with r, s.

func VerifyASN1

func VerifyASN1(pub *PublicKey, hash, sig []byte) bool

VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the public key, pub. Its return value records whether the signature is valid.

Types

type Curve

type Curve interface {
	// Params returns the parameters of the Curve y² = x³ + ax + b
	Params() *CurveParams

	// Equal returns whether this curve is identical to the given curve.
	Equal(c Curve) bool

	// IsOnCurve reports whether the given (x,y) lies on the curve.
	IsOnCurve(x, y *big.Int) bool

	// Add returns the sum of (x1,y1) and (x2,y2).
	Add(x1, y1, x2, y2 *big.Int) (x, y *big.Int)

	// Double returns 2*(x,y).
	Double(x1, y1 *big.Int) (x, y *big.Int)

	// ScalarMult returns k*(x,y) where k is an integer in big-endian form.
	ScalarMult(x1, y1 *big.Int, k []byte) (x, y *big.Int)

	// ScalarBaseMult returns k*G, where G is the base point of the group
	// and k is an integer in big-endian form.
	ScalarBaseMult(k []byte) (x, y *big.Int)

	// Polynomial returns x³ + ax + b.
	Polynomial(x *big.Int) *big.Int
}

func P224

func P224() Curve

P224 returns a Curve which implements NIST P-224 (FIPS 186-3, section D.2.2), also known as secp224r1. The CurveParams.Name of this Curve is "P-224".

Multiple invocations of this function will return the same value, so it can be used for equality checks and switch statements.

The cryptographic operations may not use constant-time algorithms.

func P256

func P256() Curve

P256 returns a Curve which implements NIST P-256 (FIPS 186-3, section D.2.3), also known as secp256r1 or prime256v1. The CurveParams.Name of this Curve is "P-256".

Multiple invocations of this function will return the same value, so it can be used for equality checks and switch statements.

The cryptographic operations may not use constant-time algorithms.

func P256k1

func P256k1() Curve

P256k1 returns a Curve which implements secp256k1 (https://www.secg.org/sec2-v2.pdf, section 2.4.1), The CurveParams.Name of this Curve is "P-256k1".

Multiple invocations of this function will return the same value, so it can be used for equality checks and switch statements.

The cryptographic operations do not use constant-time algorithms.

func P384

func P384() Curve

P384 returns a Curve which implements NIST P-384 (FIPS 186-3, section D.2.4), also known as secp384r1. The CurveParams.Name of this Curve is "P-384".

Multiple invocations of this function will return the same value, so it can be used for equality checks and switch statements.

The cryptographic operations may not use constant-time algorithms.

func P521

func P521() Curve

P521 returns a Curve which implements NIST P-521 (FIPS 186-3, section D.2.5), also known as secp521r1. The CurveParams.Name of this Curve is "P-521".

Multiple invocations of this function will return the same value, so it can be used for equality checks and switch statements.

The cryptographic operations may not use constant-time algorithms.

type CurveParams

type CurveParams struct {
	P       *big.Int // the order of the underlying field
	N       *big.Int // the order of the base point
	B       *big.Int // the constant of the curve equation
	Gx, Gy  *big.Int // (x,y) of the base point
	A       *big.Int // the linear coefficient of the curve equation
	BitSize int      // the size of the underlying field
	Name    string   // the canonical name of the curve
}

CurveParams contains the parameters of an Curve y² = x³ + ax + b,

type GenericCurve

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

GenericCurve provides a non-constant time implementation of Curve.

func (*GenericCurve) Add

func (curve *GenericCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int)

Add adds 2 points

func (*GenericCurve) Double

func (curve *GenericCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int)

Double doubles the point

func (*GenericCurve) Equal

func (curve *GenericCurve) Equal(x Curve) bool

func (*GenericCurve) IsOnCurve

func (curve *GenericCurve) IsOnCurve(x, y *big.Int) bool

IsOnCurve returns whether the point (x, y) lies on the curve or not The conventional point (0, 0) returns true, unlike in the standard library.

func (*GenericCurve) Params

func (curve *GenericCurve) Params() *CurveParams

func (*GenericCurve) Polynomial

func (curve *GenericCurve) Polynomial(x *big.Int) *big.Int

Polynomial returns x³ + ax + b.

func (*GenericCurve) ScalarBaseMult

func (curve *GenericCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int)

ScalarBaseMult computes scalar multiplication of the base point

func (*GenericCurve) ScalarMult

func (curve *GenericCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int)

ScalarMult computes scalar multiplication of a given point

type PrivateKey

type PrivateKey struct {
	PublicKey

	// D is the private scalar value.
	//
	// Modifying the raw value can produce invalid keys.
	D *big.Int
}

PrivateKey represents an ECDSA private key.

func GenerateKey

func GenerateKey(c Curve, rand io.Reader) (*PrivateKey, error)

func ParseDERPrivateKey added in v1.1.0

func ParseDERPrivateKey(der []byte) (*PrivateKey, error)

ParseDERPrivateKey parses an EC private key in SEC 1, ASN.1 DER form.

The "parameters" field, which carries the named curve, must be present; this implementation does not support curve parameters supplied out of band (as can happen when an ECPrivateKey is embedded in a PKCS#8 structure). The "publicKey" field is optional: if absent, the public key is recomputed from the private scalar.

func ParsePEMPrivateKey added in v1.1.0

func ParsePEMPrivateKey(data []byte) (*PrivateKey, error)

ParsePEMPrivateKey decodes a PEM-encoded SEC 1 "EC PRIVATE KEY" block (RFC 5915).

Data may contain other PEM blocks before the private key, any such blocks are skipped. (For ex: the "EC PARAMETERS" block is ignored)

func (*PrivateKey) Equal

func (priv *PrivateKey) Equal(x *PrivateKey) bool

Equal reports whether priv and x have the same value.

Two keys are only considered to have the same value if they have the same Curve value.

func (*PrivateKey) MarshalDER added in v1.1.0

func (priv *PrivateKey) MarshalDER() ([]byte, error)

MarshalDER encodes priv into a SEC 1, ASN.1 DER "ECPrivateKey" structure (RFC 5915).

func (*PrivateKey) MarshalPEM added in v1.1.0

func (priv *PrivateKey) MarshalPEM() ([]byte, error)

MarshalPEM encodes priv as a PEM-encoded SEC 1 "EC PRIVATE KEY" block (RFC 5915). The result is in the format matching `openssl ecparam -genkey`

type PublicKey

type PublicKey struct {
	Curve Curve

	// X, Y are the coordinates of the public key point.
	//
	// Modifying the raw coordinates can produce invalid keys
	X, Y *big.Int
}

PublicKey represents an ECDSA public key.

func ParseDERPublicKey added in v1.1.0

func ParseDERPublicKey(der []byte) (*PublicKey, error)

ParseDERPublicKey parses an EC public key in PKIX, ASN.1 DER form "SubjectPublicKeyInfo"

func ParsePEMPublicKey added in v1.1.0

func ParsePEMPublicKey(data []byte) (*PublicKey, error)

ParsePEMPublicKey decodes a PEM-encoded PKIX "PUBLIC KEY" block (RFC 5480, "SubjectPublicKeyInfo")

Any PEM blocks preceding the public key block are skipped.

func (*PublicKey) Equal

func (pub *PublicKey) Equal(x *PublicKey) bool

Equal reports whether pub and x have the same value.

Two keys are only considered to have the same value if they have the same Curve value.

func (*PublicKey) MarshalDER added in v1.1.0

func (pub *PublicKey) MarshalDER() ([]byte, error)

MarshalDER encodes pub into a PKIX, ASN.1 DER "SubjectPublicKeyInfo" structure (RFC 5480).

func (*PublicKey) MarshalPEM added in v1.1.0

func (pub *PublicKey) MarshalPEM() ([]byte, error)

MarshalPEM encodes pub as a PEM-encoded PKIX "PUBLIC KEY" block (RFC 5480, "SubjectPublicKeyInfo")

Encoded format is compatible with openssl.

Jump to

Keyboard shortcuts

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