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); }
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); }
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)); }
/// <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); }
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); }
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); }
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); }
/// <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)); }
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); } }
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); }
public static bool VerifyMessage(this KzPubKey key, ReadOnlySpan <byte> message, ReadOnlySpan <byte> signature) { var rkey = RecoverPubKeyFromMessage(message, signature); return(rkey != null && rkey == key); }
public static bool VerifyMessage(this KzPubKey key, string message, string signature) => VerifyMessage(key, message.UTF8ToBytes(), Convert.FromBase64String(signature));
public static KzPubKey RecoverPubKeyFromMessage(ReadOnlySpan <byte> message, ReadOnlySpan <byte> signature) { var(ok, key) = KzPubKey.FromRecoverCompact(GetMessageHash(message), signature); return(ok ? key : null); }
public KzPubKey ToPubKey() { var pubKey = new KzPubKey(); pubKey.Set(Op.Data.ToSpan()); return pubKey.IsValid ? pubKey : null; }
public bool Equals(KzPubKey o) => (object)o != null && Enumerable.SequenceEqual(_vch, o._vch);
/// <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); }
/// <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; }