WIP: Save agent roles integration work before CHORUS rebrand
- Agent roles and coordination features - Chat API integration testing - New configuration and workspace management 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
17
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE
generated
vendored
Normal file
17
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
ISC License
|
||||
|
||||
Copyright (c) 2013-2017 The btcsuite developers
|
||||
Copyright (c) 2015-2020 The Decred developers
|
||||
Copyright (c) 2017 The Lightning Network Developers
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
72
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md
generated
vendored
Normal file
72
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
secp256k1
|
||||
=========
|
||||
|
||||
[](https://github.com/decred/dcrd/actions)
|
||||
[](http://copyfree.org)
|
||||
[](https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v4)
|
||||
|
||||
Package secp256k1 implements optimized secp256k1 elliptic curve operations.
|
||||
|
||||
This package provides an optimized pure Go implementation of elliptic curve
|
||||
cryptography operations over the secp256k1 curve as well as data structures and
|
||||
functions for working with public and private secp256k1 keys. See
|
||||
https://www.secg.org/sec2-v2.pdf for details on the standard.
|
||||
|
||||
In addition, sub packages are provided to produce, verify, parse, and serialize
|
||||
ECDSA signatures and EC-Schnorr-DCRv0 (a custom Schnorr-based signature scheme
|
||||
specific to Decred) signatures. See the README.md files in the relevant sub
|
||||
packages for more details about those aspects.
|
||||
|
||||
An overview of the features provided by this package are as follows:
|
||||
|
||||
- Private key generation, serialization, and parsing
|
||||
- Public key generation, serialization and parsing per ANSI X9.62-1998
|
||||
- Parses uncompressed, compressed, and hybrid public keys
|
||||
- Serializes uncompressed and compressed public keys
|
||||
- Specialized types for performing optimized and constant time field operations
|
||||
- `FieldVal` type for working modulo the secp256k1 field prime
|
||||
- `ModNScalar` type for working modulo the secp256k1 group order
|
||||
- Elliptic curve operations in Jacobian projective coordinates
|
||||
- Point addition
|
||||
- Point doubling
|
||||
- Scalar multiplication with an arbitrary point
|
||||
- Scalar multiplication with the base point (group generator)
|
||||
- Point decompression from a given x coordinate
|
||||
- Nonce generation via RFC6979 with support for extra data and version
|
||||
information that can be used to prevent nonce reuse between signing algorithms
|
||||
|
||||
It also provides an implementation of the Go standard library `crypto/elliptic`
|
||||
`Curve` interface via the `S256` function so that it may be used with other
|
||||
packages in the standard library such as `crypto/tls`, `crypto/x509`, and
|
||||
`crypto/ecdsa`. However, in the case of ECDSA, it is highly recommended to use
|
||||
the `ecdsa` sub package of this package instead since it is optimized
|
||||
specifically for secp256k1 and is significantly faster as a result.
|
||||
|
||||
Although this package was primarily written for dcrd, it has intentionally been
|
||||
designed so it can be used as a standalone package for any projects needing to
|
||||
use optimized secp256k1 elliptic curve cryptography.
|
||||
|
||||
Finally, a comprehensive suite of tests is provided to provide a high level of
|
||||
quality assurance.
|
||||
|
||||
## secp256k1 use in Decred
|
||||
|
||||
At the time of this writing, the primary public key cryptography in widespread
|
||||
use on the Decred network used to secure coins is based on elliptic curves
|
||||
defined by the secp256k1 domain parameters.
|
||||
|
||||
## Installation and Updating
|
||||
|
||||
This package is part of the `github.com/decred/dcrd/dcrec/secp256k1/v4` module.
|
||||
Use the standard go tooling for working with modules to incorporate it.
|
||||
|
||||
## Examples
|
||||
|
||||
* [Encryption](https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v4#example-package-EncryptDecryptMessage)
|
||||
Demonstrates encrypting and decrypting a message using a shared key derived
|
||||
through ECDHE.
|
||||
|
||||
## License
|
||||
|
||||
Package secp256k1 is licensed under the [copyfree](http://copyfree.org) ISC
|
||||
License.
|
||||
18
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go
generated
vendored
Normal file
18
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1272
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go
generated
vendored
Normal file
1272
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
59
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go
generated
vendored
Normal file
59
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright (c) 2013-2014 The btcsuite developers
|
||||
// Copyright (c) 2015-2022 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package secp256k1 implements optimized secp256k1 elliptic curve operations in
|
||||
pure Go.
|
||||
|
||||
This package provides an optimized pure Go implementation of elliptic curve
|
||||
cryptography operations over the secp256k1 curve as well as data structures and
|
||||
functions for working with public and private secp256k1 keys. See
|
||||
https://www.secg.org/sec2-v2.pdf for details on the standard.
|
||||
|
||||
In addition, sub packages are provided to produce, verify, parse, and serialize
|
||||
ECDSA signatures and EC-Schnorr-DCRv0 (a custom Schnorr-based signature scheme
|
||||
specific to Decred) signatures. See the README.md files in the relevant sub
|
||||
packages for more details about those aspects.
|
||||
|
||||
An overview of the features provided by this package are as follows:
|
||||
|
||||
- Private key generation, serialization, and parsing
|
||||
- Public key generation, serialization and parsing per ANSI X9.62-1998
|
||||
- Parses uncompressed, compressed, and hybrid public keys
|
||||
- Serializes uncompressed and compressed public keys
|
||||
- Specialized types for performing optimized and constant time field operations
|
||||
- FieldVal type for working modulo the secp256k1 field prime
|
||||
- ModNScalar type for working modulo the secp256k1 group order
|
||||
- Elliptic curve operations in Jacobian projective coordinates
|
||||
- Point addition
|
||||
- Point doubling
|
||||
- Scalar multiplication with an arbitrary point
|
||||
- Scalar multiplication with the base point (group generator)
|
||||
- Point decompression from a given x coordinate
|
||||
- Nonce generation via RFC6979 with support for extra data and version
|
||||
information that can be used to prevent nonce reuse between signing
|
||||
algorithms
|
||||
|
||||
It also provides an implementation of the Go standard library crypto/elliptic
|
||||
Curve interface via the S256 function so that it may be used with other packages
|
||||
in the standard library such as crypto/tls, crypto/x509, and crypto/ecdsa.
|
||||
However, in the case of ECDSA, it is highly recommended to use the ecdsa sub
|
||||
package of this package instead since it is optimized specifically for secp256k1
|
||||
and is significantly faster as a result.
|
||||
|
||||
Although this package was primarily written for dcrd, it has intentionally been
|
||||
designed so it can be used as a standalone package for any projects needing to
|
||||
use optimized secp256k1 elliptic curve cryptography.
|
||||
|
||||
Finally, a comprehensive suite of tests is provided to provide a high level of
|
||||
quality assurance.
|
||||
|
||||
# Use of secp256k1 in Decred
|
||||
|
||||
At the time of this writing, the primary public key cryptography in widespread
|
||||
use on the Decred network used to secure coins is based on elliptic curves
|
||||
defined by the secp256k1 domain parameters.
|
||||
*/
|
||||
package secp256k1
|
||||
21
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go
generated
vendored
Normal file
21
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright (c) 2015 The btcsuite developers
|
||||
// Copyright (c) 2015-2023 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package secp256k1
|
||||
|
||||
// GenerateSharedSecret generates a shared secret based on a private key and a
|
||||
// public key using Diffie-Hellman key exchange (ECDH) (RFC 5903).
|
||||
// RFC5903 Section 9 states we should only return x.
|
||||
//
|
||||
// It is recommended to securely hash the result before using as a cryptographic
|
||||
// key.
|
||||
func GenerateSharedSecret(privkey *PrivateKey, pubkey *PublicKey) []byte {
|
||||
var point, result JacobianPoint
|
||||
pubkey.AsJacobian(&point)
|
||||
ScalarMultNonConst(&privkey.Key, &point, &result)
|
||||
result.ToAffine()
|
||||
xBytes := result.X.Bytes()
|
||||
return xBytes[:]
|
||||
}
|
||||
52
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/README.md
generated
vendored
Normal file
52
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/README.md
generated
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
ecdsa
|
||||
=====
|
||||
|
||||
[](https://github.com/decred/dcrd/actions)
|
||||
[](http://copyfree.org)
|
||||
[](https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa)
|
||||
|
||||
Package ecdsa provides secp256k1-optimized ECDSA signing and verification.
|
||||
|
||||
This package provides data structures and functions necessary to produce and
|
||||
verify deterministic canonical signatures in accordance with RFC6979 and
|
||||
BIP0062, optimized specifically for the secp256k1 curve using the Elliptic Curve
|
||||
Digital Signature Algorithm (ECDSA), as defined in FIPS 186-3. See
|
||||
https://www.secg.org/sec2-v2.pdf for details on the secp256k1 standard.
|
||||
|
||||
It also provides functions to parse and serialize the ECDSA signatures with the
|
||||
more strict Distinguished Encoding Rules (DER) of ISO/IEC 8825-1 and some
|
||||
additional restrictions specific to secp256k1.
|
||||
|
||||
In addition, it supports a custom "compact" signature format which allows
|
||||
efficient recovery of the public key from a given valid signature and message
|
||||
hash combination.
|
||||
|
||||
A comprehensive suite of tests is provided to ensure proper functionality.
|
||||
|
||||
## ECDSA use in Decred
|
||||
|
||||
At the time of this writing, ECDSA signatures are heavily used for proving coin
|
||||
ownership in Decred as the vast majority of transactions consist of what is
|
||||
effectively transferring ownership of coins to a public key associated with a
|
||||
private key only known to the recipient of the coins along with an encumbrance
|
||||
that requires an ECDSA signature that proves the new owner possesses the private
|
||||
key without actually revealing it.
|
||||
|
||||
## Installation and Updating
|
||||
|
||||
This package is part of the `github.com/decred/dcrd/dcrec/secp256k1/v4` module.
|
||||
Use the standard go tooling for working with modules to incorporate it.
|
||||
|
||||
## Examples
|
||||
|
||||
* [Sign Message](https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa#example-package-SignMessage)
|
||||
Demonstrates signing a message with a secp256k1 private key that is first
|
||||
parsed from raw bytes and serializing the generated signature.
|
||||
|
||||
* [Verify Signature](https://pkg.go.dev/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa#example-Signature.Verify)
|
||||
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 ecdsa is licensed under the [copyfree](http://copyfree.org) ISC License.
|
||||
42
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/doc.go
generated
vendored
Normal file
42
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/doc.go
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2020 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package ecdsa provides secp256k1-optimized ECDSA signing and verification.
|
||||
|
||||
This package provides data structures and functions necessary to produce and
|
||||
verify deterministic canonical signatures in accordance with RFC6979 and
|
||||
BIP0062, optimized specifically for the secp256k1 curve using the Elliptic Curve
|
||||
Digital Signature Algorithm (ECDSA), as defined in FIPS 186-3. See
|
||||
https://www.secg.org/sec2-v2.pdf for details on the secp256k1 standard.
|
||||
|
||||
It also provides functions to parse and serialize the ECDSA signatures with the
|
||||
more strict Distinguished Encoding Rules (DER) of ISO/IEC 8825-1 and some
|
||||
additional restrictions specific to secp256k1.
|
||||
|
||||
In addition, it supports a custom "compact" signature format which allows
|
||||
efficient recovery of the public key from a given valid signature and message
|
||||
hash combination.
|
||||
|
||||
A comprehensive suite of tests is provided to ensure proper functionality.
|
||||
|
||||
# ECDSA use in Decred
|
||||
|
||||
At the time of this writing, ECDSA signatures are heavily used for proving coin
|
||||
ownership in Decred as the vast majority of transactions consist of what is
|
||||
effectively transferring ownership of coins to a public key associated with a
|
||||
private key only known to the recipient of the coins along with an encumbrance
|
||||
that requires an ECDSA signature that proves the new owner possesses the private
|
||||
key without actually revealing it.
|
||||
|
||||
# Errors
|
||||
|
||||
Errors returned by this package are of type ecdsa.Error and fully support the
|
||||
standard library errors.Is and errors.As functions. This allows the caller to
|
||||
programmatically determine the specific error by examining the ErrorKind field
|
||||
of the type asserted ecdsa.Error while still providing rich error messages with
|
||||
contextual information. See ErrorKind in the package documentation for a full
|
||||
list.
|
||||
*/
|
||||
package ecdsa
|
||||
134
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/error.go
generated
vendored
Normal file
134
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/error.go
generated
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
// Copyright (c) 2020-2022 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ecdsa
|
||||
|
||||
// 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 ErrorKind string
|
||||
|
||||
// These constants are used to identify a specific Error.
|
||||
const (
|
||||
// ErrSigTooShort is returned when a signature that should be a DER
|
||||
// signature is too short.
|
||||
ErrSigTooShort = ErrorKind("ErrSigTooShort")
|
||||
|
||||
// ErrSigTooLong is returned when a signature that should be a DER signature
|
||||
// is too long.
|
||||
ErrSigTooLong = ErrorKind("ErrSigTooLong")
|
||||
|
||||
// ErrSigInvalidSeqID is returned when a signature that should be a DER
|
||||
// signature does not have the expected ASN.1 sequence ID.
|
||||
ErrSigInvalidSeqID = ErrorKind("ErrSigInvalidSeqID")
|
||||
|
||||
// ErrSigInvalidDataLen is returned when a signature that should be a DER
|
||||
// signature does not specify the correct number of remaining bytes for the
|
||||
// R and S portions.
|
||||
ErrSigInvalidDataLen = ErrorKind("ErrSigInvalidDataLen")
|
||||
|
||||
// ErrSigMissingSTypeID is returned when a signature that should be a DER
|
||||
// signature does not provide the ASN.1 type ID for S.
|
||||
ErrSigMissingSTypeID = ErrorKind("ErrSigMissingSTypeID")
|
||||
|
||||
// ErrSigMissingSLen is returned when a signature that should be a DER
|
||||
// signature does not provide the length of S.
|
||||
ErrSigMissingSLen = ErrorKind("ErrSigMissingSLen")
|
||||
|
||||
// ErrSigInvalidSLen is returned when a signature that should be a DER
|
||||
// signature does not specify the correct number of bytes for the S portion.
|
||||
ErrSigInvalidSLen = ErrorKind("ErrSigInvalidSLen")
|
||||
|
||||
// ErrSigInvalidRIntID is returned when a signature that should be a DER
|
||||
// signature does not have the expected ASN.1 integer ID for R.
|
||||
ErrSigInvalidRIntID = ErrorKind("ErrSigInvalidRIntID")
|
||||
|
||||
// ErrSigZeroRLen is returned when a signature that should be a DER
|
||||
// signature has an R length of zero.
|
||||
ErrSigZeroRLen = ErrorKind("ErrSigZeroRLen")
|
||||
|
||||
// ErrSigNegativeR is returned when a signature that should be a DER
|
||||
// signature has a negative value for R.
|
||||
ErrSigNegativeR = ErrorKind("ErrSigNegativeR")
|
||||
|
||||
// ErrSigTooMuchRPadding is returned when a signature that should be a DER
|
||||
// signature has too much padding for R.
|
||||
ErrSigTooMuchRPadding = ErrorKind("ErrSigTooMuchRPadding")
|
||||
|
||||
// ErrSigRIsZero is returned when a signature has R set to the value zero.
|
||||
ErrSigRIsZero = ErrorKind("ErrSigRIsZero")
|
||||
|
||||
// ErrSigRTooBig is returned when a signature has R with a value that is
|
||||
// greater than or equal to the group order.
|
||||
ErrSigRTooBig = ErrorKind("ErrSigRTooBig")
|
||||
|
||||
// ErrSigInvalidSIntID is returned when a signature that should be a DER
|
||||
// signature does not have the expected ASN.1 integer ID for S.
|
||||
ErrSigInvalidSIntID = ErrorKind("ErrSigInvalidSIntID")
|
||||
|
||||
// ErrSigZeroSLen is returned when a signature that should be a DER
|
||||
// signature has an S length of zero.
|
||||
ErrSigZeroSLen = ErrorKind("ErrSigZeroSLen")
|
||||
|
||||
// ErrSigNegativeS is returned when a signature that should be a DER
|
||||
// signature has a negative value for S.
|
||||
ErrSigNegativeS = ErrorKind("ErrSigNegativeS")
|
||||
|
||||
// ErrSigTooMuchSPadding is returned when a signature that should be a DER
|
||||
// signature has too much padding for S.
|
||||
ErrSigTooMuchSPadding = ErrorKind("ErrSigTooMuchSPadding")
|
||||
|
||||
// ErrSigSIsZero is returned when a signature has S set to the value zero.
|
||||
ErrSigSIsZero = ErrorKind("ErrSigSIsZero")
|
||||
|
||||
// ErrSigSTooBig is returned when a signature has S with a value that is
|
||||
// greater than or equal to the group order.
|
||||
ErrSigSTooBig = ErrorKind("ErrSigSTooBig")
|
||||
|
||||
// ErrSigInvalidLen is returned when a signature that should be a compact
|
||||
// signature is not the required length.
|
||||
ErrSigInvalidLen = ErrorKind("ErrSigInvalidLen")
|
||||
|
||||
// ErrSigInvalidRecoveryCode is returned when a signature that should be a
|
||||
// compact signature has an invalid value for the public key recovery code.
|
||||
ErrSigInvalidRecoveryCode = ErrorKind("ErrSigInvalidRecoveryCode")
|
||||
|
||||
// ErrSigOverflowsPrime is returned when a signature that should be a
|
||||
// compact signature has the overflow bit set but adding the order to it
|
||||
// would overflow the underlying field prime.
|
||||
ErrSigOverflowsPrime = ErrorKind("ErrSigOverflowsPrime")
|
||||
|
||||
// ErrPointNotOnCurve is returned when attempting to recover a public key
|
||||
// from a compact signature results in a point that is not on the elliptic
|
||||
// curve.
|
||||
ErrPointNotOnCurve = ErrorKind("ErrPointNotOnCurve")
|
||||
)
|
||||
|
||||
// Error satisfies the error interface and prints human-readable errors.
|
||||
func (e ErrorKind) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
// Error identifies an error related to an ECDSA signature. 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 Error struct {
|
||||
Err error
|
||||
Description string
|
||||
}
|
||||
|
||||
// Error satisfies the error interface and prints human-readable errors.
|
||||
func (e Error) Error() string {
|
||||
return e.Description
|
||||
}
|
||||
|
||||
// Unwrap returns the underlying wrapped error.
|
||||
func (e Error) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
// signatureError creates an Error given a set of arguments.
|
||||
func signatureError(kind ErrorKind, desc string) Error {
|
||||
return Error{Err: kind, Description: desc}
|
||||
}
|
||||
990
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/signature.go
generated
vendored
Normal file
990
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdsa/signature.go
generated
vendored
Normal file
@@ -0,0 +1,990 @@
|
||||
// Copyright (c) 2013-2014 The btcsuite developers
|
||||
// Copyright (c) 2015-2022 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package ecdsa
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/decred/dcrd/dcrec/secp256k1/v4"
|
||||
)
|
||||
|
||||
// References:
|
||||
// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)
|
||||
//
|
||||
// [ISO/IEC 8825-1]: Information technology — ASN.1 encoding rules:
|
||||
// Specification of Basic Encoding Rules (BER), Canonical Encoding Rules
|
||||
// (CER) and Distinguished Encoding Rules (DER)
|
||||
//
|
||||
// [SEC1]: Elliptic Curve Cryptography (May 31, 2009, Version 2.0)
|
||||
// https://www.secg.org/sec1-v2.pdf
|
||||
|
||||
var (
|
||||
// zero32 is an array of 32 bytes used for the purposes of zeroing and is
|
||||
// defined here to avoid extra allocations.
|
||||
zero32 = [32]byte{}
|
||||
|
||||
// orderAsFieldVal is the order of the secp256k1 curve group stored as a
|
||||
// field value. It is provided here to avoid the need to create it multiple
|
||||
// times.
|
||||
orderAsFieldVal = func() secp256k1.FieldVal {
|
||||
var f secp256k1.FieldVal
|
||||
f.SetByteSlice(secp256k1.Params().N.Bytes())
|
||||
return f
|
||||
}()
|
||||
)
|
||||
|
||||
const (
|
||||
// asn1SequenceID is the ASN.1 identifier for a sequence and is used when
|
||||
// parsing and serializing signatures encoded with the Distinguished
|
||||
// Encoding Rules (DER) format per section 10 of [ISO/IEC 8825-1].
|
||||
asn1SequenceID = 0x30
|
||||
|
||||
// asn1IntegerID is the ASN.1 identifier for an integer and is used when
|
||||
// parsing and serializing signatures encoded with the Distinguished
|
||||
// Encoding Rules (DER) format per section 10 of [ISO/IEC 8825-1].
|
||||
asn1IntegerID = 0x02
|
||||
)
|
||||
|
||||
// Signature is a type representing an ECDSA signature.
|
||||
type Signature struct {
|
||||
r secp256k1.ModNScalar
|
||||
s secp256k1.ModNScalar
|
||||
}
|
||||
|
||||
// NewSignature instantiates a new signature given some r and s values.
|
||||
func NewSignature(r, s *secp256k1.ModNScalar) *Signature {
|
||||
return &Signature{*r, *s}
|
||||
}
|
||||
|
||||
// Serialize returns the ECDSA signature in the Distinguished Encoding Rules
|
||||
// (DER) format per section 10 of [ISO/IEC 8825-1] and such that the S component
|
||||
// of the signature is less than or equal to the half order of the group.
|
||||
//
|
||||
// Note that the serialized bytes returned do not include the appended hash type
|
||||
// used in Decred signature scripts.
|
||||
func (sig *Signature) Serialize() []byte {
|
||||
// The format of a DER encoded signature is as follows:
|
||||
//
|
||||
// 0x30 <total length> 0x02 <length of R> <R> 0x02 <length of S> <S>
|
||||
// - 0x30 is the ASN.1 identifier for a sequence.
|
||||
// - Total length is 1 byte and specifies length of all remaining data.
|
||||
// - 0x02 is the ASN.1 identifier that specifies an integer follows.
|
||||
// - Length of R is 1 byte and specifies how many bytes R occupies.
|
||||
// - R is the arbitrary length big-endian encoded number which
|
||||
// represents the R value of the signature. DER encoding dictates
|
||||
// that the value must be encoded using the minimum possible number
|
||||
// of bytes. This implies the first byte can only be null if the
|
||||
// highest bit of the next byte is set in order to prevent it from
|
||||
// being interpreted as a negative number.
|
||||
// - 0x02 is once again the ASN.1 integer identifier.
|
||||
// - Length of S is 1 byte and specifies how many bytes S occupies.
|
||||
// - S is the arbitrary length big-endian encoded number which
|
||||
// represents the S value of the signature. The encoding rules are
|
||||
// identical as those for R.
|
||||
|
||||
// Ensure the S component of the signature is less than or equal to the half
|
||||
// order of the group because both S and its negation are valid signatures
|
||||
// modulo the order, so this forces a consistent choice to reduce signature
|
||||
// malleability.
|
||||
sigS := new(secp256k1.ModNScalar).Set(&sig.s)
|
||||
if sigS.IsOverHalfOrder() {
|
||||
sigS.Negate()
|
||||
}
|
||||
|
||||
// Serialize the R and S components of the signature into their fixed
|
||||
// 32-byte big-endian encoding. Note that the extra leading zero byte is
|
||||
// used to ensure it is canonical per DER and will be stripped if needed
|
||||
// below.
|
||||
var rBuf, sBuf [33]byte
|
||||
sig.r.PutBytesUnchecked(rBuf[1:33])
|
||||
sigS.PutBytesUnchecked(sBuf[1:33])
|
||||
|
||||
// Ensure the encoded bytes for the R and S components are canonical per DER
|
||||
// by trimming all leading zero bytes so long as the next byte does not have
|
||||
// the high bit set and it's not the final byte.
|
||||
canonR, canonS := rBuf[:], sBuf[:]
|
||||
for len(canonR) > 1 && canonR[0] == 0x00 && canonR[1]&0x80 == 0 {
|
||||
canonR = canonR[1:]
|
||||
}
|
||||
for len(canonS) > 1 && canonS[0] == 0x00 && canonS[1]&0x80 == 0 {
|
||||
canonS = canonS[1:]
|
||||
}
|
||||
|
||||
// Total length of returned signature is 1 byte for each magic and length
|
||||
// (6 total), plus lengths of R and S.
|
||||
totalLen := 6 + len(canonR) + len(canonS)
|
||||
b := make([]byte, 0, totalLen)
|
||||
b = append(b, asn1SequenceID)
|
||||
b = append(b, byte(totalLen-2))
|
||||
b = append(b, asn1IntegerID)
|
||||
b = append(b, byte(len(canonR)))
|
||||
b = append(b, canonR...)
|
||||
b = append(b, asn1IntegerID)
|
||||
b = append(b, byte(len(canonS)))
|
||||
b = append(b, canonS...)
|
||||
return b
|
||||
}
|
||||
|
||||
// zeroArray32 zeroes the provided 32-byte buffer.
|
||||
func zeroArray32(b *[32]byte) {
|
||||
copy(b[:], zero32[:])
|
||||
}
|
||||
|
||||
// fieldToModNScalar converts a field value to scalar modulo the group order and
|
||||
// returns the scalar along with either 1 if it was reduced (aka it overflowed)
|
||||
// or 0 otherwise.
|
||||
//
|
||||
// Note that a bool is not used here because it is not possible in Go to convert
|
||||
// from a bool to numeric value in constant time and many constant-time
|
||||
// operations require a numeric value.
|
||||
func fieldToModNScalar(v *secp256k1.FieldVal) (secp256k1.ModNScalar, uint32) {
|
||||
var buf [32]byte
|
||||
v.PutBytes(&buf)
|
||||
var s secp256k1.ModNScalar
|
||||
overflow := s.SetBytes(&buf)
|
||||
zeroArray32(&buf)
|
||||
return s, overflow
|
||||
}
|
||||
|
||||
// modNScalarToField converts a scalar modulo the group order to a field value.
|
||||
func modNScalarToField(v *secp256k1.ModNScalar) secp256k1.FieldVal {
|
||||
var buf [32]byte
|
||||
v.PutBytes(&buf)
|
||||
var fv secp256k1.FieldVal
|
||||
fv.SetBytes(&buf)
|
||||
return fv
|
||||
}
|
||||
|
||||
// Verify returns whether or not the signature is valid for the provided hash
|
||||
// and secp256k1 public key.
|
||||
func (sig *Signature) Verify(hash []byte, pubKey *secp256k1.PublicKey) bool {
|
||||
// The algorithm for verifying an ECDSA signature is given as algorithm 4.30
|
||||
// in [GECC].
|
||||
//
|
||||
// The following is a paraphrased version for reference:
|
||||
//
|
||||
// G = curve generator
|
||||
// N = curve order
|
||||
// Q = public key
|
||||
// m = message
|
||||
// R, S = signature
|
||||
//
|
||||
// 1. Fail if R and S are not in [1, N-1]
|
||||
// 2. e = H(m)
|
||||
// 3. w = S^-1 mod N
|
||||
// 4. u1 = e * w mod N
|
||||
// u2 = R * w mod N
|
||||
// 5. X = u1G + u2Q
|
||||
// 6. Fail if X is the point at infinity
|
||||
// 7. x = X.x mod N (X.x is the x coordinate of X)
|
||||
// 8. Verified if x == R
|
||||
//
|
||||
// However, since all group operations are done internally in Jacobian
|
||||
// projective space, the algorithm is modified slightly here in order to
|
||||
// avoid an expensive inversion back into affine coordinates at step 7.
|
||||
// Credits to Greg Maxwell for originally suggesting this optimization.
|
||||
//
|
||||
// Ordinarily, step 7 involves converting the x coordinate to affine by
|
||||
// calculating x = x / z^2 (mod P) and then calculating the remainder as
|
||||
// x = x (mod N). Then step 8 compares it to R.
|
||||
//
|
||||
// Note that since R is the x coordinate mod N from a random point that was
|
||||
// originally mod P, and the cofactor of the secp256k1 curve is 1, there are
|
||||
// only two possible x coordinates that the original random point could have
|
||||
// been to produce R: x, where x < N, and x+N, where x+N < P.
|
||||
//
|
||||
// This implies that the signature is valid if either:
|
||||
// a) R == X.x / X.z^2 (mod P)
|
||||
// => R * X.z^2 == X.x (mod P)
|
||||
// --or--
|
||||
// b) R + N < P && R + N == X.x / X.z^2 (mod P)
|
||||
// => R + N < P && (R + N) * X.z^2 == X.x (mod P)
|
||||
//
|
||||
// Therefore the following modified algorithm is used:
|
||||
//
|
||||
// 1. Fail if R and S are not in [1, N-1]
|
||||
// 2. e = H(m)
|
||||
// 3. w = S^-1 mod N
|
||||
// 4. u1 = e * w mod N
|
||||
// u2 = R * w mod N
|
||||
// 5. X = u1G + u2Q
|
||||
// 6. Fail if X is the point at infinity
|
||||
// 7. z = (X.z)^2 mod P (X.z is the z coordinate of X)
|
||||
// 8. Verified if R * z == X.x (mod P)
|
||||
// 9. Fail if R + N >= P
|
||||
// 10. Verified if (R + N) * z == X.x (mod P)
|
||||
|
||||
// Step 1.
|
||||
//
|
||||
// Fail if R and S are not in [1, N-1].
|
||||
if sig.r.IsZero() || sig.s.IsZero() {
|
||||
return false
|
||||
}
|
||||
|
||||
// Step 2.
|
||||
//
|
||||
// e = H(m)
|
||||
var e secp256k1.ModNScalar
|
||||
e.SetByteSlice(hash)
|
||||
|
||||
// Step 3.
|
||||
//
|
||||
// w = S^-1 mod N
|
||||
w := new(secp256k1.ModNScalar).InverseValNonConst(&sig.s)
|
||||
|
||||
// Step 4.
|
||||
//
|
||||
// u1 = e * w mod N
|
||||
// u2 = R * w mod N
|
||||
u1 := new(secp256k1.ModNScalar).Mul2(&e, w)
|
||||
u2 := new(secp256k1.ModNScalar).Mul2(&sig.r, w)
|
||||
|
||||
// Step 5.
|
||||
//
|
||||
// X = u1G + u2Q
|
||||
var X, Q, u1G, u2Q secp256k1.JacobianPoint
|
||||
pubKey.AsJacobian(&Q)
|
||||
secp256k1.ScalarBaseMultNonConst(u1, &u1G)
|
||||
secp256k1.ScalarMultNonConst(u2, &Q, &u2Q)
|
||||
secp256k1.AddNonConst(&u1G, &u2Q, &X)
|
||||
|
||||
// Step 6.
|
||||
//
|
||||
// Fail if X is the point at infinity
|
||||
if (X.X.IsZero() && X.Y.IsZero()) || X.Z.IsZero() {
|
||||
return false
|
||||
}
|
||||
|
||||
// Step 7.
|
||||
//
|
||||
// z = (X.z)^2 mod P (X.z is the z coordinate of X)
|
||||
z := new(secp256k1.FieldVal).SquareVal(&X.Z)
|
||||
|
||||
// Step 8.
|
||||
//
|
||||
// Verified if R * z == X.x (mod P)
|
||||
sigRModP := modNScalarToField(&sig.r)
|
||||
result := new(secp256k1.FieldVal).Mul2(&sigRModP, z).Normalize()
|
||||
if result.Equals(&X.X) {
|
||||
return true
|
||||
}
|
||||
|
||||
// Step 9.
|
||||
//
|
||||
// Fail if R + N >= P
|
||||
if sigRModP.IsGtOrEqPrimeMinusOrder() {
|
||||
return false
|
||||
}
|
||||
|
||||
// Step 10.
|
||||
//
|
||||
// Verified if (R + N) * z == X.x (mod P)
|
||||
sigRModP.Add(&orderAsFieldVal)
|
||||
result.Mul2(&sigRModP, z).Normalize()
|
||||
return result.Equals(&X.X)
|
||||
}
|
||||
|
||||
// IsEqual compares this Signature instance to the one passed, returning true if
|
||||
// both Signatures are equivalent. A signature is equivalent to another, if
|
||||
// they both have the same scalar value for R and S.
|
||||
func (sig *Signature) IsEqual(otherSig *Signature) bool {
|
||||
return sig.r.Equals(&otherSig.r) && sig.s.Equals(&otherSig.s)
|
||||
}
|
||||
|
||||
// ParseDERSignature parses a signature in the Distinguished Encoding Rules
|
||||
// (DER) format per section 10 of [ISO/IEC 8825-1] and enforces the following
|
||||
// additional restrictions specific to secp256k1:
|
||||
//
|
||||
// - The R and S values must be in the valid range for secp256k1 scalars:
|
||||
// - Negative values are rejected
|
||||
// - Zero is rejected
|
||||
// - Values greater than or equal to the secp256k1 group order are rejected
|
||||
func ParseDERSignature(sig []byte) (*Signature, error) {
|
||||
// The format of a DER encoded signature for secp256k1 is as follows:
|
||||
//
|
||||
// 0x30 <total length> 0x02 <length of R> <R> 0x02 <length of S> <S>
|
||||
// - 0x30 is the ASN.1 identifier for a sequence
|
||||
// - Total length is 1 byte and specifies length of all remaining data
|
||||
// - 0x02 is the ASN.1 identifier that specifies an integer follows
|
||||
// - Length of R is 1 byte and specifies how many bytes R occupies
|
||||
// - R is the arbitrary length big-endian encoded number which
|
||||
// represents the R value of the signature. DER encoding dictates
|
||||
// that the value must be encoded using the minimum possible number
|
||||
// of bytes. This implies the first byte can only be null if the
|
||||
// highest bit of the next byte is set in order to prevent it from
|
||||
// being interpreted as a negative number.
|
||||
// - 0x02 is once again the ASN.1 integer identifier
|
||||
// - Length of S is 1 byte and specifies how many bytes S occupies
|
||||
// - S is the arbitrary length big-endian encoded number which
|
||||
// represents the S value of the signature. The encoding rules are
|
||||
// identical as those for R.
|
||||
//
|
||||
// NOTE: The DER specification supports specifying lengths that can occupy
|
||||
// more than 1 byte, however, since this is specific to secp256k1
|
||||
// signatures, all lengths will be a single byte.
|
||||
const (
|
||||
// minSigLen is the minimum length of a DER encoded signature and is
|
||||
// when both R and S are 1 byte each.
|
||||
//
|
||||
// 0x30 + <1-byte> + 0x02 + 0x01 + <byte> + 0x2 + 0x01 + <byte>
|
||||
minSigLen = 8
|
||||
|
||||
// maxSigLen is the maximum length of a DER encoded signature and is
|
||||
// when both R and S are 33 bytes each. It is 33 bytes because a
|
||||
// 256-bit integer requires 32 bytes and an additional leading null byte
|
||||
// might be required if the high bit is set in the value.
|
||||
//
|
||||
// 0x30 + <1-byte> + 0x02 + 0x21 + <33 bytes> + 0x2 + 0x21 + <33 bytes>
|
||||
maxSigLen = 72
|
||||
|
||||
// sequenceOffset is the byte offset within the signature of the
|
||||
// expected ASN.1 sequence identifier.
|
||||
sequenceOffset = 0
|
||||
|
||||
// dataLenOffset is the byte offset within the signature of the expected
|
||||
// total length of all remaining data in the signature.
|
||||
dataLenOffset = 1
|
||||
|
||||
// rTypeOffset is the byte offset within the signature of the ASN.1
|
||||
// identifier for R and is expected to indicate an ASN.1 integer.
|
||||
rTypeOffset = 2
|
||||
|
||||
// rLenOffset is the byte offset within the signature of the length of
|
||||
// R.
|
||||
rLenOffset = 3
|
||||
|
||||
// rOffset is the byte offset within the signature of R.
|
||||
rOffset = 4
|
||||
)
|
||||
|
||||
// The signature must adhere to the minimum and maximum allowed length.
|
||||
sigLen := len(sig)
|
||||
if sigLen < minSigLen {
|
||||
str := fmt.Sprintf("malformed signature: too short: %d < %d", sigLen,
|
||||
minSigLen)
|
||||
return nil, signatureError(ErrSigTooShort, str)
|
||||
}
|
||||
if sigLen > maxSigLen {
|
||||
str := fmt.Sprintf("malformed signature: too long: %d > %d", sigLen,
|
||||
maxSigLen)
|
||||
return nil, signatureError(ErrSigTooLong, str)
|
||||
}
|
||||
|
||||
// The signature must start with the ASN.1 sequence identifier.
|
||||
if sig[sequenceOffset] != asn1SequenceID {
|
||||
str := fmt.Sprintf("malformed signature: format has wrong type: %#x",
|
||||
sig[sequenceOffset])
|
||||
return nil, signatureError(ErrSigInvalidSeqID, str)
|
||||
}
|
||||
|
||||
// The signature must indicate the correct amount of data for all elements
|
||||
// related to R and S.
|
||||
if int(sig[dataLenOffset]) != sigLen-2 {
|
||||
str := fmt.Sprintf("malformed signature: bad length: %d != %d",
|
||||
sig[dataLenOffset], sigLen-2)
|
||||
return nil, signatureError(ErrSigInvalidDataLen, str)
|
||||
}
|
||||
|
||||
// Calculate the offsets of the elements related to S and ensure S is inside
|
||||
// the signature.
|
||||
//
|
||||
// rLen specifies the length of the big-endian encoded number which
|
||||
// represents the R value of the signature.
|
||||
//
|
||||
// sTypeOffset is the offset of the ASN.1 identifier for S and, like its R
|
||||
// counterpart, is expected to indicate an ASN.1 integer.
|
||||
//
|
||||
// sLenOffset and sOffset are the byte offsets within the signature of the
|
||||
// length of S and S itself, respectively.
|
||||
rLen := int(sig[rLenOffset])
|
||||
sTypeOffset := rOffset + rLen
|
||||
sLenOffset := sTypeOffset + 1
|
||||
if sTypeOffset >= sigLen {
|
||||
str := "malformed signature: S type indicator missing"
|
||||
return nil, signatureError(ErrSigMissingSTypeID, str)
|
||||
}
|
||||
if sLenOffset >= sigLen {
|
||||
str := "malformed signature: S length missing"
|
||||
return nil, signatureError(ErrSigMissingSLen, str)
|
||||
}
|
||||
|
||||
// The lengths of R and S must match the overall length of the signature.
|
||||
//
|
||||
// sLen specifies the length of the big-endian encoded number which
|
||||
// represents the S value of the signature.
|
||||
sOffset := sLenOffset + 1
|
||||
sLen := int(sig[sLenOffset])
|
||||
if sOffset+sLen != sigLen {
|
||||
str := "malformed signature: invalid S length"
|
||||
return nil, signatureError(ErrSigInvalidSLen, str)
|
||||
}
|
||||
|
||||
// R elements must be ASN.1 integers.
|
||||
if sig[rTypeOffset] != asn1IntegerID {
|
||||
str := fmt.Sprintf("malformed signature: R integer marker: %#x != %#x",
|
||||
sig[rTypeOffset], asn1IntegerID)
|
||||
return nil, signatureError(ErrSigInvalidRIntID, str)
|
||||
}
|
||||
|
||||
// Zero-length integers are not allowed for R.
|
||||
if rLen == 0 {
|
||||
str := "malformed signature: R length is zero"
|
||||
return nil, signatureError(ErrSigZeroRLen, str)
|
||||
}
|
||||
|
||||
// R must not be negative.
|
||||
if sig[rOffset]&0x80 != 0 {
|
||||
str := "malformed signature: R is negative"
|
||||
return nil, signatureError(ErrSigNegativeR, str)
|
||||
}
|
||||
|
||||
// Null bytes at the start of R are not allowed, unless R would otherwise be
|
||||
// interpreted as a negative number.
|
||||
if rLen > 1 && sig[rOffset] == 0x00 && sig[rOffset+1]&0x80 == 0 {
|
||||
str := "malformed signature: R value has too much padding"
|
||||
return nil, signatureError(ErrSigTooMuchRPadding, str)
|
||||
}
|
||||
|
||||
// S elements must be ASN.1 integers.
|
||||
if sig[sTypeOffset] != asn1IntegerID {
|
||||
str := fmt.Sprintf("malformed signature: S integer marker: %#x != %#x",
|
||||
sig[sTypeOffset], asn1IntegerID)
|
||||
return nil, signatureError(ErrSigInvalidSIntID, str)
|
||||
}
|
||||
|
||||
// Zero-length integers are not allowed for S.
|
||||
if sLen == 0 {
|
||||
str := "malformed signature: S length is zero"
|
||||
return nil, signatureError(ErrSigZeroSLen, str)
|
||||
}
|
||||
|
||||
// S must not be negative.
|
||||
if sig[sOffset]&0x80 != 0 {
|
||||
str := "malformed signature: S is negative"
|
||||
return nil, signatureError(ErrSigNegativeS, str)
|
||||
}
|
||||
|
||||
// Null bytes at the start of S are not allowed, unless S would otherwise be
|
||||
// interpreted as a negative number.
|
||||
if sLen > 1 && sig[sOffset] == 0x00 && sig[sOffset+1]&0x80 == 0 {
|
||||
str := "malformed signature: S value has too much padding"
|
||||
return nil, signatureError(ErrSigTooMuchSPadding, str)
|
||||
}
|
||||
|
||||
// The signature is validly encoded per DER at this point, however, enforce
|
||||
// additional restrictions to ensure R and S are in the range [1, N-1] since
|
||||
// valid ECDSA signatures are required to be in that range per spec.
|
||||
//
|
||||
// Also note that while the overflow checks are required to make use of the
|
||||
// specialized mod N scalar type, rejecting zero here is not strictly
|
||||
// required because it is also checked when verifying the signature, but
|
||||
// there really isn't a good reason not to fail early here on signatures
|
||||
// that do not conform to the ECDSA spec.
|
||||
|
||||
// Strip leading zeroes from R.
|
||||
rBytes := sig[rOffset : rOffset+rLen]
|
||||
for len(rBytes) > 0 && rBytes[0] == 0x00 {
|
||||
rBytes = rBytes[1:]
|
||||
}
|
||||
|
||||
// R must be in the range [1, N-1]. Notice the check for the maximum number
|
||||
// of bytes is required because SetByteSlice truncates as noted in its
|
||||
// comment so it could otherwise fail to detect the overflow.
|
||||
var r secp256k1.ModNScalar
|
||||
if len(rBytes) > 32 {
|
||||
str := "invalid signature: R is larger than 256 bits"
|
||||
return nil, signatureError(ErrSigRTooBig, str)
|
||||
}
|
||||
if overflow := r.SetByteSlice(rBytes); overflow {
|
||||
str := "invalid signature: R >= group order"
|
||||
return nil, signatureError(ErrSigRTooBig, str)
|
||||
}
|
||||
if r.IsZero() {
|
||||
str := "invalid signature: R is 0"
|
||||
return nil, signatureError(ErrSigRIsZero, str)
|
||||
}
|
||||
|
||||
// Strip leading zeroes from S.
|
||||
sBytes := sig[sOffset : sOffset+sLen]
|
||||
for len(sBytes) > 0 && sBytes[0] == 0x00 {
|
||||
sBytes = sBytes[1:]
|
||||
}
|
||||
|
||||
// S must be in the range [1, N-1]. Notice the check for the maximum number
|
||||
// of bytes is required because SetByteSlice truncates as noted in its
|
||||
// comment so it could otherwise fail to detect the overflow.
|
||||
var s secp256k1.ModNScalar
|
||||
if len(sBytes) > 32 {
|
||||
str := "invalid signature: S is larger than 256 bits"
|
||||
return nil, signatureError(ErrSigSTooBig, str)
|
||||
}
|
||||
if overflow := s.SetByteSlice(sBytes); overflow {
|
||||
str := "invalid signature: S >= group order"
|
||||
return nil, signatureError(ErrSigSTooBig, str)
|
||||
}
|
||||
if s.IsZero() {
|
||||
str := "invalid signature: S is 0"
|
||||
return nil, signatureError(ErrSigSIsZero, str)
|
||||
}
|
||||
|
||||
// Create and return the signature.
|
||||
return NewSignature(&r, &s), nil
|
||||
}
|
||||
|
||||
// sign generates an ECDSA signature over the secp256k1 curve for the provided
|
||||
// hash (which should be the result of hashing a larger message) using the given
|
||||
// nonce and private key and returns it along with an additional public key
|
||||
// recovery code and success indicator. Upon success, the produced signature is
|
||||
// deterministic (same message, nonce, and key yield the same signature) and
|
||||
// canonical in accordance with BIP0062.
|
||||
//
|
||||
// Note that signRFC6979 makes use of this function as it is the primary ECDSA
|
||||
// signing logic. It differs in that it accepts a nonce to use when signing and
|
||||
// may not successfully produce a valid signature for the given nonce. It is
|
||||
// primarily separated for testing purposes.
|
||||
func sign(privKey, nonce *secp256k1.ModNScalar, hash []byte) (*Signature, byte, bool) {
|
||||
// The algorithm for producing an ECDSA signature is given as algorithm 4.29
|
||||
// in [GECC].
|
||||
//
|
||||
// The following is a paraphrased version for reference:
|
||||
//
|
||||
// G = curve generator
|
||||
// N = curve order
|
||||
// d = private key
|
||||
// m = message
|
||||
// r, s = signature
|
||||
//
|
||||
// 1. Select random nonce k in [1, N-1]
|
||||
// 2. Compute kG
|
||||
// 3. r = kG.x mod N (kG.x is the x coordinate of the point kG)
|
||||
// Repeat from step 1 if r = 0
|
||||
// 4. e = H(m)
|
||||
// 5. s = k^-1(e + dr) mod N
|
||||
// Repeat from step 1 if s = 0
|
||||
// 6. Return (r,s)
|
||||
//
|
||||
// This is slightly modified here to conform to RFC6979 and BIP 62 as
|
||||
// follows:
|
||||
//
|
||||
// A. Instead of selecting a random nonce in step 1, use RFC6979 to generate
|
||||
// a deterministic nonce in [1, N-1] parameterized by the private key,
|
||||
// message being signed, and an iteration count for the repeat cases
|
||||
// B. Negate s calculated in step 5 if it is > N/2
|
||||
// This is done because both s and its negation are valid signatures
|
||||
// modulo the curve order N, so it forces a consistent choice to reduce
|
||||
// signature malleability
|
||||
|
||||
// NOTE: Step 1 is performed by the caller.
|
||||
//
|
||||
// Step 2.
|
||||
//
|
||||
// Compute kG
|
||||
//
|
||||
// Note that the point must be in affine coordinates.
|
||||
k := nonce
|
||||
var kG secp256k1.JacobianPoint
|
||||
secp256k1.ScalarBaseMultNonConst(k, &kG)
|
||||
kG.ToAffine()
|
||||
|
||||
// Step 3.
|
||||
//
|
||||
// r = kG.x mod N
|
||||
// Repeat from step 1 if r = 0
|
||||
r, overflow := fieldToModNScalar(&kG.X)
|
||||
if r.IsZero() {
|
||||
return nil, 0, false
|
||||
}
|
||||
|
||||
// Since the secp256k1 curve has a cofactor of 1, when recovering a
|
||||
// public key from an ECDSA signature over it, there are four possible
|
||||
// candidates corresponding to the following cases:
|
||||
//
|
||||
// 1) The X coord of the random point is < N and its Y coord even
|
||||
// 2) The X coord of the random point is < N and its Y coord is odd
|
||||
// 3) The X coord of the random point is >= N and its Y coord is even
|
||||
// 4) The X coord of the random point is >= N and its Y coord is odd
|
||||
//
|
||||
// Rather than forcing the recovery procedure to check all possible
|
||||
// cases, this creates a recovery code that uniquely identifies which of
|
||||
// the cases apply by making use of 2 bits. Bit 0 identifies the
|
||||
// oddness case and Bit 1 identifies the overflow case (aka when the X
|
||||
// coord >= N).
|
||||
//
|
||||
// It is also worth noting that making use of Hasse's theorem shows
|
||||
// there are around log_2((p-n)/p) ~= -127.65 ~= 1 in 2^127 points where
|
||||
// the X coordinate is >= N. It is not possible to calculate these
|
||||
// points since that would require breaking the ECDLP, but, in practice
|
||||
// this strongly implies with extremely high probability that there are
|
||||
// only a few actual points for which this case is true.
|
||||
pubKeyRecoveryCode := byte(overflow<<1) | byte(kG.Y.IsOddBit())
|
||||
|
||||
// Step 4.
|
||||
//
|
||||
// e = H(m)
|
||||
//
|
||||
// Note that this actually sets e = H(m) mod N which is correct since
|
||||
// it is only used in step 5 which itself is mod N.
|
||||
var e secp256k1.ModNScalar
|
||||
e.SetByteSlice(hash)
|
||||
|
||||
// Step 5 with modification B.
|
||||
//
|
||||
// s = k^-1(e + dr) mod N
|
||||
// Repeat from step 1 if s = 0
|
||||
// s = -s if s > N/2
|
||||
kinv := new(secp256k1.ModNScalar).InverseValNonConst(k)
|
||||
s := new(secp256k1.ModNScalar).Mul2(privKey, &r).Add(&e).Mul(kinv)
|
||||
if s.IsZero() {
|
||||
return nil, 0, false
|
||||
}
|
||||
if s.IsOverHalfOrder() {
|
||||
s.Negate()
|
||||
|
||||
// Negating s corresponds to the random point that would have been
|
||||
// generated by -k (mod N), which necessarily has the opposite
|
||||
// oddness since N is prime, thus flip the pubkey recovery code
|
||||
// oddness bit accordingly.
|
||||
pubKeyRecoveryCode ^= 0x01
|
||||
}
|
||||
|
||||
// Step 6.
|
||||
//
|
||||
// Return (r,s)
|
||||
return NewSignature(&r, s), pubKeyRecoveryCode, true
|
||||
}
|
||||
|
||||
// signRFC6979 generates a deterministic ECDSA signature according to RFC 6979
|
||||
// and BIP0062 and returns it along with an additional public key recovery code
|
||||
// for efficiently recovering the public key from the signature.
|
||||
func signRFC6979(privKey *secp256k1.PrivateKey, hash []byte) (*Signature, byte) {
|
||||
// The algorithm for producing an ECDSA signature is given as algorithm 4.29
|
||||
// in [GECC].
|
||||
//
|
||||
// The following is a paraphrased version for reference:
|
||||
//
|
||||
// G = curve generator
|
||||
// N = curve order
|
||||
// d = private key
|
||||
// m = message
|
||||
// r, s = signature
|
||||
//
|
||||
// 1. Select random nonce k in [1, N-1]
|
||||
// 2. Compute kG
|
||||
// 3. r = kG.x mod N (kG.x is the x coordinate of the point kG)
|
||||
// Repeat from step 1 if r = 0
|
||||
// 4. e = H(m)
|
||||
// 5. s = k^-1(e + dr) mod N
|
||||
// Repeat from step 1 if s = 0
|
||||
// 6. Return (r,s)
|
||||
//
|
||||
// This is slightly modified here to conform to RFC6979 and BIP 62 as
|
||||
// follows:
|
||||
//
|
||||
// A. Instead of selecting a random nonce in step 1, use RFC6979 to generate
|
||||
// a deterministic nonce in [1, N-1] parameterized by the private key,
|
||||
// message being signed, and an iteration count for the repeat cases
|
||||
// B. Negate s calculated in step 5 if it is > N/2
|
||||
// This is done because both s and its negation are valid signatures
|
||||
// modulo the curve order N, so it forces a consistent choice to reduce
|
||||
// signature malleability
|
||||
|
||||
privKeyScalar := &privKey.Key
|
||||
var privKeyBytes [32]byte
|
||||
privKeyScalar.PutBytes(&privKeyBytes)
|
||||
defer zeroArray32(&privKeyBytes)
|
||||
for iteration := uint32(0); ; iteration++ {
|
||||
// Step 1 with modification A.
|
||||
//
|
||||
// Generate a deterministic nonce in [1, N-1] parameterized by the
|
||||
// private key, message being signed, and iteration count.
|
||||
k := secp256k1.NonceRFC6979(privKeyBytes[:], hash, nil, nil, iteration)
|
||||
|
||||
// Steps 2-6.
|
||||
sig, pubKeyRecoveryCode, success := sign(privKeyScalar, k, hash)
|
||||
k.Zero()
|
||||
if !success {
|
||||
continue
|
||||
}
|
||||
|
||||
return sig, pubKeyRecoveryCode
|
||||
}
|
||||
}
|
||||
|
||||
// Sign generates an ECDSA signature over the secp256k1 curve for the provided
|
||||
// hash (which should be the result of hashing a larger message) using the given
|
||||
// private key. The produced signature is deterministic (same message and same
|
||||
// key yield the same signature) and canonical in accordance with RFC6979 and
|
||||
// BIP0062.
|
||||
func Sign(key *secp256k1.PrivateKey, hash []byte) *Signature {
|
||||
signature, _ := signRFC6979(key, hash)
|
||||
return signature
|
||||
}
|
||||
|
||||
const (
|
||||
// compactSigSize is the size of a compact signature. It consists of a
|
||||
// compact signature recovery code byte followed by the R and S components
|
||||
// serialized as 32-byte big-endian values. 1+32*2 = 65.
|
||||
// for the R and S components. 1+32+32=65.
|
||||
compactSigSize = 65
|
||||
|
||||
// compactSigMagicOffset is a value used when creating the compact signature
|
||||
// recovery code inherited from Bitcoin and has no meaning, but has been
|
||||
// retained for compatibility. For historical purposes, it was originally
|
||||
// picked to avoid a binary representation that would allow compact
|
||||
// signatures to be mistaken for other components.
|
||||
compactSigMagicOffset = 27
|
||||
|
||||
// compactSigCompPubKey is a value used when creating the compact signature
|
||||
// recovery code to indicate the original public key was compressed.
|
||||
compactSigCompPubKey = 4
|
||||
|
||||
// pubKeyRecoveryCodeOddnessBit specifies the bit that indicates the oddess
|
||||
// of the Y coordinate of the random point calculated when creating a
|
||||
// signature.
|
||||
pubKeyRecoveryCodeOddnessBit = 1 << 0
|
||||
|
||||
// pubKeyRecoveryCodeOverflowBit specifies the bit that indicates the X
|
||||
// coordinate of the random point calculated when creating a signature was
|
||||
// >= N, where N is the order of the group.
|
||||
pubKeyRecoveryCodeOverflowBit = 1 << 1
|
||||
)
|
||||
|
||||
// SignCompact produces a compact ECDSA signature over the secp256k1 curve for
|
||||
// the provided hash (which should be the result of hashing a larger message)
|
||||
// using the given private key. The isCompressedKey parameter specifies if the
|
||||
// produced signature should reference a compressed public key or not.
|
||||
//
|
||||
// Compact signature format:
|
||||
// <1-byte compact sig recovery code><32-byte R><32-byte S>
|
||||
//
|
||||
// The compact sig recovery code is the value 27 + public key recovery code + 4
|
||||
// if the compact signature was created with a compressed public key.
|
||||
func SignCompact(key *secp256k1.PrivateKey, hash []byte, isCompressedKey bool) []byte {
|
||||
// Create the signature and associated pubkey recovery code and calculate
|
||||
// the compact signature recovery code.
|
||||
sig, pubKeyRecoveryCode := signRFC6979(key, hash)
|
||||
compactSigRecoveryCode := compactSigMagicOffset + pubKeyRecoveryCode
|
||||
if isCompressedKey {
|
||||
compactSigRecoveryCode += compactSigCompPubKey
|
||||
}
|
||||
|
||||
// Output <compactSigRecoveryCode><32-byte R><32-byte S>.
|
||||
var b [compactSigSize]byte
|
||||
b[0] = compactSigRecoveryCode
|
||||
sig.r.PutBytesUnchecked(b[1:33])
|
||||
sig.s.PutBytesUnchecked(b[33:65])
|
||||
return b[:]
|
||||
}
|
||||
|
||||
// RecoverCompact attempts to recover the secp256k1 public key from the provided
|
||||
// compact signature and message hash. It first verifies the signature, and, if
|
||||
// the signature matches then the recovered public key will be returned as well
|
||||
// as a boolean indicating whether or not the original key was compressed.
|
||||
func RecoverCompact(signature, hash []byte) (*secp256k1.PublicKey, bool, error) {
|
||||
// The following is very loosely based on the information and algorithm that
|
||||
// describes recovering a public key from and ECDSA signature in section
|
||||
// 4.1.6 of [SEC1].
|
||||
//
|
||||
// Given the following parameters:
|
||||
//
|
||||
// G = curve generator
|
||||
// N = group order
|
||||
// P = field prime
|
||||
// Q = public key
|
||||
// m = message
|
||||
// e = hash of the message
|
||||
// r, s = signature
|
||||
// X = random point used when creating signature whose x coordinate is r
|
||||
//
|
||||
// The equation to recover a public key candidate from an ECDSA signature
|
||||
// is:
|
||||
// Q = r^-1(sX - eG).
|
||||
//
|
||||
// This can be verified by plugging it in for Q in the sig verification
|
||||
// equation:
|
||||
// X = s^-1(eG + rQ) (mod N)
|
||||
// => s^-1(eG + r(r^-1(sX - eG))) (mod N)
|
||||
// => s^-1(eG + sX - eG) (mod N)
|
||||
// => s^-1(sX) (mod N)
|
||||
// => X (mod N)
|
||||
//
|
||||
// However, note that since r is the x coordinate mod N from a random point
|
||||
// that was originally mod P, and the cofactor of the secp256k1 curve is 1,
|
||||
// there are four possible points that the original random point could have
|
||||
// been to produce r: (r,y), (r,-y), (r+N,y), and (r+N,-y). At least 2 of
|
||||
// those points will successfully verify, and all 4 will successfully verify
|
||||
// when the original x coordinate was in the range [N+1, P-1], but in any
|
||||
// case, only one of them corresponds to the original private key used.
|
||||
//
|
||||
// The method described by section 4.1.6 of [SEC1] to determine which one is
|
||||
// the correct one involves calculating each possibility as a candidate
|
||||
// public key and comparing the candidate to the authentic public key. It
|
||||
// also hints that it is possible to generate the signature in a such a
|
||||
// way that only one of the candidate public keys is viable.
|
||||
//
|
||||
// A more efficient approach that is specific to the secp256k1 curve is used
|
||||
// here instead which is to produce a "pubkey recovery code" when signing
|
||||
// that uniquely identifies which of the 4 possibilities is correct for the
|
||||
// original random point and using that to recover the pubkey directly as
|
||||
// follows:
|
||||
//
|
||||
// 1. Fail if r and s are not in [1, N-1]
|
||||
// 2. Convert r to integer mod P
|
||||
// 3. If pubkey recovery code overflow bit is set:
|
||||
// 3.1 Fail if r + N >= P
|
||||
// 3.2 r = r + N (mod P)
|
||||
// 4. y = +sqrt(r^3 + 7) (mod P)
|
||||
// 4.1 Fail if y does not exist
|
||||
// 4.2 y = -y if needed to match pubkey recovery code oddness bit
|
||||
// 5. X = (r, y)
|
||||
// 6. e = H(m) mod N
|
||||
// 7. w = r^-1 mod N
|
||||
// 8. u1 = -(e * w) mod N
|
||||
// u2 = s * w mod N
|
||||
// 9. Q = u1G + u2X
|
||||
// 10. Fail if Q is the point at infinity
|
||||
|
||||
// A compact signature consists of a recovery byte followed by the R and
|
||||
// S components serialized as 32-byte big-endian values.
|
||||
if len(signature) != compactSigSize {
|
||||
str := fmt.Sprintf("malformed signature: wrong size: %d != %d",
|
||||
len(signature), compactSigSize)
|
||||
return nil, false, signatureError(ErrSigInvalidLen, str)
|
||||
}
|
||||
|
||||
// Parse and validate the compact signature recovery code.
|
||||
const (
|
||||
minValidCode = compactSigMagicOffset
|
||||
maxValidCode = compactSigMagicOffset + compactSigCompPubKey + 3
|
||||
)
|
||||
sigRecoveryCode := signature[0]
|
||||
if sigRecoveryCode < minValidCode || sigRecoveryCode > maxValidCode {
|
||||
str := fmt.Sprintf("invalid signature: public key recovery code %d is "+
|
||||
"not in the valid range [%d, %d]", sigRecoveryCode, minValidCode,
|
||||
maxValidCode)
|
||||
return nil, false, signatureError(ErrSigInvalidRecoveryCode, str)
|
||||
}
|
||||
sigRecoveryCode -= compactSigMagicOffset
|
||||
wasCompressed := sigRecoveryCode&compactSigCompPubKey != 0
|
||||
pubKeyRecoveryCode := sigRecoveryCode & 3
|
||||
|
||||
// Step 1.
|
||||
//
|
||||
// Parse and validate the R and S signature components.
|
||||
//
|
||||
// Fail if r and s are not in [1, N-1].
|
||||
var r, s secp256k1.ModNScalar
|
||||
if overflow := r.SetByteSlice(signature[1:33]); overflow {
|
||||
str := "invalid signature: R >= group order"
|
||||
return nil, false, signatureError(ErrSigRTooBig, str)
|
||||
}
|
||||
if r.IsZero() {
|
||||
str := "invalid signature: R is 0"
|
||||
return nil, false, signatureError(ErrSigRIsZero, str)
|
||||
}
|
||||
if overflow := s.SetByteSlice(signature[33:]); overflow {
|
||||
str := "invalid signature: S >= group order"
|
||||
return nil, false, signatureError(ErrSigSTooBig, str)
|
||||
}
|
||||
if s.IsZero() {
|
||||
str := "invalid signature: S is 0"
|
||||
return nil, false, signatureError(ErrSigSIsZero, str)
|
||||
}
|
||||
|
||||
// Step 2.
|
||||
//
|
||||
// Convert r to integer mod P.
|
||||
fieldR := modNScalarToField(&r)
|
||||
|
||||
// Step 3.
|
||||
//
|
||||
// If pubkey recovery code overflow bit is set:
|
||||
if pubKeyRecoveryCode&pubKeyRecoveryCodeOverflowBit != 0 {
|
||||
// Step 3.1.
|
||||
//
|
||||
// Fail if r + N >= P
|
||||
//
|
||||
// Either the signature or the recovery code must be invalid if the
|
||||
// recovery code overflow bit is set and adding N to the R component
|
||||
// would exceed the field prime since R originally came from the X
|
||||
// coordinate of a random point on the curve.
|
||||
if fieldR.IsGtOrEqPrimeMinusOrder() {
|
||||
str := "invalid signature: signature R + N >= P"
|
||||
return nil, false, signatureError(ErrSigOverflowsPrime, str)
|
||||
}
|
||||
|
||||
// Step 3.2.
|
||||
//
|
||||
// r = r + N (mod P)
|
||||
fieldR.Add(&orderAsFieldVal)
|
||||
}
|
||||
|
||||
// Step 4.
|
||||
//
|
||||
// y = +sqrt(r^3 + 7) (mod P)
|
||||
// Fail if y does not exist.
|
||||
// y = -y if needed to match pubkey recovery code oddness bit
|
||||
//
|
||||
// The signature must be invalid if the calculation fails because the X
|
||||
// coord originally came from a random point on the curve which means there
|
||||
// must be a Y coord that satisfies the equation for a valid signature.
|
||||
oddY := pubKeyRecoveryCode&pubKeyRecoveryCodeOddnessBit != 0
|
||||
var y secp256k1.FieldVal
|
||||
if valid := secp256k1.DecompressY(&fieldR, oddY, &y); !valid {
|
||||
str := "invalid signature: not for a valid curve point"
|
||||
return nil, false, signatureError(ErrPointNotOnCurve, str)
|
||||
}
|
||||
|
||||
// Step 5.
|
||||
//
|
||||
// X = (r, y)
|
||||
var X secp256k1.JacobianPoint
|
||||
X.X.Set(fieldR.Normalize())
|
||||
X.Y.Set(y.Normalize())
|
||||
X.Z.SetInt(1)
|
||||
|
||||
// Step 6.
|
||||
//
|
||||
// e = H(m) mod N
|
||||
var e secp256k1.ModNScalar
|
||||
e.SetByteSlice(hash)
|
||||
|
||||
// Step 7.
|
||||
//
|
||||
// w = r^-1 mod N
|
||||
w := new(secp256k1.ModNScalar).InverseValNonConst(&r)
|
||||
|
||||
// Step 8.
|
||||
//
|
||||
// u1 = -(e * w) mod N
|
||||
// u2 = s * w mod N
|
||||
u1 := new(secp256k1.ModNScalar).Mul2(&e, w).Negate()
|
||||
u2 := new(secp256k1.ModNScalar).Mul2(&s, w)
|
||||
|
||||
// Step 9.
|
||||
//
|
||||
// Q = u1G + u2X
|
||||
var Q, u1G, u2X secp256k1.JacobianPoint
|
||||
secp256k1.ScalarBaseMultNonConst(u1, &u1G)
|
||||
secp256k1.ScalarMultNonConst(u2, &X, &u2X)
|
||||
secp256k1.AddNonConst(&u1G, &u2X, &Q)
|
||||
|
||||
// Step 10.
|
||||
//
|
||||
// Fail if Q is the point at infinity.
|
||||
//
|
||||
// Either the signature or the pubkey recovery code must be invalid if the
|
||||
// recovered pubkey is the point at infinity.
|
||||
if (Q.X.IsZero() && Q.Y.IsZero()) || Q.Z.IsZero() {
|
||||
str := "invalid signature: recovered pubkey is the point at infinity"
|
||||
return nil, false, signatureError(ErrPointNotOnCurve, str)
|
||||
}
|
||||
|
||||
// Notice that the public key is in affine coordinates.
|
||||
Q.ToAffine()
|
||||
pubKey := secp256k1.NewPublicKey(&Q.X, &Q.Y)
|
||||
return pubKey, wasCompressed, nil
|
||||
}
|
||||
255
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go
generated
vendored
Normal file
255
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go
generated
vendored
Normal file
@@ -0,0 +1,255 @@
|
||||
// Copyright 2020-2022 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:
|
||||
// [SECG]: Recommended Elliptic Curve Domain Parameters
|
||||
// https://www.secg.org/sec2-v2.pdf
|
||||
//
|
||||
// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// CurveParams contains the parameters for the secp256k1 curve.
|
||||
type CurveParams struct {
|
||||
// P is the prime used in the secp256k1 field.
|
||||
P *big.Int
|
||||
|
||||
// N is the order of the secp256k1 curve group generated by the base point.
|
||||
N *big.Int
|
||||
|
||||
// Gx and Gy are the x and y coordinate of the base point, respectively.
|
||||
Gx, Gy *big.Int
|
||||
|
||||
// BitSize is the size of the underlying secp256k1 field in bits.
|
||||
BitSize int
|
||||
|
||||
// H is the cofactor of the secp256k1 curve.
|
||||
H int
|
||||
|
||||
// ByteSize is simply the bit size / 8 and is provided for convenience
|
||||
// since it is calculated repeatedly.
|
||||
ByteSize int
|
||||
}
|
||||
|
||||
// Curve parameters taken from [SECG] section 2.4.1.
|
||||
var curveParams = CurveParams{
|
||||
P: fromHex("fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"),
|
||||
N: fromHex("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),
|
||||
Gx: fromHex("79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798"),
|
||||
Gy: fromHex("483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8"),
|
||||
BitSize: 256,
|
||||
H: 1,
|
||||
ByteSize: 256 / 8,
|
||||
}
|
||||
|
||||
// Params returns the secp256k1 curve parameters for convenience.
|
||||
func Params() *CurveParams {
|
||||
return &curveParams
|
||||
}
|
||||
|
||||
// KoblitzCurve provides an implementation for secp256k1 that fits the ECC Curve
|
||||
// interface from crypto/elliptic.
|
||||
type KoblitzCurve struct {
|
||||
*elliptic.CurveParams
|
||||
}
|
||||
|
||||
// bigAffineToJacobian takes an affine point (x, y) as big integers and converts
|
||||
// it to Jacobian point with Z=1.
|
||||
func bigAffineToJacobian(x, y *big.Int, result *JacobianPoint) {
|
||||
result.X.SetByteSlice(x.Bytes())
|
||||
result.Y.SetByteSlice(y.Bytes())
|
||||
result.Z.SetInt(1)
|
||||
}
|
||||
|
||||
// jacobianToBigAffine takes a Jacobian point (x, y, z) as field values and
|
||||
// converts it to an affine point as big integers.
|
||||
func jacobianToBigAffine(point *JacobianPoint) (*big.Int, *big.Int) {
|
||||
point.ToAffine()
|
||||
|
||||
// Convert the field values for the now affine point to big.Ints.
|
||||
x3, y3 := new(big.Int), new(big.Int)
|
||||
x3.SetBytes(point.X.Bytes()[:])
|
||||
y3.SetBytes(point.Y.Bytes()[:])
|
||||
return x3, y3
|
||||
}
|
||||
|
||||
// Params returns the parameters for the curve.
|
||||
//
|
||||
// This is part of the elliptic.Curve interface implementation.
|
||||
func (curve *KoblitzCurve) Params() *elliptic.CurveParams {
|
||||
return curve.CurveParams
|
||||
}
|
||||
|
||||
// IsOnCurve returns whether or not the affine point (x,y) is on the curve.
|
||||
//
|
||||
// This is part of the elliptic.Curve interface implementation. This function
|
||||
// differs from the crypto/elliptic algorithm since a = 0 not -3.
|
||||
func (curve *KoblitzCurve) IsOnCurve(x, y *big.Int) bool {
|
||||
// Convert big ints to a Jacobian point for faster arithmetic.
|
||||
var point JacobianPoint
|
||||
bigAffineToJacobian(x, y, &point)
|
||||
return isOnCurve(&point.X, &point.Y)
|
||||
}
|
||||
|
||||
// Add returns the sum of (x1,y1) and (x2,y2).
|
||||
//
|
||||
// This is part of the elliptic.Curve interface implementation.
|
||||
func (curve *KoblitzCurve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
|
||||
// The point at infinity is the identity according to the group law for
|
||||
// elliptic curve cryptography. Thus, ∞ + P = P and P + ∞ = P.
|
||||
if x1.Sign() == 0 && y1.Sign() == 0 {
|
||||
return x2, y2
|
||||
}
|
||||
if x2.Sign() == 0 && y2.Sign() == 0 {
|
||||
return x1, y1
|
||||
}
|
||||
|
||||
// Convert the affine coordinates from big integers to Jacobian points,
|
||||
// do the point addition in Jacobian projective space, and convert the
|
||||
// Jacobian point back to affine big.Ints.
|
||||
var p1, p2, result JacobianPoint
|
||||
bigAffineToJacobian(x1, y1, &p1)
|
||||
bigAffineToJacobian(x2, y2, &p2)
|
||||
AddNonConst(&p1, &p2, &result)
|
||||
return jacobianToBigAffine(&result)
|
||||
}
|
||||
|
||||
// Double returns 2*(x1,y1).
|
||||
//
|
||||
// This is part of the elliptic.Curve interface implementation.
|
||||
func (curve *KoblitzCurve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
|
||||
if y1.Sign() == 0 {
|
||||
return new(big.Int), new(big.Int)
|
||||
}
|
||||
|
||||
// Convert the affine coordinates from big integers to Jacobian points,
|
||||
// do the point doubling in Jacobian projective space, and convert the
|
||||
// Jacobian point back to affine big.Ints.
|
||||
var point, result JacobianPoint
|
||||
bigAffineToJacobian(x1, y1, &point)
|
||||
DoubleNonConst(&point, &result)
|
||||
return jacobianToBigAffine(&result)
|
||||
}
|
||||
|
||||
// moduloReduce reduces k from more than 32 bytes to 32 bytes and under. This
|
||||
// is done by doing a simple modulo curve.N. We can do this since G^N = 1 and
|
||||
// thus any other valid point on the elliptic curve has the same order.
|
||||
func moduloReduce(k []byte) []byte {
|
||||
// Since the order of G is curve.N, we can use a much smaller number by
|
||||
// doing modulo curve.N
|
||||
if len(k) > curveParams.ByteSize {
|
||||
tmpK := new(big.Int).SetBytes(k)
|
||||
tmpK.Mod(tmpK, curveParams.N)
|
||||
return tmpK.Bytes()
|
||||
}
|
||||
|
||||
return k
|
||||
}
|
||||
|
||||
// ScalarMult returns k*(Bx, By) where k is a big endian integer.
|
||||
//
|
||||
// This is part of the elliptic.Curve interface implementation.
|
||||
func (curve *KoblitzCurve) ScalarMult(Bx, By *big.Int, k []byte) (*big.Int, *big.Int) {
|
||||
// Convert the affine coordinates from big integers to Jacobian points,
|
||||
// do the multiplication in Jacobian projective space, and convert the
|
||||
// Jacobian point back to affine big.Ints.
|
||||
var kModN ModNScalar
|
||||
kModN.SetByteSlice(moduloReduce(k))
|
||||
var point, result JacobianPoint
|
||||
bigAffineToJacobian(Bx, By, &point)
|
||||
ScalarMultNonConst(&kModN, &point, &result)
|
||||
return jacobianToBigAffine(&result)
|
||||
}
|
||||
|
||||
// ScalarBaseMult returns k*G where G is the base point of the group and k is a
|
||||
// big endian integer.
|
||||
//
|
||||
// This is part of the elliptic.Curve interface implementation.
|
||||
func (curve *KoblitzCurve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
|
||||
// Perform the multiplication and convert the Jacobian point back to affine
|
||||
// big.Ints.
|
||||
var kModN ModNScalar
|
||||
kModN.SetByteSlice(moduloReduce(k))
|
||||
var result JacobianPoint
|
||||
ScalarBaseMultNonConst(&kModN, &result)
|
||||
return jacobianToBigAffine(&result)
|
||||
}
|
||||
|
||||
// X returns the x coordinate of the public key.
|
||||
func (p *PublicKey) X() *big.Int {
|
||||
return new(big.Int).SetBytes(p.x.Bytes()[:])
|
||||
}
|
||||
|
||||
// Y returns the y coordinate of the public key.
|
||||
func (p *PublicKey) Y() *big.Int {
|
||||
return new(big.Int).SetBytes(p.y.Bytes()[:])
|
||||
}
|
||||
|
||||
// ToECDSA returns the public key as a *ecdsa.PublicKey.
|
||||
func (p *PublicKey) ToECDSA() *ecdsa.PublicKey {
|
||||
return &ecdsa.PublicKey{
|
||||
Curve: S256(),
|
||||
X: p.X(),
|
||||
Y: p.Y(),
|
||||
}
|
||||
}
|
||||
|
||||
// ToECDSA returns the private key as a *ecdsa.PrivateKey.
|
||||
func (p *PrivateKey) ToECDSA() *ecdsa.PrivateKey {
|
||||
var privKeyBytes [PrivKeyBytesLen]byte
|
||||
p.Key.PutBytes(&privKeyBytes)
|
||||
var result JacobianPoint
|
||||
ScalarBaseMultNonConst(&p.Key, &result)
|
||||
x, y := jacobianToBigAffine(&result)
|
||||
newPrivKey := &ecdsa.PrivateKey{
|
||||
PublicKey: ecdsa.PublicKey{
|
||||
Curve: S256(),
|
||||
X: x,
|
||||
Y: y,
|
||||
},
|
||||
D: new(big.Int).SetBytes(privKeyBytes[:]),
|
||||
}
|
||||
zeroArray32(&privKeyBytes)
|
||||
return newPrivKey
|
||||
}
|
||||
|
||||
// fromHex converts the passed hex string into a big integer pointer and will
|
||||
// panic is there is an error. This is only provided for the hard-coded
|
||||
// constants so errors in the source code can bet detected. It will only (and
|
||||
// must only) be called for initialization purposes.
|
||||
func fromHex(s string) *big.Int {
|
||||
if s == "" {
|
||||
return big.NewInt(0)
|
||||
}
|
||||
r, ok := new(big.Int).SetString(s, 16)
|
||||
if !ok {
|
||||
panic("invalid hex in source file: " + s)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// secp256k1 is a global instance of the KoblitzCurve implementation which in
|
||||
// turn embeds and implements elliptic.CurveParams.
|
||||
var secp256k1 = &KoblitzCurve{
|
||||
CurveParams: &elliptic.CurveParams{
|
||||
P: curveParams.P,
|
||||
N: curveParams.N,
|
||||
B: fromHex("0000000000000000000000000000000000000000000000000000000000000007"),
|
||||
Gx: curveParams.Gx,
|
||||
Gy: curveParams.Gy,
|
||||
BitSize: curveParams.BitSize,
|
||||
Name: "secp256k1",
|
||||
},
|
||||
}
|
||||
|
||||
// S256 returns an elliptic.Curve which implements secp256k1.
|
||||
func S256() *KoblitzCurve {
|
||||
return secp256k1
|
||||
}
|
||||
67
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go
generated
vendored
Normal file
67
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright (c) 2020 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package secp256k1
|
||||
|
||||
// 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 ErrorKind string
|
||||
|
||||
// These constants are used to identify a specific RuleError.
|
||||
const (
|
||||
// ErrPubKeyInvalidLen indicates that the length of a serialized public
|
||||
// key is not one of the allowed lengths.
|
||||
ErrPubKeyInvalidLen = ErrorKind("ErrPubKeyInvalidLen")
|
||||
|
||||
// ErrPubKeyInvalidFormat indicates an attempt was made to parse a public
|
||||
// key that does not specify one of the supported formats.
|
||||
ErrPubKeyInvalidFormat = ErrorKind("ErrPubKeyInvalidFormat")
|
||||
|
||||
// ErrPubKeyXTooBig indicates that the x coordinate for a public key
|
||||
// is greater than or equal to the prime of the field underlying the group.
|
||||
ErrPubKeyXTooBig = ErrorKind("ErrPubKeyXTooBig")
|
||||
|
||||
// ErrPubKeyYTooBig indicates that the y coordinate for a public key is
|
||||
// greater than or equal to the prime of the field underlying the group.
|
||||
ErrPubKeyYTooBig = ErrorKind("ErrPubKeyYTooBig")
|
||||
|
||||
// ErrPubKeyNotOnCurve indicates that a public key is not a point on the
|
||||
// secp256k1 curve.
|
||||
ErrPubKeyNotOnCurve = ErrorKind("ErrPubKeyNotOnCurve")
|
||||
|
||||
// ErrPubKeyMismatchedOddness indicates that a hybrid public key specified
|
||||
// an oddness of the y coordinate that does not match the actual oddness of
|
||||
// the provided y coordinate.
|
||||
ErrPubKeyMismatchedOddness = ErrorKind("ErrPubKeyMismatchedOddness")
|
||||
)
|
||||
|
||||
// Error satisfies the error interface and prints human-readable errors.
|
||||
func (e ErrorKind) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
// 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 Error struct {
|
||||
Err error
|
||||
Description string
|
||||
}
|
||||
|
||||
// Error satisfies the error interface and prints human-readable errors.
|
||||
func (e Error) Error() string {
|
||||
return e.Description
|
||||
}
|
||||
|
||||
// Unwrap returns the underlying wrapped error.
|
||||
func (e Error) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
// makeError creates an Error given a set of arguments.
|
||||
func makeError(kind ErrorKind, desc string) Error {
|
||||
return Error{Err: kind, Description: desc}
|
||||
}
|
||||
1681
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go
generated
vendored
Normal file
1681
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
91
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go
generated
vendored
Normal file
91
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
// Copyright 2015 The btcsuite developers
|
||||
// Copyright (c) 2015-2022 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package secp256k1
|
||||
|
||||
import (
|
||||
"compress/zlib"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
//go:generate go run genprecomps.go
|
||||
|
||||
// bytePointTable describes a table used to house pre-computed values for
|
||||
// accelerating scalar base multiplication.
|
||||
type bytePointTable [32][256]JacobianPoint
|
||||
|
||||
// compressedBytePointsFn is set to a real function by the code generation to
|
||||
// return the compressed pre-computed values for accelerating scalar base
|
||||
// multiplication.
|
||||
var compressedBytePointsFn func() string
|
||||
|
||||
// s256BytePoints houses pre-computed values used to accelerate scalar base
|
||||
// multiplication such that they are only loaded on first use.
|
||||
var s256BytePoints = func() func() *bytePointTable {
|
||||
// mustLoadBytePoints decompresses and deserializes the pre-computed byte
|
||||
// points used to accelerate scalar base multiplication for the secp256k1
|
||||
// curve.
|
||||
//
|
||||
// This approach is used since it allows the compile to use significantly
|
||||
// less ram and be performed much faster than it is with hard-coding the
|
||||
// final in-memory data structure. At the same time, it is quite fast to
|
||||
// generate the in-memory data structure on first use with this approach
|
||||
// versus computing the table.
|
||||
//
|
||||
// It will panic on any errors because the data is hard coded and thus any
|
||||
// errors means something is wrong in the source code.
|
||||
var data *bytePointTable
|
||||
mustLoadBytePoints := func() {
|
||||
// There will be no byte points to load when generating them.
|
||||
if compressedBytePointsFn == nil {
|
||||
return
|
||||
}
|
||||
bp := compressedBytePointsFn()
|
||||
|
||||
// Decompress the pre-computed table used to accelerate scalar base
|
||||
// multiplication.
|
||||
decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(bp))
|
||||
r, err := zlib.NewReader(decoder)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
serialized, err := io.ReadAll(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// Deserialize the precomputed byte points and set the memory table to
|
||||
// them.
|
||||
offset := 0
|
||||
var bytePoints bytePointTable
|
||||
for byteNum := 0; byteNum < len(bytePoints); byteNum++ {
|
||||
// All points in this window.
|
||||
for i := 0; i < len(bytePoints[byteNum]); i++ {
|
||||
p := &bytePoints[byteNum][i]
|
||||
p.X.SetByteSlice(serialized[offset:])
|
||||
offset += 32
|
||||
p.Y.SetByteSlice(serialized[offset:])
|
||||
offset += 32
|
||||
p.Z.SetInt(1)
|
||||
}
|
||||
}
|
||||
data = &bytePoints
|
||||
}
|
||||
|
||||
// Return a closure that initializes the data on first access. This is done
|
||||
// because the table takes a non-trivial amount of memory and initializing
|
||||
// it unconditionally would cause anything that imports the package, either
|
||||
// directly, or indirectly via transitive deps, to use that memory even if
|
||||
// the caller never accesses any parts of the package that actually needs
|
||||
// access to it.
|
||||
var loadBytePointsOnce sync.Once
|
||||
return func() *bytePointTable {
|
||||
loadBytePointsOnce.Do(mustLoadBytePoints)
|
||||
return data
|
||||
}
|
||||
}()
|
||||
1101
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go
generated
vendored
Normal file
1101
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
263
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go
generated
vendored
Normal file
263
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go
generated
vendored
Normal file
@@ -0,0 +1,263 @@
|
||||
// Copyright (c) 2013-2014 The btcsuite developers
|
||||
// Copyright (c) 2015-2020 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package secp256k1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"hash"
|
||||
)
|
||||
|
||||
// References:
|
||||
// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone)
|
||||
//
|
||||
// [ISO/IEC 8825-1]: Information technology — ASN.1 encoding rules:
|
||||
// Specification of Basic Encoding Rules (BER), Canonical Encoding Rules
|
||||
// (CER) and Distinguished Encoding Rules (DER)
|
||||
//
|
||||
// [SEC1]: Elliptic Curve Cryptography (May 31, 2009, Version 2.0)
|
||||
// https://www.secg.org/sec1-v2.pdf
|
||||
|
||||
var (
|
||||
// singleZero is used during RFC6979 nonce generation. It is provided
|
||||
// here to avoid the need to create it multiple times.
|
||||
singleZero = []byte{0x00}
|
||||
|
||||
// zeroInitializer is used during RFC6979 nonce generation. It is provided
|
||||
// here to avoid the need to create it multiple times.
|
||||
zeroInitializer = bytes.Repeat([]byte{0x00}, sha256.BlockSize)
|
||||
|
||||
// singleOne is used during RFC6979 nonce generation. It is provided
|
||||
// here to avoid the need to create it multiple times.
|
||||
singleOne = []byte{0x01}
|
||||
|
||||
// oneInitializer is used during RFC6979 nonce generation. It is provided
|
||||
// here to avoid the need to create it multiple times.
|
||||
oneInitializer = bytes.Repeat([]byte{0x01}, sha256.Size)
|
||||
)
|
||||
|
||||
// hmacsha256 implements a resettable version of HMAC-SHA256.
|
||||
type hmacsha256 struct {
|
||||
inner, outer hash.Hash
|
||||
ipad, opad [sha256.BlockSize]byte
|
||||
}
|
||||
|
||||
// Write adds data to the running hash.
|
||||
func (h *hmacsha256) Write(p []byte) {
|
||||
h.inner.Write(p)
|
||||
}
|
||||
|
||||
// initKey initializes the HMAC-SHA256 instance to the provided key.
|
||||
func (h *hmacsha256) initKey(key []byte) {
|
||||
// Hash the key if it is too large.
|
||||
if len(key) > sha256.BlockSize {
|
||||
h.outer.Write(key)
|
||||
key = h.outer.Sum(nil)
|
||||
}
|
||||
copy(h.ipad[:], key)
|
||||
copy(h.opad[:], key)
|
||||
for i := range h.ipad {
|
||||
h.ipad[i] ^= 0x36
|
||||
}
|
||||
for i := range h.opad {
|
||||
h.opad[i] ^= 0x5c
|
||||
}
|
||||
h.inner.Write(h.ipad[:])
|
||||
}
|
||||
|
||||
// ResetKey resets the HMAC-SHA256 to its initial state and then initializes it
|
||||
// with the provided key. It is equivalent to creating a new instance with the
|
||||
// provided key without allocating more memory.
|
||||
func (h *hmacsha256) ResetKey(key []byte) {
|
||||
h.inner.Reset()
|
||||
h.outer.Reset()
|
||||
copy(h.ipad[:], zeroInitializer)
|
||||
copy(h.opad[:], zeroInitializer)
|
||||
h.initKey(key)
|
||||
}
|
||||
|
||||
// Resets the HMAC-SHA256 to its initial state using the current key.
|
||||
func (h *hmacsha256) Reset() {
|
||||
h.inner.Reset()
|
||||
h.inner.Write(h.ipad[:])
|
||||
}
|
||||
|
||||
// Sum returns the hash of the written data.
|
||||
func (h *hmacsha256) Sum() []byte {
|
||||
h.outer.Reset()
|
||||
h.outer.Write(h.opad[:])
|
||||
h.outer.Write(h.inner.Sum(nil))
|
||||
return h.outer.Sum(nil)
|
||||
}
|
||||
|
||||
// newHMACSHA256 returns a new HMAC-SHA256 hasher using the provided key.
|
||||
func newHMACSHA256(key []byte) *hmacsha256 {
|
||||
h := new(hmacsha256)
|
||||
h.inner = sha256.New()
|
||||
h.outer = sha256.New()
|
||||
h.initKey(key)
|
||||
return h
|
||||
}
|
||||
|
||||
// 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.
|
||||
func NonceRFC6979(privKey []byte, hash []byte, extra []byte, version []byte, extraIterations uint32) *ModNScalar {
|
||||
// Input to HMAC is the 32-byte private key and the 32-byte hash. In
|
||||
// addition, it may include the optional 32-byte extra data and 16-byte
|
||||
// version. Create a fixed-size array to avoid extra allocs and slice it
|
||||
// properly.
|
||||
const (
|
||||
privKeyLen = 32
|
||||
hashLen = 32
|
||||
extraLen = 32
|
||||
versionLen = 16
|
||||
)
|
||||
var keyBuf [privKeyLen + hashLen + extraLen + versionLen]byte
|
||||
|
||||
// Truncate rightmost bytes of private key and hash if they are too long and
|
||||
// leave left padding of zeros when they're too short.
|
||||
if len(privKey) > privKeyLen {
|
||||
privKey = privKey[:privKeyLen]
|
||||
}
|
||||
if len(hash) > hashLen {
|
||||
hash = hash[:hashLen]
|
||||
}
|
||||
offset := privKeyLen - len(privKey) // Zero left padding if needed.
|
||||
offset += copy(keyBuf[offset:], privKey)
|
||||
offset += hashLen - len(hash) // Zero left padding if needed.
|
||||
offset += copy(keyBuf[offset:], hash)
|
||||
if len(extra) == extraLen {
|
||||
offset += copy(keyBuf[offset:], extra)
|
||||
if len(version) == versionLen {
|
||||
offset += copy(keyBuf[offset:], version)
|
||||
}
|
||||
} else if len(version) == versionLen {
|
||||
// When the version was specified, but not the extra data, leave the
|
||||
// extra data portion all zero.
|
||||
offset += privKeyLen
|
||||
offset += copy(keyBuf[offset:], version)
|
||||
}
|
||||
key := keyBuf[:offset]
|
||||
|
||||
// Step B.
|
||||
//
|
||||
// V = 0x01 0x01 0x01 ... 0x01 such that the length of V, in bits, is
|
||||
// equal to 8*ceil(hashLen/8).
|
||||
//
|
||||
// Note that since the hash length is a multiple of 8 for the chosen hash
|
||||
// function in this optimized implementation, the result is just the hash
|
||||
// length, so avoid the extra calculations. Also, since it isn't modified,
|
||||
// start with a global value.
|
||||
v := oneInitializer
|
||||
|
||||
// Step C (Go zeroes all allocated memory).
|
||||
//
|
||||
// K = 0x00 0x00 0x00 ... 0x00 such that the length of K, in bits, is
|
||||
// equal to 8*ceil(hashLen/8).
|
||||
//
|
||||
// As above, since the hash length is a multiple of 8 for the chosen hash
|
||||
// function in this optimized implementation, the result is just the hash
|
||||
// length, so avoid the extra calculations.
|
||||
k := zeroInitializer[:hashLen]
|
||||
|
||||
// Step D.
|
||||
//
|
||||
// K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1))
|
||||
//
|
||||
// Note that key is the "int2octets(x) || bits2octets(h1)" portion along
|
||||
// with potential additional data as described by section 3.6 of the RFC.
|
||||
hasher := newHMACSHA256(k)
|
||||
hasher.Write(oneInitializer)
|
||||
hasher.Write(singleZero[:])
|
||||
hasher.Write(key)
|
||||
k = hasher.Sum()
|
||||
|
||||
// Step E.
|
||||
//
|
||||
// V = HMAC_K(V)
|
||||
hasher.ResetKey(k)
|
||||
hasher.Write(v)
|
||||
v = hasher.Sum()
|
||||
|
||||
// Step F.
|
||||
//
|
||||
// K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1))
|
||||
//
|
||||
// Note that key is the "int2octets(x) || bits2octets(h1)" portion along
|
||||
// with potential additional data as described by section 3.6 of the RFC.
|
||||
hasher.Reset()
|
||||
hasher.Write(v)
|
||||
hasher.Write(singleOne[:])
|
||||
hasher.Write(key[:])
|
||||
k = hasher.Sum()
|
||||
|
||||
// Step G.
|
||||
//
|
||||
// V = HMAC_K(V)
|
||||
hasher.ResetKey(k)
|
||||
hasher.Write(v)
|
||||
v = hasher.Sum()
|
||||
|
||||
// Step H.
|
||||
//
|
||||
// Repeat until the value is nonzero and less than the curve order.
|
||||
var generated uint32
|
||||
for {
|
||||
// Step H1 and H2.
|
||||
//
|
||||
// Set T to the empty sequence. The length of T (in bits) is denoted
|
||||
// tlen; thus, at that point, tlen = 0.
|
||||
//
|
||||
// While tlen < qlen, do the following:
|
||||
// V = HMAC_K(V)
|
||||
// T = T || V
|
||||
//
|
||||
// Note that because the hash function output is the same length as the
|
||||
// private key in this optimized implementation, there is no need to
|
||||
// loop or create an intermediate T.
|
||||
hasher.Reset()
|
||||
hasher.Write(v)
|
||||
v = hasher.Sum()
|
||||
|
||||
// Step H3.
|
||||
//
|
||||
// k = bits2int(T)
|
||||
// If k is within the range [1,q-1], return it.
|
||||
//
|
||||
// Otherwise, compute:
|
||||
// K = HMAC_K(V || 0x00)
|
||||
// V = HMAC_K(V)
|
||||
var secret ModNScalar
|
||||
overflow := secret.SetByteSlice(v)
|
||||
if !overflow && !secret.IsZero() {
|
||||
generated++
|
||||
if generated > extraIterations {
|
||||
return &secret
|
||||
}
|
||||
}
|
||||
|
||||
// K = HMAC_K(V || 0x00)
|
||||
hasher.Reset()
|
||||
hasher.Write(v)
|
||||
hasher.Write(singleZero[:])
|
||||
k = hasher.Sum()
|
||||
|
||||
// V = HMAC_K(V)
|
||||
hasher.ResetKey(k)
|
||||
hasher.Write(v)
|
||||
v = hasher.Sum()
|
||||
}
|
||||
}
|
||||
111
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go
generated
vendored
Normal file
111
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go
generated
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
// Copyright (c) 2013-2014 The btcsuite developers
|
||||
// Copyright (c) 2015-2023 The Decred developers
|
||||
// Use of this source code is governed by an ISC
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package secp256k1
|
||||
|
||||
import (
|
||||
cryptorand "crypto/rand"
|
||||
"io"
|
||||
)
|
||||
|
||||
// PrivateKey provides facilities for working with secp256k1 private keys within
|
||||
// this package and includes functionality such as serializing and parsing them
|
||||
// as well as computing their associated public key.
|
||||
type PrivateKey struct {
|
||||
Key ModNScalar
|
||||
}
|
||||
|
||||
// NewPrivateKey instantiates a new private key from a scalar encoded as a
|
||||
// big integer.
|
||||
func NewPrivateKey(key *ModNScalar) *PrivateKey {
|
||||
return &PrivateKey{Key: *key}
|
||||
}
|
||||
|
||||
// PrivKeyFromBytes returns a private based on the provided byte slice which is
|
||||
// interpreted as an unsigned 256-bit big-endian integer in the range [0, N-1],
|
||||
// where N is the order of the curve.
|
||||
//
|
||||
// WARNING: This means passing a slice with more than 32 bytes is truncated and
|
||||
// that truncated value is reduced modulo N. Further, 0 is not a valid private
|
||||
// key. It is up to the caller to provide a value in the appropriate range of
|
||||
// [1, N-1]. Failure to do so will either result in an invalid private key or
|
||||
// potentially weak private keys that have bias that could be exploited.
|
||||
//
|
||||
// This function primarily exists to provide a mechanism for converting
|
||||
// serialized private keys that are already known to be good.
|
||||
//
|
||||
// Typically callers should make use of GeneratePrivateKey or
|
||||
// GeneratePrivateKeyFromRand when creating private keys since they properly
|
||||
// handle generation of appropriate values.
|
||||
func PrivKeyFromBytes(privKeyBytes []byte) *PrivateKey {
|
||||
var privKey PrivateKey
|
||||
privKey.Key.SetByteSlice(privKeyBytes)
|
||||
return &privKey
|
||||
}
|
||||
|
||||
// generatePrivateKey generates and returns a new private key that is suitable
|
||||
// for use with secp256k1 using the provided reader as a source of entropy. The
|
||||
// provided reader must be a source of cryptographically secure randomness to
|
||||
// avoid weak private keys.
|
||||
func generatePrivateKey(rand io.Reader) (*PrivateKey, error) {
|
||||
// The group order is close enough to 2^256 that there is only roughly a 1
|
||||
// in 2^128 chance of generating an invalid private key, so this loop will
|
||||
// virtually never run more than a single iteration in practice.
|
||||
var key PrivateKey
|
||||
var b32 [32]byte
|
||||
for valid := false; !valid; {
|
||||
if _, err := io.ReadFull(rand, b32[:]); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// The private key is only valid when it is in the range [1, N-1], where
|
||||
// N is the order of the curve.
|
||||
overflow := key.Key.SetBytes(&b32)
|
||||
valid = (key.Key.IsZeroBit() | overflow) == 0
|
||||
}
|
||||
zeroArray32(&b32)
|
||||
|
||||
return &key, nil
|
||||
}
|
||||
|
||||
// GeneratePrivateKey generates and returns a new cryptographically secure
|
||||
// private key that is suitable for use with secp256k1.
|
||||
func GeneratePrivateKey() (*PrivateKey, error) {
|
||||
return generatePrivateKey(cryptorand.Reader)
|
||||
}
|
||||
|
||||
// GeneratePrivateKeyFromRand generates a private key that is suitable for use
|
||||
// with secp256k1 using the provided reader as a source of entropy. The
|
||||
// provided reader must be a source of cryptographically secure randomness, such
|
||||
// as [crypto/rand.Reader], to avoid weak private keys.
|
||||
func GeneratePrivateKeyFromRand(rand io.Reader) (*PrivateKey, error) {
|
||||
return generatePrivateKey(rand)
|
||||
}
|
||||
|
||||
// PubKey computes and returns the public key corresponding to this private key.
|
||||
func (p *PrivateKey) PubKey() *PublicKey {
|
||||
var result JacobianPoint
|
||||
ScalarBaseMultNonConst(&p.Key, &result)
|
||||
result.ToAffine()
|
||||
return NewPublicKey(&result.X, &result.Y)
|
||||
}
|
||||
|
||||
// Zero manually clears the memory associated with the private key. This can be
|
||||
// used to explicitly clear key material from memory for enhanced security
|
||||
// against memory scraping.
|
||||
func (p *PrivateKey) Zero() {
|
||||
p.Key.Zero()
|
||||
}
|
||||
|
||||
// PrivKeyBytesLen defines the length in bytes of a serialized private key.
|
||||
const PrivKeyBytesLen = 32
|
||||
|
||||
// Serialize returns the private key as a 256-bit big-endian binary-encoded
|
||||
// number, padded to a length of 32 bytes.
|
||||
func (p PrivateKey) Serialize() []byte {
|
||||
var privKeyBytes [PrivKeyBytesLen]byte
|
||||
p.Key.PutBytes(&privKeyBytes)
|
||||
return privKeyBytes[:]
|
||||
}
|
||||
237
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go
generated
vendored
Normal file
237
vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go
generated
vendored
Normal file
@@ -0,0 +1,237 @@
|
||||
// Copyright (c) 2013-2014 The btcsuite developers
|
||||
// Copyright (c) 2015-2022 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 (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
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 FieldVal
|
||||
y 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 NewPublicKey(x, y *FieldVal) *PublicKey {
|
||||
var pubKey PublicKey
|
||||
pubKey.x.Set(x)
|
||||
pubKey.y.Set(y)
|
||||
return &pubKey
|
||||
}
|
||||
|
||||
// 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 ParsePubKey(serialized []byte) (key *PublicKey, err error) {
|
||||
var x, y FieldVal
|
||||
switch len(serialized) {
|
||||
case PubKeyBytesLenUncompressed:
|
||||
// Reject unsupported public key formats for the given length.
|
||||
format := serialized[0]
|
||||
switch format {
|
||||
case PubKeyFormatUncompressed:
|
||||
case PubKeyFormatHybridEven, PubKeyFormatHybridOdd:
|
||||
default:
|
||||
str := fmt.Sprintf("invalid public key: unsupported format: %x",
|
||||
format)
|
||||
return nil, makeError(ErrPubKeyInvalidFormat, str)
|
||||
}
|
||||
|
||||
// Parse the x and y coordinates while ensuring that they are in the
|
||||
// allowed range.
|
||||
if overflow := x.SetByteSlice(serialized[1:33]); overflow {
|
||||
str := "invalid public key: x >= field prime"
|
||||
return nil, makeError(ErrPubKeyXTooBig, str)
|
||||
}
|
||||
if overflow := y.SetByteSlice(serialized[33:]); overflow {
|
||||
str := "invalid public key: y >= field prime"
|
||||
return nil, makeError(ErrPubKeyYTooBig, str)
|
||||
}
|
||||
|
||||
// Ensure the oddness of the y coordinate matches the specified format
|
||||
// for hybrid public keys.
|
||||
if format == PubKeyFormatHybridEven || format == PubKeyFormatHybridOdd {
|
||||
wantOddY := format == PubKeyFormatHybridOdd
|
||||
if y.IsOdd() != wantOddY {
|
||||
str := fmt.Sprintf("invalid public key: y oddness does not "+
|
||||
"match specified value of %v", wantOddY)
|
||||
return nil, makeError(ErrPubKeyMismatchedOddness, str)
|
||||
}
|
||||
}
|
||||
|
||||
// Reject public keys that are not on the secp256k1 curve.
|
||||
if !isOnCurve(&x, &y) {
|
||||
str := fmt.Sprintf("invalid public key: [%v,%v] not on secp256k1 "+
|
||||
"curve", x, y)
|
||||
return nil, makeError(ErrPubKeyNotOnCurve, str)
|
||||
}
|
||||
|
||||
case PubKeyBytesLenCompressed:
|
||||
// Reject unsupported public key formats for the given length.
|
||||
format := serialized[0]
|
||||
switch format {
|
||||
case PubKeyFormatCompressedEven, PubKeyFormatCompressedOdd:
|
||||
default:
|
||||
str := fmt.Sprintf("invalid public key: unsupported format: %x",
|
||||
format)
|
||||
return nil, makeError(ErrPubKeyInvalidFormat, str)
|
||||
}
|
||||
|
||||
// Parse the x coordinate while ensuring that it is in the allowed
|
||||
// range.
|
||||
if overflow := x.SetByteSlice(serialized[1:33]); overflow {
|
||||
str := "invalid public key: x >= field prime"
|
||||
return nil, makeError(ErrPubKeyXTooBig, str)
|
||||
}
|
||||
|
||||
// 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.
|
||||
wantOddY := format == PubKeyFormatCompressedOdd
|
||||
if !DecompressY(&x, wantOddY, &y) {
|
||||
str := fmt.Sprintf("invalid public key: x coordinate %v is not on "+
|
||||
"the secp256k1 curve", x)
|
||||
return nil, makeError(ErrPubKeyNotOnCurve, str)
|
||||
}
|
||||
y.Normalize()
|
||||
|
||||
default:
|
||||
str := fmt.Sprintf("malformed public key: invalid length: %d",
|
||||
len(serialized))
|
||||
return nil, makeError(ErrPubKeyInvalidLen, str)
|
||||
}
|
||||
|
||||
return NewPublicKey(&x, &y), nil
|
||||
}
|
||||
|
||||
// SerializeUncompressed serializes a public key in the 65-byte uncompressed
|
||||
// format.
|
||||
func (p PublicKey) SerializeUncompressed() []byte {
|
||||
// 0x04 || 32-byte x coordinate || 32-byte y coordinate
|
||||
var b [PubKeyBytesLenUncompressed]byte
|
||||
b[0] = PubKeyFormatUncompressed
|
||||
p.x.PutBytesUnchecked(b[1:33])
|
||||
p.y.PutBytesUnchecked(b[33:65])
|
||||
return b[:]
|
||||
}
|
||||
|
||||
// SerializeCompressed serializes a public key in the 33-byte compressed format.
|
||||
func (p PublicKey) SerializeCompressed() []byte {
|
||||
// Choose the format byte depending on the oddness of the Y coordinate.
|
||||
format := PubKeyFormatCompressedEven
|
||||
if p.y.IsOdd() {
|
||||
format = PubKeyFormatCompressedOdd
|
||||
}
|
||||
|
||||
// 0x02 or 0x03 || 32-byte x coordinate
|
||||
var b [PubKeyBytesLenCompressed]byte
|
||||
b[0] = format
|
||||
p.x.PutBytesUnchecked(b[1:33])
|
||||
return b[:]
|
||||
}
|
||||
|
||||
// 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 (p *PublicKey) IsEqual(otherPubKey *PublicKey) bool {
|
||||
return p.x.Equals(&otherPubKey.x) && p.y.Equals(&otherPubKey.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 (p *PublicKey) AsJacobian(result *JacobianPoint) {
|
||||
result.X.Set(&p.x)
|
||||
result.Y.Set(&p.y)
|
||||
result.Z.SetInt(1)
|
||||
}
|
||||
|
||||
// IsOnCurve returns whether or not the public key represents a point on the
|
||||
// secp256k1 curve.
|
||||
func (p *PublicKey) IsOnCurve() bool {
|
||||
return isOnCurve(&p.x, &p.y)
|
||||
}
|
||||
Reference in New Issue
Block a user