public bool SigVerify(SecpSchnorrSignature signature, ReadOnlySpan <byte> msg32) { if (msg32.Length != 32) { return(false); } if (signature is null) { return(false); } ref readonly Scalar s = ref signature.s;
public static bool TryCreate(ReadOnlySpan <byte> in64, out SecpSchnorrSignature?signature) { signature = null; if (in64.Length != 64) { return(false); } if (FE.TryCreate(in64.Slice(0, 32), out var fe) && new Scalar(in64.Slice(32, 32), out int overflow) is Scalar scalar && overflow == 0) { signature = new SecpSchnorrSignature(fe, scalar); return(true); } return(false); }
public bool TrySignBIP140(ReadOnlySpan <byte> msg32, INonceFunctionHardened?nonceFunction, out SecpSchnorrSignature?signature) { signature = null; if (msg32.Length != 32) { return(false); } using var sha = new Secp256k1.SHA256(); Span <byte> buf = stackalloc byte[32]; Span <byte> sig64 = stackalloc byte[64]; Span <byte> pk_buf = stackalloc byte[32]; Span <byte> sec_key = stackalloc byte[32]; if (nonceFunction == null) { nonceFunction = new BIP340NonceFunction(true); } var pk = CreatePubKey().Q; var sk = this.sec; /* Because we are signing for a x-only pubkey, the secret key is negated * before signing if the point corresponding to the secret key does not * have an even Y. */ if (pk.y.IsOdd) { sk = sk.Negate(); } sk.WriteToSpan(sec_key); pk.x.WriteToSpan(pk_buf); var ret = nonceFunction.TryGetNonce(buf, msg32, sec_key, pk_buf, BIP340NonceFunction.ALGO_BIP340); var k = new Scalar(buf, out _); ret &= !k.IsZero; Scalar.CMov(ref k, Scalar.One, ret ? 0 : 1); var rj = ctx.EcMultGenContext.MultGen(k); var r = rj.ToGroupElement(); var ry = r.y.NormalizeVariable(); if (ry.IsOdd) { k = k.Negate(); } var rx = r.x.NormalizeVariable(); rx.WriteToSpan(sig64); /* tagged hash(r.x, pk.x, msg32) */ sha.InitializeTagged(ECXOnlyPubKey.TAG_BIP0340Challenge); sha.Write(sig64.Slice(0, 32)); sha.Write(pk_buf); sha.Write(msg32); sha.GetHash(buf); /* Set scalar e to the challenge hash modulo the curve order as per * BIP340. */ var e = new Scalar(buf, out _); e = e * sk; e = e + k; e.WriteToSpan(sig64.Slice(32)); ret &= SecpSchnorrSignature.TryCreate(sig64, out signature); k = default; sk = default; sec_key.Fill(0); sig64.Fill(0); if (!ret) { signature = null; } return(ret); }
public bool TrySignSchnorr(ReadOnlySpan <byte> msg32, INonceFunction?nonceFunction, out bool nonceIsNegated, [System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out SecpSchnorrSignature signature) { signature = null; nonceIsNegated = false; var ctx = this.ctx.EcMultGenContext; ref readonly Scalar x = ref sec;
public bool TrySignBIP340(ReadOnlySpan <byte> msg32, INonceFunctionHardened?nonceFunction, [System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out SecpSchnorrSignature signature) { return(TrySignBIP340(msg32, null, nonceFunction, out signature)); }
public bool SigVerify(SecpSchnorrSignature signature, ReadOnlySpan <byte> msg32) { return(SigVerifySchnorr(signature, msg32)); }