/// <summary> /// Sets this extended private key to be a master (depth 0) with the given private key and chaincode and verifies required key paths. /// </summary> /// <param name="privkey">Master private key.</param> /// <param name="chaincode">Master chaincode.</param> /// <param name="required">if not null, each key path will be verified as valid on the generated key or returns null.</param> /// <returns>Returns this key unless required key paths aren't valid for specified key.</returns> public KzExtPrivKey SetMaster(KzUInt256 privkey, KzUInt256 chaincode, IEnumerable <KzKeyPath> required = null) { _privkey = new KzPrivKey(privkey); _chaincode = chaincode; _depth = 0; _child = 0; _fingerprint = 0; if (_privkey == null || !_privkey.IsValid) { goto fail; } // Verify that all the required derivation paths yield valid keys. if (required != null) { foreach (var r in required) { if (Derive(r) == null) { goto fail; } } } return(this); fail: return(null); }
public KzPrivKey GetKey() { var data = Data; Debug.Assert(data.Length >= 32); var isCompressed = data.Length > 32 && data[32] == 1; var privKey = new KzPrivKey(data.Slice(0, 32), isCompressed); return(privKey); }
/// <summary> /// Implements brfc 759684b1a19a, paymentDestination: bsvalias Payment Addressing (Basic Address Resolution) /// /// </summary> /// <param name="key">Private key with which to sign this request. If null, signature will be blank. Else, must match public key returned by GetPubKey(senderHandle).</param> /// <param name="receiverHandle"></param> /// <param name="senderHandle"></param> /// <param name="senderName"></param> /// <param name="amount"></param> /// <param name="purpose"></param> /// <returns></returns> public async Task <KzScript> GetOutputScript(KzPrivKey key, string receiverHandle, string senderHandle, string senderName = null, KzAmount?amount = null, string purpose = null) { if (!amount.HasValue) { amount = KzAmount.Zero; } var dt = DateTime.UtcNow.ToString("o"); var message = $"{senderHandle}{amount.Value.Satoshis}{dt}{purpose}"; var signature = key?.SignMessageToB64(message); // var ok = key.GetPubKey().VerifyMessage(message, signature); var request = new GetOutputScriptRequest { senderHandle = senderHandle, amount = amount.Value.Satoshis, dt = dt, purpose = purpose ?? "", senderName = senderName ?? "", signature = signature ?? "" }; var jsonContent = JsonConvert.SerializeObject(request); var httpContent = new StringContent(jsonContent, Encoding.UTF8, "application/json"); var uri = await GetAddressUrl(receiverHandle); var rm = await _HttpClient.PostAsync(uri, httpContent); if (rm.StatusCode == HttpStatusCode.OK) { var response = await rm.Content.ReadAsStringAsync(); // e.g. {"output":"76a914bdfbe8a16162ba467746e382a081a1857831811088ac"} var r = JsonConvert.DeserializeObject <GetOutputScriptResponse>(response); var s = new KzScript(r.output); return(s); } if (rm.StatusCode == HttpStatusCode.NotFound) { throw new ArgumentException($"Paymail \"{receiverHandle}\" was not found by this service."); } throw new Exception($"Unhandled HTTP Post StatusCode {rm.StatusCode}."); }
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); }
public static string SignMessageToB64(this KzPrivKey key, string message) => SignMessageToB64(key, message.UTF8ToBytes());
public static byte[] SignMessage(this KzPrivKey key, string message) => SignMessage(key, message.UTF8ToBytes());
public static string SignMessageToB64(this KzPrivKey key, ReadOnlySpan <byte> message) { var sigBytes = SignMessage(key, message); return(sigBytes == null ? null : Convert.ToBase64String(sigBytes)); }
public static byte[] SignMessage(this KzPrivKey key, ReadOnlySpan <byte> message) { var(ok, sig) = key.SignCompact(GetMessageHash(message)); return(ok ? sig : null); }
public KzB58PrivKey(KzPrivKey privKey) { SetKey(privKey); }
public void SetKey(KzPrivKey privKey) { Debug.Assert(privKey.IsValid); SetData(Kz.SECRET_KEY, privKey.ReadOnlySpan, privKey.IsCompressed); }
public bool Equals(KzPrivKey o) => (object)o != null && fCompressed.Equals(o.fCompressed) && keydata.Equals(o.keydata);