public static bool TryComputeSigPoint(this ECXOnlyPubKey pubkey, ReadOnlySpan <byte> msg32, SchnorrNonce rx, out ECPubKey?sigpoint) { if (rx == null) { throw new ArgumentNullException(nameof(rx)); } 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.WriteXToSpan(pk_buf); /* tagged hash(r.x, pk.x, msg32) */ using var sha = new SHA256(); sha.InitializeTagged(TAG_BIP0340Challenge); rx.fe.WriteToSpan(buf); sha.Write(buf); sha.Write(pk_buf); sha.Write(msg32); sha.GetHash(buf); if (!pubkey.TryMultTweak(buf, out var pubkey_ge) || pubkey_ge is null) { return(false); } if (!GE.TryCreateXQuad(rx.fe, out var rx_ge)) { return(false); } var pubkey_gej = pubkey_ge.Q.ToGroupElementJacobian(); var sigpoint_gej = pubkey_gej + rx_ge; var sigpoint_ge = sigpoint_gej.ToGroupElement(); sigpoint = new ECPubKey(sigpoint_ge, pubkey.ctx); return(true); }