示例#1
0
        public static bool TryComputeSigPoint(this ECXOnlyPubKey pubkey, ReadOnlySpan <byte> msg32, SchnorrNonce nonce, out ECPubKey?sigpoint)
        {
            if (nonce is null)
            {
                throw new ArgumentNullException(nameof(nonce));
            }
            if (msg32.Length != 32)
            {
                throw new ArgumentException("Msg should be 32 bytes", nameof(msg32));
            }

            sigpoint = null;
            Span <byte> buf    = stackalloc byte[32];
            Span <byte> pk_buf = stackalloc byte[32];

            pubkey.WriteToSpan(pk_buf);
            /* tagged hash(r.x, pk.x, msg32) */
            using var sha = new SHA256();
            sha.InitializeTagged(TAG_BIP0340Challenge);
            nonce.PubKey.Q.x.WriteToSpan(buf);
            sha.Write(buf);
            sha.Write(pk_buf);
            sha.Write(msg32);
            sha.GetHash(buf);
            if (!pubkey.TryTweakMul(buf, out var pubkey_ge) || pubkey_ge is null)
            {
                return(false);
            }

            var nonce_ge     = nonce.PubKey.Q;
            var pubkey_gej   = pubkey_ge.Q.ToGroupElementJacobian();
            var sigpoint_gej = pubkey_gej + nonce_ge;
            var sigpoint_ge  = sigpoint_gej.ToGroupElement();

            sigpoint = new ECPubKey(sigpoint_ge, pubkey.ctx);
            return(true);
        }