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); }