public void TestValidateMacTag()
        {
            JPakePrimeOrderGroup pg1 = JPakePrimeOrderGroups.SUN_JCE_1024;

            SecureRandom random = new SecureRandom();
            IDigest      digest = new Sha256Digest();

            BigInteger x1 = JPakeUtilities.GenerateX1(pg1.Q, random);
            BigInteger x2 = JPakeUtilities.GenerateX2(pg1.Q, random);
            BigInteger x3 = JPakeUtilities.GenerateX1(pg1.Q, random);
            BigInteger x4 = JPakeUtilities.GenerateX2(pg1.Q, random);

            BigInteger gx1 = JPakeUtilities.CalculateGx(pg1.P, pg1.G, x1);
            BigInteger gx2 = JPakeUtilities.CalculateGx(pg1.P, pg1.G, x2);
            BigInteger gx3 = JPakeUtilities.CalculateGx(pg1.P, pg1.G, x3);
            BigInteger gx4 = JPakeUtilities.CalculateGx(pg1.P, pg1.G, x4);

            BigInteger gB = JPakeUtilities.CalculateGA(pg1.P, gx3, gx1, gx2);

            BigInteger s = JPakeUtilities.CalculateS("password".ToCharArray());

            BigInteger xs = JPakeUtilities.CalculateX2s(pg1.Q, x4, s);

            BigInteger B = JPakeUtilities.CalculateA(pg1.P, pg1.Q, gB, xs);

            BigInteger keyingMaterial = JPakeUtilities.CalculateKeyingMaterial(pg1.P, pg1.Q, gx4, x2, s, B);

            BigInteger macTag = JPakeUtilities.CalculateMacTag("participantId", "partnerParticipantId", gx1, gx2, gx3, gx4, keyingMaterial, digest);

            // should succeed
            JPakeUtilities.ValidateMacTag("partnerParticipantId", "participantId", gx3, gx4, gx1, gx2, keyingMaterial, digest, macTag);

            // validating own macTag (as opposed to the other party's mactag)
            try
            {
                JPakeUtilities.ValidateMacTag("participantId", "partnerParticipantId", gx1, gx2, gx3, gx4, keyingMaterial, digest, macTag);

                Fail("failed to throw exception on validating own macTag (calculated partner macTag)");
            }
            catch (CryptoException)
            {
                // expected
            }

            // participant ids switched
            try
            {
                JPakeUtilities.ValidateMacTag("participantId", "partnerParticipantId", gx3, gx4, gx1, gx2, keyingMaterial, digest, macTag);

                Fail("failed to throw exception on validating own macTag (calculated partner macTag");
            }
            catch (CryptoException)
            {
                // expected
            }
        }
    public virtual JPakeRound2Payload CreateRound2PayloadToSend()
    {
        if (state >= STATE_ROUND_2_CREATED)
        {
            throw new InvalidOperationException("Round 2 payload already created for " + participantId);
        }
        if (state < STATE_ROUND_1_VALIDATED)
        {
            throw new InvalidOperationException("Round 1 payload must be validated prior to creating round 2 payload for " + participantId);
        }
        BigInteger gA          = JPakeUtilities.CalculateGA(p, gx1, gx3, gx4);
        BigInteger s           = JPakeUtilities.CalculateS(password);
        BigInteger bigInteger  = JPakeUtilities.CalculateX2s(q, x2, s);
        BigInteger bigInteger2 = JPakeUtilities.CalculateA(p, q, gA, bigInteger);

        BigInteger[] knowledgeProofForX2s = JPakeUtilities.CalculateZeroKnowledgeProof(p, q, gA, bigInteger2, bigInteger, participantId, digest, random);
        state = STATE_ROUND_2_CREATED;
        return(new JPakeRound2Payload(participantId, bigInteger2, knowledgeProofForX2s));
    }