public void Process(MusigPubNonce aggregatedNonce) { if (processed_nonce) { throw new InvalidOperationException($"Nonce already processed"); } var agg_pk = this.SigningPubKey; MusigSessionCache session_cache = new MusigSessionCache(); Span <byte> fin_nonce = stackalloc byte[32]; Span <byte> agg_pk32 = stackalloc byte[32]; Span <GEJ> aggnonce_ptj = stackalloc GEJ[2]; aggnonce_ptj[0] = aggregatedNonce.K1.Q.ToGroupElementJacobian(); aggnonce_ptj[1] = aggregatedNonce.K2.Q.ToGroupElementJacobian(); agg_pk.WriteToSpan(agg_pk32); /* Add public adaptor to nonce */ if (adaptor != null) { aggnonce_ptj[0] = aggnonce_ptj[0].AddVariable(adaptor.Q); } secp256k1_musig_nonce_process_internal(this.ctx.EcMultContext, out session_cache.FinalNonceParity, fin_nonce, out session_cache.NonceCoeff, aggnonce_ptj, agg_pk32, msg32); /* Compute messagehash and store in session cache */ ECXOnlyPubKey.secp256k1_schnorrsig_challenge(out session_cache.Challenge, fin_nonce, msg32, agg_pk32); /* If there is a tweak then set `msghash` times `tweak` to the `s`-part of the sig template.*/ session_cache.SPart = Scalar.Zero; if (is_tweaked) { Scalar e_tmp = session_cache.Challenge; if (!ECPrivKey.secp256k1_eckey_privkey_tweak_mul(ref e_tmp, scalar_tweak)) { throw new InvalidOperationException("Impossible to sign (secp256k1_eckey_privkey_tweak_mul is false)"); } if (pk_parity) { e_tmp = e_tmp.Negate(); } session_cache.SPart = session_cache.SPart.Add(e_tmp); } fin_nonce.CopyTo(session_cache.FinalNonce); SessionCache = session_cache; processed_nonce = true; this.aggregateNonce = aggregatedNonce; }