public uint256_tests() { R1Array = ToBytes("\x9c\x52\x4a\xdb\xcf\x56\x11\x12\x2b\x29\x12\x5e\x5d\x35\xd2\xd2\x22\x81\xaa\xb5\x33\xf0\x08\x32\xd5\x56\xb1\xf9\xea\xe5\x1d\x7d"); R1L = new uint256(R1Array); NegR1L = ~R1L; R1S = new uint160(R1Array.Take(20).ToArray()); NegR1S = ~R1S; NegR1Array = NegR1L.ToBytes(); R2Array = ToBytes("\x70\x32\x1d\x7c\x47\xa5\x6b\x40\x26\x7e\x0a\xc3\xa6\x9c\xb6\xbf\x13\x30\x47\xa3\x19\x2d\xda\x71\x49\x13\x72\xf0\xb4\xca\x81\xd7"); R2L = new uint256(R2Array); NegR2L = ~R2L; R2S = new uint160(R2Array.Take(20).ToArray()); NegR2S = ~R2S; NegR2Array = NegR2L.ToBytes(); ZeroArray = ToBytes("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"); ZeroL = new uint256(ZeroArray); ZeroS = new uint160(ZeroArray.Take(20).ToArray()); OneArray = ToBytes("\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"); OneL = new uint256(OneArray); OneS = new uint160(OneArray.Take(20).ToArray()); MaxArray = ToBytes("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"); MaxL = new uint256(MaxArray); MaxS = new uint160(MaxArray.Take(20).ToArray()); HalfL = OneL << 255; HalfS = OneS << 159; }
public ECDSASignature Sign(uint256 hash) { AssertPrivateKey(); var signer = new DeterministicECDSA(); signer.setPrivateKey(PrivateKey); var sig = ECDSASignature.FromDER(signer.signHash(hash.ToBytes())); return sig.MakeCanonical(); }
public void uintTests() { var v = new uint256("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); var v2 = new uint256("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); var vless = new uint256("00000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffe"); var vplus = new uint256("00000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); Assert.Equal("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", v.ToString()); Assert.Equal(new uint256("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), v); Assert.Equal(new uint256("0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), v); Assert.Equal(uint256.Parse("0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"), v); Assert.True(v < vplus); Assert.True(v > vless); uint256 unused; Assert.True(uint256.TryParse("0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", out unused)); Assert.True(uint256.TryParse("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", out unused)); Assert.True(uint256.TryParse("00000000ffffFFfFffffffffffffffffffffffffffffffffffffffffffffffff", out unused)); Assert.False(uint256.TryParse("00000000gfffffffffffffffffffffffffffffffffffffffffffffffffffffff", out unused)); Assert.False(uint256.TryParse("100000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", out unused)); Assert.False(uint256.TryParse("1100000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff", out unused)); Assert.Throws<FormatException>(() => uint256.Parse("1100000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); Assert.Throws<FormatException>(() => uint256.Parse("100000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); uint256.Parse("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); Assert.Throws<FormatException>(() => uint256.Parse("000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff")); Assert.True(v >= v2); Assert.True(v <= v2); Assert.False(v < v2); Assert.False(v > v2); Assert.True(v.ToBytes()[0] == 0xFF); Assert.True(v.ToBytes(false)[0] == 0x00); AssertEquals(v, new uint256(v.ToBytes())); AssertEquals(v, new uint256(v.ToBytes(false), false)); Assert.Equal(0xFF, v.GetByte(0)); Assert.Equal(0x00, v.GetByte(31)); Assert.Equal(0x39, new uint256("39000001ffffffffffffffffffffffffffffffffffffffffffffffffffffffff").GetByte(31)); Assert.Throws<ArgumentOutOfRangeException>(() => v.GetByte(32)); }
/// <summary> /// Computes merkle root. /// </summary> /// <remarks>This implements a constant-space merkle root/path calculator, limited to 2^32 leaves.</remarks> /// <param name="leaves">Merkle tree leaves.</param> /// <param name="mutated"><c>true</c> if at least one leaf of the merkle tree has the same hash as any subtree. Otherwise: <c>false</c>.</param> public static uint256 ComputeMerkleRoot(List <uint256> leaves, out bool mutated) { var branch = new List <uint256>(); mutated = false; if (leaves.Count == 0) { return(uint256.Zero); } // count is the number of leaves processed so far. uint count = 0; // inner is an array of eagerly computed subtree hashes, indexed by tree // level (0 being the leaves). // For example, when count is 25 (11001 in binary), inner[4] is the hash of // the first 16 leaves, inner[3] of the next 8 leaves, and inner[0] equal to // the last leaf. The other inner entries are undefined. var inner = new uint256[32]; for (int i = 0; i < inner.Length; i++) { inner[i] = uint256.Zero; } // Which position in inner is a hash that depends on the matching leaf. int matchLevel = -1; // First process all leaves into 'inner' values. while (count < leaves.Count) { uint256 h = leaves[(int)count]; bool match = false; count++; int level; // For each of the lower bits in count that are 0, do 1 step. Each // corresponds to an inner value that existed before processing the // current leaf, and each needs a hash to combine it. for (level = 0; (count & (((uint)1) << level)) == 0; level++) { if (branch != null) { if (match) { branch.Add(inner[level]); } else if (matchLevel == level) { branch.Add(h); match = true; } } if (!mutated) { mutated = inner[level] == h; } var hash = new byte[64]; Buffer.BlockCopy(inner[level].ToBytes(), 0, hash, 0, 32); Buffer.BlockCopy(h.ToBytes(), 0, hash, 32, 32); h = Hashes.Hash256(hash); } // Store the resulting hash at inner position level. inner[level] = h; if (match) { matchLevel = level; } } uint256 root; { // Do a final 'sweep' over the rightmost branch of the tree to process // odd levels, and reduce everything to a single top value. // Level is the level (counted from the bottom) up to which we've sweeped. int level = 0; // As long as bit number level in count is zero, skip it. It means there // is nothing left at this level. while ((count & (((uint)1) << level)) == 0) { level++; } root = inner[level]; bool match = matchLevel == level; while (count != (((uint)1) << level)) { // If we reach this point, h is an inner value that is not the top. // We combine it with itself (Bitcoin's special rule for odd levels in // the tree) to produce a higher level one. if (match) { branch.Add(root); } var hash = new byte[64]; Buffer.BlockCopy(root.ToBytes(), 0, hash, 0, 32); Buffer.BlockCopy(root.ToBytes(), 0, hash, 32, 32); root = Hashes.Hash256(hash); // Increment count to the value it would have if two entries at this // level had existed. count += (((uint)1) << level); level++; // And propagate the result upwards accordingly. while ((count & (((uint)1) << level)) == 0) { if (match) { branch.Add(inner[level]); } else if (matchLevel == level) { branch.Add(root); match = true; } var hashh = new byte[64]; Buffer.BlockCopy(inner[level].ToBytes(), 0, hashh, 0, 32); Buffer.BlockCopy(root.ToBytes(), 0, hashh, 32, 32); root = Hashes.Hash256(hashh); level++; } } } return(root); }
/// <inheritdoc /> public uint256 GetBlockIdByTransactionId(uint256 trxid) { Guard.NotNull(trxid, nameof(trxid)); if (!this.TxIndex) { this.logger.LogTrace("(-)[NO_TXINDEX]:null"); return(default(uint256)); } if (this.genesisTransactions.ContainsKey(trxid)) { return(this.network.GenesisHash); } uint256 res = null; lock (this.Locker) { byte[] transactionRow = this.rocksdb.Get(DBH.Key(TransactionTableName, trxid.ToBytes())); if (transactionRow != null) { res = new uint256(transactionRow); } } return(res); }
private (Share Share, string nonce, string solution, string headerHash, string nTime) ProcessShareInternal( StratumClient worker, string nonce, string nTime, string solution) { var context = worker.ContextAs <AionWorkerContext>(); var solutionBytes = solution.HexToByteArray(); // serialize block-header var headerBytes = SerializeHeader(nonce); // verify solution if (!equihash.Verify(headerBytes, solutionBytes)) { throw new StratumException(StratumError.Other, "invalid solution"); } // hash block-header var headerSolutionBytes = headerBytes.Concat(solutionBytes).ToArray(); Span <byte> headerHash = stackalloc byte[32]; headerHasher.Digest(headerSolutionBytes, headerHash); var headerHashReversed = headerHash.ToNewReverseArray(); var headerValue = headerHashReversed.ToBigInteger(); var target = new BigInteger(blockTarget.ToBytes()); var isBlockCandidate = target > headerValue; logger.Debug(() => $"context.Difficulty:{context.Difficulty} Difficulty: {Difficulty}"); // calc share-diff var stratumDifficulty = context.Difficulty > Difficulty ? Difficulty : context.Difficulty; var shareDiff = stratumDifficulty; var ratio = shareDiff / stratumDifficulty; var sentTargetInt = new uint256(AionUtils.diffToTarget(context.Difficulty).HexToReverseByteArray()); var sentTarget = new BigInteger(sentTargetInt.ToBytes()); var isLowDiffShare = sentTarget <= headerValue; if (isLowDiffShare) { throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); } var result = new Share { BlockHeight = (long)BlockTemplate.Height, IpAddress = worker.RemoteEndpoint?.Address?.ToString(), Miner = context.MinerName, Worker = context.WorkerName, UserAgent = context.UserAgent, NetworkDifficulty = Difficulty, Difficulty = stratumDifficulty, IsBlockCandidate = isBlockCandidate, TransactionConfirmationData = headerHash.ToHexString(), }; if (isBlockCandidate) { // result.BlockReward = AionUtils.calculateReward((long) BlockTemplate.Height); result.BlockHash = headerHashReversed.ToHexString(); } return(result, nonce, solution, BlockTemplate.HeaderHash, nTime); }
/// <inheritdoc /> public uint256 GetBlockIdByTransactionId(uint256 trxid) { Guard.NotNull(trxid, nameof(trxid)); if (!this.TxIndex) { this.logger.LogTrace("(-)[NO_TXINDEX]:null"); return(default(uint256)); } uint256 res = null; using (DBreeze.Transactions.Transaction transaction = this.DBreeze.GetTransaction()) { transaction.ValuesLazyLoadingIsOn = false; Row <byte[], byte[]> transactionRow = transaction.Select <byte[], byte[]>(TransactionTableName, trxid.ToBytes()); if (transactionRow.Exists) { res = new uint256(transactionRow.Value); } } return(res); }
internal int GetBucketPosition(uint256 nKey, bool fNew, int nBucket) { UInt64 hash1 = Cheap( Hashes.Hash256( nKey.ToBytes() .Concat(new byte[] { (fNew ? (byte)'N' : (byte)'K') }) .Concat(Utils.ToBytes((uint)nBucket, false)) .Concat(Address.GetKey()) .ToArray())); return (int)(hash1 % ADDRMAN_BUCKET_SIZE); }
public UTXODeterministicComparer(uint256 blind) { _blind = blind.ToBytes(); }
public void methods() { Assert.True(R1L.ToString() == R1L.ToString()); Assert.True(R2L.ToString() == R2L.ToString()); Assert.True(OneL.ToString() == OneL.ToString()); Assert.True(MaxL.ToString() == MaxL.ToString()); uint256 TmpL = new uint256(R1L); Assert.True(TmpL == R1L); TmpL.SetHex(R2L.ToString()); Assert.True(TmpL == R2L); TmpL.SetHex(ZeroL.ToString()); Assert.True(TmpL == 0); TmpL.SetHex(HalfL.ToString()); Assert.True(TmpL == HalfL); TmpL.SetHex(R1L.ToString()); AssertEx.CollectionEquals(R1L.ToBytes(), R1Array); AssertEx.CollectionEquals(TmpL.ToBytes(), R1Array); AssertEx.CollectionEquals(R2L.ToBytes(), R2Array); AssertEx.CollectionEquals(ZeroL.ToBytes(), ZeroArray); AssertEx.CollectionEquals(OneL.ToBytes(), OneArray); Assert.True(R1L.Size == 32); Assert.True(R2L.Size == 32); Assert.True(ZeroL.Size == 32); Assert.True(MaxL.Size == 32); //No sense in .NET //Assert.True(R1L.begin() + 32 == R1L.end()); //Assert.True(R2L.begin() + 32 == R2L.end()); //Assert.True(OneL.begin() + 32 == OneL.end()); //Assert.True(MaxL.begin() + 32 == MaxL.end()); //Assert.True(TmpL.begin() + 32 == TmpL.end()); Assert.True(R1L.GetLow64() == R1LLow64); Assert.True(HalfL.GetLow64() == 0x0000000000000000UL); Assert.True(OneL.GetLow64() == 0x0000000000000001UL); Assert.True(R1L.GetSerializeSize(0, ProtocolVersion.PROTOCOL_VERSION) == 32); Assert.True(ZeroL.GetSerializeSize(0, ProtocolVersion.PROTOCOL_VERSION) == 32); MemoryStream ss = new MemoryStream(); R1L.ReadWrite(ss, true, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ArrayToString(ss.ToArray()) == ArrayToString(R1Array)); ss.Position = 0; TmpL.ReadWrite(ss, false, ProtocolVersion.PROTOCOL_VERSION); Assert.True(R1L == TmpL); ss = new MemoryStream(); ZeroL.ReadWrite(ss, true, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ArrayToString(ss.ToArray()) == ArrayToString(ZeroArray)); ss.Position = 0; TmpL.ReadWrite(ss, false, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ZeroL == TmpL); ss = new MemoryStream(); MaxL.ReadWrite(ss, true, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ArrayToString(ss.ToArray()) == ArrayToString(MaxArray)); ss.Position = 0; TmpL.ReadWrite(ss, false, ProtocolVersion.PROTOCOL_VERSION); Assert.True(MaxL == TmpL); ss = new MemoryStream(); uint160 TmpS = new uint160(R1S); Assert.True(TmpS == R1S); TmpS.SetHex(R2S.ToString()); Assert.True(TmpS == R2S); TmpS.SetHex(ZeroS.ToString()); Assert.True(TmpS == 0); TmpS.SetHex(HalfS.ToString()); Assert.True(TmpS == HalfS); TmpS.SetHex(R1S.ToString()); Assert.True(ArrayToString(R1S.ToBytes()) == ArrayToString(R1Array.Take(20).ToArray())); Assert.True(ArrayToString(TmpS.ToBytes()) == ArrayToString(R1Array.Take(20).ToArray())); Assert.True(ArrayToString(R2S.ToBytes()) == ArrayToString(R2Array.Take(20).ToArray())); Assert.True(ArrayToString(ZeroS.ToBytes()) == ArrayToString(ZeroArray.Take(20).ToArray())); Assert.True(ArrayToString(OneS.ToBytes()) == ArrayToString(OneArray.Take(20).ToArray())); Assert.True(R1S.Size == 20); Assert.True(R2S.Size == 20); Assert.True(ZeroS.Size == 20); Assert.True(MaxS.Size == 20); //No sense in .NET //Assert.True(R1S.begin() + 20 == R1S.end()); //Assert.True(R2S.begin() + 20 == R2S.end()); //Assert.True(OneS.begin() + 20 == OneS.end()); //Assert.True(MaxS.begin() + 20 == MaxS.end()); //Assert.True(TmpS.begin() + 20 == TmpS.end()); Assert.True(R1S.GetLow64() == R1LLow64); Assert.True(HalfS.GetLow64() == 0x0000000000000000UL); Assert.True(OneS.GetLow64() == 0x0000000000000001UL); Assert.True(R1S.GetSerializeSize(0, ProtocolVersion.PROTOCOL_VERSION) == 20); Assert.True(ZeroS.GetSerializeSize(0, ProtocolVersion.PROTOCOL_VERSION) == 20); R1S.ReadWrite(ss, true, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ArrayToString(ss.ToArray()) == ArrayToString(R1Array.Take(20).ToArray())); ss.Position = 0; TmpS.ReadWrite(ss, false, ProtocolVersion.PROTOCOL_VERSION); Assert.True(R1S == TmpS); ss = new MemoryStream(); ZeroS.ReadWrite(ss, true, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ArrayToString(ss.ToArray()) == ArrayToString(ZeroArray.Take(20).ToArray())); ss.Position = 0; TmpS.ReadWrite(ss, false, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ZeroS == TmpS); ss = new MemoryStream(); MaxS.ReadWrite(ss, true, ProtocolVersion.PROTOCOL_VERSION); Assert.True(ArrayToString(ss.ToArray()) == ArrayToString(MaxArray.Take(20).ToArray())); ss.Position = 0; TmpS.ReadWrite(ss, false, ProtocolVersion.PROTOCOL_VERSION); Assert.True(MaxS == TmpS); ss = new MemoryStream(); //for(int i = 0 ; i < 255 ; ++i) //{ // Assert.True((OneL << i).GetDouble() == Math.Pow(1.0, i)); // if(i < 160) // Assert.True((OneS << i).GetDouble() == Math.Pow(1.0, i)); //} //Assert.True(ZeroL.GetDouble() == 0.0); //Assert.True(ZeroS.GetDouble() == 0.0); //for(int i = 256 ; i > 53 ; --i) // Assert.True(almostEqual((R1L >> (256 - i)).GetDouble(), Math.Pow(R1Ldouble, i))); //for(int i = 160 ; i > 53 ; --i) // Assert.True(almostEqual((R1S >> (160 - i)).GetDouble(), Math.Pow(R1Sdouble, i))); //ulong R1L64part = (R1L >> 192).GetLow64(); //ulong R1S64part = (R1S >> 96).GetLow64(); //for(int i = 53 ; i > 0 ; --i) // doubles can store all integers in {0,...,2^54-1} exactly //{ // Assert.True((R1L >> (256 - i)).GetDouble() == (double)(R1L64part >> (64 - i))); // Assert.True((R1S >> (160 - i)).GetDouble() == (double)(R1S64part >> (64 - i))); //} }
private async Task <(Share Share, string nonce, string solution, string headerHash, string nTime)> ProcessShareInternal( StratumClient worker, string nonce, string nTime, string solution) { var context = worker.GetContextAs <AionWorkerContext>(); var solutionBytes = solution.HexToByteArray(); // serialize block-header var headerBytes = SerializeHeader(nonce); // verify solution if (!equihash.Verify210(headerBytes, solutionBytes)) { throw new StratumException(StratumError.Other, "invalid solution"); } // hash block-header var headerSolutionBytes = headerBytes.Concat(solutionBytes).ToArray(); var headerHash = headerHasher.Digest(headerSolutionBytes); var headerHashReversed = headerHash.ToReverseArray(); var headerBigInt = headerHashReversed.ToBigInteger(); var target = new BigInteger(blockTarget.ToBytes()); var isBlockCandidate = target > headerBigInt; // calc share-diff var stratumDifficulty = context.Difficulty > Difficulty ? Difficulty : context.Difficulty; var shareDiff = stratumDifficulty; var ratio = shareDiff / stratumDifficulty; var sentTargetInt = new uint256(AionUtils.diffToTarget(context.Difficulty).HexToByteArray().ReverseArray()); var sentTarget = new BigInteger(sentTargetInt.ToBytes()); var isLowDiffShare = sentTarget <= headerBigInt; if (isLowDiffShare) { // Check if matched a previous varDiff before retarget if (context.VarDiff?.LastUpdate != null && context.PreviousDifficulty.HasValue) { var prevSentTargetInt = new uint256(AionUtils.diffToTarget(context.PreviousDifficulty.Value).HexToByteArray().ReverseArray()); var prevSentTargetBi = new BigInteger(prevSentTargetInt.ToBytes()); if (prevSentTargetBi <= headerBigInt) { stratumDifficulty = context.PreviousDifficulty.Value; } } else { throw new StratumException(StratumError.LowDifficultyShare, $"low difficulty share ({shareDiff})"); } } var result = new Share { BlockHeight = (long)BlockTemplate.Height, IpAddress = worker.RemoteEndpoint?.Address?.ToString(), Miner = context.MinerName, Worker = context.WorkerName, UserAgent = context.UserAgent, NetworkDifficulty = Difficulty, Difficulty = stratumDifficulty, IsBlockCandidate = isBlockCandidate, TransactionConfirmationData = headerHash.ToHexString(), }; if (isBlockCandidate) { result.BlockReward = AionUtils.calculateReward((long)BlockTemplate.Height); result.BlockHash = headerHashReversed.ToHexString(); } return(result, nonce, solution, BlockTemplate.HeaderHash, nTime); }
public async Task NotingTestsAsync() { (string password, RPCClient rpc, Network network, Coordinator coordinator, ServiceConfiguration serviceConfiguration, BitcoinStore bitcoinStore, Backend.Global global) = await Common.InitializeTestEnvironmentAsync(RegTestFixture, 1); Money denomination = Money.Coins(1m); decimal coordinatorFeePercent = 0.1m; int anonymitySet = 2; int connectionConfirmationTimeout = 1; bool doesNoteBeforeBan = true; CoordinatorRoundConfig roundConfig = RegTestFixture.CreateRoundConfig(denomination, 140, 0.7, coordinatorFeePercent, anonymitySet, 240, connectionConfirmationTimeout, 1, 1, 1, 24, doesNoteBeforeBan, 11); coordinator.RoundConfig.UpdateOrDefault(roundConfig, toFile: true); coordinator.AbortAllRoundsInInputRegistration(""); Uri baseUri = new Uri(RegTestFixture.BackendEndPoint); var registerRequests = new List <(BitcoinWitPubKeyAddress changeOutputAddress, uint256 blindedData, InputProofModel[] inputsProofs)>(); AliceClient aliceClientBackup = null; CoordinatorRound round = coordinator.GetCurrentInputRegisterableRoundOrDefault(); for (int i = 0; i < roundConfig.AnonymitySet; i++) { BitcoinWitPubKeyAddress activeOutputAddress = new Key().PubKey.GetSegwitAddress(network); BitcoinWitPubKeyAddress changeOutputAddress = new Key().PubKey.GetSegwitAddress(network); Key inputKey = new Key(); BitcoinWitPubKeyAddress inputAddress = inputKey.PubKey.GetSegwitAddress(network); var requester = new Requester(); uint256 blinded = requester.BlindScript(round.MixingLevels.GetBaseLevel().Signer.Key.PubKey, round.MixingLevels.GetBaseLevel().Signer.R.PubKey, activeOutputAddress.ScriptPubKey); uint256 blindedOutputScriptsHash = new uint256(Hashes.SHA256(blinded.ToBytes())); uint256 txHash = await rpc.SendToAddressAsync(inputAddress, Money.Coins(2)); await rpc.GenerateAsync(1); Transaction transaction = await rpc.GetRawTransactionAsync(txHash); Coin coin = transaction.Outputs.GetCoins(inputAddress.ScriptPubKey).Single(); OutPoint input = coin.Outpoint; InputProofModel inputProof = new InputProofModel { Input = input.ToTxoRef(), Proof = inputKey.SignCompact(blindedOutputScriptsHash) }; InputProofModel[] inputsProofs = new InputProofModel[] { inputProof }; registerRequests.Add((changeOutputAddress, blinded, inputsProofs)); aliceClientBackup = await AliceClient.CreateNewAsync(round.RoundId, new[] { activeOutputAddress }, new[] { round.MixingLevels.GetBaseLevel().SchnorrKey.SchnorrPubKey }, new[] { requester }, network, changeOutputAddress, new[] { blinded }, inputsProofs, baseUri, null); } await WaitForTimeoutAsync(baseUri); int bannedCount = coordinator.UtxoReferee.CountBanned(false); Assert.Equal(0, bannedCount); int notedCount = coordinator.UtxoReferee.CountBanned(true); Assert.Equal(anonymitySet, notedCount); round = coordinator.GetCurrentInputRegisterableRoundOrDefault(); foreach (var registerRequest in registerRequests) { await AliceClient.CreateNewAsync(round.RoundId, aliceClientBackup.RegisteredAddresses, round.MixingLevels.GetAllLevels().Select(x => x.SchnorrKey.SchnorrPubKey), aliceClientBackup.Requesters, network, registerRequest.changeOutputAddress, new[] { registerRequest.blindedData }, registerRequest.inputsProofs, baseUri, null); } await WaitForTimeoutAsync(baseUri); bannedCount = coordinator.UtxoReferee.CountBanned(false); Assert.Equal(anonymitySet, bannedCount); notedCount = coordinator.UtxoReferee.CountBanned(true); Assert.Equal(anonymitySet, notedCount); }
/// <summary> /// Get the corresponding block hash by using transaction hash. /// </summary> /// <param name="trxid">transaction hash</param> public Task <uint256> GetTrxBlockIdAsync(uint256 trxid) { Guard.NotNull(trxid, nameof(trxid)); this.logger.LogTrace("({0}:'{1}')", nameof(trxid), trxid); if (!this.TxIndex) { this.logger.LogTrace("(-)[NO_TXINDEX]:null"); return(Task.FromResult(default(uint256))); } Task <uint256> task = Task.Run(() => { this.logger.LogTrace("()"); uint256 res = null; using (DBreeze.Transactions.Transaction transaction = this.DBreeze.GetTransaction()) { transaction.ValuesLazyLoadingIsOn = false; Row <byte[], uint256> transactionRow = transaction.Select <byte[], uint256>("Transaction", trxid.ToBytes()); if (transactionRow.Exists) { res = transactionRow.Value; this.PerformanceCounter.AddRepositoryHitCount(1); } else { this.PerformanceCounter.AddRepositoryMissCount(1); } } this.logger.LogTrace("(-):'{0}'", res); return(res); }); this.logger.LogTrace("(-)"); return(task); }
/// <inheritdoc /> public Transaction BuildWithdrawalTransaction(uint256 depositId, uint blockTime, Recipient recipient) { try { this.logger.LogInformation("BuildDeterministicTransaction depositId(opReturnData)={0} recipient.ScriptPubKey={1} recipient.Amount={2}", depositId, recipient.ScriptPubKey, recipient.Amount); // Build the multisig transaction template. uint256 opReturnData = depositId; string walletPassword = this.federationWalletManager.Secret.WalletPassword; bool sign = (walletPassword ?? "") != ""; var multiSigContext = new TransactionBuildContext(new[] { recipient }.ToList(), opReturnData: opReturnData.ToBytes()) { OrderCoinsDeterministic = true, TransactionFee = this.federationGatewaySettings.TransactionFee, MinConfirmations = this.federationGatewaySettings.MinCoinMaturity, Shuffle = false, IgnoreVerify = true, WalletPassword = walletPassword, Sign = sign, Time = this.network.Consensus.IsProofOfStake ? blockTime : (uint?)null }; // Build the transaction. Transaction transaction = this.federationWalletTransactionBuilder.BuildTransaction(multiSigContext); this.logger.LogInformation("transaction = {0}", transaction.ToString(this.network, RawFormat.BlockExplorer)); return(transaction); } catch (Exception error) { this.logger.LogError("Could not create transaction for deposit {0}: {1}", depositId, error.Message); } this.logger.LogTrace("(-)[FAIL]"); return(null); }
/// <summary> /// Retreive the transaction information asynchronously using transaction hash /// </summary> /// <param name="trxid">The transaction id to find</param> public Task <Transaction> GetTrxAsync(uint256 trxid) { this.logger.LogTrace("({0}:'{1}')", nameof(trxid), trxid); Guard.NotNull(trxid, nameof(trxid)); if (!this.TxIndex) { return(Task.FromResult(default(Transaction))); } Task <Transaction> task = Task.Run(() => { this.logger.LogTrace("()"); Transaction res = null; using (DBreeze.Transactions.Transaction transaction = this.DBreeze.GetTransaction()) { transaction.ValuesLazyLoadingIsOn = false; Row <byte[], uint256> transactionRow = transaction.Select <byte[], uint256>("Transaction", trxid.ToBytes()); if (!transactionRow.Exists) { this.PerformanceCounter.AddRepositoryMissCount(1); this.logger.LogTrace("(-)[NO_BLOCK]:null"); return(null); } this.PerformanceCounter.AddRepositoryHitCount(1); Row <byte[], Block> blockRow = transaction.Select <byte[], Block>("Block", transactionRow.Value.ToBytes()); if (blockRow.Exists) { res = blockRow.Value.Transactions.FirstOrDefault(t => t.GetHash() == trxid); } if (res != null) { this.PerformanceCounter.AddRepositoryHitCount(1); } else { this.PerformanceCounter.AddRepositoryMissCount(1); } } this.logger.LogTrace("(-):{0}", res); return(res); }); this.logger.LogTrace("(-)"); return(task); }
public LotteryTicket(uint256 key) : this(key.ToBytes(false)) { }
public void CanCreateChannelManager() { using var channelManager = PeerManagerTests.getTestPeerManager().ChannelManager; var nodeFeature = FeatureBit.CreateUnsafe(0b000000100100000100000000); var channelFeature = FeatureBit.CreateUnsafe(0b000000100100000100000000); var hop1 = new RouteHopWithFeature(_nodeIds[0], nodeFeature, 1, channelFeature, 1000, 72); var hop2 = new RouteHopWithFeature(_nodeIds[1], nodeFeature, 2, channelFeature, 1000, 72); var route1 = new[] { hop1, hop2 }; var routes = new RoutesWithFeature(route1); var paymentHash = new uint256(); var e = Assert.Throws <PaymentSendException>(() => channelManager.SendPayment(routes, paymentHash.ToBytes())); Assert.Equal(PaymentSendFailureType.AllFailedRetrySafe, e.Kind); channelManager.Dispose(); }
public static ECKey RecoverFromSignature(int recId, ECDSASignature sig, uint256 message, bool compressed) { if (recId < 0) { throw new ArgumentException("recId should be positive"); } if (sig.R.SignValue < 0) { throw new ArgumentException("r should be positive"); } if (sig.S.SignValue < 0) { throw new ArgumentException("s should be positive"); } if (message == null) { throw new ArgumentNullException(nameof(message)); } var curve = ECKey.Secp256k1; // 1.0 For j from 0 to h (h == recId here and the loop is outside this function) // 1.1 Let x = r + jn var n = curve.N; var i = NBitcoin.BouncyCastle.Math.BigInteger.ValueOf((long)recId / 2); var x = sig.R.Add(i.Multiply(n)); // 1.2. Convert the integer x to an octet string X of length mlen using the conversion routine // specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or mlen = ⌈m/8⌉. // 1.3. Convert the octet string (16 set binary digits)||X to an elliptic curve point R using the // conversion routine specified in Section 2.3.4. If this conversion routine outputs “invalid”, then // do another iteration of Step 1. // // More concisely, what these points mean is to use X as a compressed public key. var prime = ((SecP256K1Curve)curve.Curve).QQ; if (x.CompareTo(prime) >= 0) { return(null); } // Compressed keys require you to know an extra bit of data about the y-coord as there are two possibilities. // So it's encoded in the recId. ECPoint R = DecompressKey(x, (recId & 1) == 1); // 1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility). if (!R.Multiply(n).IsInfinity) { return(null); } // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification. var e = new NBitcoin.BouncyCastle.Math.BigInteger(1, message.ToBytes()); // 1.6. For k from 1 to 2 do the following. (loop is outside this function via iterating recId) // 1.6.1. Compute a candidate public key as: // Q = mi(r) * (sR - eG) // // Where mi(x) is the modular multiplicative inverse. We transform this into the following: // Q = (mi(r) * s ** R) + (mi(r) * -e ** G) // Where -e is the modular additive inverse of e, that is z such that z + e = 0 (mod n). In the above equation // ** is point multiplication and + is point addition (the EC group operator). // // We can find the additive inverse by subtracting e from zero then taking the mod. For example the additive // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod 11 = 8. var eInv = NBitcoin.BouncyCastle.Math.BigInteger.Zero.Subtract(e).Mod(n); var rInv = sig.R.ModInverse(n); var srInv = rInv.Multiply(sig.S).Mod(n); var eInvrInv = rInv.Multiply(eInv).Mod(n); ECPoint q = ECAlgorithms.SumOfTwoMultiplies(curve.G, eInvrInv, R, srInv); q = q.Normalize(); if (compressed) { q = new SecP256K1Point(curve.Curve, q.XCoord, q.YCoord, true); } return(new ECKey(q.GetEncoded(), false)); }
public ECDSASignature Sign(uint256 hash) { AssertPrivateKey(); ECDsaSigner signer = new ECDsaSigner(); signer.Init(true, PrivateKey); BigInteger[] components = signer.GenerateSignature(hash.ToBytes()); ECDSASignature signature = new ECDSASignature(components[0], components[1]); signature = signature.MakeCanonical(); return signature; }
public uint256 BlindMessage(uint256 message, PubKey rpubkey, PubKey signerPubKey) { var ctx = new ECMultGenContext(); Span <byte> tmp = stackalloc byte[32]; if (!Context.Instance.TryCreatePubKey(signerPubKey.ToBytes(), out var signerECPubkey)) { throw new FormatException("Invalid signer pubkey."); } if (!Context.Instance.TryCreatePubKey(rpubkey.ToBytes(), out var rECPubKey)) { throw new FormatException("Invalid r pubkey."); } var p = signerECPubkey.Q; var r = rECPubKey.Q.ToGroupElementJacobian(); var t = FE.Zero; retry: RandomUtils.GetBytes(tmp); _v = new Scalar(tmp, out int overflow); if (overflow != 0 || _v.IsZero) { goto retry; } RandomUtils.GetBytes(tmp); _w = new Scalar(tmp, out overflow); if (overflow != 0 || _v.IsZero) { goto retry; } var a1 = ctx.MultGen(_v); var a2 = _w * p; var a = r.AddVariable(a1, out _).AddVariable(a2, out _).ToGroupElement(); t = a.x.Normalize(); if (t.IsZero) { goto retry; } using (var sha = new SHA256()) { message.ToBytes(tmp, false); sha.Write(tmp); t.WriteToSpan(tmp); sha.Write(tmp); sha.GetHash(tmp); } _c = new Scalar(tmp, out overflow); if (overflow != 0 || _c.IsZero) { goto retry; } var cp = _c + _w.Negate(); // this is sent to the signer (blinded message) if (cp.IsZero) { goto retry; } cp.WriteToSpan(tmp); return(new uint256(tmp)); }
internal bool Verify(uint256 hash, ECDSASignature sig) { var signer = new ECDsaSigner(); signer.Init(false, GetPublicKeyParameters()); return signer.VerifySignature(hash.ToBytes(), sig.R, sig.S); }
/// <inheritdoc /> public Transaction GetTransactionById(uint256 trxid) { Guard.NotNull(trxid, nameof(trxid)); if (!this.TxIndex) { this.logger.LogTrace("(-)[TX_INDEXING_DISABLED]:null"); return(default(Transaction)); } if (this.genesisTransactions.TryGetValue(trxid, out Transaction genesisTransaction)) { return(genesisTransaction); } Transaction res = null; lock (this.Locker) { byte[] transactionRow = this.rocksdb.Get(DBH.Key(TransactionTableName, trxid.ToBytes())); if (transactionRow == null) { this.logger.LogTrace("(-)[NO_BLOCK]:null"); return(null); } byte[] blockRow = this.rocksdb.Get(DBH.Key(BlockTableName, transactionRow)); if (blockRow != null) { var block = this.dataStoreSerializer.Deserialize <Block>(blockRow); res = block.Transactions.FirstOrDefault(t => t.GetHash() == trxid); } } return(res); }
internal int GetNewBucket(uint256 nKey, IPAddress src) { byte[] vchSourceGroupKey = src.GetGroup(); UInt64 hash1 = Cheap(Hashes.Hash256( nKey.ToBytes(true) .Concat(Address.Endpoint.Address.GetGroup()) .Concat(vchSourceGroupKey) .ToArray())); UInt64 hash2 = Cheap(Hashes.Hash256( nKey.ToBytes(true) .Concat(vchSourceGroupKey) .Concat(Utils.ToBytes(hash1 % AddressManager.ADDRMAN_NEW_BUCKETS_PER_SOURCE_GROUP, true)) .ToArray())); return (int)(hash2 % ADDRMAN_NEW_BUCKET_COUNT); }
public async Task BanningTestsAsync() { (string password, RPCClient rpc, Network network, Coordinator coordinator, ServiceConfiguration serviceConfiguration, BitcoinStore bitcoinStore, Backend.Global global) = await Common.InitializeTestEnvironmentAsync(RegTestFixture, 1); Money denomination = Money.Coins(0.1m); decimal coordinatorFeePercent = 0.1m; int anonymitySet = 3; int connectionConfirmationTimeout = 120; var roundConfig = RegTestFixture.CreateRoundConfig(denomination, 140, 0.7, coordinatorFeePercent, anonymitySet, 240, connectionConfirmationTimeout, 1, 1, 1, 24, true, 11); coordinator.RoundConfig.UpdateOrDefault(roundConfig, toFile: true); coordinator.AbortAllRoundsInInputRegistration(""); await rpc.GenerateAsync(3); // So to make sure we have enough money. Uri baseUri = new Uri(RegTestFixture.BackendEndPoint); var fundingTxCount = 0; var inputRegistrationUsers = new List <(Requester requester, uint256 blinded, BitcoinAddress activeOutputAddress, BitcoinAddress changeOutputAddress, IEnumerable <InputProofModel> inputProofModels, List <(Key key, BitcoinWitPubKeyAddress address, uint256 txHash, Transaction tx, OutPoint input)> userInputData)>(); CoordinatorRound round = null; for (int i = 0; i < roundConfig.AnonymitySet; i++) { var userInputData = new List <(Key key, BitcoinWitPubKeyAddress inputAddress, uint256 txHash, Transaction tx, OutPoint input)>(); var activeOutputAddress = new Key().PubKey.GetAddress(ScriptPubKeyType.Segwit, network); var changeOutputAddress = new Key().PubKey.GetAddress(ScriptPubKeyType.Segwit, network); round = coordinator.GetCurrentInputRegisterableRoundOrDefault(); Requester requester = new Requester(); uint256 blinded = requester.BlindScript(round.MixingLevels.GetBaseLevel().Signer.Key.PubKey, round.MixingLevels.GetBaseLevel().Signer.R.PubKey, activeOutputAddress.ScriptPubKey); uint256 blindedOutputScriptsHash = new uint256(Hashes.SHA256(blinded.ToBytes())); var inputProofModels = new List <InputProofModel>(); int numberOfInputs = new Random().Next(1, 7); var receiveSatoshiSum = 0; for (int j = 0; j < numberOfInputs; j++) { var key = new Key(); var receiveSatoshi = new Random().Next(1000, 100000000); receiveSatoshiSum += receiveSatoshi; if (j == numberOfInputs - 1) { receiveSatoshi = 100000000; } BitcoinWitPubKeyAddress inputAddress = key.PubKey.GetSegwitAddress(network); uint256 txHash = await rpc.SendToAddressAsync(inputAddress, Money.Satoshis(receiveSatoshi)); fundingTxCount++; Assert.NotNull(txHash); Transaction transaction = await rpc.GetRawTransactionAsync(txHash); var coin = transaction.Outputs.GetCoins(inputAddress.ScriptPubKey).Single(); OutPoint input = coin.Outpoint; var inputProof = new InputProofModel { Input = input.ToTxoRef(), Proof = key.SignCompact(blindedOutputScriptsHash) }; inputProofModels.Add(inputProof); GetTxOutResponse getTxOutResponse = await rpc.GetTxOutAsync(input.Hash, (int)input.N, includeMempool : true); // Check if inputs are unspent. Assert.NotNull(getTxOutResponse); userInputData.Add((key, inputAddress, txHash, transaction, input)); } inputRegistrationUsers.Add((requester, blinded, activeOutputAddress, changeOutputAddress, inputProofModels, userInputData)); } var mempool = await rpc.GetRawMempoolAsync(); Assert.Equal(inputRegistrationUsers.SelectMany(x => x.userInputData).Count(), mempool.Length); while ((await rpc.GetRawMempoolAsync()).Length != 0) { await rpc.GenerateAsync(1); } var aliceClients = new List <Task <AliceClient> >(); foreach (var user in inputRegistrationUsers) { aliceClients.Add(AliceClient.CreateNewAsync(round.RoundId, new[] { user.activeOutputAddress }, new[] { round.MixingLevels.GetBaseLevel().SchnorrKey.SchnorrPubKey }, new[] { user.requester }, network, user.changeOutputAddress, new[] { user.blinded }, user.inputProofModels, baseUri, null)); } long roundId = 0; var users = new List <(Requester requester, uint256 blinded, BitcoinAddress activeOutputAddress, BitcoinAddress changeOutputAddress, IEnumerable <InputProofModel> inputProofModels, List <(Key key, BitcoinWitPubKeyAddress address, uint256 txHash, Transaction tx, OutPoint input)> userInputData, AliceClient aliceClient, UnblindedSignature unblindedSignature)>(); for (int i = 0; i < inputRegistrationUsers.Count; i++) { var user = inputRegistrationUsers[i]; var request = aliceClients[i]; var aliceClient = await request; if (roundId == 0) { roundId = aliceClient.RoundId; } else { Assert.Equal(roundId, aliceClient.RoundId); } // Because it's valuetuple. users.Add((user.requester, user.blinded, user.activeOutputAddress, user.changeOutputAddress, user.inputProofModels, user.userInputData, aliceClient, null)); } Assert.Equal(users.Count, roundConfig.AnonymitySet); var confirmationRequests = new List <Task <(RoundPhase currentPhase, IEnumerable <ActiveOutput>)> >(); foreach (var user in users) { confirmationRequests.Add(user.aliceClient.PostConfirmationAsync()); } RoundPhase roundPhase = RoundPhase.InputRegistration; int k = 0; foreach (var request in confirmationRequests) { var resp = await request; if (roundPhase == RoundPhase.InputRegistration) { roundPhase = resp.currentPhase; } else { Assert.Equal(roundPhase, resp.currentPhase); } var user = users.ElementAt(k); user.unblindedSignature = resp.Item2.First().Signature; } using (var satoshiClient = new SatoshiClient(baseUri, null)) { var times = 0; while (!(await satoshiClient.GetAllRoundStatesAsync()).All(x => x.Phase == RoundPhase.InputRegistration)) { await Task.Delay(100); if (times > 50) // 5 sec, 3 should be enough { throw new TimeoutException("Not all rounds were in InputRegistration."); } times++; } } int bannedCount = coordinator.UtxoReferee.CountBanned(false); Assert.Equal(0, bannedCount); aliceClients.Clear(); round = coordinator.GetCurrentInputRegisterableRoundOrDefault(); foreach (var user in inputRegistrationUsers) { aliceClients.Add(AliceClient.CreateNewAsync(round.RoundId, new[] { user.activeOutputAddress }, new[] { round.MixingLevels.GetBaseLevel().SchnorrKey.SchnorrPubKey }, new[] { user.requester }, network, user.changeOutputAddress, new[] { user.blinded }, user.inputProofModels, baseUri, null)); } roundId = 0; users = new List <(Requester requester, uint256 blinded, BitcoinAddress activeOutputAddress, BitcoinAddress changeOutputAddress, IEnumerable <InputProofModel> inputProofModels, List <(Key key, BitcoinWitPubKeyAddress address, uint256 txHash, Transaction tx, OutPoint input)> userInputData, AliceClient aliceClient, UnblindedSignature unblindedSignature)>(); for (int i = 0; i < inputRegistrationUsers.Count; i++) { var user = inputRegistrationUsers[i]; var request = aliceClients[i]; var aliceClient = await request; if (roundId == 0) { roundId = aliceClient.RoundId; } else { Assert.Equal(roundId, aliceClient.RoundId); } // Because it's valuetuple. users.Add((user.requester, user.blinded, user.activeOutputAddress, user.changeOutputAddress, user.inputProofModels, user.userInputData, aliceClient, null)); } Assert.Equal(users.Count, roundConfig.AnonymitySet); confirmationRequests = new List <Task <(RoundPhase currentPhase, IEnumerable <ActiveOutput>)> >(); foreach (var user in users) { confirmationRequests.Add(user.aliceClient.PostConfirmationAsync()); } using (var satoshiClient = new SatoshiClient(baseUri, null)) { var times = 0; while (!(await satoshiClient.GetAllRoundStatesAsync()).All(x => x.Phase == RoundPhase.InputRegistration)) { await Task.Delay(100); if (times > 50) // 5 sec, 3 should be enough { throw new TimeoutException("Not all rounds were in InputRegistration."); } times++; } } bannedCount = coordinator.UtxoReferee.CountBanned(false); Assert.True(bannedCount >= roundConfig.AnonymitySet); foreach (var aliceClient in aliceClients) { aliceClient?.Dispose(); } }
/// <inheritdoc /> public Transaction GetTransactionById(uint256 trxid) { Guard.NotNull(trxid, nameof(trxid)); if (!this.TxIndex) { this.logger.LogTrace("(-)[TX_INDEXING_DISABLED]:null"); return(default(Transaction)); } Transaction res = null; using (DBreeze.Transactions.Transaction transaction = this.DBreeze.GetTransaction()) { transaction.ValuesLazyLoadingIsOn = false; Row <byte[], byte[]> transactionRow = transaction.Select <byte[], byte[]>(TransactionTableName, trxid.ToBytes()); if (!transactionRow.Exists) { this.logger.LogTrace("(-)[NO_BLOCK]:null"); return(null); } Row <byte[], byte[]> blockRow = transaction.Select <byte[], byte[]>(BlockTableName, transactionRow.Value); if (blockRow.Exists) { var block = this.dBreezeSerializer.Deserialize <Block>(blockRow.Value); res = block.Transactions.FirstOrDefault(t => t.GetHash() == trxid); } } return(res); }
public static ECKey RecoverFromSignature(int recId, ECDSASignature sig, uint256 message, bool compressed) { if(recId < 0) throw new ArgumentException("recId should be positive"); if(sig.R.SignValue < 0) throw new ArgumentException("r should be positive"); if(sig.S.SignValue < 0) throw new ArgumentException("s should be positive"); if(message == null) throw new ArgumentNullException("message"); var curve = ECKey.CreateCurve(); // 1.0 For j from 0 to h (h == recId here and the loop is outside this function) // 1.1 Let x = r + jn var n = curve.N; var i = Org.BouncyCastle.Math.BigInteger.ValueOf((long)recId / 2); var x = sig.R.Add(i.Multiply(n)); // 1.2. Convert the integer x to an octet string X of length mlen using the conversion routine // specified in Section 2.3.7, where mlen = ⌈(log2 p)/8⌉ or mlen = ⌈m/8⌉. // 1.3. Convert the octet string (16 set binary digits)||X to an elliptic curve point R using the // conversion routine specified in Section 2.3.4. If this conversion routine outputs “invalid”, then // do another iteration of Step 1. // // More concisely, what these points mean is to use X as a compressed public key. var prime = ((FpCurve)curve.Curve).Q; if(x.CompareTo(prime) >= 0) { return null; } // Compressed keys require you to know an extra bit of data about the y-coord as there are two possibilities. // So it's encoded in the recId. ECPoint R = DecompressKey(x, (recId & 1) == 1); // 1.4. If nR != point at infinity, then do another iteration of Step 1 (callers responsibility). if(!R.Multiply(n).IsInfinity) return null; // 1.5. Compute e from M using Steps 2 and 3 of ECDSA signature verification. var e = new Org.BouncyCastle.Math.BigInteger(1, message.ToBytes()); // 1.6. For k from 1 to 2 do the following. (loop is outside this function via iterating recId) // 1.6.1. Compute a candidate public key as: // Q = mi(r) * (sR - eG) // // Where mi(x) is the modular multiplicative inverse. We transform this into the following: // Q = (mi(r) * s ** R) + (mi(r) * -e ** G) // Where -e is the modular additive inverse of e, that is z such that z + e = 0 (mod n). In the above equation // ** is point multiplication and + is point addition (the EC group operator). // // We can find the additive inverse by subtracting e from zero then taking the mod. For example the additive // inverse of 3 modulo 11 is 8 because 3 + 8 mod 11 = 0, and -3 mod 11 = 8. var eInv = Org.BouncyCastle.Math.BigInteger.Zero.Subtract(e).Mod(n); var rInv = sig.R.ModInverse(n); var srInv = rInv.Multiply(sig.S).Mod(n); var eInvrInv = rInv.Multiply(eInv).Mod(n); var q = (FpPoint)ECAlgorithms.SumOfTwoMultiplies(curve.G, eInvrInv, R, srInv); if(compressed) { q = new FpPoint(curve.Curve, q.X, q.Y, true); } return new ECKey(q.GetEncoded(), false); }
/// <inheritdoc /> /// <exception cref="ConsensusErrors.BadWitnessNonceSize">The witness nonce size is invalid.</exception> /// <exception cref="ConsensusErrors.BadWitnessMerkleMatch">The witness merkle commitment does not match the computed commitment.</exception> /// <exception cref="ConsensusErrors.UnexpectedWitness">The block does not expect witness transactions but contains a witness transaction.</exception> public override Task RunAsync(RuleContext context) { if (context.SkipValidation) { return(Task.CompletedTask); } DeploymentFlags deploymentFlags = context.Flags; Block block = context.ValidationContext.BlockToValidate; // Validation for witness commitments. // * We compute the witness hash (which is the hash including witnesses) of all the block's transactions, except the // coinbase (where 0x0000....0000 is used instead). // * The coinbase scriptWitness is a stack of a single 32-byte vector, containing a witness nonce (unconstrained). // * We build a merkle tree with all those witness hashes as leaves (similar to the hashMerkleRoot in the block header). // * There must be at least one output whose scriptPubKey is a single 36-byte push, the first 4 bytes of which are // {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness nonce). In case there are // multiple, the last one is used. bool fHaveWitness = false; if (deploymentFlags.ScriptFlags.HasFlag(ScriptVerify.Witness)) { Script commitment = GetWitnessCommitment(this.Parent.Network, block); if (commitment != null) { uint256 hashWitness = this.BlockWitnessMerkleRoot(block, out bool malleated); // The malleation check is ignored; as the transaction tree itself // already does not permit it, it is impossible to trigger in the // witness tree. WitScript witness = block.Transactions[0].Inputs[0].WitScript; if ((witness.PushCount != 1) || (witness.Pushes.First().Length != 32)) { // Witness information is missing, activating witness requirement for peers is required. context.ValidationContext.MissingServices = NetworkPeerServices.NODE_WITNESS; this.Logger.LogTrace("(-)[BAD_WITNESS_NONCE_SIZE]"); ConsensusErrors.BadWitnessNonceSize.Throw(); } var hashed = new byte[64]; Buffer.BlockCopy(hashWitness.ToBytes(), 0, hashed, 0, 32); Buffer.BlockCopy(witness.Pushes.First(), 0, hashed, 32, 32); hashWitness = Hashes.Hash256(hashed); if (!this.EqualsArray(hashWitness.ToBytes(), commitment.ToBytes(true).Skip(6).ToArray(), 32)) { this.Logger.LogTrace("(-)[WITNESS_MERKLE_MISMATCH]"); ConsensusErrors.BadWitnessMerkleMatch.Throw(); } fHaveWitness = true; } } if (!fHaveWitness) { for (int i = 0; i < block.Transactions.Count; i++) { if (block.Transactions[i].HasWitness) { this.Logger.LogTrace("(-)[UNEXPECTED_WITNESS]"); ConsensusErrors.UnexpectedWitness.Throw(); } } } return(Task.CompletedTask); }
string GetDLCFilePath(uint256 contractId) { var fileName = Encoders.Base58.EncodeData(contractId.ToBytes(false)); return(Path.Combine(RepositoryDirectory, "DLCs", $"{fileName}.json")); }
/// <summary> /// Context-dependent validity checks. /// </summary> /// <param name="context">Context that contains variety of information regarding blocks validation and execution.</param> /// <exception cref="ConsensusErrors.BadTransactionNonFinal">Thrown if one or more transactions are not finalized.</exception> /// <exception cref="ConsensusErrors.BadCoinbaseHeight">Thrown if coinbase doesn't start with serialized block height.</exception> public virtual void ContextualCheckBlock(RuleContext context) { this.logger.LogTrace("()"); Block block = context.BlockValidationContext.Block; DeploymentFlags deploymentFlags = context.Flags; int height = context.BestBlock == null ? 0 : context.BestBlock.Height + 1; // Start enforcing BIP113 (Median Time Past) using versionbits logic. DateTimeOffset lockTimeCutoff = deploymentFlags.LockTimeFlags.HasFlag(Transaction.LockTimeFlags.MedianTimePast) ? context.BestBlock.MedianTimePast : block.Header.BlockTime; // Check that all transactions are finalized. foreach (Transaction transaction in block.Transactions) { if (!transaction.IsFinal(lockTimeCutoff, height)) { this.logger.LogTrace("(-)[TX_NON_FINAL]"); ConsensusErrors.BadTransactionNonFinal.Throw(); } } // Enforce rule that the coinbase starts with serialized block height. if (deploymentFlags.EnforceBIP34) { var expect = new Script(Op.GetPushOp(height)); Script actual = block.Transactions[0].Inputs[0].ScriptSig; if (!this.StartWith(actual.ToBytes(true), expect.ToBytes(true))) { this.logger.LogTrace("(-)[BAD_COINBASE_HEIGHT]"); ConsensusErrors.BadCoinbaseHeight.Throw(); } } // Validation for witness commitments. // * We compute the witness hash (which is the hash including witnesses) of all the block's transactions, except the // coinbase (where 0x0000....0000 is used instead). // * The coinbase scriptWitness is a stack of a single 32-byte vector, containing a witness nonce (unconstrained). // * We build a merkle tree with all those witness hashes as leaves (similar to the hashMerkleRoot in the block header). // * There must be at least one output whose scriptPubKey is a single 36-byte push, the first 4 bytes of which are // {0xaa, 0x21, 0xa9, 0xed}, and the following 32 bytes are SHA256^2(witness root, witness nonce). In case there are // multiple, the last one is used. bool haveWitness = false; if (deploymentFlags.ScriptFlags.HasFlag(ScriptVerify.Witness)) { int commitpos = this.GetWitnessCommitmentIndex(block); if (commitpos != -1) { uint256 hashWitness = this.BlockWitnessMerkleRoot(block, out bool unused); // The malleation check is ignored; as the transaction tree itself // already does not permit it, it is impossible to trigger in the // witness tree. WitScript witness = block.Transactions[0].Inputs[0].WitScript; if ((witness.PushCount != 1) || (witness.Pushes.First().Length != 32)) { this.logger.LogTrace("(-)[BAD_WITNESS_NONCE_SIZE]"); ConsensusErrors.BadWitnessNonceSize.Throw(); } var hashed = new byte[64]; Buffer.BlockCopy(hashWitness.ToBytes(), 0, hashed, 0, 32); Buffer.BlockCopy(witness.Pushes.First(), 0, hashed, 32, 32); hashWitness = Hashes.Hash256(hashed); if (!this.EqualsArray(hashWitness.ToBytes(), block.Transactions[0].Outputs[commitpos].ScriptPubKey.ToBytes(true).Skip(6).ToArray(), 32)) { this.logger.LogTrace("(-)[WITNESS_MERKLE_MISMATCH]"); ConsensusErrors.BadWitnessMerkleMatch.Throw(); } haveWitness = true; } } if (!haveWitness) { for (int i = 0; i < block.Transactions.Count; i++) { if (block.Transactions[i].HasWitness) { this.logger.LogTrace("(-)[UNEXPECTED_WITNESS]"); ConsensusErrors.UnexpectedWitness.Throw(); } } } // After the coinbase witness nonce and commitment are verified, // we can check if the block weight passes (before we've checked the // coinbase witness, it would be possible for the weight to be too // large by filling up the coinbase witness, which doesn't change // the block hash, so we couldn't mark the block as permanently // failed). if (this.GetBlockWeight(block) > this.ConsensusOptions.MaxBlockWeight) { this.logger.LogTrace("(-)[BAD_BLOCK_WEIGHT]"); ConsensusErrors.BadBlockWeight.Throw(); } this.logger.LogTrace("(-)[OK]"); }
private ulong Cheap(uint256 v) { return Utils.ToUInt64(v.ToBytes(), true); }
private ulong Cheap(uint256 v) { return(Utils.ToUInt64(v.ToBytes(), true)); }
internal int GetTriedBucket(uint256 nKey) { UInt64 hash1 = Cheap(Hashes.Hash256(nKey.ToBytes().Concat(Address.GetKey()).ToArray())); UInt64 hash2 = Cheap(Hashes.Hash256(nKey.ToBytes().Concat(Address.Endpoint.Address.GetGroup()).Concat(Utils.ToBytes(hash1 % AddressManager.ADDRMAN_TRIED_BUCKETS_PER_GROUP, true)).ToArray())); return (int)(hash2 % ADDRMAN_TRIED_BUCKET_COUNT); }
public ILocalExecutionResult Execute(ulong blockHeight, uint160 sender, Money txOutValue, ContractTxData callData) { bool creation = callData.IsCreateContract; var block = new Block( blockHeight, Address.Zero ); ChainedHeader chainedHeader = this.chainIndexer.GetHeader((int)blockHeight); var scHeader = chainedHeader?.Header as ISmartContractBlockHeader; uint256 hashStateRoot = scHeader?.HashStateRoot ?? new uint256("21B463E3B52F6201C0AD6C991BE0485B6EF8C092E64583FFA655CC1B171FE856"); // StateRootEmptyTrie IStateRepositoryRoot stateAtHeight = this.stateRoot.GetSnapshotTo(hashStateRoot.ToBytes()); IState state = this.stateFactory.Create( stateAtHeight.StartTracking(), block, txOutValue, new uint256()); StateTransitionResult result; IState newState = state.Snapshot(); if (creation) { var message = new ExternalCreateMessage( sender, txOutValue, callData.GasLimit, callData.ContractExecutionCode, callData.MethodParameters ); result = this.stateProcessor.Apply(newState, message); } else { var message = new ExternalCallMessage( callData.ContractAddress, sender, txOutValue, callData.GasLimit, new MethodCall(callData.MethodName, callData.MethodParameters) ); result = this.stateProcessor.Apply(newState, message); } var executionResult = new LocalExecutionResult { ErrorMessage = result.Error?.GetErrorMessage(), Revert = result.IsFailure, GasConsumed = result.GasConsumed, Return = result.Success?.ExecutionResult, InternalTransfers = state.InternalTransfers.ToList(), Logs = state.GetLogs(this.contractPrimitiveSerializer) }; return(executionResult); }