Commit Graph

4967 Commits

Author SHA1 Message Date
matthawkins90
b60c60ffe9 docs: Clarify README.md installation guides. 2020-04-21 16:38:27 -05:00
Dave Collins
307bf49936
schnorr: Correct a couple of typos in README.md. 2020-04-13 13:07:17 -05:00
Dave Collins
3487f099ee
docs: Update README.md to reflect reality.
This updates the primary `README.md` for the most recent versions of Go,
minimum recommended requirements, and to reflect reality for the latest
version of the test script.
2020-04-13 13:06:49 -05:00
Dave Collins
71f06fbd45
secp256k1: Optimize pubkey parse.
This modifies the ParsePubKey function to avoid an additional
unnecessary check if the point is on the curve in the compressed pubkey
case because it necessarily has already determined if that is true via
the point decompression from the x coordinate.

Also, prevent x from escaping to the heap for the error print in
compressed case while here.

benchmark                          old ns/op    new ns/op   delta
------------------------------------------------------------------
BenchmarkParsePubKeyCompressed     11901        11745       -1.31%
BenchmarkParsePubKeyUncompressed   335          325         -2.99%

benchmark                          old allocs   new allocs  delta
-------------------------------------------------------------------
BenchmarkParsePubKeyCompressed     2            1           -50.00%
BenchmarkParsePubKeyUncompressed   2            1           -50.00%

benchmark                          old bytes    new bytes   delta
-------------------------------------------------------------------
BenchmarkParsePubKeyCompressed     128          80          -37.50%
BenchmarkParsePubKeyUncompressed   128          80          -37.50%
2020-04-13 13:05:57 -05:00
Dave Collins
f5800f367f
secp256k1: Add uncompressed pubkey parse benchmark. 2020-04-13 13:05:57 -05:00
Dave Collins
2f1f4e4ba3
secp256k1: Add compressed pubkey parse benchmark. 2020-04-13 13:05:56 -05:00
Dave Collins
4fc3c02ca0
secp256k1: Update README.md and doc.go.
This updates the README.md and doc.go files to reflect reality after all
of the latest changes.
2020-04-13 13:01:06 -05:00
Dave Collins
6ab35c24d3
schnorr: Add verify signature example. 2020-04-08 14:08:16 -05:00
Dave Collins
008388b6fe
schnorr: Add sign message example. 2020-04-08 14:08:16 -05:00
Dave Collins
6da2ef8106
secp256k1: Use specialized types in public key.
This updates the internal implementation of the PublicKey type to use
the FieldVal type instead of big.Ints and modifies NewPublicKey to
accept the FieldVals and updates all callers and tests in the repository
accordingly.

Public key parsing and serialization are now completely free of
big.Ints.

Finally, it moves the X and Y methods to the ellipticadaptor.go file
since they are only intended to provide interop with the standard
library elliptic curve adaptor code.

This reduces the number of allocations needed in the ecdsa compact
signature recovery as well as schnorr signature verification and results
in a slight speedup for both.

The following benchmarks show the before and after comparison:

benchmark                 old ns/op    new ns/op    delta
----------------------------------------------------------
BenchmarkRecoverCompact   198012       196173       -0.93%
BenchmarkSigVerify        179170       177805       -0.76%

benchmark                 old allocs   new allocs   delta
-----------------------------------------------------------
BenchmarkRecoverCompact   36           32           -11.11%
BenchmarkSigVerify        19           15           -21.05%

benchmark                 old bytes    new bytes    delta
-----------------------------------------------------------
BenchmarkRecoverCompact   1745         1617         -7.34%
BenchmarkSigVerify        977          848          -13.20%
2020-04-08 14:07:18 -05:00
Dave Collins
2f7c043d84
secp256k1: Add IsOnCurve method to PublicKey.
This adds a new method to the PublicKey type which can be used to
determine if the public key is on the secp256k1 curve directly.

It also adds tests to ensure proper functionality.
2020-04-08 14:02:37 -05:00
Dave Collins
0486437cb2
hdkeychain: Use errors api and require go 1.13+. 2020-04-08 13:59:05 -05:00
Dave Collins
063bf26a1c
secp256k1: Explicit pubkey parsing errors in tests.
This updates the public key parsing tests to test for the explicit
reason for the failure to ensure that each test is actually testing the
intended condition.
2020-04-08 13:54:06 -05:00
Dave Collins
9060dc3afe
secp256k1: Add pubkey parsing error infrastructure.
This introduces a new error type and associated error code for public
key errors which can be used with the errors.Is and errors.As interfaces
to programmatically detect the failure reason and updates the public key
parsing code to return appropriate error codes.

It includes full tests for the new error infrastructure.
2020-04-08 13:54:06 -05:00
Dave Collins
86b11abbd6
secp256k1: Rework pubkey tests.
This reworks the tests related to public keys to them more consistent
with the rest of the package and improve their coverage to include all
of the possible error paths.

It also brings back the hybrid pubkey parsing to match what the function
comment claims and corrects the tests accordingly.  The restriction as
to which specific types of pubkeys are allowed must be (and is) enforced
by the opcode(s) that interpret them as opposed to the lib that
implements the more generic specification.

The following is an overview of the changes:

- Convert all tests to use hex strings
- Add and verify the expected x and y coordinates from a parsed pubkey
- Bring back support for parsing hybrid keys
- Correct remaining existing tests for hybrid pubkeys
- Add negative tests for all combinations of encoding what would
  otherwise be valid pubkey with the wrong format byte and y coord
  oddness
- Add negative tests for x and y coordinates == p for the uncompressed,
  compressed, and hybrid formats
- Add negative tests for all formats such that either the x or y
  coordinate are > p and are constructed in such a way that they would
  be valid if the coordinate is taken mod p to ensure implementations
  don't incorrectly ignore the range check
2020-04-08 13:54:02 -05:00
Dave Collins
10224b9c3c
ecdsa: Use PutBytesUnchecked for serialize.
This updates the code to use the recently-added PutBytesUnchecked of
the FieldVal and ModNScalar types to serialize directly into larger
buffers where possible to avoid the need for additional copies.
2020-04-08 13:27:01 -05:00
Dave Collins
e31486afc6
schnorr: Use PutBytesUnchecked for serialize.
This updates the code to use the recently-added PutBytesUnchecked of
the FieldVal and ModNScalar types to serialize directly into larger
buffers where possible to avoid the need for additional copies.

The following benchmarks show a before and after comparison of the
affected operations:

benchmark               old ns/op    new ns/op    delta
--------------------------------------------------------
BenchmarkSign           52682        52284        -0.76%
BenchmarkSigVerify      178050       176977       -0.60%
BenchmarkSigSerialize   87.5         73.3         -16.23%

benchmark               old allocs   new allocs   delta
--------------------------------------------------------
BenchmarkSign           16           16           +0.00%
BenchmarkSigVerify      21           21           +0.00%
BenchmarkSigSerialize   1            1            +0.00%

benchmark               old bytes    new bytes    delta
--------------------------------------------------------
BenchmarkSign           960          960          +0.00%
BenchmarkSigVerify      1105         1105         +0.00%
2020-04-08 13:23:13 -05:00
Dave Collins
72fee1dc72
schnorr: Add benchmark for Signature.Serialize. 2020-04-08 13:23:13 -05:00
Dave Collins
00629c7982
hdkeychain: Use specialized secp256k1 types.
This optimizes the various internal implementations that make use of
secp256k1 to use the specialized ModNScalar and JacobianPoint types
instead of big.Ints.

The following benchmarks show a before and after comparison:

benchmark                 old ns/op     new ns/op   delta
-----------------------------------------------------------
BenchmarkDeriveHardened   3702          3547        -4.19%
BenchmarkDeriveNormal     4053          3587        -11.50%
BenchmarkPrivToPub        94.7          94.0        -0.74%
BenchmarkDeserialize      5825          5797        -0.48%
BenchmarkSerialize        9509          9402        -1.13%

benchmark                 old allocs   new allocs   delta
-----------------------------------------------------------
BenchmarkDeriveHardened   14           12           -14.29%
BenchmarkDeriveNormal     15           12           -20.00%
BenchmarkPrivToPub        1            1            +0.00%
BenchmarkDeserialize      4            3            -25.00%
BenchmarkSerialize        3            3            +0.00%

benchmark                 old bytes    new bytes    delta
-----------------------------------------------------------
BenchmarkDeriveHardened   1360         1232         -9.41%
BenchmarkDeriveNormal     1409         1232         -12.56%
BenchmarkPrivToPub        112          112          +0.00%
BenchmarkDeserialize      320          256          -20.00%
BenchmarkSerialize        272          272          +0.00%
2020-04-08 13:18:13 -05:00
Dave Collins
984e09db00
ecdsa: Correct README.md documentation links. 2020-04-08 05:11:12 -05:00
Dave Collins
6f9bcbbebc
secp256k1: Add PutBytesUnchecked to ModNScalar.
This adds a new method to ModNScalar named PutBytesUnchecked which can
be used by callers to serialize the scalar directly into a target byte
slice with the caveat that the caller must ensure the target has at
least 32 bytes available or it will panic.

This is useful in cases where the caller wishes to write into a larger
buffer without having to first serialize into a 32-byte array and copy
it.

It also updates the tests to ensure it works as expected.
2020-04-08 04:22:45 -05:00
Dave Collins
be20f291c8
secp256k1: Add PutBytesUnchecked to FieldVal.
This adds a new method to FieldVal named PutBytesUnchecked which can be
used by callers to serialize the field value directly into a target byte
slice with the caveat that the caller must ensure the target has at
least 32 bytes available or it will panic.

This is useful in cases where the caller wishes to write into a larger
buffer without having to first serialize into a 32-byte array and copy
it.

It also updates the tests to ensure it works as expected.
2020-04-08 04:22:41 -05:00
Dave Collins
277e4e4574
schnorr: Rename error codes to better match reality.
This renames some error codes to more closely match the failure as
follows:

- ErrBadInputSize -> ErrInvalidHashLen
- ErrInputValue -> ErrPrivateKeyIsZero
- ErrPointNotOnCurve -> ErrPubKeyNotOnCurve
- ErrBadSigRYValue -> ErrSigRYIsOdd
- ErrBadSigRNotOnCurve -> ErrSigRNotOnCurve
2020-04-08 04:08:49 -05:00
Dave Collins
0cd04a0b0c
schnorr: Remove unused error codes.
This removes the following unused error codes:

- ErrRegenSig
- ErrRegenerateRPoint
- ErrBadNonce
- ErrNonmatchingR
2020-04-08 04:08:49 -05:00
Dave Collins
bba36ac56e
schnorr: Use specialized types in signature type.
This updates the internal implementation of the Signature type to use
the ModNScalar and FieldVal types instead of big.Ints and modifies
NewSignature to accept the types accordingly.

Signature parsing and signing operations are now completely free of
big.Ints.  Verification still relies on them due to their use in public
keys.

It also removes the now unused primitives.go file.
2020-04-08 04:03:34 -05:00
Dave Collins
300fa12fdb
schnorr: Optimize sig verify with specialized types.
This modifies the signature verification function use the
ModNScalar and FieldVal types instead of big ints.

This is work towards eventually using the specialized types throughout.

The following benchmark shows a before and after comparison of typical
signature verification:

benchmark            old ns/op    new ns/op    delta
------------------------------------------------------
BenchmarkSigVerify   203206       182142       -10.37%

benchmark            old allocs   new allocs   delta
------------------------------------------------------
BenchmarkSigVerify   45           21           -53.33%

benchmark            old bytes    new bytes    delta
------------------------------------------------------
BenchmarkSigVerify   2066         1041         -49.61%
2020-04-08 03:58:20 -05:00
Dave Collins
4fa0208d32
schnorr: Use specialized types when signing.
This modifies the function that produces signatures to use the
ModNScalar and FieldVal types instead of big ints and also fleshes out
the comments to include a reference to the signing algorithm specified
in README.md.

This is work towards eventually using the specialized types throughout.

While the primary focus of this change is not optimization since signing
happens infrequently enough that it is not in a performance hot path, as
can be seen from the benchmark below, it does have the effect of making
signing a bit faster.

The following benchmark shows a before and after comparison of producing
a typical signature:

benchmark       old ns/op    new ns/op    delta
-------------------------------------------------
BenchmarkSign   54270        52622        -3.04%

benchmark       old allocs   new allocs   delta
-------------------------------------------------
BenchmarkSign   34           20           -41.18%

benchmark       old bytes    new bytes    delta
-------------------------------------------------
BenchmarkSign   1809         1088         -39.86%
2020-04-06 16:37:39 -05:00
Dave Collins
522fbd20be
schnorr: Add doc.go.
This adds doc.go to provide package documentation via godoc.
2020-04-06 16:33:50 -05:00
Dave Collins
3260979691
schnorr: Add README.md.
This adds a README.md file for the package which includes the custom
EC-Schnorr-DCRv0 specification along with the design details and
rationale for why its various characteristics were chosen.
2020-04-06 16:33:50 -05:00
Dave Collins
796e8c663c
schnorr: Remove unused copyBytes func. 2020-04-06 16:31:07 -05:00
Dave Collins
f812519df0
schnorr: Rework signature parsing.
This reworks the Schnorr signature parsing code to be more consistent
with the ecdsa parsing code and pave the way for eventually being able
to remove the reliance on big ints.

It also adds a full set of signature parsing tests that include 100%
coverage of all branches in the parsing code and test for the explicit
reason for the failure to ensure that each test is actually testing the
intended condition.

In particular, the parsing code has been changed as follows:

- Reject signatures that have the r and/or s components out of
  the allowed ranges for their respective type
- Make use of the specialized mod N scalar and field val types
- Introduce new error codes for signature errors and return them
2020-04-06 16:31:06 -05:00
Dave Collins
8c6b52d574
secp256k1: Add overflow check to field val set.
This modifies the SetBytes and SetByteSlice methods of the FieldVal type
to return whether or not the provided value was greater than or equal to
the field prime and adds tests to ensure  it works as expected.

This allows callers to easily check if a given uint256 value will fit
within the field element without modular reduction and makes it more
consistent with the ModNScalar type.

Finally, it updates all of the callers in the repository accordingly.
2020-04-06 16:24:30 -05:00
Dave Collins
79fa2f0c12
hdkeychain: Use secp256k1 privkey to pubkey method.
This makes use of the PubKey method on secp256k1.PrivateKey to convert a
private key to a public key instead of manually performing the
conversion.

This is desirable since secp256k1 provides the method specifically for
this purpose and it also has the benefit of allowing secp256k1 to
perform the task without round tripping through big integers which
results in slightly faster derivation.

The following benchmarks show a before and after comparison of the
affected operations:

benchmark                 old ns/op    new ns/op    delta
----------------------------------------------------------
BenchmarkDeriveHardened   3702         3671         -0.84%
BenchmarkDeriveNormal     4053         3999         -1.33%

benchmark                 old allocs   new allocs   delta
----------------------------------------------------------
BenchmarkDeriveHardened   14           14           +0.00%
BenchmarkDeriveNormal     15           15           +0.00%

benchmark                 old bytes    new bytes    delta
----------------------------------------------------------
BenchmarkDeriveHardened   1360         1360         +0.00%
BenchmarkDeriveNormal     1409         1409         +0.00%
2020-04-06 15:38:41 -05:00
Dave Collins
c8468e90b9
hdkeychain: Add child key with leading zeros test.
This adds a modification of a new test vector added to BIP32 which tests
for the case of a child key with leading zeros.  It was modified to
ensure it tests the intended condition with the new hash function Decred
uses.
2020-04-06 14:21:44 -05:00
Dave Collins
2f2a729db6
schnorr: Add negative tests for sig verification.
This adds several tests to help ensure the signature verification code
works as intended with invalid signatures by crafting signatures that
are specifically designed to hit the various failure cases and checking
the verification failed for that explicit reason.
2020-04-04 23:19:52 -05:00
Dave Collins
09f57f235f
schnorr: Add error support for errors.Is/As.
This updates the Error and ErrorCode types to provide support for
errors.Is and errors.As and adds a full set of tests for the error
infrastructure so the error handling is more consistent with the rest of
the secp256k1 module.

While here, it removes the unused ErrPubKeyOffCurve error and renames
the error creation func to signatureError to be more consistent.
2020-04-04 23:19:49 -05:00
David Hill
3c04174f55 txscript: use errors api; require go 1.13+ 2020-04-04 07:12:01 -05:00
David Hill
2c39d3b692 rpcclient: use NewRequestWithContext 2020-04-04 07:07:40 -05:00
David Hill
877b527200 rpcclient: use errors api; require go 1.13+ 2020-04-04 07:07:40 -05:00
David Hill
0142883ef3 mempool: use errors api; require go 1.13+ 2020-04-04 07:03:05 -05:00
David Hill
e1e11efd0e dcrutil: use errors api; require go 1.13+ 2020-04-04 06:59:54 -05:00
Dave Collins
bcc1a227a6
schnorr: Use extra data for RFC6979 nonces.
This modifies the signing code to use extra data that specifically
identifies the custom schnorr signature scheme used when generating
RFC6979 nonces to ensure the same nonce is not generated for the same
message and key as for other signing algorithms such as ECDSA.

While nobody realistically should ever be signing the same message with
the same private key with both Schnorr and ECDSA at the same time, it's
safer to ensure that even if they do, the same nonce value isn't used
since that could lead to revealing the private key.

It also updates the relevant tests to use the new deterministic nonces
and signatures which have been independently verified with the Sage
computer algebra system.
2020-03-31 15:52:24 -05:00
Dave Collins
4fcea17b28
chaincfg: Remove unused modules.
This updates the go.mod and go.sum files to remove modules that are no
longer needed since the removal of chainec.
2020-03-31 14:03:59 -05:00
Dave Collins
76a18d1716
secp256k1/ecdsa: Decouple ECDSA from secp256k1.
Currently, the secp256k1 package is rather tightly bound to ECDSA
signatures which makes them the only real first-class citizen in the
code.  In an effort to make it clear the ECDSA is only one possible
digital signature algorithms and to enable Schnorr signatures to also be
made first class citizens, this decouples all code related to producing
and parsing ECDSA signatures into a separate package under secp256k1
named ecdsa.

This is a fairly large change in terms of the number of lines changed,
however, the vast majority of the changes are mechanical to deal with
the package name changes and moved code.  The only real new code is
documentation for the new package.

The following is a high level overview of the changes:

- Rename signature.go to ecdsa/signature.go
- Rename signature_test.go to ecdsa/signature_test.go
- Rename sigerror.go to ecdsa/error.go
  - Rename SignatureErrorCode type to ErrorCode
  - Rename SignatureError type to Error
- Rename sigerror_test.go to ecdsa/error_test.go
- Rename signature_bench_test.go to ecdsa/bench_test.go
- Move signing-related examples from example_test.go to
  ecdsa/example_test.go
- Update all moved code to reference secp256k1 types and funcs
- Remove Sign from the secp256k1.PrivateKey type in favor of ecdsa.Sign
- Add ecdsa/README.md to describe the new package
- Add ecdsa/doc.go to provide package documentation via godoc
- Move signing examples from README.md to new ecdsa/README.md
- Update txscript and rpcserver to use the new package methods
2020-03-28 13:32:04 -05:00
Dave Collins
dcadf8fb9c
secp256k1: Split nonce code into separate files.
This moves the code for generating an RFC6979 nonce and the related
tests into separate files named nonce.go and nonce_test.go,
respectively.  The nonce is not specific to ecdsa and therefore it is
being split out so it remains accessible to multiple signing algorithms.
2020-03-28 13:32:03 -05:00
Dave Collins
a183a4a9ba
secp256k1: Export scalar from PrivateKey.
This exports the internal scalar that is used to house the private key
so that it can be used by external callers without having to round trip
through serializing the bytes.
2020-03-28 13:32:03 -05:00
Dave Collins
990076ec2e
secp256k1: Add AsJacobian method to pubkey.
This add a new method to the PublicKey type named AsJacobian which
converts the public key into a Jacobian point with Z=1.  This allows the
public key to be treated a Jacobian point in the secp256k1 group in
calculations.

It also adds an associated test to ensure proper functionality.
2020-03-28 13:32:03 -05:00
Dave Collins
b9695b4828
secp256k1: Export DecompressY.
This exports the decompressY func as DecompressY in order to allow
external callers to perform optimized elliptic curve point decompression
for a given X coordinate when possible.

It also moves the function and related tests from pubkey.go and
pubkey_test.go to curve.go and curve_test.go, respectively, since it
more correctly belongs there given it is not specific to public keys.

This is part of exposing the ec group operations so callers are not
forced to round trip through big ints.
2020-03-28 13:32:02 -05:00
Dave Collins
0dca15f1d7
secp256k1: Export ScalarBaseMultNonConst.
This exports the scalarBaseMultJacobian func as ScalarBaseMultNonConst
in order to allow external callers to perform optimized elliptic curve
point multiplication of the group base point with a scalar in Jacobian
project coordinates in addition to more clearly indentifying that the
function is not constant time.

This is part of exposing the ec group operations so callers are not
forced to round trip through big ints in affine space.
2020-03-28 13:32:02 -05:00
Dave Collins
88a2c01958
secp256k1: Export SclarMultNonConst.
This exports the scalarMultJacobian func as SclarMultNonConst in order
to allow external callers to perform optimized elliptic curve point
multiplication with a scalar in Jacobian project coordinates in addition
to more clearly indentifying that the function is not constant time.

This is part of exposing the ec group operations so callers are not
forced to round trip through big ints in affine space.
2020-03-28 13:32:02 -05:00