From c65cc1b2d63eb623eafb702e4da4240d228380a8 Mon Sep 17 00:00:00 2001 From: Peter Dettman Date: Fri, 23 Dec 2022 12:08:08 +0700 Subject: JPAKE: Improved calculation of s --- .../src/crypto/agreement/jpake/JPakeParticipant.cs | 4 +-- .../src/crypto/agreement/jpake/JPakeUtilities.cs | 34 ++++++++++++++++++---- .../crypto/agreement/test/JPakeUtilitiesTest.cs | 2 +- 3 files changed, 31 insertions(+), 9 deletions(-) (limited to 'crypto') 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. /// + [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)); } + /// Converts the given password to a BigInteger mod q. + 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; + } + + /// Converts the given password (UTF8 encoded) to a BigInteger mod q. + public static BigInteger CalculateS(BigInteger q, char[] password) + { + return CalculateS(q, Strings.ToUtf8ByteArray(password)); + } + +#if NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER + /// Converts the given password (UTF8 encoded) to a BigInteger mod q. + public static BigInteger CalculateS(BigInteger q, ReadOnlySpan password) + { + return CalculateS(q, Strings.ToUtf8ByteArray(password)); + } +#endif + /// /// Calculate g^x mod p as done in round 1. /// @@ -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); -- cgit 1.4.1