Example #1
0
        public SolverClientSession(SolverParameters parameters, State state) : this(parameters)
        {
            if (state == null)
            {
                return;
            }
            InternalState = state;
            if (InternalState.FakeIndexes != null)
            {
                _PuzzleElements = new PuzzleSetElement[_Parameters.GetTotalCount()];
                int fakeI = 0, realI = 0;
                for (int i = 0; i < _PuzzleElements.Length; i++)
                {
                    PuzzleSetElement element = null;
                    var puzzle = new Puzzle(_Parameters.ServerKey, state.Puzzles[i]);

                    if (InternalState.FakeIndexes.Contains(i))
                    {
                        element = new FakePuzzle(puzzle, state.FakeSolutions[fakeI++]);
                    }
                    else
                    {
                        element = new RealPuzzle(puzzle, state.BlindFactors[realI++]);
                    }
                    element.Index      = i;
                    element.Commitment = state.Commitments[i];
                    _PuzzleElements[i] = element;
                }
            }
        }
        public void CheckSolutions(SolutionKey[] keys)
        {
            if (keys == null)
            {
                throw new ArgumentNullException(nameof(keys));
            }
            if (keys.Length != Parameters.RealPuzzleCount)
            {
                throw new ArgumentException("Expecting " + Parameters.RealPuzzleCount + " keys");
            }
            AssertState(SolverClientStates.WaitingPuzzleSolutions);
            PuzzleSolution solution     = null;
            RealPuzzle     solvedPuzzle = null;
            int            y            = 0;

            foreach (var puzzle in _PuzzleElements.OfType <RealPuzzle>())
            {
                var key        = keys[y++].ToBytes(true);
                var commitment = puzzle.Commitment;

                var hash = new uint160(Hashes.RIPEMD160(key, key.Length));
                if (hash == commitment.KeyHash)
                {
                    var decryptedSolution = new PuzzleSolution(Utils.ChachaDecrypt(commitment.EncryptedSolution, key));
                    if (puzzle.Puzzle.Verify(decryptedSolution))
                    {
                        solution     = decryptedSolution;
                        solvedPuzzle = puzzle;
                        break;
                    }
                }
            }

            if (solution == null)
            {
                throw new PuzzleException("Impossible to find solution to the puzzle");
            }

            InternalState.PuzzleSolution = solution.Unblind(ServerKey, solvedPuzzle.BlindFactor);
            InternalState.Status         = SolverClientStates.Completed;
        }