示例#1
0
 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;
示例#2
0
 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);
 }
示例#3
0
        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);
        }
示例#4
0
 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;
示例#5
0
 public bool TrySignBIP340(ReadOnlySpan <byte> msg32, INonceFunctionHardened?nonceFunction, [System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)] out SecpSchnorrSignature signature)
 {
     return(TrySignBIP340(msg32, null, nonceFunction, out signature));
 }
示例#6
0
 public bool SigVerify(SecpSchnorrSignature signature, ReadOnlySpan <byte> msg32)
 {
     return(SigVerifySchnorr(signature, msg32));
 }