Exemple #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);
        }
Exemple #2
0
 public static (bool ok, KzPubKey key) FromRecoverCompact(KzUInt256 hash, ReadOnlySpan<byte> sig)
 {
     var key = new KzPubKey();
     var ok = key.RecoverCompact(hash, sig);
     if (!ok) key = null;
     return (ok, key);
 }
Exemple #3
0
 public void Decode(ReadOnlySpan <byte> code)
 {
     _depth = code[0];
     code.Slice(1, 4).CopyTo(_fingerprint.AsSpan());
     _child = (uint)code[5] << 24 | (uint)code[6] << 16 | (uint)code[7] << 8 | (uint)(code[8]);
     code.Slice(9, 32).CopyTo(_chaincode.Span);
     pubkey = new KzPubKey();
     pubkey.Set(code.Slice(41, 33));
 }
Exemple #4
0
        /// <summary>
        /// Creates a copy of this key.
        /// </summary>
        /// <returns></returns>
        public KzPubKey Clone()
        {
            var clone = new KzPubKey();

            if (_vch != null)
            {
                clone._vch = _vch.ToArray();
            }
            return(clone);
        }
Exemple #5
0
        public KzPubKey GetPubKey()
        {
            Trace.Assert(fValid);
            var pubKeySecp256k1 = new byte[PubKeyLength];
            var ok = secp256k1.PublicKeyCreate(pubKeySecp256k1, keydata.ReadOnlySpan);

            Trace.Assert(ok);
            var pubKey = new KzPubKey(fCompressed);

            secp256k1.PublicKeySerialize(pubKey.Span, pubKeySecp256k1, IsCompressedFlag);
            Trace.Assert(pubKey.IsValid);
            return(pubKey);
        }
Exemple #6
0
        public async Task <bool> VerifyPubKey(string receiverHandle, KzPubKey pubKey)
        {
            var uri = await GetVerifyUrl(receiverHandle, pubKey.ToHex());

            var r = await _HttpClient.GetAsync(uri);

            if (r.StatusCode == HttpStatusCode.OK)
            {
                var json = await r.Content.ReadAsStringAsync();

                var vpkr = JsonConvert.DeserializeObject <VerifyPubKeyResponse>(json);
                if (vpkr.pubkey == pubKey.ToHex())
                {
                    return(vpkr.match);
                }
            }

            return(false);
        }
Exemple #7
0
        public async Task <KzPubKey> GetPubKey(string receiverHandle)
        {
            var uri = await GetIdentityUrl(receiverHandle);

            var r = await _HttpClient.GetAsync(uri);

            if (r.StatusCode == HttpStatusCode.OK)
            {
                var json = await r.Content.ReadAsStringAsync();

                var gpkr   = JsonConvert.DeserializeObject <GetPubKeyResponse>(json);
                var pubkey = new KzPubKey(gpkr.pubkey);
                if (pubkey != null && pubkey.IsCompressed && new[] { 2, 3 }.Contains(pubkey.ReadOnlySpan[0]))
                {
                    return(pubkey);
                }
            }

            return(null);
        }
Exemple #8
0
        /// <summary>
        /// Verify thoroughly whether a private key and a public key match.
        /// This is done using a different mechanism than just regenerating it.
        /// </summary>
        /// <param name="pubKey"></param>
        /// <returns></returns>
        public bool VerifyPubKey(KzPubKey pubkey)
        {
            if (pubkey.IsCompressed != fCompressed)
            {
                return(false);
            }

            var rnd = KzRandom.GetStrongRandBytes(8).ToArray();
            var str = "Bitcoin key verification\n";

            var hash = KzHashes.HASH256(Encoding.ASCII.GetBytes(str).Concat(rnd).ToArray());

            var(ok, sig) = Sign(hash);

            if (!ok)
            {
                return(false);
            }

            return(pubkey.Verify(hash, sig));
        }
Exemple #9
0
        public KzMerchantClient(string baseUrl, KzPubKey pubKey = null)
        {
            var parts = baseUrl.Split(',');
            var token = string.Empty;

            if (parts.Length == 2)
            {
                token   = parts[1];
                baseUrl = parts[0];
            }
            _PubKey     = pubKey;
            _BaseUrl    = baseUrl;
            _HttpClient = new HttpClient();
            _HttpClient.DefaultRequestHeaders.Accept.Clear();
            _HttpClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
            _HttpClient.DefaultRequestHeaders.Add("User-Agent", UserAgent);
            if (token != string.Empty)
            {
                _HttpClient.DefaultRequestHeaders.Add("token", token);
            }
        }
Exemple #10
0
        bool Verify()
        {
            var s = _Static;

            var message         = $"{s.prevMinerId}{s.minerId}{s.vctx.txid}";
            var verifyHash      = KzHashes.SHA256(message.UTF8ToBytes());
            var verifySignature = s.prevMinerIdSig.HexToBytes();

            PrevPubKeyBytes = s.prevMinerId.HexToBytes();
            PrevPubKey      = new KzPubKey(PrevPubKeyBytes);

            var verified = PrevPubKey.IsValid && PrevPubKey.Verify(verifyHash, verifySignature);

            if (verified)
            {
                PubKeyBytes = s.minerId.HexToBytes();
                PubKey      = new KzPubKey(PubKeyBytes);
                verified    = PubKey.IsValid;
            }

            return(verified);
        }
Exemple #11
0
        public static bool VerifyMessage(this KzPubKey key, ReadOnlySpan <byte> message, ReadOnlySpan <byte> signature)
        {
            var rkey = RecoverPubKeyFromMessage(message, signature);

            return(rkey != null && rkey == key);
        }
Exemple #12
0
 public static bool VerifyMessage(this KzPubKey key, string message, string signature) => VerifyMessage(key, message.UTF8ToBytes(), Convert.FromBase64String(signature));
Exemple #13
0
 public static KzPubKey RecoverPubKeyFromMessage(ReadOnlySpan <byte> message, ReadOnlySpan <byte> signature)
 {
     var(ok, key) = KzPubKey.FromRecoverCompact(GetMessageHash(message), signature);
     return(ok ? key : null);
 }
Exemple #14
0
 public KzPubKey ToPubKey() {
     var pubKey = new KzPubKey();
     pubKey.Set(Op.Data.ToSpan());
     return pubKey.IsValid ? pubKey : null;
 }
Exemple #15
0
 public bool Equals(KzPubKey o) => (object)o != null && Enumerable.SequenceEqual(_vch, o._vch);
Exemple #16
0
        /// <summary>
        /// Verifies that the message was signed by the private key corresponding the paymail's public key.
        /// </summary>
        /// <param name="message">A copy of the message which was originally signed.</param>
        /// <param name="signature">The signature received for validation.</param>
        /// <param name="paymail">The paymail claiming to have signed the message.</param>
        /// <param name="pubkey">If known, the public key corresponding to the private key used by the paymail to sign messages.</param>
        /// <returns>(ok, pubkey) where ok is true only if both the public key and signature were confirmed as valid.
        /// If ok is true, the returned public key is valid and can be saved for future validations.
        /// </returns>
        public async Task <(bool ok, KzPubKey pubkey)> IsValidSignature(string message, string signature, string paymail, KzPubKey pubkey = null)
        {
            var(ok, alias, domain) = KzPaymail.Parse(paymail);

            if (!ok)
            {
                goto fail;
            }

            if (pubkey != null)
            {
                // If a pubkey is provided and the domain is capable, verify that it is correct
                // If it is not correct, forget the input value and attempt to obtain the valid key.
                if (await DomainHasCapability(domain, KzPaymail.Capability.verifyPublicKeyOwner))
                {
                    if (!await VerifyPubKey(paymail, pubkey))
                    {
                        pubkey = null;
                    }
                }
            }

            if (pubkey == null)
            {
                // Attempt to determine the correct pubkey for the paymail.
                if (await DomainHasCapability(domain, KzPaymail.Capability.pki))
                {
                    pubkey = await GetPubKey(paymail);
                }
            }

            if (pubkey == null)
            {
                goto fail;
            }

            ok = pubkey.VerifyMessage(message, signature);

            return(ok, pubkey);

fail:
            return(false, pubkey);
        }
Exemple #17
0
 /// <summary>
 /// Creates a copy of this key.
 /// </summary>
 /// <returns></returns>
 public KzPubKey Clone() {
     var clone = new KzPubKey();
     if (_vch != null)
         clone._vch = _vch.ToArray();
     return clone;
 }