Exemplo n.º 1
0
        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;
        }