/// <summary> /// Initializes a new instance of <see cref="TransactionVerifier"/> using given parameters. /// </summary> /// <exception cref="ArgumentNullException"/> /// <param name="isMempool">Indicates whether this instance is used by the memory pool or block</param> /// <param name="utxoDatabase">UTXO database</param> /// <param name="memoryPool">Memory pool</param> /// <param name="consensus">Consensus rules</param> public TransactionVerifier(bool isMempool, IUtxoDatabase utxoDatabase, IMemoryPool memoryPool, IConsensus consensus) { if (utxoDatabase is null) { throw new ArgumentNullException(nameof(utxoDatabase), "UTXO database can not be null."); } if (memoryPool is null) { throw new ArgumentNullException(nameof(memoryPool), "Memory pool can not be null."); } if (consensus is null) { throw new ArgumentNullException(nameof(consensus), "Consensus rules can not be null."); } this.isMempool = isMempool; utxoDb = utxoDatabase; mempool = memoryPool; this.consensus = consensus; calc = new EllipticCurveCalculator(); scrSer = new ScriptSerializer(); hash160 = new Ripemd160Sha256(); sha256 = new Sha256(); }
public RedeemScript() { IsWitness = false; OperationList = new IOperation[0]; ScriptType = ScriptType.ScriptRedeem; hashFunc = new Ripemd160Sha256() /*coin.AddressHashFunction*/; witHashFunc = new Sha256(false); // TODO: set this field in ICoin maxLenOrCount = 10000; // TODO: set this to a real value and from ICoin }
/// <summary> /// Replaces top stack item with its hash digest. Return value indicates success. /// </summary> /// <param name="opData">Data to use</param> /// <param name="error">Error message (null if sucessful, otherwise will contain information about the failure)</param> /// <returns>True if operation was successful, false if otherwise</returns> public override bool Run(IOpData opData, out string error) { if (opData.ItemCount < 1) { error = Err.OpNotEnoughItems; return(false); } using Ripemd160Sha256 hash = new Ripemd160Sha256(); opData.Push(hash.ComputeHash(opData.Pop())); error = null; return(true); }
/// <summary> /// Initializes a new instance of <see cref="PubkeyScript"/> using given parameters of the <see cref="ICoin"/>. /// </summary> public PubkeyScript() { IsWitness = false; OperationList = new IOperation[0]; ScriptType = ScriptType.ScriptPub; addrManager = new Address(); hashFunc = new Ripemd160Sha256(); witHashFunc = new Sha256(false); redeemScrBuilder = new RedeemScript(); op_return_MaxSize = 80; compPubKeyLength = (/*coin.Curve.NSizeInBits*/ 256 / 8) + 1; uncompPubKeyLength = ((compPubKeyLength - 1) * 2) + 1; minMultiPubCount = 0; maxMultiPubCount = 20; maxLenOrCount = 10000; }
public Address() { b58Encoder = new Base58(); b32Encoder = new Bech32(); hashFunc = new Ripemd160Sha256() /*coin.AddressHashFunction*/; witHashFunc = new Sha256(); // TODO: set this from ICoin versionByte_P2pkh_MainNet = 0; versionByte_P2pkh_TestNet = 111; versionByte_P2pkh_RegTest = 0; versionByte_P2sh_MainNet = 5; versionByte_P2sh_TestNet = 196; versionByte_P2sh_RegTest = 5; hrp_MainNet = "bc"; hrp_TestNet = "tb"; hrp_RegTest = "bcrt"; }
public Address() { b58Encoder = new Base58(); b32Encoder = new Bech32(); hashFunc = new Ripemd160Sha256(); witHashFunc = new Sha256(); versionByte_P2pkh_MainNet = 0; versionByte_P2pkh_TestNet = 111; versionByte_P2pkh_RegTest = 0; versionByte_P2sh_MainNet = 5; versionByte_P2sh_TestNet = 196; versionByte_P2sh_RegTest = 5; hrp_MainNet = "bc"; hrp_TestNet = "tb"; hrp_RegTest = "bcrt"; }
/// <summary> /// Return the pay to script hash address from the given <see cref="IScript"/>. /// </summary> /// <exception cref="ArgumentException"/> /// <exception cref="ArgumentNullException"/> /// <param name="redeem">Redeem script to use</param> /// <param name="netType">[Default value = <see cref="NetworkType.MainNet"/>] Network type</param> /// <returns>The resulting address</returns> public string GetP2sh(IScript redeem, NetworkType netType = NetworkType.MainNet) { if (redeem is null) { throw new ArgumentNullException(nameof(redeem), "Redeem script can not be null."); } byte ver = netType switch { NetworkType.MainNet => P2shVerMainNet, NetworkType.TestNet => P2shVerTestNet, NetworkType.RegTest => P2shVerRegTest, _ => throw new ArgumentException(Err.InvalidNetwork) }; using Ripemd160Sha256 hashFunc = new Ripemd160Sha256(); byte[] data = hashFunc.ComputeHash(redeem.Data).AppendToBeginning(ver); return(b58Encoder.EncodeWithCheckSum(data)); }
/// <summary> /// Return the pay to public key hash address from the given <see cref="PublicKey"/>. /// </summary> /// <exception cref="ArgumentException"/> /// <exception cref="ArgumentNullException"/> /// <param name="pubk">Public key to use</param> /// <param name="useCompressed"> /// [Default value = true] /// Indicates wheter to use compressed or compressed public key to generate the address /// </param> /// <param name="netType">[Default value = <see cref="NetworkType.MainNet"/>] Network type</param> /// <returns>The resulting address</returns> public string GetP2pkh(PublicKey pubk, bool useCompressed = true, NetworkType netType = NetworkType.MainNet) { if (pubk is null) { throw new ArgumentNullException(nameof(pubk), "Public key can not be null."); } byte ver = netType switch { NetworkType.MainNet => P2pkhVerMainNet, NetworkType.TestNet => P2pkhVerTestNet, NetworkType.RegTest => P2pkhVerRegTest, _ => throw new ArgumentException(Err.InvalidNetwork) }; using Ripemd160Sha256 hashFunc = new Ripemd160Sha256(); byte[] data = hashFunc.ComputeHash(pubk.ToByteArray(useCompressed)).AppendToBeginning(ver); return(b58Encoder.EncodeWithCheckSum(data)); }
public void ComputeHash_ReuseTest() { using Ripemd160Sha256 hash160 = new Ripemd160Sha256(); byte[] data1 = Helper.HexToBytes(PubComp); byte[] expected1 = Helper.HexToBytes(PubComp_hash); byte[] data2 = Helper.HexToBytes(PubUnComp); byte[] expected2 = Helper.HexToBytes(PubUnComp_hash); byte[] data3 = Helper.HexToBytes("1e26fa6d260804f1a6d94b24be80ec1ab0ac6f7483dbb3dc9d30fb47bf50c514471040e26a9a8379"); byte[] expected3 = Helper.HexToBytes("3900c473d221f26099b6df89526b7203d1a7b5d2"); hash160.ComputeHash(data1); byte[] actual1 = hash160.ComputeHash(data1); byte[] actual2 = hash160.ComputeHash(data2); byte[] actual3 = hash160.ComputeHash(data3); Assert.Equal(expected1, actual1); Assert.Equal(expected2, actual2); Assert.Equal(expected3, actual3); }
/// <summary> /// Return the pay to witness public key hash address from the given <see cref="PublicKey"/>. /// </summary> /// <exception cref="ArgumentException"/> /// <exception cref="ArgumentNullException"/> /// <param name="pubk">Public key to use</param> /// <param name="witVer">Witness version to use</param> /// <param name="useCompressed"> /// [Default value = true] /// Indicates wheter to use compressed or compressed public key to generate the address /// <para/> Note: using uncompressed public keys makes the output non-standard and can lead to money loss. /// </param> /// <param name="netType">[Default value = <see cref="NetworkType.MainNet"/>] Network type</param> /// <returns>The resulting address</returns> public string GetP2wpkh(PublicKey pubk, byte witVer, bool useCompressed = true, NetworkType netType = NetworkType.MainNet) { if (pubk is null) { throw new ArgumentNullException(nameof(pubk), "Public key can not be null."); } if (witVer != 0) { throw new ArgumentException("Currently only address version 0 is defined for P2WPKH.", nameof(witVer)); } string hrp = netType switch { NetworkType.MainNet => HrpMainNet, NetworkType.TestNet => HrpTestNet, NetworkType.RegTest => HrpRegTest, _ => throw new ArgumentException(Err.InvalidNetwork), }; using Ripemd160Sha256 hashFunc = new Ripemd160Sha256(); byte[] hash160 = hashFunc.ComputeHash(pubk.ToByteArray(useCompressed)); return(b32Encoder.Encode(hash160, witVer, hrp)); }
public void ComputeHashTest(byte[] data, byte[] expected) { using Ripemd160Sha256 hash160 = new Ripemd160Sha256(); byte[] actual = hash160.ComputeHash(data); Assert.Equal(expected, actual); }
private unsafe bool LoopComp(string key, int missingCount, char missingChar, byte[] expectedHash) { int[] missingIndexes = new int[missingCount]; byte[] ba = new byte[32]; for (int i = 0, j = 0; i < ba.Length; i++) { int hi, lo; if (key[i * 2] == missingChar) { hi = 0; missingIndexes[j++] = i * 2; } else { hi = key[i * 2] - 65; hi = hi + 10 + ((hi >> 31) & 7); } if (key[i * 2 + 1] == '*') { lo = 0; missingIndexes[j++] = i * 2 + 1; } else { lo = key[i * 2 + 1] - 65; lo = lo + 10 + ((lo >> 31) & 7) & 0x0f; } ba[i] = (byte)(lo | hi << 4); } var cartesian = CartesianProduct.Create(Enumerable.Repeat(Enumerable.Range(0, 16), missingCount)); EllipticCurveCalculator calc = new EllipticCurveCalculator(); BigInteger smallVal = new BigInteger(ba, true, true); EllipticCurvePoint smallPub = calc.MultiplyByG(smallVal); Ripemd160Sha256 hash = new Ripemd160Sha256(); Parallel.ForEach(cartesian, (item, loopState) => { Span <byte> temp = new byte[32]; int mis = 0; foreach (int keyItem in item) { int misIndex = missingIndexes[mis]; if (misIndex % 2 == 0) { temp[misIndex / 2] |= (byte)(keyItem << 4); } else { temp[misIndex / 2] |= (byte)keyItem; } mis++; } BigInteger tempVal = new BigInteger(temp, true, true); EllipticCurvePoint tempPub = calc.MultiplyByG(tempVal); EllipticCurvePoint pub = calc.AddChecked(tempPub, smallPub); byte[] toHash = new byte[33]; toHash[0] = pub.Y.IsEven ? (byte)2 : (byte)3; byte[] xBytes = pub.X.ToByteArray(true, true); Buffer.BlockCopy(xBytes, 0, toHash, 33 - xBytes.Length, xBytes.Length); ReadOnlySpan <byte> actual = hash.ComputeHash(toHash); if (actual.SequenceEqual(expectedHash)) { char[] origHex = key.ToCharArray(); int index = 0; foreach (var keyItem in item) { origHex[missingIndexes[index++]] = GetHex(keyItem); } AddQueue($"Found a key: {new string(origHex)}"); loopState.Break(); } }); AddQueue("Failed to find any key."); return(false); }