In this commit, we enable early nonce generation, allowing callers to
obtain generated nonces before the total set of signers is actually
known. This type of nonce generation is useful for contexts like LN
funding when we want to minimize the round trips and send nonces before
we know the pubkey of the other party.
In this commit, we update the nonce generation to support optional
parameters defined in the latest BIP draft. These parameters are
optional, but if specified my mitigate the effect of weak randomness
when generating the nonce.
Given the protocol doesn't require signers to prove how they generate
their nonces, this update is mainly to ensure strict spec compliance,
and is effectively optional.
In this commit, we add a series of new functional optinos to make
signing for an aggregated key where the final taproot output key was
derived using BIP 86. This can be used in cases where no script path
shuold be allowed, and only an n-of-n multi-sig should be used.
In this commit, we add a series of new options and methods to make it
easier to use the package in the context of a taproot output that
commits to a script root or some other value. Before this series of
changes, the API was hard to use in this context as the taproot tweak
actually includes the internal public key, which in this case is the
aggregated public key. So you actually needed to call that API w/o the
tweak, get that, then recompute the tweak itself.
To make things easier in the taproot context, we've added a series of
new options that'll return the aggregated key before any tweaks (to be
used as the internal key), and also handle computing the BIP 341 tweak
value for the caller.
In this commit, we add support for signing with tweaked aggregated keys.
Such signing is required when signing for a taproot output key that
actually commits to a script tree root, or was generated using BIP 86.
A series of new functional arguments (that can likely be de-dup'd using
Go's new type params), have been added to allow callers to optionally
flip on this new behavior.
In this commit, we introduce an easier to use API for musig2 signing in
the Session and Context structs.
The Context struct represents a particular musig2 signing context which
is defined by the set of signers. The struct can be serialized to disk
as it contains no volatile information. A given context can be kept for
each signer in the final set.
The Session struct represents an ephemeral musig2 signing session. It
handles nonce generation, key aggregation, nonce combination, signature
combination, and final sig verification all in one API. The API also
protects against nonce generation by not exposing nonces to the end user
and also attempting to catch nonce re-use (assuming no process forking)
across sessions.
In this commit, we add a final test case that exercises the act of
generating partial signatures amongst 100 signers, combining them into a
single signature, and finally verifying to make sure the final signature
is valid.
In this commit, we build on the prior two commits by adding the ability
to generate partial musig2 signatures, validate them individually, and
finally combine them into a single signature.
Much of the logic here is unoptimized, and will be optimized in a later
commit. In addition, we also want to eventually have a nicer API to
support the book keeping necessary during multi signing.
In this commit, we add the ability to generate the secret+public nonces,
as well as combine a series of nonces into a single combined nonce
(which is used when doing multi signing).
In this commit, we add the set of key aggregation routines for musig2.
This includes the main public key aggregation method, as well as the
aggregation coefficient which is used to compute "mu" when signing.
The logic in this implementation is based on the musig2 paper, as well
as this spec:
https://github.com/ElementsProject/secp256k1-zkp/blob/master/doc/musig-spec.mediawiki.
In this commit, we add a new function `RawTxInTapscriptSignature` that
will be used to generate signatures in the _tapscript_ context. Note
that this differs from top-level taproot as a distinct sighash is used,
and we _always_ accept a root hash to perform the proper tweak.
In this commit, we optimize our signature implementation slightly, by
defining pre-computed sha256(tag) variables for the commonly used
values. If a tag matches this, then we'll use that hash value to avoid
an extra round of hashing.
In this commit, we add an initial implementation of BIP-340. Mirroring
the recently added `ecsda` package, we create a new `schnorr` package
with a unique `Signature` type and `ParsePubkey` function. The new
`Signature` type implements the fixed-sized 64-byte signatures, and the
`ParsePubkey` method only accepts pubkeys that are 32-bytes in length,
with an implicit sign byte.
The signing implementation by default, deviates from BIP-340 as it opts
to use rfc6979 deterministic signatures by default, which means callers
don't need to always pass in their own `auxNonce` randomness. A set of
functional arguments allows callers to pass in their own value, which is
the way all the included test vectors function.
The other optional functional argument added is the `FastSign` option
that allows callers to skip the final step of verifying each signature
they generate.
In this commit, we create a new package to house the ECDSA-specific
logic in the new `btcec/v2` pacakge. Thsi c hange is meant to mirror the
structure of the `dcrec` package, as we'll soon slot in our own custom
BIP-340 implementation.
In this commit, we turn the package into a new Go module (version 2),
and then port over the current set of types and functions to mainly
alias to the more optimized and maintained dcrec variant.
Taking a look at the benchmarks, most operations other than
normalization (which IIRC is a bit slower now due to constant time
fixes) enjoy some nice speeds up:
```
benchcmp is deprecated in favor of benchstat: https://pkg.go.dev/golang.org/x/perf/cmd/benchstat
benchmark old ns/op new ns/op delta
BenchmarkAddJacobian-8 464 328 -29.20%
BenchmarkAddJacobianNotZOne-8 1138 372 -67.27%
BenchmarkScalarBaseMult-8 47336 31531 -33.39%
BenchmarkScalarBaseMultLarge-8 42465 32057 -24.51%
BenchmarkScalarMult-8 123355 117579 -4.68%
BenchmarkNAF-8 582 168 -71.12%
BenchmarkSigVerify-8 175414 120794 -31.14%
BenchmarkFieldNormalize-8 23.8 24.4 +2.39%
BenchmarkParseCompressedPubKey-8 24282 10907 -55.08%
```
The implementation has been adapted from the dcrec module in dcrd. The
bug was initially fixed in decred/dcrd@3d9cda1 while transitioning to a
constant time algorithm. A large set of test vectors were subsequently
added in decred/dcrd@8c6b52d.
The function signature has been preserved for backwards compatibility.
This means that returning whether the value has overflowed, and the
corresponding test vectors have not been backported.
This fixes#1170 and closes a previous attempt to fix the bug in #1178.