diff --git a/crypto/src/crypto/agreement/jpake/JPakeParticipant.cs b/crypto/src/crypto/agreement/jpake/JPakeParticipant.cs
index d6ed37032..5613c35cb 100755
--- a/crypto/src/crypto/agreement/jpake/JPakeParticipant.cs
+++ b/crypto/src/crypto/agreement/jpake/JPakeParticipant.cs
@@ -278,7 +278,7 @@ namespace Org.BouncyCastle.Crypto.Agreement.JPake
throw new InvalidOperationException("Round 1 payload must be validated prior to creating round 2 payload for " + this.participantId);
BigInteger gA = JPakeUtilities.CalculateGA(p, gx1, gx3, gx4);
- BigInteger s = JPakeUtilities.CalculateS(password);
+ BigInteger s = JPakeUtilities.CalculateS(q, password);
BigInteger x2s = JPakeUtilities.CalculateX2s(q, x2, s);
BigInteger A = JPakeUtilities.CalculateA(p, q, gA, x2s);
BigInteger[] knowledgeProofForX2s = JPakeUtilities.CalculateZeroKnowledgeProof(p, q, gA, A, x2s, participantId, digest, random);
@@ -352,7 +352,7 @@ namespace Org.BouncyCastle.Crypto.Agreement.JPake
if (this.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);
+ BigInteger s = JPakeUtilities.CalculateS(q, password);
// Clear the password array from memory, since we don't need it anymore.
// Also set the field to null as a flag to indicate that the key has already been calculated.
diff --git a/crypto/src/crypto/agreement/jpake/JPakeUtilities.cs b/crypto/src/crypto/agreement/jpake/JPakeUtilities.cs
index b23518a8c..51a1ca61c 100644
--- a/crypto/src/crypto/agreement/jpake/JPakeUtilities.cs
+++ b/crypto/src/crypto/agreement/jpake/JPakeUtilities.cs
@@ -1,7 +1,5 @@
using System;
-using System.Text;
-using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Macs;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Crypto.Utilities;
@@ -51,11 +49,35 @@ namespace Org.BouncyCastle.Crypto.Agreement.JPake
/// Converts the given password to a BigInteger
/// for use in arithmetic calculations.
/// </summary>
+ [Obsolete("Use version including the modulus instead")]
public static BigInteger CalculateS(char[] password)
{
- return new BigInteger(Encoding.UTF8.GetBytes(password));
+ return new BigInteger(1, Strings.ToUtf8ByteArray(password));
}
+ /// <summary>Converts the given password to a BigInteger mod q.</summary>
+ public static BigInteger CalculateS(BigInteger q, byte[] password)
+ {
+ BigInteger s = new BigInteger(1, password).Mod(q);
+ if (s.SignValue == 0)
+ throw new CryptoException("MUST ensure s is not equal to 0 modulo q");
+ return s;
+ }
+
+ /// <summary>Converts the given password (UTF8 encoded) to a BigInteger mod q.</summary>
+ public static BigInteger CalculateS(BigInteger q, char[] password)
+ {
+ return CalculateS(q, Strings.ToUtf8ByteArray(password));
+ }
+
+#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER
+ /// <summary>Converts the given password (UTF8 encoded) to a BigInteger mod q.</summary>
+ public static BigInteger CalculateS(BigInteger q, ReadOnlySpan<char> password)
+ {
+ return CalculateS(q, Strings.ToUtf8ByteArray(password));
+ }
+#endif
+
/// <summary>
/// Calculate g^x mod p as done in round 1.
/// </summary>
@@ -340,7 +362,7 @@ namespace Org.BouncyCastle.Crypto.Agreement.JPake
private static void UpdateDigest(IDigest digest, string str)
{
- UpdateDigest(digest, Encoding.UTF8.GetBytes(str));
+ UpdateDigest(digest, Strings.ToUtf8ByteArray(str));
}
private static void UpdateDigest(IDigest digest, byte[] bytes)
@@ -356,7 +378,7 @@ namespace Org.BouncyCastle.Crypto.Agreement.JPake
private static void UpdateDigestIncludingSize(IDigest digest, string str)
{
- UpdateDigestIncludingSize(digest, Encoding.UTF8.GetBytes(str));
+ UpdateDigestIncludingSize(digest, Strings.ToUtf8ByteArray(str));
}
private static void UpdateDigestIncludingSize(IDigest digest, byte[] bytes)
@@ -373,7 +395,7 @@ namespace Org.BouncyCastle.Crypto.Agreement.JPake
private static void UpdateMac(IMac mac, string str)
{
- UpdateMac(mac, Encoding.UTF8.GetBytes(str));
+ UpdateMac(mac, Strings.ToUtf8ByteArray(str));
}
private static void UpdateMac(IMac mac, byte[] bytes)
diff --git a/crypto/test/src/crypto/agreement/test/JPakeUtilitiesTest.cs b/crypto/test/src/crypto/agreement/test/JPakeUtilitiesTest.cs
index b3fabcfbb..b6011526d 100644
--- a/crypto/test/src/crypto/agreement/test/JPakeUtilitiesTest.cs
+++ b/crypto/test/src/crypto/agreement/test/JPakeUtilitiesTest.cs
@@ -124,7 +124,7 @@ namespace Org.BouncyCastle.Crypto.Agreement.Tests
BigInteger gB = JPakeUtilities.CalculateGA(pg1.P, gx3, gx1, gx2);
- BigInteger s = JPakeUtilities.CalculateS("password".ToCharArray());
+ BigInteger s = JPakeUtilities.CalculateS(pg1.Q, "password".ToCharArray());
BigInteger xs = JPakeUtilities.CalculateX2s(pg1.Q, x4, s);
|