Secp256k1.MuSig
(secp256k1 v0.7.1)
View Source
Module implementing MuSig2 multi-signatures as defined in BIP327. EXPERIMENTAL: This module uses experimental features of libsecp256k1.
Example
# 1. Key Aggregation
{alice_sec, alice_pub} = Secp256k1.keypair(:compressed)
{bob_sec, bob_pub} = Secp256k1.keypair(:compressed)
{:ok, agg_pubkey, cache} = Secp256k1.MuSig.pubkey_agg([alice_pub, bob_pub])
# 2. Nonce Generation
msg_hash = :crypto.hash(:sha256, "Joint Account")
{:ok, alice_secnonce, alice_pubnonce} = Secp256k1.MuSig.nonce_gen(alice_sec, alice_pub, msg_hash, cache, nil)
{:ok, bob_secnonce, bob_pubnonce} = Secp256k1.MuSig.nonce_gen(bob_sec, bob_pub, msg_hash, cache, nil)
# 3. Nonce Aggregation
aggnonce = Secp256k1.MuSig.nonce_agg([alice_pubnonce, bob_pubnonce])
# 4. Session Setup
session = Secp256k1.MuSig.nonce_process(aggnonce, msg_hash, cache)
# 5. Partial Signing
alice_sig = Secp256k1.MuSig.partial_sign(alice_secnonce, alice_sec, cache, session)
bob_sig = Secp256k1.MuSig.partial_sign(bob_secnonce, bob_sec, cache, session)
# 6. Signature Aggregation
final_sig = Secp256k1.MuSig.partial_sig_agg(session, [alice_sig, bob_sig])
# 7. Verification
Secp256k1.Schnorr.valid?(final_sig, msg_hash, agg_pubkey)
# => true
Summary
Functions
Aggregates public nonces from all signers.
Generates a nonce for the signing session.
Processes the aggregate nonce and creates a signing session.
Aggregates partial signatures into the final Schnorr signature.
Verifies a partial signature.
Creates a partial signature.
Aggregates public keys.
Applies a plain EC tweak to the aggregated public key.
Gets the full public key from the key aggregation cache.
Applies an x-only tweak to the aggregated public key.
Types
Functions
Aggregates public nonces from all signers.
@spec nonce_gen( Secp256k1.seckey() | nil, Secp256k1.pubkey() | nil, binary() | nil, keyagg_cache() | nil, binary() | nil ) :: {:ok, secnonce(), pubnonce()} | {:error, term()}
Generates a nonce for the signing session.
Arguments:
seckey: (Optional) The secret key of the signer.pubkey: (Optional) The public key of the signer.msg: (Optional) The message to be signed (32-byte hash).cache: (Optional) The key aggregation cache.extra: (Optional) Extra input for nonce derivation (32 bytes).
Returns a secret nonce resource and a public nonce.
@spec nonce_process(aggnonce(), binary(), keyagg_cache()) :: session() | {:error, term()}
Processes the aggregate nonce and creates a signing session.
@spec partial_sig_agg(session(), [partial_sig()]) :: Secp256k1.schnorr_sig() | {:error, term()}
Aggregates partial signatures into the final Schnorr signature.
@spec partial_sig_verify( partial_sig(), pubnonce(), Secp256k1.pubkey(), keyagg_cache(), session() ) :: boolean()
Verifies a partial signature.
@spec partial_sign(secnonce(), Secp256k1.seckey(), keyagg_cache(), session()) :: partial_sig() | {:error, term()}
Creates a partial signature.
This function consumes the secret nonce.
@spec pubkey_agg([Secp256k1.pubkey()]) :: {:ok, Secp256k1.xonly_pubkey(), keyagg_cache()} | {:error, term()}
Aggregates public keys.
Returns the aggregated x-only public key and a key aggregation cache.
@spec pubkey_ec_tweak_add(keyagg_cache(), <<_::256>>) :: {:ok, keyagg_cache(), Secp256k1.pubkey()} | {:error, term()}
Applies a plain EC tweak to the aggregated public key.
Returns the new cache and the tweaked public key.
@spec pubkey_get(keyagg_cache()) :: Secp256k1.pubkey() | {:error, term()}
Gets the full public key from the key aggregation cache.
@spec pubkey_xonly_tweak_add(keyagg_cache(), <<_::256>>) :: {:ok, keyagg_cache(), Secp256k1.pubkey()} | {:error, term()}
Applies an x-only tweak to the aggregated public key.
Returns the new cache and the tweaked public key.