btcec

package
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Aug 2, 2023 License: ISC Imports: 2 Imported by: 0

README

btcec

Build Status ISC License GoDoc

Package btcec implements elliptic curve cryptography needed for working with Bitcoin (secp256k1 only for now). It is designed so that it may be used with the standard crypto/ecdsa packages provided with go. A comprehensive suite of test is provided to ensure proper functionality. Package btcec was originally based on work from ThePiachu which is licensed under the same terms as Go, but it has signficantly diverged since then. The btcsuite developers original is licensed under the liberal ISC license.

Although this package was primarily written for btcd, it has intentionally been designed so it can be used as a standalone package for any projects needing to use secp256k1 elliptic curve cryptography.

Installation and Updating

$ go install -u -v github.com/btcsuite/btcd/btcec/v2

Examples

  • Sign Message
    Demonstrates signing a message with a secp256k1 private key that is first parsed form raw bytes and serializing the generated signature.

  • Verify Signature
    Demonstrates verifying a secp256k1 signature against a public key that is first parsed from raw bytes. The signature is also parsed from raw bytes.

License

Package btcec is licensed under the copyfree ISC License except for btcec.go and btcec_test.go which is under the same license as Go.

Documentation

Overview

Package btcec implements support for the elliptic curves needed for bitcoin.

Bitcoin uses elliptic curve cryptography using koblitz curves (specifically secp256k1) for cryptographic functions. See http://www.secg.org/collateral/sec2_final.pdf for details on the standard.

This package provides the data structures and functions implementing the crypto/elliptic Curve interface in order to permit using these curves with the standard crypto/ecdsa package provided with go. Helper functionality is provided to parse signatures and public keys from standard formats. It was designed for use with btcd, but should be general enough for other uses of elliptic curve crypto. It was originally based on some initial work by ThePiachu, but has significantly diverged since then.

Index

Constants

View Source
const PrivKeyBytesLen = 32

PrivKeyBytesLen defines the length in bytes of a serialized private key.

View Source
const (
	PubKeyBytesLenCompressed = 33
)

These constants define the lengths of serialized public keys.

Variables

This section is empty.

Functions

func AddNonConst

func AddNonConst(p1, p2, result *JacobianPoint)

AddNonConst adds the passed Jacobian points together and stores the result in the provided result param in *non-constant* time.

func DecompressY

func DecompressY(x *FieldVal, odd bool, resultY *FieldVal) bool

DecompressY attempts to calculate the Y coordinate for the given X coordinate such that the result pair is a point on the secp256k1 curve. It adjusts Y based on the desired oddness and returns whether or not it was successful since not all X coordinates are valid.

The magnitude of the provided X coordinate field val must be a max of 8 for a correct result. The resulting Y field val will have a max magnitude of 2.

func DoubleNonConst

func DoubleNonConst(p, result *JacobianPoint)

DoubleNonConst doubles the passed Jacobian point and stores the result in the provided result parameter in *non-constant* time.

NOTE: The point must be normalized for this function to return the correct result. The resulting point will be normalized.

func GenerateSharedSecret

func GenerateSharedSecret(privkey *PrivateKey, pubkey *PublicKey) []byte

GenerateSharedSecret generates a shared secret based on a private key and a public key using Diffie-Hellman key exchange (ECDH) (RFC 4753). RFC5903 Section 9 states we should only return x.

func GeneratorJacobian

func GeneratorJacobian(jacobian *JacobianPoint)

GeneratorJacobian sets the passed JacobianPoint to the Generator Point.

func IsCompressedPubKey

func IsCompressedPubKey(pubKey []byte) bool

IsCompressedPubKey returns true the the passed serialized public key has been encoded in compressed format, and false otherwise.

func JacobianToByteSlice

func JacobianToByteSlice(point JacobianPoint) []byte

JacobianToByteSlice converts the passed JacobianPoint to a Pubkey and serializes that to a byte slice. If the JacobianPoint is the infinity point, a zero slice is returned.

func PrivKeyFromBytes

func PrivKeyFromBytes(pk []byte) (*PrivateKey, *PublicKey)

PrivKeyFromBytes returns a private and public key for `curve' based on the private key passed as an argument as a byte slice.

func ScalarBaseMultNonConst

func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint)

ScalarBaseMultNonConst multiplies k*G where G is the base point of the group and k is a big endian integer. The result is stored in Jacobian coordinates (x1, y1, z1).

NOTE: The resulting point will be normalized.

func ScalarMultNonConst

func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint)

ScalarMultNonConst multiplies k*P where k is a big endian integer modulo the curve order and P is a point in Jacobian projective coordinates and stores the result in the provided Jacobian point.

NOTE: The point must be normalized for this function to return the correct result. The resulting point will be normalized.

Types

type CurveParams

type CurveParams = secp.CurveParams

CurveParams contains the parameters for the secp256k1 curve.

func Params

func Params() *CurveParams

Params returns the secp256k1 curve parameters for convenience.

type Error

type Error = secp.Error

Error identifies an error related to public key cryptography using a sec256k1 curve. It has full support for errors.Is and errors.As, so the caller can ascertain the specific reason for the error by checking the underlying error.

type ErrorKind

type ErrorKind = secp.ErrorKind

ErrorKind identifies a kind of error. It has full support for errors.Is and errors.As, so the caller can directly check against an error kind when determining the reason for an error.

type FieldVal

type FieldVal = secp.FieldVal

FieldVal implements optimized fixed-precision arithmetic over the secp256k1 finite field. This means all arithmetic is performed modulo '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'.

WARNING: Since it is so important for the field arithmetic to be extremely fast for high performance crypto, this type does not perform any validation of documented preconditions where it ordinarily would. As a result, it is IMPERATIVE for callers to understand some key concepts that are described below and ensure the methods are called with the necessary preconditions that each method is documented with. For example, some methods only give the correct result if the field value is normalized and others require the field values involved to have a maximum magnitude and THERE ARE NO EXPLICIT CHECKS TO ENSURE THOSE PRECONDITIONS ARE SATISFIED. This does, unfortunately, make the type more difficult to use correctly and while I typically prefer to ensure all state and input is valid for most code, this is a bit of an exception because those extra checks really add up in what ends up being critical hot paths.

The first key concept when working with this type is normalization. In order to avoid the need to propagate a ton of carries, the internal representation provides additional overflow bits for each word of the overall 256-bit value. This means that there are multiple internal representations for the same value and, as a result, any methods that rely on comparison of the value, such as equality and oddness determination, require the caller to provide a normalized value.

The second key concept when working with this type is magnitude. As previously mentioned, the internal representation provides additional overflow bits which means that the more math operations that are performed on the field value between normalizations, the more those overflow bits accumulate. The magnitude is effectively that maximum possible number of those overflow bits that could possibly be required as a result of a given operation. Since there are only a limited number of overflow bits available, this implies that the max possible magnitude MUST be tracked by the caller and the caller MUST normalize the field value if a given operation would cause the magnitude of the result to exceed the max allowed value.

IMPORTANT: The max allowed magnitude of a field value is 64.

type JacobianPoint

type JacobianPoint = secp.JacobianPoint

JacobianPoint is an element of the group formed by the secp256k1 curve in Jacobian projective coordinates and thus represents a point on the curve.

func MakeJacobianPoint

func MakeJacobianPoint(x, y, z *FieldVal) JacobianPoint

MakeJacobianPoint returns a Jacobian point with the provided X, Y, and Z coordinates.

func ParseJacobian

func ParseJacobian(point []byte) (JacobianPoint, error)

ParseJacobian parses a byte slice point as a secp.Publickey and returns the pubkey as a JacobianPoint. If the nonce is a zero slice, the infinityPoint is returned.

type KoblitzCurve

type KoblitzCurve = secp.KoblitzCurve

KoblitzCurve provides an implementation for secp256k1 that fits the ECC Curve interface from crypto/elliptic.

func S256

func S256() *KoblitzCurve

S256 returns a Curve which implements secp256k1.

type ModNScalar

type ModNScalar = secp.ModNScalar

ModNScalar implements optimized 256-bit constant-time fixed-precision arithmetic over the secp256k1 group order. This means all arithmetic is performed modulo:

0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141

It only implements the arithmetic needed for elliptic curve operations, however, the operations that are not implemented can typically be worked around if absolutely needed. For example, subtraction can be performed by adding the negation.

Should it be absolutely necessary, conversion to the standard library math/big.Int can be accomplished by using the Bytes method, slicing the resulting fixed-size array, and feeding it to big.Int.SetBytes. However, that should typically be avoided when possible as conversion to big.Ints requires allocations, is not constant time, and is slower when working modulo the group order.

func NonceRFC6979

func NonceRFC6979(privKey []byte, hash []byte, extra []byte, version []byte,
	extraIterations uint32) *ModNScalar

NonceRFC6979 generates a nonce deterministically according to RFC 6979 using HMAC-SHA256 for the hashing function. It takes a 32-byte hash as an input and returns a 32-byte nonce to be used for deterministic signing. The extra and version arguments are optional, but allow additional data to be added to the input of the HMAC. When provided, the extra data must be 32-bytes and version must be 16 bytes or they will be ignored.

Finally, the extraIterations parameter provides a method to produce a stream of deterministic nonces to ensure the signing code is able to produce a nonce that results in a valid signature in the extremely unlikely event the original nonce produced results in an invalid signature (e.g. R == 0). Signing code should start with 0 and increment it if necessary.

type PrivateKey

type PrivateKey = secp.PrivateKey

PrivateKey wraps an ecdsa.PrivateKey as a convenience mainly for signing things with the the private key without having to directly import the ecdsa package.

func NewPrivateKey

func NewPrivateKey() (*PrivateKey, error)

NewPrivateKey is a wrapper for ecdsa.GenerateKey that returns a PrivateKey instead of the normal ecdsa.PrivateKey.

func PrivKeyFromScalar

func PrivKeyFromScalar(key *ModNScalar) *PrivateKey

PrivKeyFromScalar instantiates a new private key from a scalar encoded as a big integer.

type PublicKey

type PublicKey = secp.PublicKey

PublicKey is an ecdsa.PublicKey with additional functions to serialize in uncompressed, compressed, and hybrid formats.

func Generator

func Generator() *PublicKey

Generator returns the public key at the Generator Point.

func NewPublicKey

func NewPublicKey(x, y *FieldVal) *PublicKey

NewPublicKey instantiates a new public key with the given x and y coordinates.

It should be noted that, unlike ParsePubKey, since this accepts arbitrary x and y coordinates, it allows creation of public keys that are not valid points on the secp256k1 curve. The IsOnCurve method of the returned instance can be used to determine validity.

func ParsePubKey

func ParsePubKey(pubKeyStr []byte) (*PublicKey, error)

ParsePubKey parses a public key for a koblitz curve from a bytestring into a ecdsa.Publickey, verifying that it is valid. It supports compressed, uncompressed and hybrid signature formats.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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