KzUInt256 ComputeHash(KzMerkleTreeNode n) { // This ToArray call could be eliminated. var h = new KzUInt256(); KzHashes.HASH256(n.LeftRightHashes, h.Span); return(h); }
/// <summary> /// Appends first 4 bytes of double SHA256 hash to bytes before standard Base58 encoding. /// </summary> /// <param name="bytes"></param> /// <returns></returns> public override string Encode(ReadOnlySpan <byte> bytes) { var checksum = KzHashes.HASH256(bytes); var buf = new byte[bytes.Length + 4]; bytes.CopyTo(buf); checksum.Span.Slice(0, 4).CopyTo(buf.AsSpan().Slice(bytes.Length)); return(KzEncoders.B58.Encode(buf)); }
public override (bool ok, byte[] bytes) TryDecode(string encoded) { var(ok, bytes) = KzEncoders.B58.TryDecode(encoded); if (ok) { var span = bytes.AsSpan(); var checksum = span.Slice(span.Length - 4); bytes = span.Slice(0, span.Length - 4).ToArray(); var hash = KzHashes.HASH256(bytes); ok = checksum.SequenceEqual(hash.Span.Slice(0, 4)); } return(ok, bytes); }
/// <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)); }