/// <summary> /// Sign message with private key. /// </summary> /// <param name="bytes">Message to sign.</param> /// <param name="sk">Secret key used to sign.</param> /// <param name="watermark">Watermark</param> /// <returns>Signed message.</returns> public SignedMessage Sign(string bytes, Keys keys, byte[] watermark = null) { byte[] bb = bytes.HexToByteArray(); if (watermark?.Length > 0) { byte[] bytesWithWatermark = new byte[bb.Length + watermark.Length]; Array.Copy(watermark, 0, bytesWithWatermark, 0, watermark.Length); Array.Copy(bb, 0, bytesWithWatermark, watermark.Length, bb.Length); bb = bytesWithWatermark; } // TODO: See if there's a way to further reduce potential attack vectors. string sk = keys.DecryptPrivateKey(); byte[] dsk = B58C.Decode(sk, Prefix.edsk); byte[] hash = Hashing.Generic(32 * 8, bb); byte[] sig = Ed25519.Sign(hash, dsk); string edsignature = B58C.Encode(sig, Prefix.edsig); string sbytes = bytes + sig.ToHexString(); return(new SignedMessage { Bytes = bb, SignedHash = sig, EncodedSignature = edsignature, SignedBytes = sbytes }); }
public Keys(byte[] pk, byte[] sk) { PublicHash = B58C.Encode(Hashing.Generic(PKHASH_BIT_SIZE, pk), Prefix.tz1); PublicKey = new SecureString(); PrivateKey = new SecureString(); string encodedPK = B58C.Encode(pk, Prefix.edpk); foreach (char c in encodedPK) { PublicKey.AppendChar(c); } string encodedSK = B58C.Encode(sk, Prefix.edsk); foreach (char c in encodedSK) { PrivateKey.AppendChar(c); } // Quickly zero out the unneeded key arrays so it doesn't linger in memory before the GC can sweep it up. Array.Clear(pk, 0, pk.Length); Array.Clear(sk, 0, sk.Length); }
/// <summary> /// Verify a signed message with public key. /// </summary> /// <param name="bytes"></param> /// <param name="sig">Signed message to verify.</param> /// <param name="pk">Public key used for verification.</param> /// <returns></returns> public bool Verify(string bytes, byte[] sig, string pk) { byte[] bb = bytes.HexToByteArray(); byte[] edpk = B58C.Decode(pk, Prefix.edpk); return(Ed25519.Verify(sig, bb, edpk)); }
/// <summary> /// Checks that a tz1 address is valid. /// </summary> /// <param name="tz1">tz1 address to check for validity.</param> /// <returns>True if valid address.</returns> public bool CheckAddress(string tz1) { try { B58C.Decode(tz1, Prefix.tz1); return(true); } catch { return(false); } }
public static Wallet FromStringSeed(string seed, byte[] prefix = null) { return(new Wallet(B58C.Decode(seed, prefix ?? Prefix.edsk))); }
public string HashBytes() { return(B58C.Encode(Hashing.Generic(HASH_SIZE_BITS, Bytes))); }