示例#1
0
        public void Initialize(ReadOnlySpan <byte> key)
        {
            int         n;
            Span <byte> rkey = stackalloc byte[64];

            rkey.Clear();
            if (key.Length <= 64)
            {
                key.CopyTo(rkey);
            }
            else
            {
                using var sha = new NBitcoin.Secp256k1.SHA256();
                sha.Write(key);
                sha.GetHash(rkey);
            }
            outer = new Secp256k1.SHA256();
            for (n = 0; n < 64; n++)
            {
                rkey[n] ^= 0x5c;
            }
            outer.Write(rkey);

            inner = new Secp256k1.SHA256();
            for (n = 0; n < 64; n++)
            {
                rkey[n] ^= 0x5c ^ 0x36;
            }
            inner.Write(rkey);
            rkey.Clear();
        }
示例#2
0
        public void Initialize(ReadOnlySpan <byte> key)
        {
            int         n;
            Span <byte> rkey = stackalloc byte[64];

            rkey.Clear();
            if (key.Length <= 64)
            {
                key.CopyTo(rkey);
            }
            else
            {
                Crypto.Hashes.SHA256(key).AsSpan().CopyTo(rkey);
            }
            outer = new Secp256k1.SHA256();
            for (n = 0; n < 64; n++)
            {
                rkey[n] ^= 0x5c;
            }
            outer.Write(rkey);

            inner = new Secp256k1.SHA256();
            for (n = 0; n < 64; n++)
            {
                rkey[n] ^= 0x5c ^ 0x36;
            }
            inner.Write(rkey);
            rkey.Clear();
        }
示例#3
0
        public bool TryGetNonce(Span <byte> nonce32, ReadOnlySpan <byte> msg32, ReadOnlySpan <byte> key32, ReadOnlySpan <byte> algo16, uint counter)
        {
            using var sha = new Secp256k1.SHA256();
            /* Hash x||msg as per the spec */
            sha.Write(key32.Slice(0, 32));
            sha.Write(msg32.Slice(0, 32));

            /* Hash in algorithm, which is not in the spec, but may be critical to
             * users depending on it to avoid nonce reuse across algorithms. */
            if (algo16.Length == 16)
            {
                sha.Write(algo16.Slice(0, 16));
            }
            if (data != null)
            {
                sha.Write(data.AsSpan().Slice(0, 32));
            }
            sha.GetHash(nonce32);
            return(true);
        }
示例#4
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);
        }