Ejemplo n.º 1
0
        public static bool TryExtractPrivateKey(this ECPubKey pubKey, ReadOnlySpan <byte> msg1, SecpSchnorrSignature sig1, ReadOnlySpan <byte> msg2, SecpSchnorrSignature sig2, out ECPrivKey?key)
        {
            key = null;
            if (msg1.Length != 32)
            {
                return(false);
            }
            if (msg2.Length != 32)
            {
                return(false);
            }
            if (msg1.SequenceCompareTo(msg2) == 0)
            {
                return(false);
            }

            Span <byte> sig64 = stackalloc byte[64];

            sig1.WriteToSpan(sig64);
            Span <byte> pk_buf = stackalloc byte[32];
            Span <byte> buf    = stackalloc byte[32];

            pubKey.Q.x.WriteToSpan(pk_buf);
            using var sha = new SHA256();
            sha.InitializeTagged(TAG_BIP0340Challenge);
            sha.Write(sig64.Slice(0, 32));
            sha.Write(pk_buf);
            sha.Write(msg1);
            sha.GetHash(buf);

            var n1 = new Scalar(buf, out _);

            sig2.WriteToSpan(sig64);
            sha.InitializeTagged(TAG_BIP0340Challenge);
            sha.Write(sig64.Slice(0, 32));
            sha.Write(pk_buf);
            sha.Write(msg2);
            sha.GetHash(buf);

            var n2 = new Scalar(buf, out _);

            var s  = sig2.s + sig1.s.Negate();
            var n  = (n2 + n1.Negate());
            var sk = s * n.Inverse();

            if (pubKey.Q.y.IsOdd)
            {
                sk = sk.Negate();
            }
            if (!pubKey.ctx.TryCreateECPrivKey(sk, out key))
            {
                return(false);
            }
            return(true);
        }