/// <summary> /// Returns base58-encoded string representation of this instance. /// </summary> /// <exception cref="ObjectDisposedException"/> /// <exception cref="ArgumentNullException"/> /// <param name="xType">Extended key type to return</param> /// <returns>Base58-encoded extended key</returns> public string ToBase58(XType xType) { if (isDisposed) { throw new ObjectDisposedException(nameof(BIP0032), "Instance was disposed."); } bool isPub = IsPublic(xType); if (!isPub && PrvKey is null) { throw new ArgumentNullException(nameof(PrvKey), "Can not get extended private key from public key."); } FastStream stream = new FastStream(ExtendedKeyLength); stream.WriteBigEndian((uint)xType); stream.Write(ExtendedKeyDepth); stream.Write(ParentFingerPrint); stream.Write(ChildNumber); stream.Write(ChainCode); if (isPub) { stream.Write(PubKey.ToByteArray(true)); } else { stream.Write((byte)0); stream.Write(PrvKey.ToBytes()); } return(Base58.EncodeWithChecksum(stream.ToByteArray())); }
public string DataAsJson() { var data = new JObject { { "version", Version }, { "watch_addresses", new JArray() }, { "public_addresses", new JArray() }, { "key_hashes", KeyHashes }, { "encrypted", new JObject { { "iv", Base58.EncodeWithChecksum(IV) }, { "salt", Base58.EncodeWithChecksum(Salt) }, { "data", Base58.EncodeWithChecksum(EncryptedData) } } } }; foreach (var address in WatchAddresses) { var addressJson = new JObject { { "addr", address.Address.ToString() } }; if (!String.IsNullOrWhiteSpace(address.Label)) { addressJson.Add("label", address.Label); } data["watch_addresses"].Value <JArray>().Add(addressJson); } foreach (var address in PublicAddresses) { var addressJson = new JObject { { "addr", address.Address.ToString() } }; if (!String.IsNullOrWhiteSpace(address.Label)) { addressJson.Add("label", address.Label); } data["public_addresses"].Value <JArray>().Add(addressJson); } return(JsonConvert.SerializeObject(data)); }
/// <summary> /// Returns the address that corresponds to the public part of this ECKey. Note that an address is derived from /// the RIPEMD-160 hash of the public key and is not the public key itself (which is too large to be convenient). /// </summary> public Address ToAddress() { byte[] hashedPubKey = Digest.Hash <RIPEMD160, SHA256>(PubKey); return(new Address(Base58.EncodeWithChecksum(ArrayHelpers.ConcatArrays(new byte[] { 0x00 }, hashedPubKey)))); }
// public byte[] ToAsn1() { // using(var baos = new MemoryStream(400)) { // using(var encoder = new Asn1OutputStream(baos)) { // // ASN1_SEQUENCE(EC_PRIVATEKEY) = { // // ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG), // // ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING), // // ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0), // // ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1) // // } ASN1_SEQUENCE_END(EC_PRIVATEKEY) // var seq = new DerSequenceGenerator(encoder); // seq.AddObject(new DerInteger(1)); // version // seq.AddObject(new DerOctetString(_priv.ToByteArray())); // seq.AddObject(new DerTaggedObject(0, SecNamedCurves.GetByName("secp256k1").ToAsn1Object())); // seq.AddObject(new DerTaggedObject(1, new DerBitString(PubKey))); // seq.Close(); // } // return baos.ToArray(); // } // } public string ToWalletImportFormat() { return(Base58.EncodeWithChecksum(ArrayHelpers.ConcatArrays(new byte[] { 0x80 }, _priv.ToByteArrayUnsigned()))); }
public void EncodeBitcoinAddress() { var actualText = Base58.EncodeWithChecksum(addressBytes); Assert.AreEqual(addressText, actualText); }
public void EncodeWithChecksum_ExceptionTest() { Assert.Throws <ArgumentNullException>(() => Base58.EncodeWithChecksum(null)); }
public void EncodeWithChecksumTest(string expected, byte[] data) { string actual = Base58.EncodeWithChecksum(data); Assert.Equal(expected, actual); }
/// <summary> /// Initializes a new instance of <see cref="MiniPrivateKey"/> with a randomly generated key /// using the given <see cref="IRandomNumberGenerator"/> instance. /// </summary> /// <exception cref="ArgumentNullException"/> /// <param name="rng">Random number generator to use</param> public MiniPrivateKey(IRandomNumberGenerator rng) { if (rng is null) { throw new ArgumentNullException("Random number generator can not be null."); } // This is the way Casascius does it. // https://github.com/casascius/Bitcoin-Address-Utility/blob/e493d51e4a1da7536fc8e8aea38eeaee38abf4cb/Model/MiniKeyPair.cs#L54-L80 // Create a random 256 bit key. It will only be used for its characters byte[] tempBa = new byte[32 + 1]; rng.GetBytes(tempBa); tempBa[0] = GetWifFirstByte(NetworkType.MainNet); string b58 = 'S' + Base58.EncodeWithChecksum(tempBa).Replace("1", "").Substring(4, 29); char[] chars = b58.ToCharArray(); char[] charstest = (b58 + "?").ToCharArray(); while (hash.ComputeHash(Encoding.UTF8.GetBytes(charstest))[0] != 0) { // As long as key doesn't pass typo check, increment it. for (int i = chars.Length - 1; i >= 0; i--) { char c = chars[i]; if (c == '9') { charstest[i] = chars[i] = 'A'; break; } else if (c == 'H') { charstest[i] = chars[i] = 'J'; break; } else if (c == 'N') { charstest[i] = chars[i] = 'P'; break; } else if (c == 'Z') { charstest[i] = chars[i] = 'a'; break; } else if (c == 'k') { charstest[i] = chars[i] = 'm'; break; } else if (c == 'z') { charstest[i] = chars[i] = '2'; // No break - let loop increment prior character. } else { charstest[i] = chars[i] = ++c; break; } } } smallBytes = Encoding.UTF8.GetBytes(chars); SetBytes(hash.ComputeHash(smallBytes)); }