pub struct Session(/* private fields */);Expand description
A musig Signing session.
Implementations§
Source§impl Session
impl Session
Sourcepub fn new(
key_agg_cache: &KeyAggCache,
agg_nonce: AggregatedNonce,
msg: &[u8; 32],
) -> Session
pub fn new( key_agg_cache: &KeyAggCache, agg_nonce: AggregatedNonce, msg: &[u8; 32], ) -> Session
Creates a new musig signing session.
Takes the public nonces of all signers and computes a session that is required for signing and verification of partial signatures.
§Returns:
A Session that can be later used for signing.
§Arguments:
secp:Secp256k1context object initialized for signingkey_agg_cache:KeyAggCacheto be used for this sessionagg_nonce:AggregatedNonce, the aggregate noncemsg: message that will be signed later on.
Example:
// The session id must be sampled at random. Read documentation for more details.
let msg = b"Public message we want to sign!!";
// Provide the current time for mis-use resistance
let session_secrand1 = SessionSecretRand::from_rng(&mut rand::rng());
let extra_rand1 : Option<[u8; 32]> = None;
let (_sec_nonce1, pub_nonce1) = key_agg_cache.nonce_gen(session_secrand1, pub_key1, msg, extra_rand1);
// Signer two does the same. Possibly on a different device
let session_secrand2 = SessionSecretRand::from_rng(&mut rand::rng());
let extra_rand2 : Option<[u8; 32]> = None;
let (_sec_nonce2, pub_nonce2) = key_agg_cache.nonce_gen(session_secrand2, pub_key2, msg, extra_rand2);
let aggnonce = AggregatedNonce::new(&[&pub_nonce1, &pub_nonce2]);
let session = Session::new(
&key_agg_cache,
aggnonce,
msg,
);Sourcepub fn partial_sign(
&self,
secnonce: SecretNonce,
keypair: &Keypair,
key_agg_cache: &KeyAggCache,
) -> PartialSignature
pub fn partial_sign( &self, secnonce: SecretNonce, keypair: &Keypair, key_agg_cache: &KeyAggCache, ) -> PartialSignature
Produces a partial signature for a given key pair and secret nonce.
Remember that nonce reuse will immediately leak the secret key!
§Returns:
A PartialSignature that can be later be aggregated into a schnorr::Signature
§Arguments:
secp:Secp256k1context object initialized for signingsec_nonce:SecretNonceto be used for this session that has never been used before. For mis-use resistance, this API takes a mutable reference tosec_nonceand sets it to zero even if the partial signing fails.key_pair: TheKeypairto sign the messagekey_agg_cache:KeyAggCachecontaining the aggregate pubkey used in the creation of this session
§Errors:
- If the provided
SecretNoncehas already been used for signing
Sourcepub fn partial_verify(
&self,
key_agg_cache: &KeyAggCache,
partial_sig: &PartialSignature,
pub_nonce: &PublicNonce,
pub_key: PublicKey,
) -> bool
pub fn partial_verify( &self, key_agg_cache: &KeyAggCache, partial_sig: &PartialSignature, pub_nonce: &PublicNonce, pub_key: PublicKey, ) -> bool
Checks that an individual partial signature verifies
This function is essential when using protocols with adaptor signatures. However, it is not essential for regular MuSig’s, in the sense that if any partial signatures does not verify, the full signature will also not verify, so the problem will be caught. But this function allows determining the specific party who produced an invalid signature, so that signing can be restarted without them.
§Returns:
true if the partial signature successfully verifies, otherwise returns false
§Arguments:
secp:Secp256k1context object initialized for signingkey_agg_cache:KeyAggCachecontaining the aggregate pubkey used in the creation of this sessionpartial_sig:PartialSignaturesent by the signer associated with the givenpub_nonceandpubkeypub_nonce: ThePublicNonceof the signer associated with thepartial_sigandpub_keypub_key: TheXOnlyPublicKeyof the signer associated with the givenpartial_sigandpub_nonce
Example:
// The session id must be sampled at random. Read documentation for more details.
let msg = b"Public message we want to sign!!";
// Provide the current time for mis-use resistance
let session_secrand1 = SessionSecretRand::from_rng(&mut rand::rng());
let (mut sec_nonce1, pub_nonce1) = key_agg_cache.nonce_gen(session_secrand1, pub_key1, msg, None);
// Signer two does the same. Possibly on a different device
let session_secrand2 = SessionSecretRand::from_rng(&mut rand::rng());
let (_sec_nonce2, pub_nonce2) = key_agg_cache.nonce_gen(session_secrand2, pub_key2, msg, None);
let aggnonce = AggregatedNonce::new(&[&pub_nonce1, &pub_nonce2]);
let session = Session::new(
&key_agg_cache,
aggnonce,
msg,
);
let keypair = Keypair::from_secret_key(&sk1);
let partial_sig1 = session.partial_sign(
sec_nonce1,
&keypair,
&key_agg_cache,
);
assert!(session.partial_verify(
&key_agg_cache,
&partial_sig1,
&pub_nonce1,
pub_key1,
));Sourcepub fn partial_sig_agg(
&self,
partial_sigs: &[&PartialSignature],
) -> AggregatedSignature
pub fn partial_sig_agg( &self, partial_sigs: &[&PartialSignature], ) -> AggregatedSignature
Aggregate partial signatures for this session into a single schnorr::Signature
§Returns:
A single schnorr::Signature. Note that this does NOT mean that the signature verifies with respect to the
aggregate public key.
§Arguments:
partial_sigs: Array ofPartialSignatureto be aggregated
let key_agg_cache = KeyAggCache::new(&[pub_key1, pub_key2]);
// The session id must be sampled at random. Read documentation for more details.
let msg = b"Public message we want to sign!!";
// Provide the current time for mis-use resistance
let session_secrand1 = SessionSecretRand::from_rng(&mut rand::rng());
let (mut sec_nonce1, pub_nonce1) = key_agg_cache.nonce_gen(session_secrand1, pub_key1, msg, None)
.expect("non zero session id");
// Signer two does the same. Possibly on a different device
let session_secrand2 = SessionSecretRand::from_rng(&mut rand::rng());
let (mut sec_nonce2, pub_nonce2) = key_agg_cache.nonce_gen(session_secrand2, pub_key2, msg, None)
.expect("non zero session id");
let aggnonce = AggregatedNonce::new(&[pub_nonce1, pub_nonce2]);
let session = Session::new(
&key_agg_cache,
aggnonce,
msg,
);
let partial_sig1 = session.partial_sign(
sec_nonce1,
&Keypair::from_secret_key(&sk1),
&key_agg_cache,
).unwrap();
// Other party creates the other partial signature
let partial_sig2 = session.partial_sign(
sec_nonce2,
&Keypair::from_secret_key(&sk2),
&key_agg_cache,
).unwrap();
let partial_sigs = [partial_sign1, partial_sign2];
let partial_sigs_ref: Vec<&PartialSignature> = partial_sigs.iter().collect();
let partial_sigs_ref = partial_sigs_ref.as_slice();
let aggregated_signature = session.partial_sig_agg(partial_sigs_ref);
// Get the final schnorr signature
assert!(aggregated_signature.verify(&agg_pk, &msg_bytes).is_ok());§Panics
Panics if an empty slice of partial signatures is provided.
Sourcepub fn as_ptr(&self) -> *const MusigSession
pub fn as_ptr(&self) -> *const MusigSession
Get a const pointer to the inner Session
Sourcepub fn as_mut_ptr(&mut self) -> *mut MusigSession
pub fn as_mut_ptr(&mut self) -> *mut MusigSession
Get a mut pointer to the inner Session