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 TestPuzzlePromise()
        {
            RsaKey key = TestKeys.Default;

            Key serverEscrow = new Key();
            Key clientEscrow = new Key();

            var parameters = new PromiseParameters(key.PubKey)
            {
                FakeTransactionCount = 5,
                RealTransactionCount = 5
            };

            var client = new PromiseClientSession(parameters);
            var server = new PromiseServerSession(parameters);

            var coin = CreateEscrowCoin(serverEscrow.PubKey, clientEscrow.PubKey);

            client.ConfigureEscrowedCoin(coin, clientEscrow);
            SignaturesRequest request = client.CreateSignatureRequest(clientEscrow.PubKey.Hash, FeeRate);

            RoundTrip(ref client, parameters);
            RoundTrip(ref request);

            server.ConfigureEscrowedCoin(coin, serverEscrow, new Key().ScriptPubKey);
            PuzzlePromise.ServerCommitment[] commitments = server.SignHashes(request);
            RoundTrip(ref server, parameters);
            RoundTrip(ref commitments);

            PuzzlePromise.ClientRevelation revelation = client.Reveal(commitments);
            RoundTrip(ref client, parameters);
            RoundTrip(ref revelation);

            ServerCommitmentsProof proof = server.CheckRevelation(revelation);

            RoundTrip(ref server, parameters);
            RoundTrip(ref proof);

            var puzzleToSolve = client.CheckCommitmentProof(proof);

            RoundTrip(ref client, parameters);
            Assert.NotNull(puzzleToSolve);

            var solution     = key.SolvePuzzle(puzzleToSolve);
            var transactions = client.GetSignedTransactions(solution).ToArray();

            RoundTrip(ref client, parameters);
            Assert.True(transactions.Length == parameters.RealTransactionCount);


            var escrow = server.GetInternalState().EscrowedCoin;
            // In case things do not go well and timeout is hit...
            var redeemTransaction = server.CreateRedeemTransaction(FeeRate);
            var resigned          = redeemTransaction.ReSign(escrow);
            TransactionBuilder bb = new TransactionBuilder();

            bb.AddCoins(server.GetInternalState().EscrowedCoin);
            Assert.True(bb.Verify(resigned));

            //Check can ve reclaimed if malleated
            bb = new TransactionBuilder();
            escrow.Outpoint = new OutPoint(escrow.Outpoint.Hash, 10);
            bb.AddCoins(escrow);
            resigned = redeemTransaction.ReSign(escrow);
            Assert.False(bb.Verify(redeemTransaction.Transaction));
            Assert.True(bb.Verify(resigned));
        }
Exemple #3
0
        public void TestPuzzlePromise()
        {
            RsaKey key = TestKeys.Default;

            Key serverEscrow = new Key();
            Key clientEscrow = new Key();

            var parameters = new PromiseParameters(key.PubKey)
            {
                FakeTransactionCountPerLevel = 5,
                RealTransactionCountPerLevel = 5,
                PaymentsCount = 5 //Not sure if this is the way to go.
            };

            var client = new PromiseClientSession(parameters);
            var server = new PromiseServerSession(parameters);

            var coin = CreateEscrowCoin(serverEscrow.PubKey, clientEscrow.PubKey);

            client.ConfigureEscrowedCoin(coin, clientEscrow);
            SignaturesRequest request = client.CreateSignatureRequest(clientEscrow.PubKey.Hash, FeeRate);

            RoundTrip(ref client, parameters);
            RoundTrip(ref request);

            server.ConfigureEscrowedCoin(uint160.Zero, coin, serverEscrow, new Key().ScriptPubKey);
            PuzzlePromise.ServerCommitment[][] commitments = server.SignHashes(request);
            RoundTrip(ref server, parameters);
            RoundTrip(ref commitments);

            PuzzlePromise.ClientRevelation revelation = client.Reveal(commitments);
            RoundTrip(ref client, parameters);
            RoundTrip(ref revelation);

            ServerCommitmentsProof proof = server.CheckRevelation(revelation, clientEscrow.PubKey.Hash, FeeRate);

            RoundTrip(ref server, parameters);
            RoundTrip(ref proof);

            var puzzlesToSolve = client.CheckCommitmentProof(proof);

            RoundTrip(ref client, parameters);
            foreach (var puzzle in puzzlesToSolve)
            {
                Assert.NotNull(puzzle);
            }

            for (int i = 0; i < puzzlesToSolve.Length; i++)
            {
                // Doesn't work for now! Need to figure how Bob will be spending the puzzles.
                var solution = key.SolvePuzzle(puzzlesToSolve[i]);
                // I'm not sure if GetSignedTransactions should handle all payments or only one payment at a time.
                var transactions = client.GetSignedTransactions(solution, i).ToArray();
                RoundTrip(ref client, parameters);
                Assert.True(transactions.Length == parameters.RealTransactionCountPerLevel);
            }


            var escrow = server.GetInternalState().EscrowedCoin;
            // In case things do not go well and timeout is hit...
            var redeemTransaction = server.CreateRedeemTransaction(FeeRate);
            var resigned          = redeemTransaction.ReSign(escrow);
            TransactionBuilder bb = new TransactionBuilder();

            bb.AddCoins(server.GetInternalState().EscrowedCoin);
            Assert.True(bb.Verify(resigned));

            //Check can ve reclaimed if malleated
            bb = new TransactionBuilder();
            escrow.Outpoint = new OutPoint(escrow.Outpoint.Hash, 10);
            bb.AddCoins(escrow);
            resigned = redeemTransaction.ReSign(escrow);
            Assert.False(bb.Verify(redeemTransaction.Transaction));
            Assert.True(bb.Verify(resigned));
        }