ec

package
v0.0.4 Latest Latest
Warning

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

Go to latest
Published: Jun 9, 2024 License: CC0-1.0, ISC Imports: 2 Imported by: 0

README

mleku.online/git/ec

This is a full drop-in replacement for github.com/btcsuite/btcd/btcec eliminating the import from the Decred repository, and including the chainhash helper functions, needed for hashing messages for signatures.

The decred specific tests also have been removed, as well as all tests that use blake256 hashes as these are irrelevant to bitcoin and nostr. Some of them remain present, commented out, in case it is worth regenerating the vectors based on sha256 hashes, but on first blush it seems unlikely to be any benefit.

This includes the old style compact secp256k1 ECDSA signatures, that recover the public key rather than take a key as a parameter as used in Bitcoin transactions, the new style Schnorr signatures, and the Musig2 implementation.

BIP 340 Schnorr signatures are implemented except for the nonstandard message length tests, that nobody uses anyway.

The remainder of this document is from the original README.md.


Package ec implements elliptic curve cryptography needed for working with Bitcoin. It is designed so that it may be used with the standard crypto/ecdsa packages provided with Go.

A comprehensive suite of testis 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.

Installation and Updating

$ go install -u -v mleku.online/git/ec

Documentation

Overview

Package ec 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 = SecKeyBytesLen
View Source
const (
	PubKeyBytesLenCompressed = 33
)
View Source
const SecKeyBytesLen = 32

SecKeyBytesLen defines the length in bytes of a serialized secret key.

Variables

View Source
var NewPrivateKey = NewSecretKey
View Source
var PrivKeyFromBytes = SecKeyFromBytes
View Source
var PrivKeyFromScalar = SecKeyFromScalar

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 *SecretKey, pubkey *PublicKey) []byte

GenerateSharedSecret generates a shared secret based on a secret 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 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 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.

func SecKeyFromBytes

func SecKeyFromBytes(pk []byte) (*SecretKey, *PublicKey)

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

Types

type CurveParams

type CurveParams = secp256k1.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 = secp256k1.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 = secp256k1.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 = secp256k1.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 = secp256k1.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 secp256k1.Publickey and returns the pubkey as a JacobianPoint. If the nonce is a zero slice, the infinityPoint is returned.

type KoblitzCurve

type KoblitzCurve = secp256k1.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 = secp256k1.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 = SecretKey

type PublicKey

type PublicKey = secp256k1.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.

type SecretKey

type SecretKey = secp256k1.SecretKey

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

func NewSecretKey

func NewSecretKey() (*SecretKey, error)

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

func SecKeyFromScalar

func SecKeyFromScalar(key *ModNScalar) *SecretKey

SecKeyFromScalar instantiates a new secret key from a scalar encoded as a big integer.

Directories

Path Synopsis
Package chainhash provides abstracted hash functionality.
Package chainhash provides abstracted hash functionality.
Package ecdsa provides secp256k1-optimized ECDSA signing and verification.
Package ecdsa provides secp256k1-optimized ECDSA signing and verification.
Package schnorr provides custom Schnorr signing and verification via secp256k1.
Package schnorr provides custom Schnorr signing and verification via secp256k1.
Package secp256k1 implements optimized secp256k1 elliptic curve operations in pure Go.
Package secp256k1 implements optimized secp256k1 elliptic curve operations in pure Go.

Jump to

Keyboard shortcuts

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