Documentation ¶
Index ¶
- Constants
- Variables
- func AggregateNonces(pubNonces [][PubNonceSize]byte) ([PubNonceSize]byte, error)
- func CombineSigs(combinedNonce *btcec.PublicKey, partialSigs []*PartialSignature, ...) *schnorr.Signature
- type AggregateKey
- type CombineOption
- func WithBip86TweakedCombine(msg [32]byte, keys []*btcec.PublicKey, sort bool) CombineOption
- func WithTaprootTweakedCombine(msg [32]byte, keys []*btcec.PublicKey, scriptRoot []byte, sort bool) CombineOption
- func WithTweakedCombine(msg [32]byte, keys []*btcec.PublicKey, tweaks []KeyTweakDesc, sort bool) CombineOption
- type Context
- func (c *Context) CombinedKey() (*btcec.PublicKey, error)
- func (c *Context) EarlySessionNonce() (*Nonces, error)
- func (c *Context) NewSession(options ...SessionOption) (*Session, error)
- func (c *Context) NumRegisteredSigners() int
- func (c *Context) PubKey() btcec.PublicKey
- func (c *Context) RegisterSigner(pub *btcec.PublicKey) (bool, error)
- func (c *Context) SigningKeys() []*btcec.PublicKey
- func (c *Context) TaprootInternalKey() (*btcec.PublicKey, error)
- type ContextOption
- func WithBip86TweakCtx() ContextOption
- func WithEarlyNonceGen() ContextOption
- func WithKnownSigners(signers []*btcec.PublicKey) ContextOption
- func WithNumSigners(n int) ContextOption
- func WithTaprootTweakCtx(scriptRoot []byte) ContextOption
- func WithTweakedContext(tweaks ...KeyTweakDesc) ContextOption
- type KeyAggOption
- type KeyTweakDesc
- type NonceGenOption
- func WithCustomRand(r io.Reader) NonceGenOption
- func WithNonceAuxInput(aux []byte) NonceGenOption
- func WithNonceCombinedKeyAux(combinedKey *btcec.PublicKey) NonceGenOption
- func WithNonceMessageAux(msg [32]byte) NonceGenOption
- func WithNonceSecretKeyAux(secKey *btcec.PrivateKey) NonceGenOption
- func WithPublicKey(pubKey *btcec.PublicKey) NonceGenOption
- type Nonces
- type PartialSignature
- type Session
- func (s *Session) CombineSig(sig *PartialSignature) (bool, error)
- func (s *Session) FinalSig() *schnorr.Signature
- func (s *Session) NumRegisteredNonces() int
- func (s *Session) PublicNonce() [PubNonceSize]byte
- func (s *Session) RegisterPubNonce(nonce [PubNonceSize]byte) (bool, error)
- func (s *Session) Sign(msg [32]byte, signOpts ...SignOption) (*PartialSignature, error)
- type SessionOption
- type SignOption
Constants ¶
const ( // PubNonceSize is the size of the public nonces. Each public nonce is // serialized the full compressed encoding, which uses 32 bytes for each // nonce. PubNonceSize = 66 // SecNonceSize is the size of the secret nonces for musig2. The secret // nonces are the corresponding private keys to the public nonce points. SecNonceSize = 97 )
Variables ¶
var ( // ErrSignersNotSpecified is returned when a caller attempts to create // a context without specifying either the total number of signers, or // the complete set of singers. ErrSignersNotSpecified = fmt.Errorf("total number of signers or all " + "signers must be known") // ErrSignerNotInKeySet is returned when a the private key for a signer // isn't included in the set of signing public keys. ErrSignerNotInKeySet = fmt.Errorf("signing key is not found in key" + " set") // ErrAlredyHaveAllNonces is called when RegisterPubNonce is called too // many times for a given signing session. ErrAlredyHaveAllNonces = fmt.Errorf("already have all nonces") // ErrNotEnoughSigners is returned when a caller attempts to create a // session from a context, but before all the required signers are // known. ErrNotEnoughSigners = fmt.Errorf("not enough signers") // ErrAlredyHaveAllNonces is returned when a caller attempts to // register a signer, once we already have the total set of known // signers. ErrAlreadyHaveAllSigners = fmt.Errorf("all signers registered") // ErrAlredyHaveAllSigs is called when CombineSig is called too many // times for a given signing session. ErrAlredyHaveAllSigs = fmt.Errorf("already have all sigs") // ErrSigningContextReuse is returned if a user attempts to sign using // the same signing context more than once. ErrSigningContextReuse = fmt.Errorf("nonce already used") // ErrFinalSigInvalid is returned when the combined signature turns out // to be invalid. ErrFinalSigInvalid = fmt.Errorf("final signature is invalid") // sign a partial signature, without first having collected all the // required combined nonces. ErrCombinedNonceUnavailable = fmt.Errorf("missing combined nonce") // obtain the ErrTaprootInternalKeyUnavailable = fmt.Errorf("taproot tweak not used") // ErrNotEnoughSigners is returned if a caller attempts to obtain an // early nonce when it wasn't specified ErrNoEarlyNonce = fmt.Errorf("no early nonce available") )
var ( // KeyAggTagList is the tagged hash tag used to compute the hash of the // list of sorted public keys. KeyAggTagList = []byte("KeyAgg list") // KeyAggTagCoeff is the tagged hash tag used to compute the key // aggregation coefficient for each key. KeyAggTagCoeff = []byte("KeyAgg coefficient") // ErrTweakedKeyIsInfinity is returned if while tweaking a key, we end // up with the point at infinity. ErrTweakedKeyIsInfinity = fmt.Errorf("tweaked key is infinity point") // ErrTweakedKeyOverflows is returned if a tweaking key is larger than // 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141. ErrTweakedKeyOverflows = fmt.Errorf("tweaked key is too large") )
var ( // NonceAuxTag is the tag used to optionally mix in the secret key with // the set of aux randomness. NonceAuxTag = []byte("MuSig/aux") // NonceGenTag is used to generate the value (from a set of required an // optional field) that will be used as the part of the secret nonce. NonceGenTag = []byte("MuSig/nonce") // ErrPubkeyInvalid is returned when the pubkey of the WithPublicKey // option is not passed or of invalid length. ErrPubkeyInvalid = errors.New("nonce generation requires a valid pubkey") )
var ( // NonceBlindTag is that tag used to construct the value b, which // blinds the second public nonce of each party. NonceBlindTag = []byte("MuSig/noncecoef") // ChallengeHashTag is the tag used to construct the challenge hash ChallengeHashTag = []byte("BIP0340/challenge") // ErrNoncePointAtInfinity is returned if during signing, the fully // combined public nonce is the point at infinity. ErrNoncePointAtInfinity = fmt.Errorf("signing nonce is the infinity " + "point") // ErrPrivKeyZero is returned when the private key for signing is // actually zero. ErrPrivKeyZero = fmt.Errorf("priv key is zero") // ErrPartialSigInvalid is returned when a partial is found to be // invalid. ErrPartialSigInvalid = fmt.Errorf("partial signature is invalid") // ErrSecretNonceZero is returned when a secret nonce is passed in a // zero. ErrSecretNonceZero = fmt.Errorf("secret nonce is blank") // ErrSecNoncePubkey is returned when the signing key does not match the // sec nonce pubkey ErrSecNoncePubkey = fmt.Errorf("public key does not match secnonce") // ErrPubkeyNotIncluded is returned when the signers pubkey is not included // in the list of pubkeys. ErrPubkeyNotIncluded = fmt.Errorf("signer's pubkey must be included" + " in the list of pubkeys") )
Functions ¶
func AggregateNonces ¶
func AggregateNonces(pubNonces [][PubNonceSize]byte) ([PubNonceSize]byte, error)
AggregateNonces aggregates the set of a pair of public nonces for each party into a single aggregated nonces to be used for multi-signing.
func CombineSigs ¶
func CombineSigs(combinedNonce *btcec.PublicKey, partialSigs []*PartialSignature, combineOpts ...CombineOption) *schnorr.Signature
CombineSigs combines the set of public keys given the final aggregated nonce, and the series of partial signatures for each nonce.
Types ¶
type AggregateKey ¶
type AggregateKey struct { // FinalKey is the final aggregated key which may include one or more // tweaks applied to it. FinalKey *btcec.PublicKey // PreTweakedKey is the aggregated *before* any tweaks have been // applied. This should be used as the internal key in taproot // contexts. PreTweakedKey *btcec.PublicKey }
AggregateKey is a final aggregated key along with a possible version of the key without any tweaks applied.
func AggregateKeys ¶
func AggregateKeys(keys []*btcec.PublicKey, sort bool, keyOpts ...KeyAggOption) ( *AggregateKey, *btcec.ModNScalar, *btcec.ModNScalar, error)
AggregateKeys takes a list of possibly unsorted keys and returns a single aggregated key as specified by the musig2 key aggregation algorithm. A nil value can be passed for keyHash, which causes this function to re-derive it. In addition to the combined public key, the parity accumulator and the tweak accumulator are returned as well.
type CombineOption ¶
type CombineOption func(*combineOptions)
CombineOption is a functional option argument that allows callers to modify the way we combine musig2 schnorr signatures.
func WithBip86TweakedCombine ¶
func WithBip86TweakedCombine(msg [32]byte, keys []*btcec.PublicKey, sort bool) CombineOption
WithBip86TweakedCombine is similar to the WithTaprootTweakedCombine option, but assumes a BIP 341 + BIP 86 context where the final tweaked key is to be used as the output key, where the internal key is the aggregated key pre-tweak.
This option should be used over WithTaprootTweakedCombine when attempting to aggregate signatures for a top-level taproot keyspend, where the output key was generated using BIP 86.
func WithTaprootTweakedCombine ¶
func WithTaprootTweakedCombine(msg [32]byte, keys []*btcec.PublicKey, scriptRoot []byte, sort bool) CombineOption
WithTaprootTweakedCombine is similar to the WithTweakedCombine option, but assumes a BIP 341 context where the final tweaked key is to be used as the output key, where the internal key is the aggregated key pre-tweak.
This option should be used over WithTweakedCombine when attempting to aggregate signatures for a top-level taproot keyspend, where the output key commits to a script root.
func WithTweakedCombine ¶
func WithTweakedCombine(msg [32]byte, keys []*btcec.PublicKey, tweaks []KeyTweakDesc, sort bool) CombineOption
WithTweakedCombine is a functional option that allows callers to specify that the signature was produced using a tweaked aggregated public key. In order to properly aggregate the partial signatures, the caller must specify enough information to reconstruct the challenge, and also the final accumulated tweak value.
type Context ¶
type Context struct {
// contains filtered or unexported fields
}
Context is a managed signing context for musig2. It takes care of things like securely generating secret nonces, aggregating keys and nonces, etc.
func NewContext ¶
func NewContext(signingKey *btcec.PrivateKey, shouldSort bool, ctxOpts ...ContextOption) (*Context, error)
NewContext creates a new signing context with the passed singing key and set of public keys for each of the other signers.
NOTE: This struct should be used over the raw Sign API whenever possible.
func (*Context) CombinedKey ¶
CombinedKey returns the combined public key that will be used to generate multi-signatures against.
func (*Context) EarlySessionNonce ¶
EarlySessionNonce returns the early session nonce, if available.
func (*Context) NewSession ¶
func (c *Context) NewSession(options ...SessionOption) (*Session, error)
NewSession creates a new musig2 signing session.
func (*Context) NumRegisteredSigners ¶
NumRegisteredSigners returns the total number of registered signers.
func (*Context) PubKey ¶
func (c *Context) PubKey() btcec.PublicKey
PubKey returns the public key of the signer of this session.
func (*Context) RegisterSigner ¶
RegisterSigner allows a caller to register a signer after the context has been created. This will be used in scenarios where the total number of signers is known, but nonce exchange needs to happen before all the signers are known.
A bool is returned which indicates if all the signers have been registered.
NOTE: If the set of keys are not to be sorted during signing, then the ordering each key is registered with MUST match the desired ordering.
func (*Context) SigningKeys ¶
func (c *Context) SigningKeys() []*btcec.PublicKey
SigningKeys returns the set of keys used for signing.
func (*Context) TaprootInternalKey ¶
TaprootInternalKey returns the internal taproot key, which is the aggregated key _before_ the tweak is applied. If a taproot tweak was specified, then CombinedKey() will return the fully tweaked output key, with this method returning the internal key. If a taproot tweak wasn't specified, then this method will return an error.
type ContextOption ¶
type ContextOption func(*contextOptions)
ContextOption is a functional option argument that allows callers to modify the musig2 signing is done within a context.
func WithBip86TweakCtx ¶
func WithBip86TweakCtx() ContextOption
WithBip86TweakCtx specifies that within this context, the final key should use the taproot tweak as defined in BIP 341, with the BIP 86 modification: outputKey = internalKey + h_tapTweak(internalKey)*G. In this case, the aggreaged key before the tweak will be used as the internal key.
func WithEarlyNonceGen ¶
func WithEarlyNonceGen() ContextOption
WithEarlyNonceGen allow a caller to specify that a nonce should be generated early, before the session is created. This should be used in protocols that require some partial nonce exchange before all the signers are known.
NOTE: This option must only be specified with the WithNumSigners option.
func WithKnownSigners ¶
func WithKnownSigners(signers []*btcec.PublicKey) ContextOption
WithKnownSigners is an optional parameter that should be used if a session can be created as soon as all the singers are known.
func WithNumSigners ¶
func WithNumSigners(n int) ContextOption
WithNumSigners is a functional option used to specify that a context should be created without knowing all the signers. Instead the total number of signers is specified to ensure that a session can only be created once all the signers are known.
NOTE: Either WithKnownSigners or WithNumSigners MUST be specified.
func WithTaprootTweakCtx ¶
func WithTaprootTweakCtx(scriptRoot []byte) ContextOption
WithTaprootTweakCtx specifies that within this context, the final key should use the taproot tweak as defined in BIP 341: outputKey = internalKey + h_tapTweak(internalKey || scriptRoot). In this case, the aggreaged key before the tweak will be used as the internal key.
func WithTweakedContext ¶
func WithTweakedContext(tweaks ...KeyTweakDesc) ContextOption
WithTweakedContext specifies that within the context, the aggregated public key should be tweaked with the specified tweaks.
type KeyAggOption ¶
type KeyAggOption func(*keyAggOption)
KeyAggOption is a functional option argument that allows callers to specify more or less information that has been pre-computed to the main routine.
func WithBIP86KeyTweak ¶
func WithBIP86KeyTweak() KeyAggOption
WithBIP86KeyTweak specifies that then during key aggregation, the BIP 86 tweak which just commits to the hash of the serialized public key should be used. This option should be used when signing with a key that was derived using BIP 86.
func WithKeyTweaks ¶
func WithKeyTweaks(tweaks ...KeyTweakDesc) KeyAggOption
WithKeyTweaks allows a caller to specify a series of 32-byte tweaks that should be applied to the final aggregated public key.
func WithKeysHash ¶
func WithKeysHash(keyHash []byte) KeyAggOption
WithKeysHash allows key aggregation to be optimize, by allowing the caller to specify the hash of all the keys.
func WithTaprootKeyTweak ¶
func WithTaprootKeyTweak(scriptRoot []byte) KeyAggOption
WithTaprootKeyTweak specifies that within this context, the final key should use the taproot tweak as defined in BIP 341: outputKey = internalKey + h_tapTweak(internalKey || scriptRoot). In this case, the aggregated key before the tweak will be used as the internal key.
This option should be used instead of WithKeyTweaks when the aggregated key is intended to be used as a taproot output key that commits to a script root.
func WithUniqueKeyIndex ¶
func WithUniqueKeyIndex(idx int) KeyAggOption
WithUniqueKeyIndex allows the caller to specify the index of the second unique key.
type KeyTweakDesc ¶
type KeyTweakDesc struct { // Tweak is the 32-byte value that will modify the public key. Tweak [32]byte // IsXOnly if true, then the public key will be mapped to an x-only key // before the tweaking operation is applied. IsXOnly bool }
KeyTweakDesc describes a tweak to be applied to the aggregated public key generation and signing process. The IsXOnly specifies if the target key should be converted to an x-only public key before tweaking.
type NonceGenOption ¶
type NonceGenOption func(*nonceGenOpts)
NonceGenOption is a function option that allows callers to modify how nonce generation happens.
func WithCustomRand ¶
func WithCustomRand(r io.Reader) NonceGenOption
WithCustomRand allows a caller to use a custom random number generator in place for crypto/rand. This should only really be used to generate deterministic tests.
func WithNonceAuxInput ¶
func WithNonceAuxInput(aux []byte) NonceGenOption
WithNonceAuxInput is a set of auxiliary randomness, similar to BIP 340 that can be used to further augment the nonce generation process.
func WithNonceCombinedKeyAux ¶
func WithNonceCombinedKeyAux(combinedKey *btcec.PublicKey) NonceGenOption
WithNonceCombinedKeyAux allows a caller to optionally specify the combined key used in this signing session to further augment the randomness used to generate nonces.
func WithNonceMessageAux ¶
func WithNonceMessageAux(msg [32]byte) NonceGenOption
WithNonceMessageAux allows a caller to optionally specify a message to be mixed into the randomness generated to create the nonce.
func WithNonceSecretKeyAux ¶
func WithNonceSecretKeyAux(secKey *btcec.PrivateKey) NonceGenOption
WithNonceSecretKeyAux allows a caller to optionally specify a secret key that should be used to augment the randomness used to generate the nonces.
func WithPublicKey ¶ added in v2.3.2
func WithPublicKey(pubKey *btcec.PublicKey) NonceGenOption
WithPublicKey is the mandatory public key that will be mixed into the nonce generation.
type Nonces ¶
type Nonces struct { // PubNonce holds the two 33-byte compressed encoded points that serve // as the public set of nonces. PubNonce [PubNonceSize]byte // SecNonce holds the two 32-byte scalar values that are the private // keys to the two public nonces. SecNonce [SecNonceSize]byte }
Nonces holds the public and secret nonces required for musig2.
TODO(roasbeef): methods on this to help w/ parsing, etc?
func GenNonces ¶
func GenNonces(options ...NonceGenOption) (*Nonces, error)
GenNonces generates the secret nonces, as well as the public nonces which correspond to an EC point generated using the secret nonce as a private key.
type PartialSignature ¶
type PartialSignature struct { S *btcec.ModNScalar R *btcec.PublicKey }
PartialSignature reprints a partial (s-only) musig2 multi-signature. This isn't a valid schnorr signature by itself, as it needs to be aggregated along with the other partial signatures to be completed.
func NewPartialSignature ¶
func NewPartialSignature(s *btcec.ModNScalar, r *btcec.PublicKey) PartialSignature
NewPartialSignature returns a new instances of the partial sig struct.
func Sign ¶
func Sign(secNonce [SecNonceSize]byte, privKey *btcec.PrivateKey, combinedNonce [PubNonceSize]byte, pubKeys []*btcec.PublicKey, msg [32]byte, signOpts ...SignOption) (*PartialSignature, error)
Sign generates a musig2 partial signature given the passed key set, secret nonce, public nonce, and private keys. This method returns an error if the generated nonces are either too large, or end up mapping to the point at infinity.
func (*PartialSignature) Decode ¶
func (p *PartialSignature) Decode(r io.Reader) error
Decode attempts to parse a serialized PartialSignature stored in the passed io reader.
func (*PartialSignature) Encode ¶
func (p *PartialSignature) Encode(w io.Writer) error
Encode writes a serialized version of the partial signature to the passed io.Writer
func (*PartialSignature) Verify ¶
func (p *PartialSignature) Verify(pubNonce [PubNonceSize]byte, combinedNonce [PubNonceSize]byte, keySet []*btcec.PublicKey, signingKey *btcec.PublicKey, msg [32]byte, signOpts ...SignOption) bool
Verify implements partial signature verification given the public nonce for the signer, aggregate nonce, signer set and finally the message being signed.
type Session ¶
type Session struct {
// contains filtered or unexported fields
}
Session represents a musig2 signing session. A new instance should be created each time a multi-signature is needed. The session struct handles nonces management, incremental partial sig vitrifaction, as well as final signature combination. Errors are returned when unsafe behavior such as nonce re-use is attempted.
NOTE: This struct should be used over the raw Sign API whenever possible.
func (*Session) CombineSig ¶
func (s *Session) CombineSig(sig *PartialSignature) (bool, error)
CombineSig buffers a partial signature received from a signing party. The method returns true once all the signatures are available, and can be combined into the final signature.
func (*Session) NumRegisteredNonces ¶
NumRegisteredNonces returns the total number of nonces that have been registered so far.
func (*Session) PublicNonce ¶
func (s *Session) PublicNonce() [PubNonceSize]byte
PublicNonce returns the public nonce for a signer. This should be sent to other parties before signing begins, so they can compute the aggregated public nonce.
func (*Session) RegisterPubNonce ¶
func (s *Session) RegisterPubNonce(nonce [PubNonceSize]byte) (bool, error)
RegisterPubNonce should be called for each public nonce from the set of signers. This method returns true once all the public nonces have been accounted for.
func (*Session) Sign ¶
func (s *Session) Sign(msg [32]byte, signOpts ...SignOption) (*PartialSignature, error)
Sign generates a partial signature for the target message, using the target context. If this method is called more than once per context, then an error is returned, as that means a nonce was re-used.
type SessionOption ¶
type SessionOption func(*sessionOptions)
SessionOption is a functional option argument that allows callers to modify the musig2 signing is done within a session.
func WithPreGeneratedNonce ¶
func WithPreGeneratedNonce(nonce *Nonces) SessionOption
WithPreGeneratedNonce allows a caller to start a session using a nonce they've generated themselves. This may be useful in protocols where all the signer keys may not be known before nonce exchange needs to occur.
type SignOption ¶
type SignOption func(*signOptions)
SignOption is a functional option argument that allows callers to modify the way we generate musig2 schnorr signatures.
func WithBip86SignTweak ¶
func WithBip86SignTweak() SignOption
WithBip86SignTweak allows a caller to specify a tweak that should be used in a bip 340 manner when signing, factoring in BIP 86 as well. This differs from WithTaprootSignTweak as no true script root will be committed to, instead we just commit to the internal key.
This option should be used in the taproot context to create a valid signature for the keypath spend for taproot, when the output key was generated using BIP 86.
func WithFastSign ¶
func WithFastSign() SignOption
WithFastSign forces signing to skip the extra verification step at the end. Performance sensitive applications may opt to use this option to speed up the signing operation.
func WithSortedKeys ¶
func WithSortedKeys() SignOption
WithSortedKeys determines if the set of signing public keys are to be sorted or not before doing key aggregation.
func WithTaprootSignTweak ¶
func WithTaprootSignTweak(scriptRoot []byte) SignOption
WithTaprootSignTweak allows a caller to specify a tweak that should be used in a bip 340 manner when signing. This differs from WithTweaks as the tweak will be assumed to always be x-only and the intermediate aggregate key before tweaking will be used to generate part of the tweak (as the taproot tweak also commits to the internal key).
This option should be used in the taproot context to create a valid signature for the keypath spend for taproot, when the output key is actually committing to a script path, or some other data.
func WithTweaks ¶
func WithTweaks(tweaks ...KeyTweakDesc) SignOption
WithTweaks determines if the aggregated public key used should apply a series of tweaks before key aggregation.