예제 #1
0
        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;
        }
예제 #2
0
파일: ECKey.cs 프로젝트: crowar/NBitcoin
		public ECDSASignature Sign(uint256 hash)
		{
			AssertPrivateKey();
			var signer = new DeterministicECDSA();
			signer.setPrivateKey(PrivateKey);
			var sig = ECDSASignature.FromDER(signer.signHash(hash.ToBytes()));
			return sig.MakeCanonical();
		}
예제 #3
0
		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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        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);
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
			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);
			}
예제 #9
0
 public UTXODeterministicComparer(uint256 blind)
 {
     _blind = blind.ToBytes();
 }
예제 #10
0
		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)));
			//}
		}
예제 #11
0
        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);
        }
예제 #12
0
        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);
        }
예제 #16
0
 public LotteryTicket(uint256 key) : this(key.ToBytes(false))
 {
 }
예제 #17
0
        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();
        }
예제 #18
0
        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));
        }
예제 #19
0
 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;
 }
예제 #20
0
            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));
            }
예제 #21
0
파일: ECKey.cs 프로젝트: nikropht/NBitcoin
 internal bool Verify(uint256 hash, ECDSASignature sig)
 {
     var signer = new ECDsaSigner();
     signer.Init(false, GetPublicKeyParameters());
     return signer.VerifySignature(hash.ToBytes(), sig.R, sig.S);
 }
예제 #22
0
        /// <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);
        }
예제 #23
0
			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);
			}
예제 #24
0
        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();
            }
        }
예제 #25
0
        /// <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);
        }
예제 #26
0
파일: ECKey.cs 프로젝트: nikropht/NBitcoin
        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);
        }
예제 #28
0
        string GetDLCFilePath(uint256 contractId)
        {
            var fileName = Encoders.Base58.EncodeData(contractId.ToBytes(false));

            return(Path.Combine(RepositoryDirectory, "DLCs", $"{fileName}.json"));
        }
예제 #29
0
        /// <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]");
        }
예제 #30
0
			private ulong Cheap(uint256 v)
			{
				return Utils.ToUInt64(v.ToBytes(), true);
			}
예제 #31
0
 private ulong Cheap(uint256 v)
 {
     return(Utils.ToUInt64(v.ToBytes(), true));
 }
예제 #32
0
			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);
			}
예제 #33
0
        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);
        }