示例#1
0
        public (bool ok, KzPubKey keyChild, KzUInt256 ccChild) Derive(uint nChild, KzUInt256 cc)
        {
            if (!IsValid || !IsCompressed || nChild >= HardenedBit) goto fail;

            var vout = new byte[64];
            KzHashes.BIP32Hash(cc, nChild, ReadOnlySpan[0], ReadOnlySpan.Slice(1), vout);

            var sout = vout.AsSpan();
            var ccChild = new KzUInt256();
            sout.Slice(32, 32).CopyTo(ccChild.Span);

            var pkbs = new byte[64];
            if (!secp256k1.PublicKeyParse(pkbs.AsSpan(), ReadOnlySpan)) goto fail;

            if (!secp256k1.PubKeyTweakAdd(pkbs.AsSpan(), sout.Slice(0, 32))) goto fail;

            var dataChild = new byte[33];
            if (!secp256k1.PublicKeySerialize(dataChild.AsSpan(), pkbs, Flags.SECP256K1_EC_COMPRESSED)) goto fail;

            var keyChild = new KzPubKey(true);
            dataChild.AsSpan().CopyTo(keyChild.Span);

            return (true, keyChild, ccChild);

        fail:
            return (false, null, KzUInt256.Zero);
        }
示例#2
0
        public (bool ok, KzPrivKey keyChild, KzUInt256 ccChild) Derive(uint nChild, KzUInt256 cc)
        {
            if (!IsValid || !IsCompressed)
            {
                goto fail;
            }

            var vout = new byte[64];

            if (nChild < HardenedBit)
            {
                // Not hardened.
                var pubkey = GetPubKey();
                Debug.Assert(pubkey.ReadOnlySpan.Length == 33);
                KzHashes.BIP32Hash(cc, nChild, pubkey.ReadOnlySpan[0], pubkey.ReadOnlySpan.Slice(1), vout);
            }
            else
            {
                // Hardened.
                Debug.Assert(keydata.Span.Length == 32);
                KzHashes.BIP32Hash(cc, nChild, 0, keydata.Span, vout);
            }

            var sout    = vout.AsSpan();
            var ccChild = new KzUInt256();

            sout.Slice(32, 32).CopyTo(ccChild.Span);

            var dataChild = new KzUInt256();

            keydata.Span.CopyTo(dataChild.Span);

            var ok = secp256k1.PrivKeyTweakAdd(dataChild.Span, sout.Slice(0, 32));

            if (!ok)
            {
                goto fail;
            }
            var keyChild = new KzPrivKey(dataChild);

            return(ok, keyChild, ccChild);

fail:
            return(false, null, KzUInt256.Zero);
        }