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; }