diff --git a/crypto/test/src/crypto/agreement/test/AllTests.cs b/crypto/test/src/crypto/agreement/test/AllTests.cs
new file mode 100644
index 000000000..ea8f438e5
--- /dev/null
+++ b/crypto/test/src/crypto/agreement/test/AllTests.cs
@@ -0,0 +1,31 @@
+using System;
+
+using NUnit.Core;
+using NUnit.Framework;
+
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Crypto.Agreement.Tests
+{
+ [TestFixture]
+ public class AllTests
+ {
+ public static void Main(string[] args)
+ {
+ Suite.Run(new NullListener(), NUnit.Core.TestFilter.Empty);
+ }
+
+ [Suite]
+ public static TestSuite Suite
+ {
+ get
+ {
+ TestSuite suite = new TestSuite("JPAKE Engine Tests");
+ suite.Add(new JPakeParticipantTest());
+ suite.Add(new JPakePrimeOrderGroupTest());
+ suite.Add(new JPakeUtilitiesTest());
+ return suite;
+ }
+ }
+ }
+}
diff --git a/crypto/test/src/crypto/agreement/test/JPakeParticipantTest.cs b/crypto/test/src/crypto/agreement/test/JPakeParticipantTest.cs
new file mode 100644
index 000000000..c84264aa5
--- /dev/null
+++ b/crypto/test/src/crypto/agreement/test/JPakeParticipantTest.cs
@@ -0,0 +1,566 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Crypto.Agreement.JPake;
+using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Crypto.Agreement.Tests
+{
+ [TestFixture]
+ public class JPakeParticipantTest
+ : SimpleTest
+ {
+ public override void PerformTest()
+ {
+ TestConstruction();
+ TestSuccessfulExchange();
+ TestIncorrectPassword();
+ TestStateValidation();
+ TestValidateRound1PayloadReceived();
+ TestValidateRound2PayloadReceived();
+ }
+
+ public override string Name
+ {
+ get { return "JPakeParticipant"; }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new JPakeParticipantTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+
+ public void TestConstruction()
+ {
+ JPakePrimeOrderGroup group = JPakePrimeOrderGroups.SUN_JCE_1024;
+ SecureRandom random = new SecureRandom();
+ IDigest digest = new Sha256Digest();
+ string participantId = "participantId";
+ char[] password = "password".ToCharArray();
+
+ // should succeed
+ new JPakeParticipant(participantId, password, group, digest, random);
+
+ // null participantId
+ try
+ {
+ new JPakeParticipant(null, password, group, digest, random);
+
+ Fail("failed to throw exception on null participantId");
+ }
+ catch (ArgumentNullException)
+ {
+ // expected
+ }
+
+ // null password
+ try
+ {
+ new JPakeParticipant(participantId, null, group, digest, random);
+
+ Fail("failed to throw exception on null password");
+ }
+ catch (ArgumentNullException)
+ {
+ // expected
+ }
+
+ // empty password
+ try
+ {
+ new JPakeParticipant(participantId, "".ToCharArray(), group, digest, random);
+
+ Fail("failed to throw exception on empty password");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ // null group
+ try
+ {
+ new JPakeParticipant(participantId, password, null, digest, random);
+
+ Fail("failed to throw exception on null group");
+ }
+ catch (ArgumentNullException)
+ {
+ // expected
+ }
+
+ // null digest
+ try
+ {
+ new JPakeParticipant(participantId, password, group, null, random);
+
+ Fail("failed to throw exception on null digest");
+ }
+ catch (ArgumentNullException)
+ {
+ // expected
+ }
+
+ // null random
+ try
+ {
+ new JPakeParticipant(participantId, password, group, digest, null);
+
+ Fail("failed to throw exception on null random");
+ }
+ catch (ArgumentNullException)
+ {
+ // expected
+ }
+ }
+
+ public void TestSuccessfulExchange()
+ {
+ JPakeParticipant alice = CreateAlice();
+ JPakeParticipant bob = CreateBob();
+
+ ExchangeAfterRound2Creation exchange = RunExchangeUntilRound2Creation(alice, bob);
+
+ alice.ValidateRound2PayloadReceived(exchange.bobRound2Payload);
+ bob.ValidateRound2PayloadReceived(exchange.aliceRound2Payload);
+
+ BigInteger aliceKeyingMaterial = alice.CalculateKeyingMaterial();
+ BigInteger bobKeyingMaterial = bob.CalculateKeyingMaterial();
+
+ JPakeRound3Payload aliceRound3Payload = alice.CreateRound3PayloadToSend(aliceKeyingMaterial);
+ JPakeRound3Payload bobRound3Payload = bob.CreateRound3PayloadToSend(bobKeyingMaterial);
+
+ alice.ValidateRound3PayloadReceived(bobRound3Payload, aliceKeyingMaterial);
+ bob.ValidateRound3PayloadReceived(aliceRound3Payload, bobKeyingMaterial);
+
+ Assert.AreEqual(aliceKeyingMaterial, bobKeyingMaterial);
+ }
+
+ public void TestIncorrectPassword()
+ {
+ JPakeParticipant alice = CreateAlice();
+ JPakeParticipant bob = CreateBobWithWrongPassword();
+
+ ExchangeAfterRound2Creation exchange = RunExchangeUntilRound2Creation(alice, bob);
+
+ alice.ValidateRound2PayloadReceived(exchange.bobRound2Payload);
+ bob.ValidateRound2PayloadReceived(exchange.aliceRound2Payload);
+
+ BigInteger aliceKeyingMaterial = alice.CalculateKeyingMaterial();
+ BigInteger bobKeyingMaterial = bob.CalculateKeyingMaterial();
+
+ JPakeRound3Payload aliceRound3Payload = alice.CreateRound3PayloadToSend(aliceKeyingMaterial);
+ JPakeRound3Payload bobRound3Payload = bob.CreateRound3PayloadToSend(bobKeyingMaterial);
+
+ try
+ {
+ alice.ValidateRound3PayloadReceived(bobRound3Payload, aliceKeyingMaterial);
+
+ Fail("failed to throw exception on incorrect password");
+ }
+ catch (CryptoException)
+ {
+ // expected
+ }
+
+ try
+ {
+ bob.ValidateRound3PayloadReceived(aliceRound3Payload, bobKeyingMaterial);
+
+ Fail("failed to throw exception on incorrect password");
+ }
+ catch (CryptoException)
+ {
+ // expected
+ }
+ }
+
+ 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);
+ }
+
+ public void TestValidateRound1PayloadReceived()
+ {
+ // We're testing alice here. Bob is just used for help.
+
+ JPakeRound1Payload bobRound1Payload = CreateBob().CreateRound1PayloadToSend();
+
+ // should succeed
+ CreateAlice().ValidateRound1PayloadReceived(bobRound1Payload);
+
+ // alice verifies alice's payload
+ try
+ {
+ JPakeParticipant alice = CreateAlice();
+ alice.ValidateRound1PayloadReceived(alice.CreateRound1PayloadToSend());
+
+ Fail("failed to throw on participant validating own payload");
+ }
+ catch (CryptoException)
+ {
+ // expected
+ }
+
+ // g^x4 == 1
+ try
+ {
+ CreateAlice().ValidateRound1PayloadReceived(new JPakeRound1Payload(
+ bobRound1Payload.ParticipantId,
+ bobRound1Payload.Gx1,
+ BigInteger.One,
+ bobRound1Payload.KnowledgeProofForX1,
+ bobRound1Payload.KnowledgeProofForX2));
+
+ Fail("failed to throw on g^x4 == 1");
+ }
+ catch (CryptoException)
+ {
+ // expected
+ }
+
+ // zero knowledge proof for x3 fails
+ try
+ {
+ JPakeRound1Payload bobRound1Payload2 = CreateBob().CreateRound1PayloadToSend();
+ CreateAlice().ValidateRound1PayloadReceived(new JPakeRound1Payload(
+ bobRound1Payload.ParticipantId,
+ bobRound1Payload.Gx1,
+ bobRound1Payload.Gx2,
+ bobRound1Payload2.KnowledgeProofForX1,
+ bobRound1Payload.KnowledgeProofForX2));
+
+ Fail("failed to throw on incorrect zero knowledge proof for x3");
+ }
+ catch (CryptoException)
+ {
+ // expected
+ }
+
+ // zero knowledge proof for x4 fails
+ try
+ {
+ JPakeRound1Payload bobRound1Payload2 = CreateBob().CreateRound1PayloadToSend();
+ CreateAlice().ValidateRound1PayloadReceived(new JPakeRound1Payload(
+ bobRound1Payload.ParticipantId,
+ bobRound1Payload.Gx1,
+ bobRound1Payload.Gx2,
+ bobRound1Payload.KnowledgeProofForX1,
+ bobRound1Payload2.KnowledgeProofForX2));
+
+ Fail("failed to throw on incorrect zero knowledge proof for x4");
+ }
+ catch (CryptoException)
+ {
+ // expected
+ }
+ }
+
+ public void TestValidateRound2PayloadReceived()
+ {
+ // We're testing alice here. Bob is just used for help.
+
+ // should succeed
+ ExchangeAfterRound2Creation exchange1 = RunExchangeUntilRound2Creation(CreateAlice(), CreateBob());
+ exchange1.alice.ValidateRound2PayloadReceived(exchange1.bobRound2Payload);
+
+ // alice verified alice's payload
+ ExchangeAfterRound2Creation exchange2 = RunExchangeUntilRound2Creation(CreateAlice(), CreateBob());
+ try
+ {
+ exchange2.alice.ValidateRound2PayloadReceived(exchange2.aliceRound2Payload);
+
+ Fail("failed to throw on participant verifying own payload 2");
+ }
+ catch (CryptoException)
+ {
+ // expected
+ }
+
+ // wrong z
+ ExchangeAfterRound2Creation exchange3 = RunExchangeUntilRound2Creation(CreateAlice(), CreateBob());
+ ExchangeAfterRound2Creation exchange4 = RunExchangeUntilRound2Creation(CreateAlice(), CreateBob());
+ try
+ {
+ exchange3.alice.ValidateRound2PayloadReceived(exchange4.bobRound2Payload);
+
+ Fail("failed to throw on wrong z");
+ }
+ catch (CryptoException)
+ {
+ // expected
+ }
+ }
+
+ private class ExchangeAfterRound2Creation
+ {
+ public JPakeParticipant alice;
+ public JPakeRound2Payload aliceRound2Payload;
+ public JPakeRound2Payload bobRound2Payload;
+
+ 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);
+ }
+
+ private JPakeParticipant CreateAlice()
+ {
+ return CreateParticipant("alice", "password");
+ }
+
+ private JPakeParticipant CreateBob()
+ {
+ return CreateParticipant("bob", "password");
+ }
+
+ private JPakeParticipant CreateBobWithWrongPassword()
+ {
+ return CreateParticipant("bob", "wrong");
+ }
+
+ private JPakeParticipant CreateParticipant(string participantId, string password)
+ {
+ return new JPakeParticipant(
+ participantId,
+ password.ToCharArray(),
+ JPakePrimeOrderGroups.SUN_JCE_1024);
+ }
+ }
+}
diff --git a/crypto/test/src/crypto/agreement/test/JPakePrimeOrderGroupTest.cs b/crypto/test/src/crypto/agreement/test/JPakePrimeOrderGroupTest.cs
new file mode 100644
index 000000000..0f089f93c
--- /dev/null
+++ b/crypto/test/src/crypto/agreement/test/JPakePrimeOrderGroupTest.cs
@@ -0,0 +1,117 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Crypto.Agreement.JPake;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Crypto.Agreement.Tests
+{
+ [TestFixture]
+ public class JPakePrimeOrderGroupTest
+ : SimpleTest
+ {
+ public override void PerformTest()
+ {
+ TestConstruction();
+ }
+
+ public override string Name
+ {
+ get { return "JPakePrimeOrderGroup"; }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new JPakePrimeOrderGroupTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+
+ public void TestConstruction()
+ {
+ // p-1 not evenly divisible by q
+ try
+ {
+ new JPakePrimeOrderGroup(BigInteger.ValueOf(7), BigInteger.ValueOf(5), BigInteger.ValueOf(6));
+
+ Fail("failed to throw exception on p-1 not evenly divisible by q");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ // g < 2
+ try
+ {
+ new JPakePrimeOrderGroup(BigInteger.ValueOf(11), BigInteger.ValueOf(5), BigInteger.ValueOf(1));
+
+ Fail("failed to throw exception on g < 2");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ // g > p - 1
+ try
+ {
+ new JPakePrimeOrderGroup(BigInteger.ValueOf(11), BigInteger.ValueOf(5), BigInteger.ValueOf(11));
+
+ Fail("failed to throw exception on g > p - 1");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ //g^q mod p not equal 1
+ try
+ {
+ new JPakePrimeOrderGroup(BigInteger.ValueOf(11), BigInteger.ValueOf(5), BigInteger.ValueOf(6));
+
+ Fail("failed to throw exception on g^q mod p not equal 1");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ // p not prime
+ try
+ {
+ new JPakePrimeOrderGroup(BigInteger.ValueOf(15), BigInteger.ValueOf(2), BigInteger.ValueOf(4));
+
+ Fail("failed to throw exception on p not prime");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ // q not prime
+ try
+ {
+ new JPakePrimeOrderGroup(BigInteger.ValueOf(7), BigInteger.ValueOf(6), BigInteger.ValueOf(3));
+
+ Fail("failed to throw exception on q not prime");
+ }
+ catch (ArgumentException)
+ {
+ // expected
+ }
+
+ // should succeed
+ new JPakePrimeOrderGroup(BigInteger.ValueOf(7), BigInteger.ValueOf(3), BigInteger.ValueOf(4));
+ }
+ }
+}
diff --git a/crypto/test/src/crypto/agreement/test/JPakeUtilitiesTest.cs b/crypto/test/src/crypto/agreement/test/JPakeUtilitiesTest.cs
new file mode 100644
index 000000000..04a52cc06
--- /dev/null
+++ b/crypto/test/src/crypto/agreement/test/JPakeUtilitiesTest.cs
@@ -0,0 +1,306 @@
+using System;
+
+using NUnit.Framework;
+
+using Org.BouncyCastle.Crypto.Agreement.JPake;
+using Org.BouncyCastle.Crypto.Digests;
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Utilities.Test;
+
+namespace Org.BouncyCastle.Crypto.Agreement.Tests
+{
+ [TestFixture]
+ public class JPakeUtilitiesTest
+ : SimpleTest
+ {
+ private static readonly BigInteger Ten = BigInteger.ValueOf(10);
+
+ public override void PerformTest()
+ {
+ TestValidateGx4();
+ TestValidateGa();
+ TestValidateParticipantIdsDiffer();
+ TestValidateParticipantsIdsEqual();
+ TestValidateMacTag();
+ TestValidateNotNull();
+ TestValidateZeroKnowledgeProof();
+ }
+
+ public override string Name
+ {
+ get { return "JPakeUtilities"; }
+ }
+
+ public static void Main(
+ string[] args)
+ {
+ RunTest(new JPakeUtilitiesTest());
+ }
+
+ [Test]
+ public void TestFunction()
+ {
+ string resultText = Perform().ToString();
+
+ Assert.AreEqual(Name + ": Okay", resultText);
+ }
+
+ public void TestValidateGx4()
+ {
+ JPakeUtilities.ValidateGx4(Ten);
+
+ try
+ {
+ JPakeUtilities.ValidateGx4(BigInteger.One);
+
+ Fail("exception not thrown for g^x4 equal to 1");
+ }
+ catch (CryptoException)
+ {
+ // expected
+ }
+ }
+
+ public void TestValidateGa()
+ {
+ JPakeUtilities.ValidateGa(Ten);
+
+ try
+ {
+ JPakeUtilities.ValidateGa(BigInteger.One);
+
+ Fail("exception not thrown for g^a equal to 1");
+ }
+ catch (CryptoException)
+ {
+ // expected
+ }
+ }
+
+ 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 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 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 void TestValidateNotNull()
+ {
+ JPakeUtilities.ValidateNotNull("a", "description");
+
+ try
+ {
+ JPakeUtilities.ValidateNotNull(null, "description");
+
+ Fail("failed to throw exception on null");
+ }
+ catch (ArgumentNullException)
+ {
+ // expected
+ }
+ }
+
+ 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
+ }
+ }
+ }
+}
diff --git a/crypto/test/src/crypto/tls/test/TlsProtocolNonBlockingTest.cs b/crypto/test/src/crypto/tls/test/TlsProtocolNonBlockingTest.cs
index 5fe0f32ad..477e287f1 100644
--- a/crypto/test/src/crypto/tls/test/TlsProtocolNonBlockingTest.cs
+++ b/crypto/test/src/crypto/tls/test/TlsProtocolNonBlockingTest.cs
@@ -104,7 +104,7 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests
protocol.OfferInput(new byte[10]);
Assert.Fail("Input was accepted after close");
}
- catch (IOException e)
+ catch (IOException)
{
}
@@ -113,7 +113,7 @@ namespace Org.BouncyCastle.Crypto.Tls.Tests
protocol.OfferOutput(new byte[10], 0, 10);
Assert.Fail("Output was accepted after close");
}
- catch (IOException e)
+ catch (IOException)
{
}
}
diff --git a/crypto/test/src/openpgp/examples/ByteArrayHandler.cs b/crypto/test/src/openpgp/examples/ByteArrayHandler.cs
index 676db8766..b5098ff66 100644
--- a/crypto/test/src/openpgp/examples/ByteArrayHandler.cs
+++ b/crypto/test/src/openpgp/examples/ByteArrayHandler.cs
@@ -123,7 +123,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
}
PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator(algorithm, new SecureRandom());
- encGen.AddMethod(passPhrase);
+ encGen.AddMethod(passPhrase, HashAlgorithmTag.Sha1);
Stream encOut = encGen.Open(output, compressedData.Length);
diff --git a/crypto/test/src/openpgp/examples/PbeFileProcessor.cs b/crypto/test/src/openpgp/examples/PbeFileProcessor.cs
index 66b1cc4ed..961704407 100644
--- a/crypto/test/src/openpgp/examples/PbeFileProcessor.cs
+++ b/crypto/test/src/openpgp/examples/PbeFileProcessor.cs
@@ -127,7 +127,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Examples
PgpEncryptedDataGenerator encGen = new PgpEncryptedDataGenerator(
SymmetricKeyAlgorithmTag.Cast5, withIntegrityCheck, new SecureRandom());
- encGen.AddMethod(passPhrase);
+ encGen.AddMethod(passPhrase, HashAlgorithmTag.Sha1);
Stream encOut = encGen.Open(outputStream, compressedData.Length);
diff --git a/crypto/test/src/openpgp/test/PGPPBETest.cs b/crypto/test/src/openpgp/test/PGPPBETest.cs
index 621cef684..29b786a83 100644
--- a/crypto/test/src/openpgp/test/PGPPBETest.cs
+++ b/crypto/test/src/openpgp/test/PGPPBETest.cs
@@ -168,7 +168,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
PgpEncryptedDataGenerator cPk = new PgpEncryptedDataGenerator(
SymmetricKeyAlgorithmTag.Cast5, new SecureRandom());
- cPk.AddMethod(pass);
+ cPk.AddMethod(pass, HashAlgorithmTag.Sha1);
byte[] bOutData = bOut.ToArray();
Stream cOut = cPk.Open(new UncloseableStream(cbOut), bOutData.Length);
@@ -188,7 +188,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
cPk = new PgpEncryptedDataGenerator(
SymmetricKeyAlgorithmTag.Cast5, new SecureRandom());
- cPk.AddMethod(pass);
+ cPk.AddMethod(pass, HashAlgorithmTag.Sha1);
bOutData = bOut.ToArray();
cOut = cPk.Open(new UncloseableStream(cbOut), bOutData.Length);
@@ -233,7 +233,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
cPk = new PgpEncryptedDataGenerator(
SymmetricKeyAlgorithmTag.Cast5, rand);
- cPk.AddMethod(pass);
+ cPk.AddMethod(pass, HashAlgorithmTag.Sha1);
cOut = cPk.Open(new UncloseableStream(cbOut), new byte[16]);
{
@@ -256,7 +256,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
cPk = new PgpEncryptedDataGenerator(
SymmetricKeyAlgorithmTag.Cast5, true, rand);
- cPk.AddMethod(pass);
+ cPk.AddMethod(pass, HashAlgorithmTag.Sha1);
cOut = cPk.Open(new UncloseableStream(cbOut), new byte[16]);
bOutData = bOut.ToArray();
@@ -328,7 +328,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
cbOut = new MemoryStream();
cPk = new PgpEncryptedDataGenerator(SymmetricKeyAlgorithmTag.Cast5, true, rand);
- cPk.AddMethod(pass);
+ cPk.AddMethod(pass, HashAlgorithmTag.Sha1);
cOut = cPk.Open(new UncloseableStream(cbOut), new byte[16]);
diff --git a/crypto/test/src/openpgp/test/PGPRSATest.cs b/crypto/test/src/openpgp/test/PGPRSATest.cs
index 35f844483..82b569bbb 100644
--- a/crypto/test/src/openpgp/test/PGPRSATest.cs
+++ b/crypto/test/src/openpgp/test/PGPRSATest.cs
@@ -381,7 +381,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
encGen.AddMethod(pgpPubKey);
- encGen.AddMethod("password".ToCharArray());
+ encGen.AddMethod("password".ToCharArray(), HashAlgorithmTag.Sha1);
Stream cOut = encGen.Open(bcOut, bytes.Length);
diff --git a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
index 9896c1ef6..43aef5afa 100644
--- a/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
+++ b/crypto/test/src/openpgp/test/PgpKeyRingTest.cs
@@ -1844,7 +1844,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
PgpKeyPair elgKeyPair = new PgpKeyPair(PublicKeyAlgorithmTag.ElGamalEncrypt, elgKp, DateTime.UtcNow);
PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification, dsaKeyPair,
- "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, null, null, new SecureRandom());
+ "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, false, null, null, new SecureRandom());
keyRingGen.AddSubKey(elgKeyPair);
@@ -1904,12 +1904,12 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
PgpKeyPair rsaKeyPair2 = new PgpKeyPair(PublicKeyAlgorithmTag.RsaGeneral, rsaKp, DateTime.UtcNow);
PgpKeyRingGenerator keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification,
- rsaKeyPair1, "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, null, null, random);
+ rsaKeyPair1, "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, false, null, null, random);
PgpSecretKeyRing secRing1 = keyRingGen.GenerateSecretKeyRing();
PgpPublicKeyRing pubRing1 = keyRingGen.GeneratePublicKeyRing();
keyRingGen = new PgpKeyRingGenerator(PgpSignature.PositiveCertification,
- rsaKeyPair2, "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, null, null, random);
+ rsaKeyPair2, "test", SymmetricKeyAlgorithmTag.Aes256, passPhrase, false, null, null, random);
PgpSecretKeyRing secRing2 = keyRingGen.GenerateSecretKeyRing();
PgpPublicKeyRing pubRing2 = keyRingGen.GeneratePublicKeyRing();
diff --git a/crypto/test/src/openpgp/test/PgpUnicodeTest.cs b/crypto/test/src/openpgp/test/PgpUnicodeTest.cs
index ce1df8980..534e8a471 100644
--- a/crypto/test/src/openpgp/test/PgpUnicodeTest.cs
+++ b/crypto/test/src/openpgp/test/PgpUnicodeTest.cs
@@ -13,7 +13,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
[TestFixture]
public class PgpUnicodeTest
{
- private void DoTestKey(BigInteger keyId, string passphrase)
+ private void DoTestKey(BigInteger keyId, string passphrase, bool utf8)
{
PgpSecretKeyRingBundle secretKeyRing = LoadSecretKeyCollection("secring.gpg");
@@ -25,7 +25,11 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
try
{
- PgpPrivateKey privateKey = key.ExtractPrivateKey(passphrase.ToCharArray());
+ char[] pass = passphrase.ToCharArray();
+
+ PgpPrivateKey privateKey = utf8
+ ? key.ExtractPrivateKeyUtf8(pass)
+ : key.ExtractPrivateKey(pass);
Assert.IsTrue(privateKey.KeyId == keyId.LongValue);
}
@@ -53,7 +57,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
// passwordFile.close();
// String passphrase = new String(password);
- DoTestKey(keyId, passphrase);
+ DoTestKey(keyId, passphrase, true);
// all fine!
@@ -75,7 +79,8 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
string passphrase = "Admin123";
- DoTestKey(keyId, passphrase);
+ DoTestKey(keyId, passphrase, false);
+ DoTestKey(keyId, passphrase, true);
// all fine!
}
@@ -102,7 +107,7 @@ namespace Org.BouncyCastle.Bcpg.OpenPgp.Tests
string passphrase = reader.ReadLine();
passwordFile.Close();
- DoTestKey(keyId, passphrase);
+ DoTestKey(keyId, passphrase, true);
// all fine!
}
|