public static byte[] AddressToBin(string aAddress, Network aNetwork) { byte[] lData = null; const int SCRIPT_ADDRESS = 1; const int PUBKEY_ADDRESS = 0; if (!string.IsNullOrEmpty(aAddress)) { lData = (aNetwork.NetworkStringParser.GetBase58CheckEncoder()).IsValidData(aAddress) ? (aNetwork.NetworkStringParser.GetBase58CheckEncoder()).DecodeData(aAddress) : null; if (lData != null) { var lScriptVer = aNetwork.GetVersionBytes(SCRIPT_ADDRESS, true); var lPubVer = aNetwork.GetVersionBytes(PUBKEY_ADDRESS, true); if (!(((lScriptVer != null && lData.StartWith(lScriptVer)) && (lData.Length == lScriptVer.Length + 20)) || ((lPubVer != null && lData.StartWith(lPubVer)) && (lData.Length == lPubVer.Length + 20)))) { lData = null; } } else if (aNetwork.ChainParams.Capabilities.HasFlag(CapablityFlags.SegWitSupport)) { int i = Network.BEACH32_WITNESS_PUBKEY_ADDRESS; while (lData == null && i < Network.BEACH32_WITNESS_SCRIPT_ADDRESS) { var encoder = aNetwork.GetBech32Encoder(i, true); if (encoder == null) { continue; } Int32 type = i; i++; try { byte witVersion; var bytes = encoder.Decode(aAddress, out witVersion); if (witVersion == 0 && bytes.Length == 20 && type == Network.BEACH32_WITNESS_PUBKEY_ADDRESS) { lData = bytes; } else if (witVersion == 0 && bytes.Length == 32 && type == Network.BEACH32_WITNESS_SCRIPT_ADDRESS) { lData = bytes; } } catch (Bech32FormatException) { throw; } catch (FormatException) { continue; } } } } return(lData); }
private static string GenerateWif(string passphrase, Network network, LotSequence lotsequence, byte[] ownersalt) { bool hasLotSequence = lotsequence != null; //ownersalt is 8 random bytes ownersalt = ownersalt ?? RandomUtils.GetBytes(8); var ownerEntropy = ownersalt; if (hasLotSequence) { ownersalt = ownersalt.Take(4).ToArray(); ownerEntropy = ownersalt.Concat(lotsequence.ToBytes()).ToArray(); } var prefactor = SCrypt.CoinComputeDerivedKey(Encoding.UTF8.GetBytes(passphrase), ownersalt, 32); var passfactor = prefactor; if (hasLotSequence) { passfactor = Hashes.Hash256(prefactor.Concat(ownerEntropy).ToArray()).ToBytes(); } var passpoint = new CCKey(passfactor, fCompressedIn: true).PubKey.ToBytes(); var bytes = network.GetVersionBytes(Network.BASE58_PASSPHRASE_CODE, true) .Concat(new[] { hasLotSequence ? (byte)0x51 : (byte)0x53 }) .Concat(ownerEntropy) .Concat(passpoint) .ToArray(); return(Encoders.Base58Check.EncodeData(bytes)); }
public CoinScriptAddress(string base58, Network expectedNetwork) : base(Validate(base58, ref expectedNetwork), expectedNetwork) { var decoded = Encoders.Base58Check.DecodeData(base58); _Hash = new ScriptId(new uint160(decoded.Skip(expectedNetwork.GetVersionBytes(Type, true).Length).ToArray())); }
private static string GenerateWif(CCKey key, string password, Network network) { var vch = key.ToBytes(); //Compute the Coin address (ASCII), var addressBytes = Encoders.ASCII.DecodeData(key.PubKey.GetAddress(network).ToString()); // and take the first four bytes of SHA256(SHA256()) of it. Let's call this "addresshash". var addresshash = Hashes.Hash256(addressBytes).ToBytes().SafeSubarray(0, 4); var derived = SCrypt.CoinComputeDerivedKey(Encoding.UTF8.GetBytes(password), addresshash); var encrypted = EncryptKey(vch, derived); var version = network.GetVersionBytes(Network.BASE58_ENCRYPTED_SECRET_KEY_NO_EC, true); byte flagByte = 0; flagByte |= 0x0C0; flagByte |= (key.IsCompressed ? (byte)0x20 : (byte)0x00); var bytes = version .Concat(new[] { flagByte }) .Concat(addresshash) .Concat(encrypted).ToArray(); return(Encoders.Base58Check.EncodeData(bytes)); }
public CoinPubKeyAddress(string base58, Network expectedNetwork) : base(Validate(base58, ref expectedNetwork), expectedNetwork) { Type = Base58Type; var decoded = Encoders.Base58Check.DecodeData(base58); _KeyId = new KeyId(new uint160(decoded.Skip(expectedNetwork.GetVersionBytes(Base58Type, true).Length).ToArray())); }
public static string CreateBase58(Base58Type type, byte[] bytes, Network network) { if (network == null) { throw new ArgumentNullException("network"); } if (bytes == null) { throw new ArgumentNullException("bytes"); } var versionBytes = network.GetVersionBytes(type, true); return(Encoders.Base58Check.EncodeData(versionBytes.Concat(bytes))); }
public EncryptedKeyResult GenerateEncryptedSecret(bool isCompressed = true, byte[] seedb = null) { //Set flagbyte. byte flagByte = 0; //Turn on bit 0x20 if the Coin address will be formed by hashing the compressed public key flagByte |= isCompressed ? (byte)0x20 : (byte)0x00; flagByte |= LotSequence != null ? (byte)0x04 : (byte)0x00; //Generate 24 random bytes, call this seedb. Take SHA256(SHA256(seedb)) to yield 32 bytes, call this factorb. seedb = seedb ?? RandomUtils.GetBytes(24); var factorb = Hashes.Hash256(seedb).ToBytes(); //ECMultiply passpoint by factorb. var curve = ECKey.Secp256k1; var passpoint = curve.Curve.DecodePoint(Passpoint); var pubPoint = passpoint.Multiply(new BigInteger(1, factorb)); //Use the resulting EC point as a public key var pubKey = new PubKey(pubPoint.GetEncoded()); //and hash it into a Coin address using either compressed or uncompressed public key //This is the generated Coin address, call it generatedaddress. pubKey = isCompressed ? pubKey.Compress() : pubKey.Decompress(); //call it generatedaddress. var generatedaddress = pubKey.GetAddress(Network); //Take the first four bytes of SHA256(SHA256(generatedaddress)) and call it addresshash. var addresshash = CoinEncryptedSecretEC.HashAddress(generatedaddress); //Derive a second key from passpoint using scrypt //salt is addresshash + ownerentropy var derived = CoinEncryptedSecretEC.CalculateDecryptionKey(Passpoint, addresshash, OwnerEntropy); //Now we will encrypt seedb. var encrypted = CoinEncryptedSecret.EncryptSeed (seedb, derived); //0x01 0x43 + flagbyte + addresshash + ownerentropy + encryptedpart1[0...7] + encryptedpart2 which totals 39 bytes var bytes = new[] { flagByte } .Concat(addresshash) .Concat(this.OwnerEntropy) .Concat(encrypted.Take(8).ToArray()) .Concat(encrypted.Skip(16).ToArray()) .ToArray(); var encryptedSecret = new CoinEncryptedSecretEC(bytes, Network); return(new EncryptedKeyResult(encryptedSecret, generatedaddress, seedb, () => { //ECMultiply factorb by G, call the result pointb. The result is 33 bytes. var pointb = new CCKey(factorb).PubKey.ToBytes(); //The first byte is 0x02 or 0x03. XOR it by (derivedhalf2[31] & 0x01), call the resulting byte pointbprefix. var pointbprefix = (byte)(pointb[0] ^ (byte)(derived[63] & 0x01)); var pointbx = CoinEncryptedSecret.EncryptKey(pointb.Skip(1).ToArray(), derived); var encryptedpointb = new byte[] { pointbprefix }.Concat(pointbx).ToArray(); var confirmBytes = Network.GetVersionBytes(Network.BASE58_CONFIRMATION_CODE, true) .Concat(new[] { flagByte }) .Concat(addresshash) .Concat(OwnerEntropy) .Concat(encryptedpointb) .ToArray(); return new CoinConfirmationCode(Encoders.Base58Check.EncodeData(confirmBytes), Network); })); }
private void SetString <T>(string psz) where T : Base58Data { if (_Network == null) { _Network = Network.GetNetworkFromBase58Data(psz, Type); if (_Network == null) { throw new FormatException("Invalid " + this.GetType().Name); } } byte[] vchTemp = _Network.NetworkStringParser.GetBase58CheckEncoder().DecodeData(psz); #if HAS_SPAN if (!(_Network.GetVersionMemory(Type, false) is ReadOnlyMemory <byte> expectedVersion)) { throw new FormatException("Invalid " + this.GetType().Name); } #else var expectedVersion = _Network.GetVersionBytes(Type, false); if (expectedVersion is null) { throw new FormatException("Invalid " + this.GetType().Name); } #endif #if HAS_SPAN var vchTempMemory = vchTemp.AsMemory(); vchVersion = vchTempMemory.Slice(0, expectedVersion.Length); #else vchVersion = vchTemp.SafeSubarray(0, expectedVersion.Length); #endif #if HAS_SPAN if (!vchVersion.Span.SequenceEqual(expectedVersion.Span)) #else if (!Utils.ArrayEqual(vchVersion, expectedVersion)) #endif { if (_Network.NetworkStringParser.TryParse(psz, Network, out T other)) { this.vchVersion = other.vchVersion; this.vchData = other.vchData; this.wifData = other.wifData; } else { throw new FormatException("The version prefix does not match the expected one " + String.Join(",", expectedVersion)); } } else { #if HAS_SPAN vchData = vchTempMemory.Slice(expectedVersion.Length).ToArray(); #else vchData = vchTemp.SafeSubarray(expectedVersion.Length); #endif wifData = psz; } if (!IsValid) { throw new FormatException("Invalid " + this.GetType().Name); } }