Session

Struct Session 

Source
pub struct Session(/* private fields */);
Expand description

A musig Signing session.

Implementations§

Source§

impl Session

Source

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 : Secp256k1 context object initialized for signing
  • key_agg_cache: KeyAggCache to be used for this session
  • agg_nonce: AggregatedNonce, the aggregate nonce
  • msg: 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,
);
Source

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 : Secp256k1 context object initialized for signing
  • sec_nonce: SecretNonce to be used for this session that has never been used before. For mis-use resistance, this API takes a mutable reference to sec_nonce and sets it to zero even if the partial signing fails.
  • key_pair: The Keypair to sign the message
  • key_agg_cache: KeyAggCache containing the aggregate pubkey used in the creation of this session
§Errors:
  • If the provided SecretNonce has already been used for signing
Source

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 : Secp256k1 context object initialized for signing
  • key_agg_cache: KeyAggCache containing the aggregate pubkey used in the creation of this session
  • partial_sig: PartialSignature sent by the signer associated with the given pub_nonce and pubkey
  • pub_nonce: The PublicNonce of the signer associated with the partial_sig and pub_key
  • pub_key: The XOnlyPublicKey of the signer associated with the given partial_sig and pub_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,
));
Source

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:

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.

Source

pub fn as_ptr(&self) -> *const MusigSession

Get a const pointer to the inner Session

Source

pub fn as_mut_ptr(&mut self) -> *mut MusigSession

Get a mut pointer to the inner Session

Trait Implementations§

Source§

impl Clone for Session

Source§

fn clone(&self) -> Session

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Session

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Hash for Session

Source§

fn hash<__H>(&self, state: &mut __H)
where __H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl Ord for Session

Source§

fn cmp(&self, other: &Session) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · Source§

fn max(self, other: Self) -> Self
where Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · Source§

fn min(self, other: Self) -> Self
where Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · Source§

fn clamp(self, min: Self, max: Self) -> Self
where Self: Sized,

Restrict a value to a certain interval. Read more
Source§

impl PartialEq for Session

Source§

fn eq(&self, other: &Session) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialOrd for Session

Source§

fn partial_cmp(&self, other: &Session) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · Source§

fn lt(&self, other: &Rhs) -> bool

Tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · Source§

fn le(&self, other: &Rhs) -> bool

Tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · Source§

fn gt(&self, other: &Rhs) -> bool

Tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · Source§

fn ge(&self, other: &Rhs) -> bool

Tests greater than or equal to (for self and other) and is used by the >= operator. Read more
Source§

impl Copy for Session

Source§

impl Eq for Session

Source§

impl StructuralPartialEq for Session

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V