internal IEnumerable <Transaction> GetSignedTransactions(PuzzleSolution solution) { if (solution == null) { throw new ArgumentNullException(nameof(solution)); } AssertState(PromiseClientStates.Completed); solution = solution.Unblind(Parameters.ServerKey, InternalState.BlindFactor); BigInteger cumul = solution._Value; var hashes = _Hashes.OfType <RealHash>().ToArray(); for (int i = 0; i < Parameters.RealTransactionCount; i++) { var hash = hashes[i]; var quotient = i == 0 ? BigInteger.One : InternalState.Quotients[i - 1]._Value; cumul = cumul.Multiply(quotient).Mod(Parameters.ServerKey._Key.Modulus); solution = new PuzzleSolution(cumul); ECDSASignature signature; PubKey signer; if (!IsValidSignature(solution, hash, out signer, out signature)) { continue; } var transaction = hash.GetTransaction(); TransactionBuilder txBuilder = new TransactionBuilder(); txBuilder.Extensions.Add(new EscrowBuilderExtension()); txBuilder.AddCoins(InternalState.EscrowedCoin); txBuilder.AddKeys(InternalState.EscrowKey); txBuilder.AddKnownSignature(signer, signature); txBuilder.SignTransactionInPlace(transaction); yield return(transaction); } }
internal IEnumerable <Transaction> GetSignedTransactions(PuzzleSolution solution) { if (solution == null) { throw new ArgumentNullException(nameof(solution)); } AssertState(PromiseClientStates.Completed); solution = solution.Unblind(Parameters.ServerKey, InternalState.BlindFactor); BigInteger cumul = solution._Value; var hashes = _Hashes.OfType <RealHash>().ToArray(); for (int i = 0; i < Parameters.RealTransactionCount; i++) { var hash = hashes[i]; var quotient = i == 0 ? BigInteger.One : InternalState.Quotients[i - 1]._Value; cumul = cumul.Multiply(quotient).Mod(Parameters.ServerKey._Key.Modulus); solution = new PuzzleSolution(cumul); if (!IsValidSignature(solution, hash, out ECDSASignature tumblerSig)) { continue; } var transaction = hash.GetTransaction(); var bobSig = transaction.SignInput(InternalState.EscrowKey, InternalState.EscrowedCoin); transaction.Inputs[0].WitScript = new WitScript( Op.GetPushOp(new TransactionSignature(tumblerSig, SigHash.All).ToBytes()), Op.GetPushOp(bobSig.ToBytes()), Op.GetPushOp(InternalState.EscrowedCoin.Redeem.ToBytes()) ); //transaction is already witnessified if (transaction.Inputs.AsIndexedInputs().First().VerifyScript(InternalState.EscrowedCoin)) { yield return(transaction); } } }
public State GetInternalState() { var state = Serializer.Clone(InternalState); if (_PuzzleElements != null) { var commitments = new ServerCommitment[_PuzzleElements.Length]; var puzzles = new PuzzleValue[_PuzzleElements.Length]; var fakeSolutions = new PuzzleSolution[Parameters.FakePuzzleCount]; var blinds = new BlindFactor[Parameters.RealPuzzleCount]; int fakeI = 0, realI = 0; for (int i = 0; i < _PuzzleElements.Length; i++) { commitments[i] = _PuzzleElements[i].Commitment; puzzles[i] = _PuzzleElements[i].Puzzle.PuzzleValue; var fake = _PuzzleElements[i] as FakePuzzle; if (fake != null) { fakeSolutions[fakeI++] = fake.Solution; } var real = _PuzzleElements[i] as RealPuzzle; if (real != null) { blinds[realI++] = real.BlindFactor; } } state.FakeSolutions = fakeSolutions; state.BlindFactors = blinds; state.Commitments = commitments; state.Puzzles = puzzles; } return(state); }
public PartialViewResult GetBoardSolution(string board, string wordLengths) { ModelState.Clear(); var solutionModel = new PuzzleSolutionModel(); string[] splitLengths = wordLengths.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); int dummy; if (splitLengths.Any(sl => !Int32.TryParse(sl, out dummy))) { solutionModel.ErrorMessage = "Word lengths must be comma separated numbers."; return(PartialView("_BoardSolutionView", solutionModel)); } int[] lengths = splitLengths.Select(w => Convert.ToInt32(w)).ToArray(); string message = PuzzlePlant.IsValidPuzzle(board, lengths); if (!string.IsNullOrWhiteSpace(message)) { solutionModel.ErrorMessage = message; return(PartialView("_BoardSolutionView", solutionModel)); } IBoardSolver boardSolver = Plant.Plant.BoardSolver; Puzzle puzzle = PuzzlePlant.BuildPuzzle(board, lengths); PuzzleSolution solution = boardSolver.SolvePuzzle(puzzle); solutionModel.Words = solution.Solutions.Select(words => words.Select(w => w.Letters).ToList()).ToList(); return(PartialView("_BoardSolutionView", solutionModel)); }
public SolvedPuzzle(PuzzleValue puzzle, SolutionKey key, PuzzleSolution solution) { Puzzle = puzzle; SolutionKey = key; Solution = solution; EncryptedSolution = GetEncryptedSolution(); }
public SolverServerSession ConfirmClientEscrow(Transaction transaction, out PuzzleSolution solvedVoucher) { AssertState(AliceServerChannelNegotiationStates.WaitingClientEscrow); solvedVoucher = null; var escrow = CreateEscrowScript(); var coin = transaction.Outputs.AsCoins().FirstOrDefault(txout => txout.ScriptPubKey == escrow.Hash.ScriptPubKey); if (coin == null) { throw new PuzzleException("No output containing the escrowed coin"); } if (coin.Amount != Parameters.Denomination + Parameters.Fee) { throw new PuzzleException("Incorrect amount"); } var voucher = InternalState.UnsignedVoucher; var escrowedCoin = coin.ToScriptCoin(escrow); var session = new SolverServerSession(TumblerKey, Parameters.CreateSolverParamaters()); session.ConfigureEscrowedCoin(escrowedCoin, InternalState.EscrowKey); InternalState.UnsignedVoucher = null; InternalState.OtherEscrowKey = null; InternalState.RedeemKey = null; InternalState.EscrowKey = null; solvedVoucher = voucher.WithRsaKey(VoucherKey.PubKey).Solve(VoucherKey); InternalState.Status = AliceServerChannelNegotiationStates.Completed; return(session); }
public ServerCommitment[] SignHashes(SignaturesRequest sigRequest) { if (sigRequest == null) { throw new ArgumentNullException(nameof(sigRequest)); } if (sigRequest.Hashes.Length != Parameters.GetTotalTransactionsCount()) { throw new ArgumentException("Incorrect number of hashes, expected " + sigRequest.Hashes.Length); } AssertState(PromiseServerStates.WaitingHashes); List <ServerCommitment> promises = new List <ServerCommitment>(); List <EncryptedSignature> encryptedSignatures = new List <EncryptedSignature>(); foreach (var hash in sigRequest.Hashes) { var ecdsa = InternalState.EscrowKey.Sign(hash); var ecdsaDER = ecdsa.ToDER(); var key = new XORKey(Parameters.ServerKey); var promise = key.XOR(ecdsaDER); PuzzleSolution solution = new PuzzleSolution(key.ToBytes()); var puzzle = Parameters.ServerKey.GeneratePuzzle(ref solution); promises.Add(new ServerCommitment(puzzle.PuzzleValue, promise)); encryptedSignatures.Add(new EncryptedSignature(ecdsa, hash, solution)); } InternalState.Status = PromiseServerStates.WaitingRevelation; InternalState.EncryptedSignatures = encryptedSignatures.ToArray(); InternalState.FakeIndexesHash = sigRequest.FakeIndexesHash; return(promises.ToArray()); }
public PuzzleValue[] GeneratePuzzles() { AssertState(SolverClientStates.WaitingGeneratePuzzles); List <PuzzleSetElement> puzzles = new List <PuzzleSetElement>(); for (int i = 0; i < Parameters.RealPuzzleCount; i++) { BlindFactor blind = null; Puzzle puzzle = new Puzzle(ServerKey, InternalState.Puzzle).Blind(ref blind); puzzles.Add(new RealPuzzle(puzzle, blind)); } for (int i = 0; i < Parameters.FakePuzzleCount; i++) { PuzzleSolution solution = null; Puzzle puzzle = ServerKey.GeneratePuzzle(ref solution); puzzles.Add(new FakePuzzle(puzzle, solution)); } _PuzzleElements = puzzles.ToArray(); NBitcoin.Utils.Shuffle(_PuzzleElements, RandomUtils.GetInt32()); InternalState.FakeIndexes = new int[Parameters.FakePuzzleCount]; int fakeI = 0; for (int i = 0; i < _PuzzleElements.Length; i++) { _PuzzleElements[i].Index = i; if (_PuzzleElements[i] is FakePuzzle) { InternalState.FakeIndexes[fakeI++] = i; } } InternalState.Status = SolverClientStates.WaitingCommitments; return(_PuzzleElements.Select(p => p.Puzzle.PuzzleValue).ToArray()); }
public BlindFactor[] GetBlindFactors(SolutionKey[] keys) { if (keys == null) { throw new ArgumentNullException(nameof(keys)); } if (keys.Length != Parameters.FakePuzzleCount) { throw new ArgumentException("Expecting " + Parameters.FakePuzzleCount + " keys"); } AssertState(SolverClientStates.WaitingFakeCommitmentsProof); int y = 0; foreach (var puzzle in _PuzzleElements.OfType <FakePuzzle>()) { var key = keys[y++].ToBytes(true); var hash = new uint160(Hashes.RIPEMD160(key, key.Length)); if (hash != puzzle.Commitment.KeyHash) { throw new PuzzleException("Commitment hash invalid"); } var solution = new PuzzleSolution(Utils.ChachaDecrypt(puzzle.Commitment.EncryptedSolution, key)); if (solution != puzzle.Solution) { throw new PuzzleException("Commitment encrypted solution invalid"); } } InternalState.Status = SolverClientStates.WaitingOffer; return(_PuzzleElements.OfType <RealPuzzle>() .Select(p => p.BlindFactor) .ToArray()); }
private PuzzleSolution OptimizeSolution(PuzzleSolution solution) { sm_log.Info("Optimizing solution"); new CostOptimizer(solution).Optimize(); return(solution); }
// The function that collects all the cubes in the scene and saves them for later as a // JSON file. public void SavePuzzle(string filePath) { // Create an array of all the cubes with the BuildCube tag. cubesToSave = GameObject.FindGameObjectsWithTag("BuildCube"); // Get the minimum and maximum values for each dimension of the puzzle. int[] minMaxValues = GetMinMaxValues(cubesToSave); PuzzleSolution newPuzzleSolution = new PuzzleSolution(minMaxValues, true); // Add each puzzleUnit attached to the cubes in cubesToSave to the PuzzleSolution. foreach (GameObject cube in cubesToSave) { newPuzzleSolution.AddUnit(cube.GetComponent <CubeScript>().GetPuzzleUnit()); } // goal make a PuzzleSolution from cubesToSave. // Create a string that is made from the PuzzleSolution object string jsonString = JsonUtility.ToJson(newPuzzleSolution, true); // Write the json string to the file. File.WriteAllText(filePath, jsonString); // Call the function that shows the puzzle save confirmation text on UIManager. uiManager.StartSavedTextTimer(); // Refreshes the assets in the Editor so you can immediately see the new file made. //AssetDatabase.Refresh(); // If the solution was saved successfully, we are no longer using the save UI // so the puzzle can be interacted with again. usingSaveUI = false; }
public ServerCommitment[][] SignHashes(SignaturesRequest sigRequest) { // Almost done, just need to confirm a typo and a function. // Step 5 if (sigRequest == null) { throw new ArgumentNullException(nameof(sigRequest)); } var hashesCount = sigRequest.Hashes.Select(a => a.Length).Sum(); if (hashesCount != Parameters.GetTotalTransactionsCount()) { throw new ArgumentException($"Incorrect number of hashes, expected {Parameters.GetTotalTransactionsCount()}"); } AssertState(PromiseServerStates.WaitingHashes); // 2D array of pairs of puzzles and promises (z_i, c_i). var promises = new ServerCommitment[Parameters.PaymentsCount][]; // 2D array of encrypted signatures with their solutions. var encryptedSignatures = new EncryptedSignature[Parameters.PaymentsCount][]; // 1-D array is used to store the epsilons for each column to be used when Hashing. var previousSolutions = new byte[Parameters.GetTotalTransactionsCountPerLevel()][]; previousSolutions = previousSolutions.Select(a => new byte[0]).ToArray(); // Initialize to empty array of bytes for (int i = 0; i < Parameters.PaymentsCount; i++) { promises[i] = new ServerCommitment[sigRequest.Hashes[i].Length]; // Initialization encryptedSignatures[i] = new EncryptedSignature[promises[i].Length]; // Initialization for (int j = 0; j < promises[i].Length; j++) { var hash = sigRequest.Hashes[i][j]; // Sign the hash value var ecdsa = InternalState.EscrowKey.Sign(hash); // Convert Signature to Bytes. var ecdsaDER = ecdsa.ToDER(); // This can be replaced by "Utils.GenerateEncryptableInteger(Key)" if padding when XORing is not important. var key = (new XORKey(Parameters.ServerKey)).ToBytes(); // This just generates a random epsilon. // Append the new epsilon to the list of epsilons we have for that column to create "epsilon_{i-1,j}|| . . . , epsilon_{0,j}". previousSolutions[j] = Utils.Combine(key, previousSolutions[j]); // Create the padded solution with the following format "i||j||epsilon_{i,j}||epsilon_{i-1,j}|| . . . , epsilon_{0,j}" var paddedSolutions = new PuzzleSolution(Utils.Combine(NBitcoin.Utils.ToBytes((uint)i, true), NBitcoin.Utils.ToBytes((uint)j, true), previousSolutions[j])); // Hash and XOR the padded solution with the signature we have. var promise = XORKey.XOR(paddedSolutions._Value.ToByteArrayUnsigned(), ecdsaDER); // This function needs to be approved "XOR". PuzzleSolution solution = new PuzzleSolution(key); // Epsilon // Encrypt the epsilon value using RSA var puzzle = Parameters.ServerKey.GeneratePuzzle(ref solution); promises[i][j] = new ServerCommitment(puzzle.PuzzleValue, promise); encryptedSignatures[i][j] = new EncryptedSignature(ecdsa, hash, solution); } } InternalState.Status = PromiseServerStates.WaitingRevelation; InternalState.EncryptedSignatures = encryptedSignatures; InternalState.FakeIndexesHash = sigRequest.FakeIndexesHash; return(promises); }
public Transaction GetSignedTransaction(PuzzleSolution solution) { var tx = GetSignedTransactions(solution).FirstOrDefault(); if (tx == null) { throw new PuzzleException("Wrong solution for the puzzle"); } return(tx); }
public void SolveBoard_16_Test() { Puzzle puzzle = GeneratePuzzle("aynedhecrtcaibkl", 8, 8); // cupboard roof oval IWordDictionary dictionary = GetDictionary(); IBoardCop boardCop = new BoardCop.BoardCop(); IBoardSolver solver = new BoardSolver.BoardSolver(boardCop, dictionary); PuzzleSolution solutions = solver.SolvePuzzle(puzzle); Assert.IsNotNull(solutions); }
public Transaction GetSignedTransaction(PuzzleSolution solution, int paymentNumber) { // Fix the Exception message to include the number of the puzzle. var tx = GetSignedTransactions(solution, paymentNumber).FirstOrDefault(); if (tx == null) { throw new PuzzleException($"Wrong solution for the puzzle {paymentNumber}"); } return(tx); }
public void SolveBoard_4_Test() { Puzzle puzzle = GeneratePuzzle("cart", 4); IWordDictionary dictionary = GetDictionary(); IBoardCop boardCop = new BoardCop.BoardCop(); IBoardSolver solver = new BoardSolver.BoardSolver(boardCop, dictionary); PuzzleSolution ps = solver.SolvePuzzle(puzzle); Assert.IsNotNull(ps); }
public void SolveBoard_9_Test_WrongFirstChoice() { Puzzle puzzle = GeneratePuzzle("efdidlrie", 4, 5); // ride field IWordDictionary dictionary = GetDictionary(); IBoardCop boardCop = new BoardCop.BoardCop(); IBoardSolver solver = new BoardSolver.BoardSolver(boardCop, dictionary); PuzzleSolution solutions = solver.SolvePuzzle(puzzle); Assert.IsNotNull(solutions); }
public void SolveBoard_9_Test() { Puzzle puzzle = GeneratePuzzle("flfooirde", 4, 5); // roof field IWordDictionary dictionary = GetDictionary(); IBoardCop boardCop = new BoardCop.BoardCop(); IBoardSolver solver = new BoardSolver.BoardSolver(boardCop, dictionary); PuzzleSolution solutions = solver.SolvePuzzle(puzzle); Assert.IsNotNull(solutions); }
public void CheckVoucherSolution(PuzzleSolution blindedVoucherSignature) { AssertState(TumblerClientSessionStates.WaitingSolvedVoucher); var solution = blindedVoucherSignature.Unblind(Parameters.VoucherKey.PublicKey, InternalState.BlindedVoucherFactor); if (!InternalState.UnsignedVoucher.Puzzle.WithRsaKey(Parameters.VoucherKey.PublicKey).Verify(solution)) { throw new PuzzleException("Incorrect puzzle solution"); } InternalState.BlindedVoucherFactor = null; InternalState.SignedVoucher = new XORKey(solution).XOR(InternalState.UnsignedVoucher.EncryptedSignature); InternalState.UnsignedVoucher.EncryptedSignature = new byte[0]; InternalState.ClientEscrowKey = null; InternalState.Status = TumblerClientSessionStates.WaitingGenerateTumblerTransactionKey; }
public UnsignedVoucherInformation GenerateUnsignedVoucher() { PuzzleSolution solution = null; var puzzle = Parameters.VoucherKey.GeneratePuzzle(ref solution); uint160 nonce; var cycle = GetCycle().Start; var signature = VoucherKey.Sign(NBitcoin.Utils.ToBytes((uint)cycle, true), out nonce); return(new UnsignedVoucherInformation { CycleStart = cycle, Nonce = nonce, Puzzle = puzzle.PuzzleValue, EncryptedSignature = new XORKey(solution).XOR(signature) }); }
public static void Main() { string?searchType = null; while (true) { Console.Write("Depth-first or Breadth-first search? (d/b): "); searchType = Console.ReadLine(); if ((searchType == "d") || (searchType == "b")) { break; } Console.WriteLine("Invalid Selection"); Console.WriteLine(); } try { var findStarted = DateTime.UtcNow; var initialState = new PuzzleState( AirTimeMinutesRemaining: 21, AstronautLocations: ImmutableDictionary.CreateRange(new[] { new KeyValuePair <Astronaut, StationSection>(Astronaut.Neil, StationSection.SectionA), new KeyValuePair <Astronaut, StationSection>(Astronaut.Michael, StationSection.SectionA), new KeyValuePair <Astronaut, StationSection>(Astronaut.Valentina, StationSection.SectionA), new KeyValuePair <Astronaut, StationSection>(Astronaut.Yuri, StationSection.SectionA), new KeyValuePair <Astronaut, StationSection>(Astronaut.Edwin, StationSection.SectionA) }), SuitsLocation: StationSection.SectionA); var(solution, solutionsChecked) = (searchType == "d") ? PuzzleSolution.FindDepth(initialState) : PuzzleSolution.FindBreadth(initialState); var findDuration = DateTime.UtcNow - findStarted; Console.WriteLine("Solution found"); Console.WriteLine("Steps:"); foreach (var mutation in solution.Mutations) { Console.WriteLine($"\t{string.Join(" and ", mutation.AstronautsMoved)} spend{((mutation.AstronautsMoved.Length == 1) ? "s" : "")} {mutation.TravelTimeMinutes} minute{((mutation.TravelTimeMinutes == 1) ? "" : "s")} moving to {mutation.TargetStationSection}"); } var finalState = solution.States[^ 1];
public void CanSolvePuzzle() { RsaKey key = TestKeys.Default; PuzzleSolution solution = null; var puzzle = key.PubKey.GeneratePuzzle(ref solution); PuzzleSolution solution2 = puzzle.Solve(key); Assert.True(puzzle.Verify(solution)); Assert.True(solution == solution2); puzzle = key.PubKey.GeneratePuzzle(ref solution); BlindFactor blind = null; Puzzle blindedPuzzle = puzzle.Blind(ref blind); PuzzleSolution blindedSolution = key.SolvePuzzle(blindedPuzzle); var unblinded = blindedSolution.Unblind(key.PubKey, blind); Assert.True(unblinded == solution); }
public void CanBlind() { RsaKey key = TestKeys.Default; PuzzleSolution solution = null; BlindFactor blind = null; Puzzle puzzle = key.PubKey.GeneratePuzzle(ref solution); Puzzle blindedPuzzle = puzzle.Blind(ref blind); Assert.True(puzzle != blindedPuzzle); Assert.True(puzzle == blindedPuzzle.Unblind(blind)); PuzzleSolution blindedSolution = blindedPuzzle.Solve(key); Assert.False(puzzle.Verify(blindedSolution)); Assert.True(puzzle.Verify(blindedSolution.Unblind(key.PubKey, blind))); }
internal IEnumerable <Transaction> GetSignedTransactions(PuzzleSolution solution, int paymentNumber) { /* * parameter "paymentNumber" indicates which j payment this is. * TODO: In order to solve the puzzle using the "solution", we need the previous solution * to get the signatures. * */ if (solution == null) { throw new ArgumentNullException(nameof(solution)); } AssertState(PromiseClientStates.Completed); solution = solution.Unblind(Parameters.ServerKey, InternalState.BlindFactors[paymentNumber]); BigInteger cumul = solution._Value; var hashes = _Hashes[paymentNumber].OfType <RealHash>().ToArray(); for (int i = 0; i < Parameters.RealTransactionCountPerLevel; i++) { var hash = hashes[i]; var quotient = i == 0 ? BigInteger.One : InternalState.Quotients[paymentNumber][i - 1]._Value; cumul = cumul.Multiply(quotient).Mod(Parameters.ServerKey._Key.Modulus); // Epsilon_i // Need to fix how the solution is recovered given how we need the previous solutions to get the current one. solution = new PuzzleSolution(cumul); if (!IsValidSignature(solution, hash, out ECDSASignature tumblerSig)) { continue; } var transaction = hash.GetTransaction(); var bobSig = transaction.SignInput(InternalState.EscrowKey, InternalState.EscrowedCoin); transaction.Inputs[0].ScriptSig = new Script( Op.GetPushOp(new TransactionSignature(tumblerSig, SigHash.All).ToBytes()), Op.GetPushOp(bobSig.ToBytes()), Op.GetPushOp(InternalState.EscrowedCoin.Redeem.ToBytes()) ); if (transaction.Inputs.AsIndexedInputs().First().VerifyScript(InternalState.EscrowedCoin)) { yield return(transaction); } } }
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; }
private bool IsValidSignature(PuzzleSolution solution, HashBase hash, out ECDSASignature signature) { signature = null; var escrow = EscrowScriptPubKeyParameters.GetFromCoin(InternalState.EscrowedCoin); try { var key = new XORKey(solution); signature = new ECDSASignature(key.XOR(hash.Commitment.Promise)); var ok = escrow.Initiator.Verify(hash.GetHash(), signature); if (!ok) { signature = null; } return(ok); } catch { } return(false); }
private void CheckAllowedGlyphs(PuzzleSolution solution) { var usedGlyphs = solution.GetObjects <Glyph>().Select(glyph => glyph.Type).Distinct(); var missingGlyphs = usedGlyphs.Except(Puzzle.AllowedGlyphs); // We only check the basic glyphs as the others are checked when generating the pipeline. if (missingGlyphs.Contains(GlyphType.Bonding)) { throw new SolverException("This puzzle doesn't allow the glyph of bonding."); } if (missingGlyphs.Contains(GlyphType.Unbonding)) { throw new SolverException("This puzzle doesn't allow the glyph of unbonding."); } if (missingGlyphs.Contains(GlyphType.TriplexBonding)) { throw new SolverException("One or more products contain triplex bonds but the puzzle doesn't allow the glyph of triplex bonding."); } }
public UnsignedVoucherInformation AskUnsignedVoucher( [ModelBinder(BinderType = typeof(TumblerParametersModelBinder))] ClassicTumblerParameters tumblerId) { if (tumblerId == null) { throw new ArgumentNullException(nameof(tumblerId)); } var height = Services.BlockExplorerService.GetCurrentHeight(); var cycleParameters = Parameters.CycleGenerator.GetRegisteringCycle(height); PuzzleSolution solution = null; var puzzle = Parameters.VoucherKey.PublicKey.GeneratePuzzle(ref solution); var cycle = cycleParameters.Start; var signature = Runtime.VoucherKey.Sign(NBitcoin.Utils.ToBytes((uint)cycle, true), out uint160 nonce); return(new UnsignedVoucherInformation { CycleStart = cycle, Nonce = nonce, Puzzle = puzzle.PuzzleValue, EncryptedSignature = new XORKey(solution).XOR(signature) }); }
private bool IsValidSignature(PuzzleSolution solution, HashBase hash, out PubKey signer, out ECDSASignature signature) { signer = null; signature = null; try { var key = new XORKey(solution); signature = new ECDSASignature(key.XOR(hash.Commitment.Promise)); foreach (var sig in GetExpectedSigners()) { if (sig.Verify(hash.GetHash(), signature)) { signer = sig; return(true); } } return(false); } catch { } return(false); }
public void GeneratePuzzle() { // Select moon phase for this round MoonPhase = Random.Range (0, 5); PuzzleSolutions = new Dictionary<int, PuzzleSolution> (); // Generate Puzzle // Repeat for each phase of the moon for (int i=0; i<5; i++) { List<GameObject> tmpRuneList = new List<GameObject>(Runes); List<GameObject> tmpRitualObjectsList = new List<GameObject>(RitualObjects); PuzzleSolution aSolution = new PuzzleSolution() { BlackPair = new Dictionary<GameObject, GameObject>(), GreenPair = new Dictionary<GameObject, GameObject>(), RedPair = new Dictionary<GameObject, GameObject>() }; //aSolution.BlackPair.Add(tmpRitualObjectsList[tmpRitualObjectIndex], tmpRuneList[tmpRuneIndex]); CreatePair(aSolution.BlackPair, tmpRitualObjectsList, tmpRuneList); CreatePair(aSolution.RedPair, tmpRitualObjectsList, tmpRuneList); CreatePair(aSolution.GreenPair, tmpRitualObjectsList, tmpRuneList); PuzzleSolutions.Add (i, aSolution); } // Generate the five hint pages, one for each phase of the moon // Decide which puzzle to use based on the moon phase ActualSolution = PuzzleSolutions [MoonPhase]; // Put a costume on the red, green and black the ritual objects // Hook up the coloured candles to their ritual objects //KeyCollection kc = GameObject RedRitualObject = null; var keys = ActualSolution.RedPair.Keys; foreach (GameObject go in keys) { RedRitualObject = go; break; } GameObject RedGlyph = null; ActualSolution.RedPair.TryGetValue (RedRitualObject, out RedGlyph); ParticleSystem[] redParticles = RedGlyph.GetComponentsInChildren<ParticleSystem> (); foreach (ParticleSystem p in redParticles) { p.Play(); } Imposter RedImposter = RedRitualObject.GetComponent<Imposter> (); RedCandle.RevealedObject = RedImposter; GameObject GreenRitualObject = null; keys = ActualSolution.GreenPair.Keys; foreach (GameObject go in keys) { GreenRitualObject = go; break; } GameObject GreenGlyph = null; ActualSolution.GreenPair.TryGetValue (GreenRitualObject, out GreenGlyph); ParticleSystem[] greenParticles = GreenGlyph.GetComponentsInChildren<ParticleSystem> (); foreach (ParticleSystem p in greenParticles) { p.startColor = Color.green; p.Play(); } Imposter GreenImposter = GreenRitualObject.GetComponent<Imposter> (); GreenCandle.RevealedObject = GreenImposter; GameObject BlackRitualObject = null; keys = ActualSolution.BlackPair.Keys; foreach (GameObject go in keys) { BlackRitualObject = go; break; } GameObject BlackGlyph = null; ActualSolution.BlackPair.TryGetValue (BlackRitualObject, out BlackGlyph); ParticleSystem[] blackParticles = BlackGlyph.GetComponentsInChildren<ParticleSystem> (); foreach (ParticleSystem p in blackParticles) { p.startColor = Color.black; p.Play(); } Imposter BlackImposter = BlackRitualObject.GetComponent<Imposter> (); BlackCandle.RevealedObject = BlackImposter; }
public void SaveSignedVoucher(int start, uint160 channelId, PuzzleSolution solution) { Repository.UpdateOrInsert(GetCyclePartition(start), "V-" + channelId, solution, (o, n) => o); }