Source File
pubkey.go
Belonging Package
github.com/decred/dcrd/dcrec/secp256k1/v4
// Copyright (c) 2013-2014 The btcsuite developers// Copyright (c) 2015-2024 The Decred developers// Use of this source code is governed by an ISC// license that can be found in the LICENSE file.package secp256k1// References:// [SEC1] Elliptic Curve Cryptography// https://www.secg.org/sec1-v2.pdf//// [SEC2] Recommended Elliptic Curve Domain Parameters// https://www.secg.org/sec2-v2.pdf//// [ANSI X9.62-1998] Public Key Cryptography For The Financial Services// Industry: The Elliptic Curve Digital Signature Algorithm (ECDSA)import ()const (// PubKeyBytesLenCompressed is the number of bytes of a serialized// compressed public key.PubKeyBytesLenCompressed = 33// PubKeyBytesLenUncompressed is the number of bytes of a serialized// uncompressed public key.PubKeyBytesLenUncompressed = 65// PubKeyFormatCompressedEven is the identifier prefix byte for a public key// whose Y coordinate is even when serialized in the compressed format per// section 2.3.4 of [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.4).PubKeyFormatCompressedEven byte = 0x02// PubKeyFormatCompressedOdd is the identifier prefix byte for a public key// whose Y coordinate is odd when serialized in the compressed format per// section 2.3.4 of [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.4).PubKeyFormatCompressedOdd byte = 0x03// PubKeyFormatUncompressed is the identifier prefix byte for a public key// when serialized according in the uncompressed format per section 2.3.3 of// [SEC1](https://secg.org/sec1-v2.pdf#subsubsection.2.3.3).PubKeyFormatUncompressed byte = 0x04// PubKeyFormatHybridEven is the identifier prefix byte for a public key// whose Y coordinate is even when serialized according to the hybrid format// per section 4.3.6 of [ANSI X9.62-1998].//// NOTE: This format makes little sense in practice an therefore this// package will not produce public keys serialized in this format. However,// it will parse them since they exist in the wild.PubKeyFormatHybridEven byte = 0x06// PubKeyFormatHybridOdd is the identifier prefix byte for a public key// whose Y coordingate is odd when serialized according to the hybrid format// per section 4.3.6 of [ANSI X9.62-1998].//// NOTE: This format makes little sense in practice an therefore this// package will not produce public keys serialized in this format. However,// it will parse them since they exist in the wild.PubKeyFormatHybridOdd byte = 0x07)// PublicKey provides facilities for efficiently working with secp256k1 public// keys within this package and includes functions to serialize in both// uncompressed and compressed SEC (Standards for Efficient Cryptography)// formats.type PublicKey struct {x FieldValy FieldVal}// 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 (, *FieldVal) *PublicKey {var PublicKey.x.Set().y.Set()return &}// ParsePubKey parses a secp256k1 public key encoded according to the format// specified by ANSI X9.62-1998, which means it is also compatible with the// SEC (Standards for Efficient Cryptography) specification which is a subset of// the former. In other words, it supports the uncompressed, compressed, and// hybrid formats as follows://// Compressed://// <format byte = 0x02/0x03><32-byte X coordinate>//// Uncompressed://// <format byte = 0x04><32-byte X coordinate><32-byte Y coordinate>//// Hybrid://// <format byte = 0x05/0x06><32-byte X coordinate><32-byte Y coordinate>//// NOTE: The hybrid format makes little sense in practice an therefore this// package will not produce public keys serialized in this format. However,// this function will properly parse them since they exist in the wild.func ( []byte) ( *PublicKey, error) {var , FieldValswitch len() {case PubKeyBytesLenUncompressed:// Reject unsupported public key formats for the given length.:= [0]switch {case PubKeyFormatUncompressed:case PubKeyFormatHybridEven, PubKeyFormatHybridOdd:default::= fmt.Sprintf("invalid public key: unsupported format: %x",)return nil, makeError(ErrPubKeyInvalidFormat, )}// Parse the x and y coordinates while ensuring that they are in the// allowed range.if := .SetByteSlice([1:33]); {:= "invalid public key: x >= field prime"return nil, makeError(ErrPubKeyXTooBig, )}if := .SetByteSlice([33:]); {:= "invalid public key: y >= field prime"return nil, makeError(ErrPubKeyYTooBig, )}// Ensure the oddness of the y coordinate matches the specified format// for hybrid public keys.if == PubKeyFormatHybridEven || == PubKeyFormatHybridOdd {:= == PubKeyFormatHybridOddif .IsOdd() != {:= fmt.Sprintf("invalid public key: y oddness does not "+"match specified value of %v", )return nil, makeError(ErrPubKeyMismatchedOddness, )}}// Reject public keys that are not on the secp256k1 curve.if !isOnCurve(&, &) {:= fmt.Sprintf("invalid public key: [%v,%v] not on secp256k1 "+"curve", , )return nil, makeError(ErrPubKeyNotOnCurve, )}case PubKeyBytesLenCompressed:// Reject unsupported public key formats for the given length.:= [0]switch {case PubKeyFormatCompressedEven, PubKeyFormatCompressedOdd:default::= fmt.Sprintf("invalid public key: unsupported format: %x",)return nil, makeError(ErrPubKeyInvalidFormat, )}// Parse the x coordinate while ensuring that it is in the allowed// range.if := .SetByteSlice([1:33]); {:= "invalid public key: x >= field prime"return nil, makeError(ErrPubKeyXTooBig, )}// Attempt to calculate the y coordinate for the given x coordinate such// that the result pair is a point on the secp256k1 curve and the// solution with desired oddness is chosen.:= == PubKeyFormatCompressedOddif !DecompressY(&, , &) {:= fmt.Sprintf("invalid public key: x coordinate %v is not on "+"the secp256k1 curve", )return nil, makeError(ErrPubKeyNotOnCurve, )}default::= fmt.Sprintf("malformed public key: invalid length: %d",len())return nil, makeError(ErrPubKeyInvalidLen, )}return NewPublicKey(&, &), nil}// SerializeUncompressed serializes a public key in the 65-byte uncompressed// format.func ( PublicKey) () []byte {// 0x04 || 32-byte x coordinate || 32-byte y coordinatevar [PubKeyBytesLenUncompressed]byte[0] = PubKeyFormatUncompressed.x.PutBytesUnchecked([1:33]).y.PutBytesUnchecked([33:65])return [:]}// SerializeCompressed serializes a public key in the 33-byte compressed format.func ( PublicKey) () []byte {// Choose the format byte depending on the oddness of the Y coordinate.:= PubKeyFormatCompressedEvenif .y.IsOdd() {= PubKeyFormatCompressedOdd}// 0x02 or 0x03 || 32-byte x coordinatevar [PubKeyBytesLenCompressed]byte[0] =.x.PutBytesUnchecked([1:33])return [:]}// IsEqual compares this public key instance to the one passed, returning true// if both public keys are equivalent. A public key is equivalent to another,// if they both have the same X and Y coordinates.func ( *PublicKey) ( *PublicKey) bool {return .x.Equals(&.x) && .y.Equals(&.y)}// AsJacobian converts the public key into a Jacobian point with Z=1 and stores// the result in the provided result param. This allows the public key to be// treated a Jacobian point in the secp256k1 group in calculations.func ( *PublicKey) ( *JacobianPoint) {.X.Set(&.x).Y.Set(&.y).Z.SetInt(1)}// IsOnCurve returns whether or not the public key represents a point on the// secp256k1 curve.func ( *PublicKey) () bool {return isOnCurve(&.x, &.y)}
![]() |
The pages are generated with Golds v0.8.2. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |