public ExchangeAfterRound2Creation(
     JPakeParticipant alice,
     JPakeRound2Payload aliceRound2Payload,
     JPakeRound2Payload bobRound2Payload)
 {
     this.alice = alice;
     this.aliceRound2Payload = aliceRound2Payload;
     this.bobRound2Payload   = bobRound2Payload;
 }
        private ExchangeAfterRound2Creation RunExchangeUntilRound2Creation(JPakeParticipant alice, JPakeParticipant bob)
        {
            JPakeRound1Payload aliceRound1Payload = alice.CreateRound1PayloadToSend();
            JPakeRound1Payload bobRound1Payload   = bob.CreateRound1PayloadToSend();

            alice.ValidateRound1PayloadReceived(bobRound1Payload);
            bob.ValidateRound1PayloadReceived(aliceRound1Payload);

            JPakeRound2Payload aliceRound2Payload = alice.CreateRound2PayloadToSend();
            JPakeRound2Payload bobRound2Payload   = bob.CreateRound2PayloadToSend();

            return(new ExchangeAfterRound2Creation(
                       alice,
                       aliceRound2Payload,
                       bobRound2Payload));
        }
    public virtual void ValidateRound2PayloadReceived(JPakeRound2Payload round2PayloadReceived)
    {
        if (state >= STATE_ROUND_2_VALIDATED)
        {
            throw new InvalidOperationException("Validation already attempted for round 2 payload for " + participantId);
        }
        if (state < STATE_ROUND_1_VALIDATED)
        {
            throw new InvalidOperationException("Round 1 payload must be validated prior to validation round 2 payload for " + participantId);
        }
        BigInteger ga = JPakeUtilities.CalculateGA(p, gx3, gx1, gx2);

        b = round2PayloadReceived.A;
        BigInteger[] knowledgeProofForX2s = round2PayloadReceived.KnowledgeProofForX2s;
        JPakeUtilities.ValidateParticipantIdsDiffer(participantId, round2PayloadReceived.ParticipantId);
        JPakeUtilities.ValidateParticipantIdsEqual(partnerParticipantId, round2PayloadReceived.ParticipantId);
        JPakeUtilities.ValidateGa(ga);
        JPakeUtilities.ValidateZeroKnowledgeProof(p, q, ga, b, knowledgeProofForX2s, round2PayloadReceived.ParticipantId, digest);
        state = STATE_ROUND_2_VALIDATED;
    }
        public void TestStateValidation()
        {
            JPakeParticipant alice = CreateAlice();
            JPakeParticipant bob   = CreateBob();

            // We're testing alice here. Bob is just used for help.

            // START ROUND 1 CHECKS

            Assert.AreEqual(JPakeParticipant.STATE_INITIALIZED, alice.State);

            // create round 2 before round 1
            try
            {
                alice.CreateRound2PayloadToSend();

                Fail("failed to throw on round 2 creation before 1");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            JPakeRound1Payload aliceRound1Payload = alice.CreateRound1PayloadToSend();

            Assert.AreEqual(JPakeParticipant.STATE_ROUND_1_CREATED, alice.State);

            // create round 1 twice
            try
            {
                alice.CreateRound1PayloadToSend();

                Fail("failed to throw on round 1 creation twice");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            // create round 2 before validation round 1
            try
            {
                alice.CreateRound2PayloadToSend();

                Fail("failed to throw on round 2 creation before round 1 validation");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            // validate round 2 before validation round 1
            try
            {
                alice.ValidateRound2PayloadReceived(null);

                Fail("failed to throw on round 2 validation before round 1 validation");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            JPakeRound1Payload bobRound1Payload = bob.CreateRound1PayloadToSend();

            alice.ValidateRound1PayloadReceived(bobRound1Payload);
            Assert.AreEqual(JPakeParticipant.STATE_ROUND_1_VALIDATED, alice.State);

            // validate round 1 payload twice
            try
            {
                alice.ValidateRound1PayloadReceived(bobRound1Payload);

                Fail("failed to throw on round 1 validation twice");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            bob.ValidateRound1PayloadReceived(aliceRound1Payload);

            // START ROUND 2 CHECKS

            JPakeRound2Payload aliceRound2Payload = alice.CreateRound2PayloadToSend();

            Assert.AreEqual(JPakeParticipant.STATE_ROUND_2_CREATED, alice.State);

            // create round 2 payload twice
            try
            {
                alice.CreateRound2PayloadToSend();

                Fail("failed to throw on round 2 creation twice");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            // create key before validation round 2
            try
            {
                alice.CalculateKeyingMaterial();

                Fail("failed to throw on calculating keying material before round 2 validation");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            // validate round 3 before validating round 2
            try
            {
                alice.ValidateRound3PayloadReceived(null, null);

                Fail("failed to throw on validating round 3 before 2");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            JPakeRound2Payload bobRound2Payload = bob.CreateRound2PayloadToSend();

            alice.ValidateRound2PayloadReceived(bobRound2Payload);
            Assert.AreEqual(JPakeParticipant.STATE_ROUND_2_VALIDATED, alice.State);

            // validate round 2 payload twice
            try
            {
                alice.ValidateRound2PayloadReceived(bobRound2Payload);

                Fail("failed to throw on validating round 2 twice");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            bob.ValidateRound2PayloadReceived(aliceRound2Payload);

            // create round 3 before calculating key
            try
            {
                alice.CreateRound3PayloadToSend(BigInteger.One);

                Fail("failed to throw on creating round 3 before calculating key aterial");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            // START KEY CALCULATION CHECKS

            BigInteger aliceKeyingMaterial = alice.CalculateKeyingMaterial();

            Assert.AreEqual(JPakeParticipant.STATE_KEY_CALCULATED, alice.State);

            // calculate key twice
            try
            {
                alice.CalculateKeyingMaterial();

                Fail("failed to throw on calculating key twice");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            BigInteger bobKeyingMaterial = bob.CalculateKeyingMaterial();

            // START ROUND 3 CHECKS

            JPakeRound3Payload aliceRound3Payload = alice.CreateRound3PayloadToSend(aliceKeyingMaterial);

            Assert.AreEqual(JPakeParticipant.STATE_ROUND_3_CREATED, alice.State);

            // create round 3 payload twice
            try
            {
                alice.CreateRound3PayloadToSend(aliceKeyingMaterial);

                Fail("failed to throw on creation round 3 twice");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            JPakeRound3Payload bobRound3Payload = bob.CreateRound3PayloadToSend(bobKeyingMaterial);

            alice.ValidateRound3PayloadReceived(bobRound3Payload, aliceKeyingMaterial);
            Assert.AreEqual(JPakeParticipant.STATE_ROUND_3_VALIDATED, alice.State);

            // validate round 3 payload twice
            try
            {
                alice.ValidateRound3PayloadReceived(bobRound3Payload, aliceKeyingMaterial);

                Fail("failed to throw on validation round 3 twice");
            }
            catch (InvalidOperationException)
            {
                // expected
            }

            bob.ValidateRound3PayloadReceived(aliceRound3Payload, bobKeyingMaterial);
        }