Пример #1
0
 public JPakePrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, bool skipChecks)
 {
     JPakeUtilities.ValidateNotNull(p, "p");
     JPakeUtilities.ValidateNotNull(q, "q");
     JPakeUtilities.ValidateNotNull(g, "g");
     if (!skipChecks)
     {
         if (!p.Subtract(JPakeUtilities.One).Mod(q).Equals(JPakeUtilities.Zero))
         {
             throw new ArgumentException("p-1 must be evenly divisible by q");
         }
         if (g.CompareTo(BigInteger.Two) == -1 || g.CompareTo(p.Subtract(JPakeUtilities.One)) == 1)
         {
             throw new ArgumentException("g must be in [2, p-1]");
         }
         if (!g.ModPow(q, p).Equals(JPakeUtilities.One))
         {
             throw new ArgumentException("g^q mod p must equal 1");
         }
         if (!p.IsProbablePrime(20))
         {
             throw new ArgumentException("p must be prime");
         }
         if (!q.IsProbablePrime(20))
         {
             throw new ArgumentException("q must be prime");
         }
     }
     this.p = p;
     this.q = q;
     this.g = g;
 }
Пример #2
0
        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 JPakeRound2Payload(string participantId, BigInteger a, BigInteger[] knowledgeProofForX2s)
 {
     JPakeUtilities.ValidateNotNull(participantId, "participantId");
     JPakeUtilities.ValidateNotNull(a, "a");
     JPakeUtilities.ValidateNotNull(knowledgeProofForX2s, "knowledgeProofForX2s");
     this.participantId        = participantId;
     this.a                    = a;
     this.knowledgeProofForX2s = new BigInteger[knowledgeProofForX2s.Length];
     knowledgeProofForX2s.CopyTo(this.knowledgeProofForX2s, 0);
 }
Пример #4
0
 public JPakeRound1Payload(string participantId, BigInteger gx1, BigInteger gx2, BigInteger[] knowledgeProofForX1, BigInteger[] knowledgeProofForX2)
 {
     JPakeUtilities.ValidateNotNull(participantId, "participantId");
     JPakeUtilities.ValidateNotNull(gx1, "gx1");
     JPakeUtilities.ValidateNotNull(gx2, "gx2");
     JPakeUtilities.ValidateNotNull(knowledgeProofForX1, "knowledgeProofForX1");
     JPakeUtilities.ValidateNotNull(knowledgeProofForX2, "knowledgeProofForX2");
     this.participantId       = participantId;
     this.gx1                 = gx1;
     this.gx2                 = gx2;
     this.knowledgeProofForX1 = new BigInteger[knowledgeProofForX1.Length];
     Array.Copy(knowledgeProofForX1, this.knowledgeProofForX1, knowledgeProofForX1.Length);
     this.knowledgeProofForX2 = new BigInteger[knowledgeProofForX2.Length];
     Array.Copy(knowledgeProofForX2, this.knowledgeProofForX2, knowledgeProofForX2.Length);
 }
Пример #5
0
        public void TestValidateParticipantsIdsEqual()
        {
            JPakeUtilities.ValidateParticipantIdsEqual("a", "a");

            try
            {
                JPakeUtilities.ValidateParticipantIdsEqual("a", "b");

                Fail("validate participant ids equal not throwing exception for different participant ids");
            }
            catch (CryptoException)
            {
                // expected
            }
        }
 public virtual JPakeRound1Payload CreateRound1PayloadToSend()
 {
     if (state >= STATE_ROUND_1_CREATED)
     {
         throw new InvalidOperationException("Round 1 payload already created for " + participantId);
     }
     x1  = JPakeUtilities.GenerateX1(q, random);
     x2  = JPakeUtilities.GenerateX2(q, random);
     gx1 = JPakeUtilities.CalculateGx(p, g, x1);
     gx2 = JPakeUtilities.CalculateGx(p, g, x2);
     BigInteger[] knowledgeProofForX  = JPakeUtilities.CalculateZeroKnowledgeProof(p, q, g, gx1, x1, participantId, digest, random);
     BigInteger[] knowledgeProofForX2 = JPakeUtilities.CalculateZeroKnowledgeProof(p, q, g, gx2, x2, participantId, digest, random);
     state = STATE_ROUND_1_CREATED;
     return(new JPakeRound1Payload(participantId, gx1, gx2, knowledgeProofForX, knowledgeProofForX2));
 }
Пример #7
0
        public void TestValidateGa()
        {
            JPakeUtilities.ValidateGa(Ten);

            try
            {
                JPakeUtilities.ValidateGa(BigInteger.One);

                Fail("exception not thrown for g^a equal to 1");
            }
            catch (CryptoException)
            {
                // expected
            }
        }
Пример #8
0
        public void TestValidateNotNull()
        {
            JPakeUtilities.ValidateNotNull("a", "description");

            try
            {
                JPakeUtilities.ValidateNotNull(null, "description");

                Fail("failed to throw exception on null");
            }
            catch (ArgumentNullException)
            {
                // expected
            }
        }
    public virtual JPakeRound3Payload CreateRound3PayloadToSend(BigInteger keyingMaterial)
    {
        if (state >= STATE_ROUND_3_CREATED)
        {
            throw new InvalidOperationException("Round 3 payload already created for " + participantId);
        }
        if (state < STATE_KEY_CALCULATED)
        {
            throw new InvalidOperationException("Keying material must be calculated prior to creating round 3 payload for " + participantId);
        }
        BigInteger magTag = JPakeUtilities.CalculateMacTag(participantId, partnerParticipantId, gx1, gx2, gx3, gx4, keyingMaterial, digest);

        state = STATE_ROUND_3_CREATED;
        return(new JPakeRound3Payload(participantId, magTag));
    }
Пример #10
0
        public void TestValidateParticipantIdsDiffer()
        {
            JPakeUtilities.ValidateParticipantIdsDiffer("a", "b");
            JPakeUtilities.ValidateParticipantIdsDiffer("a", "A");

            try
            {
                JPakeUtilities.ValidateParticipantIdsDiffer("a", "a");

                Fail("validate participant ids differ not throwing exception for equal participant ids");
            }
            catch (CryptoException)
            {
                // expected
            }
        }
 public virtual void ValidateRound1PayloadReceived(JPakeRound1Payload round1PayloadReceived)
 {
     if (state >= STATE_ROUND_1_VALIDATED)
     {
         throw new InvalidOperationException("Validation already attempted for round 1 payload for " + participantId);
     }
     partnerParticipantId = round1PayloadReceived.ParticipantId;
     gx3 = round1PayloadReceived.Gx1;
     gx4 = round1PayloadReceived.Gx2;
     BigInteger[] knowledgeProofForX  = round1PayloadReceived.KnowledgeProofForX1;
     BigInteger[] knowledgeProofForX2 = round1PayloadReceived.KnowledgeProofForX2;
     JPakeUtilities.ValidateParticipantIdsDiffer(participantId, round1PayloadReceived.ParticipantId);
     JPakeUtilities.ValidateGx4(gx4);
     JPakeUtilities.ValidateZeroKnowledgeProof(p, q, g, gx3, knowledgeProofForX, round1PayloadReceived.ParticipantId, digest);
     JPakeUtilities.ValidateZeroKnowledgeProof(p, q, g, gx4, knowledgeProofForX2, round1PayloadReceived.ParticipantId, digest);
     state = STATE_ROUND_1_VALIDATED;
 }
    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));
    }
 public virtual void ValidateRound3PayloadReceived(JPakeRound3Payload round3PayloadReceived, BigInteger keyingMaterial)
 {
     if (state >= STATE_ROUND_3_VALIDATED)
     {
         throw new InvalidOperationException("Validation already attempted for round 3 payload for " + participantId);
     }
     if (state < STATE_KEY_CALCULATED)
     {
         throw new InvalidOperationException("Keying material must be calculated prior to validating round 3 payload for " + participantId);
     }
     JPakeUtilities.ValidateParticipantIdsDiffer(participantId, round3PayloadReceived.ParticipantId);
     JPakeUtilities.ValidateParticipantIdsEqual(partnerParticipantId, round3PayloadReceived.ParticipantId);
     JPakeUtilities.ValidateMacTag(participantId, partnerParticipantId, gx1, gx2, gx3, gx4, keyingMaterial, digest, round3PayloadReceived.MacTag);
     gx1   = null;
     gx2   = null;
     gx3   = null;
     gx4   = null;
     state = STATE_ROUND_3_VALIDATED;
 }
    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 JPakeParticipant(string participantId, char[] password, JPakePrimeOrderGroup group, IDigest digest, SecureRandom random)
 {
     JPakeUtilities.ValidateNotNull(participantId, "participantId");
     JPakeUtilities.ValidateNotNull(password, "password");
     JPakeUtilities.ValidateNotNull(group, "p");
     JPakeUtilities.ValidateNotNull(digest, "digest");
     JPakeUtilities.ValidateNotNull(random, "random");
     if (password.Length == 0)
     {
         throw new ArgumentException("Password must not be empty.");
     }
     this.participantId = participantId;
     this.password      = new char[password.Length];
     Array.Copy(password, this.password, password.Length);
     p           = group.P;
     q           = group.Q;
     g           = group.G;
     this.digest = digest;
     this.random = random;
     state       = STATE_INITIALIZED;
 }
    public virtual BigInteger CalculateKeyingMaterial()
    {
        if (state >= STATE_KEY_CALCULATED)
        {
            throw new InvalidOperationException("Key already calculated for " + participantId);
        }
        if (state < STATE_ROUND_2_VALIDATED)
        {
            throw new InvalidOperationException("Round 2 payload must be validated prior to creating key for " + participantId);
        }
        BigInteger s = JPakeUtilities.CalculateS(password);

        Array.Clear(password, 0, password.Length);
        password = null;
        BigInteger result = JPakeUtilities.CalculateKeyingMaterial(p, q, gx4, x2, s, b);

        x1    = null;
        x2    = null;
        b     = null;
        state = STATE_KEY_CALCULATED;
        return(result);
    }
Пример #17
0
        public void TestValidateZeroKnowledgeProof()
        {
            JPakePrimeOrderGroup pg1 = JPakePrimeOrderGroups.SUN_JCE_1024;

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

            BigInteger x1             = JPakeUtilities.GenerateX1(pg1.Q, random);
            BigInteger gx1            = JPakeUtilities.CalculateGx(pg1.P, pg1.G, x1);
            string     participantId1 = "participant1";

            BigInteger[] zkp1 = JPakeUtilities.CalculateZeroKnowledgeProof(pg1.P, pg1.Q, pg1.G, gx1, x1, participantId1, digest1, random);

            // should succeed
            JPakeUtilities.ValidateZeroKnowledgeProof(pg1.P, pg1.Q, pg1.G, gx1, zkp1, participantId1, digest1);

            // wrong group
            JPakePrimeOrderGroup pg2 = JPakePrimeOrderGroups.NIST_3072;

            try
            {
                JPakeUtilities.ValidateZeroKnowledgeProof(pg2.P, pg2.Q, pg2.G, gx1, zkp1, participantId1, digest1);

                Fail("failed to throw exception on wrong prime order group");
            }
            catch (CryptoException)
            {
                // expected
            }

            // wrong digest
            IDigest digest2 = new Sha1Digest();

            try
            {
                JPakeUtilities.ValidateZeroKnowledgeProof(pg1.P, pg1.Q, pg1.G, gx1, zkp1, participantId1, digest2);

                Fail("failed to throw exception on wrong digest");
            }
            catch (CryptoException)
            {
                // expected
            }

            // wrong participant
            string participantId2 = "participant2";

            try
            {
                JPakeUtilities.ValidateZeroKnowledgeProof(pg1.P, pg1.Q, pg1.G, gx1, zkp1, participantId2, digest1);

                Fail("failed to throw exception on wrong participant");
            }
            catch (CryptoException)
            {
                // expected
            }

            // wrong gx
            BigInteger x2  = JPakeUtilities.GenerateX2(pg1.Q, random);
            BigInteger gx2 = JPakeUtilities.CalculateGx(pg1.P, pg1.G, x2);

            try
            {
                JPakeUtilities.ValidateZeroKnowledgeProof(pg1.P, pg1.Q, pg1.G, gx2, zkp1, participantId1, digest1);

                Fail("failed to throw exception on wrong gx");
            }
            catch (CryptoException)
            {
                // expected
            }

            // wrong zkp
            BigInteger[] zkp2 = JPakeUtilities.CalculateZeroKnowledgeProof(pg1.P, pg1.Q, pg1.G, gx2, x2, participantId1, digest1, random);
            try
            {
                JPakeUtilities.ValidateZeroKnowledgeProof(pg1.P, pg1.Q, pg1.G, gx1, zkp2, participantId1, digest1);

                Fail("failed to throw exception on wrong zero knowledge proof");
            }
            catch (CryptoException)
            {
                // expected
            }

            // gx <= 0
            try
            {
                JPakeUtilities.ValidateZeroKnowledgeProof(pg1.P, pg1.Q, pg1.G, BigInteger.Zero, zkp1, participantId1, digest1);

                Fail("failed to throw exception on g^x <= 0");
            }
            catch (CryptoException)
            {
                // expected
            }

            // gx >= p
            try
            {
                JPakeUtilities.ValidateZeroKnowledgeProof(pg1.P, pg1.Q, pg1.G, pg1.P, zkp1, participantId1, digest1);

                Fail("failed to throw exception on g^x >= p");
            }
            catch (CryptoException)
            {
                // expected
            }

            // gx mod q == 1
            try
            {
                JPakeUtilities.ValidateZeroKnowledgeProof(pg1.P, pg1.Q, pg1.G, pg1.Q.Add(BigInteger.One), zkp1, participantId1, digest1);

                Fail("failed to throw exception on g^x mod q == 1");
            }
            catch (CryptoException)
            {
                // expected
            }
        }