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
- Variables
- func AddNonConst(p1, p2, result *JacobianPoint)
- func DecompressY(x *FieldVal, odd bool, resultY *FieldVal) bool
- func DoubleNonConst(p, result *JacobianPoint)
- func GenerateSharedSecret(privkey *SecretKey, pubkey *PublicKey) []byte
- func GeneratorJacobian(jacobian *JacobianPoint)
- func IsCompressedPubKey(pubKey []byte) bool
- func JacobianToByteSlice(point JacobianPoint) []byte
- func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint)
- func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint)
- func SecKeyFromBytes(pk []byte) (*SecretKey, *PublicKey)
- type CurveParams
- type Error
- type ErrorKind
- type FieldVal
- type JacobianPoint
- type KoblitzCurve
- type ModNScalar
- type PrivateKey
- type PublicKey
- type SecretKey
Constants ¶
const PrivKeyBytesLen = SecKeyBytesLen
const (
PubKeyBytesLenCompressed = 33
)
const SecKeyBytesLen = 32
SecKeyBytesLen defines the length in bytes of a serialized secret key.
Variables ¶
var NewPrivateKey = NewSecretKey
var PrivKeyFromBytes = SecKeyFromBytes
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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.
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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.
Source Files ¶
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. |