コード例 #1
0
        internal MusigSessionCache Clone()
        {
            var c = new MusigSessionCache()
            {
                FinalNonceParity = FinalNonceParity,
                NonceCoeff       = NonceCoeff,
                Challenge        = Challenge,
                SPart            = SPart
            };

            FinalNonce.AsSpan().CopyTo(c.FinalNonce);
            return(c);
        }
コード例 #2
0
        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;
        }
コード例 #3
0
ファイル: MusigContext.cs プロジェクト: MichalisN/NBitcoin
        public void Process(MusigPubNonce combinedNonce)
        {
            if (processed_nonce)
            {
                throw new InvalidOperationException($"Nonce already processed");
            }
            var combined_pk = this.SigningPubKey;

            MusigSessionCache session_cache     = new MusigSessionCache();
            Span <byte>       noncehash         = stackalloc byte[32];
            Span <byte>       sig_template_data = stackalloc byte[32];

            Span <byte> combined_pk32 = stackalloc byte[32];
            Span <GEJ>  summed_nonces = stackalloc GEJ[2];

            summed_nonces[0] = combinedNonce.K1.Q.ToGroupElementJacobian();
            summed_nonces[1] = combinedNonce.K2.Q.ToGroupElementJacobian();

            combined_pk.WriteToSpan(combined_pk32);
            /* Add public adaptor to nonce */
            if (adaptor != null)
            {
                summed_nonces[0] = summed_nonces[0].AddVariable(adaptor.Q);
            }
            var combined_nonce = secp256k1_musig_process_nonces_internal(
                this.ctx.EcMultContext,
                noncehash,
                summed_nonces,
                combined_pk32,
                msg32);

            session_cache.B = new Scalar(noncehash);

            ECXOnlyPubKey.secp256k1_xonly_ge_serialize(sig_template_data, ref combined_nonce);
            var rx = combined_nonce.x;

            /* Negate nonce if Y coordinate is not square */
            combined_nonce = combined_nonce.NormalizeYVariable();
            /* Store nonce parity in session cache */
            session_cache.CombinedNonceParity = combined_nonce.y.IsOdd;

            /* Compute messagehash and store in session cache */
            ECXOnlyPubKey.secp256k1_musig_compute_messagehash(noncehash, sig_template_data, combined_pk32, msg32);
            session_cache.E = new Scalar(noncehash);

            /* If there is a tweak then set `msghash` times `tweak` to the `s`-part of the sig template.*/
            Scalar s = Scalar.Zero;

            if (is_tweaked)
            {
                Scalar e = session_cache.E;
                if (!ECPrivKey.secp256k1_eckey_privkey_tweak_mul(ref e, scalar_tweak))
                {
                    throw new InvalidOperationException("Impossible to sign (secp256k1_eckey_privkey_tweak_mul is false)");
                }
                if (pk_parity)
                {
                    e = e.Negate();
                }
                s = s.Add(e);
            }
            SessionCache       = session_cache;
            Template           = new SecpSchnorrSignature(rx, s);
            processed_nonce    = true;
            this.combinedNonce = combinedNonce;
        }