diff --git a/crypto/src/crypto/agreement/jpake/JPAKEParticipant.cs b/crypto/src/crypto/agreement/jpake/JPAKEParticipant.cs
index f36069262..bd18765b4 100755
--- a/crypto/src/crypto/agreement/jpake/JPAKEParticipant.cs
+++ b/crypto/src/crypto/agreement/jpake/JPAKEParticipant.cs
@@ -5,62 +5,57 @@ using Org.BouncyCastle.Crypto.Digests;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Security;
-/**
- * A participant in a Password Authenticated Key Exchange by Juggling (J-PAKE) exchange.
- * <p>
- * The J-PAKE exchange is defined by Feng Hao and Peter Ryan in the paper
- * <a href="http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf">
- * "Password Authenticated Key Exchange by Juggling, 2008."</a>
- * <p>
- * The J-PAKE protocol is symmetric.
- * There is no notion of a <i>client</i> or <i>server</i>, but rather just two <i>participants</i>.
- * An instance of {@link JPAKEParticipant} represents one participant, and
- * is the primary interface for executing the exchange.
- * <p>
- * To execute an exchange, construct a {@link JPAKEParticipant} on each end,
- * and call the following 7 methods
- * (once and only once, in the given order, for each participant, sending messages between them as described):
- * <ol>
- * <li>{@link #createRound1PayloadToSend()} - and send the payload to the other participant</li>
- * <li>{@link #validateRound1PayloadReceived(JPAKERound1Payload)} - use the payload received from the other participant</li>
- * <li>{@link #createRound2PayloadToSend()} - and send the payload to the other participant</li>
- * <li>{@link #validateRound2PayloadReceived(JPAKERound2Payload)} - use the payload received from the other participant</li>
- * <li>{@link #calculateKeyingMaterial()}</li>
- * <li>{@link #createRound3PayloadToSend(BigInteger)} - and send the payload to the other participant</li>
- * <li>{@link #validateRound3PayloadReceived(JPAKERound3Payload, BigInteger)} - use the payload received from the other participant</li>
- * </ol>
- * <p>
- * Each side should derive a session key from the keying material returned by {@link #calculateKeyingMaterial()}.
- * The caller is responsible for deriving the session key using a secure key derivation function (KDF).
- * <p>
- * Round 3 is an optional key confirmation process.
- * If you do not execute round 3, then there is no assurance that both participants are using the same key.
- * (i.e. if the participants used different passwords, then their session keys will differ.)
- * <p>
- * If the round 3 validation succeeds, then the keys are guaranteed to be the same on both sides.
- * <p>
- * The symmetric design can easily support the asymmetric cases when one party initiates the communication.
- * e.g. Sometimes the round1 payload and round2 payload may be sent in one pass.
- * Also, in some cases, the key confirmation payload can be sent together with the round2 payload.
- * These are the trivial techniques to optimize the communication.
- * <p>
- * The key confirmation process is implemented as specified in
- * <a href="http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf">NIST SP 800-56A Revision 1</a>,
- * Section 8.2 Unilateral Key Confirmation for Key Agreement Schemes.
- * <p>
- * This class is stateful and NOT threadsafe.
- * Each instance should only be used for ONE complete J-PAKE exchange
- * (i.e. a new {@link JPAKEParticipant} should be constructed for each new J-PAKE exchange).
- * <p>
- */
namespace Org.BouncyCastle.Crypto.Agreement.Jpake
{
+ /// <summary>
+ /// A participant in a Password Authenticated Key Exchange by Juggling (J-PAKE) exchange.
+ ///
+ /// The J-PAKE exchange is defined by Feng Hao and Peter Ryan in the paper
+ /// <a href="http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf">
+ /// "Password Authenticated Key Exchange by Juggling, 2008."</a>
+ ///
+ /// The J-PAKE protocol is symmetric.
+ /// There is no notion of a <i>client</i> or <i>server</i>, but rather just two <i>participants</i>.
+ /// An instance of JPAKEParticipant represents one participant, and
+ /// is the primary interface for executing the exchange.
+ ///
+ /// To execute an exchange, construct a JPAKEParticipant on each end,
+ /// and call the following 7 methods
+ /// (once and only once, in the given order, for each participant, sending messages between them as described):
+ ///
+ /// CreateRound1PayloadToSend() - and send the payload to the other participant
+ /// ValidateRound1PayloadReceived(JPAKERound1Payload) - use the payload received from the other participant
+ /// CreateRound2PayloadToSend() - and send the payload to the other participant
+ /// ValidateRound2PayloadReceived(JPAKERound2Payload) - use the payload received from the other participant
+ /// CalculateKeyingMaterial()
+ /// CreateRound3PayloadToSend(BigInteger) - and send the payload to the other participant
+ /// ValidateRound3PayloadReceived(JPAKERound3Payload, BigInteger) - use the payload received from the other participant
+ ///
+ /// Each side should derive a session key from the keying material returned by CalculateKeyingMaterial().
+ /// The caller is responsible for deriving the session key using a secure key derivation function (KDF).
+ ///
+ /// Round 3 is an optional key confirmation process.
+ /// If you do not execute round 3, then there is no assurance that both participants are using the same key.
+ /// (i.e. if the participants used different passwords, then their session keys will differ.)
+ ///
+ /// If the round 3 validation succeeds, then the keys are guaranteed to be the same on both sides.
+ ///
+ /// The symmetric design can easily support the asymmetric cases when one party initiates the communication.
+ /// e.g. Sometimes the round1 payload and round2 payload may be sent in one pass.
+ /// Also, in some cases, the key confirmation payload can be sent together with the round2 payload.
+ /// These are the trivial techniques to optimize the communication.
+ ///
+ /// The key confirmation process is implemented as specified in
+ /// <a href="http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf">NIST SP 800-56A Revision 1</a>,
+ /// Section 8.2 Unilateral Key Confirmation for Key Agreement Schemes.
+ ///
+ /// This class is stateful and NOT threadsafe.
+ /// Each instance should only be used for ONE complete J-PAKE exchange
+ /// (i.e. a new JPAKEParticipant should be constructed for each new J-PAKE exchange).
+ /// </summary>
public class JPAKEParticipant
{
- /*
- * Possible internal states. Used for state checking.
- */
-
+ // Possible internal states. Used for state checking.
public static readonly int STATE_INITIALIZED = 0;
public static readonly int STATE_ROUND_1_CREATED = 10;
public static readonly int STATE_ROUND_1_VALIDATED = 20;
@@ -70,131 +65,103 @@ namespace Org.BouncyCastle.Crypto.Agreement.Jpake
public static readonly int STATE_ROUND_3_CREATED = 60;
public static readonly int STATE_ROUND_3_VALIDATED = 70;
- /**
- * Unique identifier of this participant.
- * The two participants in the exchange must NOT share the same id.
- */
+ // Unique identifier of this participant.
+ // The two participants in the exchange must NOT share the same id.
private string participantId;
- /**
- * Shared secret. This only contains the secret between construction
- * and the call to {@link #calculateKeyingMaterial()}.
- * <p>
- * i.e. When {@link #calculateKeyingMaterial()} is called, this buffer overwritten with 0's,
- * and the field is set to null.
- * </p>
- */
+ // Shared secret. This only contains the secret between construction
+ // and the call to CalculateKeyingMaterial().
+ //
+ // i.e. When CalculateKeyingMaterial() is called, this buffer overwritten with 0's,
+ // and the field is set to null.
private char[] password;
- /**
- * Digest to use during calculations.
- */
+ // Digest to use during calculations.
private IDigest digest;
- /**
- * Source of secure random data.
- */
+ // Source of secure random data.
private readonly SecureRandom random;
private readonly BigInteger p;
private readonly BigInteger q;
private readonly BigInteger g;
- /**
- * The participantId of the other participant in this exchange.
- */
+ // The participantId of the other participant in this exchange.
private string partnerParticipantId;
- /**
- * Alice's x1 or Bob's x3.
- */
+ // Alice's x1 or Bob's x3.
private BigInteger x1;
- /**
- * Alice's x2 or Bob's x4.
- */
+ // Alice's x2 or Bob's x4.
private BigInteger x2;
- /**
- * Alice's g^x1 or Bob's g^x3.
- */
+ // Alice's g^x1 or Bob's g^x3.
private BigInteger gx1;
- /**
- * Alice's g^x2 or Bob's g^x4.
- */
+ // Alice's g^x2 or Bob's g^x4.
private BigInteger gx2;
- /**
- * Alice's g^x3 or Bob's g^x1.
- */
+ // Alice's g^x3 or Bob's g^x1.
private BigInteger gx3;
- /**
- * Alice's g^x4 or Bob's g^x2.
- */
+ // Alice's g^x4 or Bob's g^x2.
private BigInteger gx4;
- /**
- * Alice's B or Bob's A.
- */
+ // Alice's B or Bob's A.
private BigInteger b;
- /**
- * The current state.
- * See the <tt>STATE_*</tt> constants for possible values.
- */
+ // The current state.
+ // See the <tt>STATE_*</tt> constants for possible values.
private int state;
- /**
- * Convenience constructor for a new {@link JPAKEParticipant} that uses
- * the {@link JPAKEPrimeOrderGroups#NIST_3072} prime order group,
- * a SHA-256 digest, and a default {@link SecureRandom} implementation.
- * <p>
- * After construction, the {@link #getState() state} will be {@link #STATE_INITIALIZED}.
- *
- * @param participantId unique identifier of this participant.
- * The two participants in the exchange must NOT share the same id.
- * @param password shared secret.
- * A defensive copy of this array is made (and cleared once {@link #calculateKeyingMaterial()} is called).
- * Caller should clear the input password as soon as possible.
- * @throws NullReferenceException if any argument is null
- * @throws ArgumentException if password is empty
- */
+ /// Convenience constructor for a new JPAKEParticipant that uses
+ /// the JPAKEPrimeOrderGroups#NIST_3072 prime order group,
+ /// a SHA-256 digest, and a default SecureRandom implementation.
+ ///
+ /// After construction, the State state will be STATE_INITIALIZED.
+ ///
+ /// Throws NullReferenceException if any argument is null. Throws
+ /// ArgumentException if password is empty.
+ /// </summary>
+ /// <param name="participantId">Unique identifier of this participant.
+ /// The two participants in the exchange must NOT share the same id.</param>
+ /// <param name="password">Shared secret.
+ /// A defensive copy of this array is made (and cleared once CalculateKeyingMaterial() is called).
+ /// Caller should clear the input password as soon as possible.</param>
public JPAKEParticipant(string participantId, char[] password)
: this(participantId, password, JPAKEPrimeOrderGroups.NIST_3072) { }
- /**
- * Convenience constructor for a new {@link JPAKEParticipant} that uses
- * a SHA-256 digest and a default {@link SecureRandom} implementation.
- * <p>
- * After construction, the {@link #getState() state} will be {@link #STATE_INITIALIZED}.
- *
- * @param participantId unique identifier of this participant.
- * The two participants in the exchange must NOT share the same id.
- * @param password shared secret.
- * A defensive copy of this array is made (and cleared once {@link #calculateKeyingMaterial()} is called).
- * Caller should clear the input password as soon as possible.
- * @param group prime order group.
- * See {@link JPAKEPrimeOrderGroups} for standard groups
- * @throws NullReferenceException if any argument is null
- * @throws ArgumentException if password is empty
- */
+ /// Convenience constructor for a new JPAKEParticipant that uses
+ /// the JPAKEPrimeOrderGroups#NIST_3072 prime order group,
+ /// a SHA-256 digest, and a default SecureRandom implementation.
+ ///
+ /// After construction, the State state will be STATE_INITIALIZED.
+ ///
+ /// Throws NullReferenceException if any argument is null. Throws
+ /// ArgumentException if password is empty.
+ /// </summary>
+ /// <param name="participantId">Unique identifier of this participant.
+ /// The two participants in the exchange must NOT share the same id.</param>
+ /// <param name="password">Shared secret.
+ /// A defensive copy of this array is made (and cleared once CalculateKeyingMaterial() is called).
+ /// Caller should clear the input password as soon as possible.</param>
+ /// <param name="group">Prime order group. See JPAKEPrimeOrderGroups for standard groups.</param>
public JPAKEParticipant(string participantId, char[] password, JPAKEPrimeOrderGroup group)
: this(participantId, password, group, new Sha256Digest(), new SecureRandom()) { }
- /**
- * Construct a new {@link JPAKEParticipant}.
- * <p>
- * After construction, the {@link #getState() state} will be {@link #STATE_INITIALIZED}.
- *
- * @param participantId unique identifier of this participant.
- * The two participants in the exchange must NOT share the same id.
- * @param password shared secret.
- * A defensive copy of this array is made (and cleared once {@link #calculateKeyingMaterial()} is called).
- * Caller should clear the input password as soon as possible.
- * @param group prime order group.
- * See {@link JPAKEPrimeOrderGroups} for standard groups
- * @param digest digest to use during zero knowledge proofs and key confirmation (SHA-256 or stronger preferred)
- * @param random source of secure random data for x1 and x2, and for the zero knowledge proofs
- * @throws NullReferenceException if any argument is null
- * @throws IllegalArgumentException if password is empty
- */
+ /// Convenience constructor for a new JPAKEParticipant that uses
+ /// the JPAKEPrimeOrderGroups#NIST_3072 prime order group,
+ /// a SHA-256 digest, and a default SecureRandom implementation.
+ ///
+ /// After construction, the State state will be STATE_INITIALIZED.
+ ///
+ /// Throws NullReferenceException if any argument is null. Throws
+ /// ArgumentException if password is empty.
+ /// </summary>
+ /// <param name="participantId">Unique identifier of this participant.
+ /// The two participants in the exchange must NOT share the same id.</param>
+ /// <param name="password">Shared secret.
+ /// A defensive copy of this array is made (and cleared once CalculateKeyingMaterial() is called).
+ /// Caller should clear the input password as soon as possible.</param>
+ /// <param name="group">Prime order group. See JPAKEPrimeOrderGroups for standard groups.</param>
+ /// <param name="digest">Digest to use during zero knowledge proofs and key confirmation
+ /// (SHA-256 or stronger preferred).</param>
+ /// <param name="random">Source of secure random data for x1 and x2, and for the zero knowledge proofs.</param>
public JPAKEParticipant(string participantId, char[] password, JPAKEPrimeOrderGroup group, IDigest digest, SecureRandom random)
{
JPAKEUtil.ValidateNotNull(participantId, "participantId");
@@ -210,18 +177,16 @@ namespace Org.BouncyCastle.Crypto.Agreement.Jpake
this.participantId = participantId;
- /*
- * Create a defensive copy so as to fully encapsulate the password.
- *
- * This array will contain the password for the lifetime of this
- * participant BEFORE {@link #calculateKeyingMaterial()} is called.
- *
- * i.e. When {@link #calculateKeyingMaterial()} is called, the array will be cleared
- * in order to remove the password from memory.
- *
- * The caller is responsible for clearing the original password array
- * given as input to this constructor.
- */
+ // Create a defensive copy so as to fully encapsulate the password.
+ //
+ // This array will contain the password for the lifetime of this
+ // participant BEFORE CalculateKeyingMaterial() is called.
+ //
+ // i.e. When CalculateKeyingMaterial() is called, the array will be cleared
+ // in order to remove the password from memory.
+ //
+ // The caller is responsible for clearing the original password array
+ // given as input to this constructor.
this.password = new char[password.Length];
Array.Copy(password, this.password, password.Length);
@@ -235,21 +200,21 @@ namespace Org.BouncyCastle.Crypto.Agreement.Jpake
this.state = STATE_INITIALIZED;
}
- /**
- * Gets the current state of this participant.
- * See the <tt>STATE_*</tt> constants for possible values.
- */
+ /// <summary>
+ /// Gets the current state of this participant.
+ /// See the <tt>STATE_*</tt> constants for possible values.
+ /// </summary>
public int State
{
get { return state; }
}
- /**
- * Creates and returns the payload to send to the other participant during round 1.
- * <p>
- * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_CREATED}.
- */
+ /// <summary>
+ /// Creates and returns the payload to send to the other participant during round 1.
+ ///
+ /// After execution, the State state} will be STATE_ROUND_1_CREATED}.
+ /// </summary>
public JPAKERound1Payload CreateRound1PayloadToSend()
{
if (this.state >= STATE_ROUND_1_CREATED)
@@ -270,16 +235,15 @@ namespace Org.BouncyCastle.Crypto.Agreement.Jpake
return new JPAKERound1Payload(participantId, gx1, gx2, knowledgeProofForX1, knowledgeProofForX2);
}
- /**
- * Validates the payload received from the other participant during round 1.
- * <p>
- * Must be called prior to {@link #createRound2PayloadToSend()}.
- * <p>
- * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_1_VALIDATED}.
- *
- * @throws CryptoException if validation fails.
- * @throws InvalidOperationException if called multiple times.
- */
+ /// <summary>
+ /// Validates the payload received from the other participant during round 1.
+ ///
+ /// Must be called prior to CreateRound2PayloadToSend().
+ ///
+ /// After execution, the State state will be STATE_ROUND_1_VALIDATED.
+ /// Throws CryptoException if validation fails. Throws InvalidOperationException
+ /// if called multiple times.
+ /// </summary>
public void ValidateRound1PayloadReceived(JPAKERound1Payload round1PayloadReceived)
{
if (this.state >= STATE_ROUND_1_VALIDATED)
@@ -297,20 +261,19 @@ namespace Org.BouncyCastle.Crypto.Agreement.Jpake
JPAKEUtil.ValidateParticipantIdsDiffer(participantId, round1PayloadReceived.ParticipantId);
JPAKEUtil.ValidateGx4(gx4);
JPAKEUtil.ValidateZeroKnowledgeProof(p, q, g, gx3, knowledgeProofForX3, round1PayloadReceived.ParticipantId, digest);
- JPAKEUtil.ValidateZeroKnowledgeProof(p, q, g, gx4, knowledgeProofForX4, round1PayloadReceived.ParticipantId, digest);
-
+ JPAKEUtil.ValidateZeroKnowledgeProof(p, q, g, gx4, knowledgeProofForX4, round1PayloadReceived.ParticipantId, digest);
this.state = STATE_ROUND_1_VALIDATED;
}
- /**
- * Creates and returns the payload to send to the other participant during round 2.
- * <p>
- * {@link #validateRound1PayloadReceived(JPAKERound1Payload)} must be called prior to this method.
- * <p>
- * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_2_CREATED}.
- *
- * @throws InvalidOperationException if called prior to {@link #validateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times
- */
+ /// <summary>
+ /// Creates and returns the payload to send to the other participant during round 2.
+ ///
+ /// ValidateRound1PayloadReceived(JPAKERound1Payload)} must be called prior to this method.
+ ///
+ //// After execution, the State state will be STATE_ROUND_2_CREATED.
+ ///
+ /// Throws InvalidOperationException if called prior to ValidateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times
+ /// </summary>
public JPAKERound2Payload CreateRound2PayloadToSend()
{
if (this.state >= STATE_ROUND_2_CREATED)
@@ -333,20 +296,19 @@ namespace Org.BouncyCastle.Crypto.Agreement.Jpake
return new JPAKERound2Payload(participantId, A, knowledgeProofForX2s);
}
- /**
- * Validates the payload received from the other participant during round 2.
- * <p>
- * Note that this DOES NOT detect a non-common password.
- * The only indication of a non-common password is through derivation
- * of different keys (which can be detected explicitly by executing round 3 and round 4)
- * <p>
- * Must be called prior to {@link #calculateKeyingMaterial()}.
- * <p>
- * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_2_VALIDATED}.
- *
- * @throws CryptoException if validation fails.
- * @throws InvalidOperationException if called prior to {@link #validateRound1PayloadReceived(JPAKERound1Payload)}, or multiple times
- */
+ /// <summary>
+ /// Validates the payload received from the other participant during round 2.
+ /// Note that this DOES NOT detect a non-common password.
+ /// The only indication of a non-common password is through derivation
+ /// of different keys (which can be detected explicitly by executing round 3 and round 4)
+ ///
+ /// Must be called prior to CalculateKeyingMaterial().
+ ///
+ /// After execution, the State state will be STATE_ROUND_2_VALIDATED.
+ ///
+ /// Throws CryptoException if validation fails. Throws
+ /// InvalidOperationException if called prior to ValidateRound1PayloadReceived(JPAKERound1Payload), or multiple times
+ /// </summary>
public void ValidateRound2PayloadReceived(JPAKERound2Payload round2PayloadReceived)
{
if (this.state >= STATE_ROUND_2_VALIDATED)
@@ -370,31 +332,31 @@ namespace Org.BouncyCastle.Crypto.Agreement.Jpake
this.state = STATE_ROUND_2_VALIDATED;
}
- /**
- * Calculates and returns the key material.
- * A session key must be derived from this key material using a secure key derivation function (KDF).
- * The KDF used to derive the key is handled externally (i.e. not by {@link JPAKEParticipant}).
- * <p>
- * The keying material will be identical for each participant if and only if
- * each participant's password is the same. i.e. If the participants do not
- * share the same password, then each participant will derive a different key.
- * Therefore, if you immediately start using a key derived from
- * the keying material, then you must handle detection of incorrect keys.
- * If you want to handle this detection explicitly, you can optionally perform
- * rounds 3 and 4. See {@link JPAKEParticipant} for details on how to execute
- * rounds 3 and 4.
- * <p>
- * The keying material will be in the range <tt>[0, p-1]</tt>.
- * <p>
- * {@link #validateRound2PayloadReceived(JPAKERound2Payload)} must be called prior to this method.
- * <p>
- * As a side effect, the internal {@link #password} array is cleared, since it is no longer needed.
- * <p>
- * After execution, the {@link #getState() state} will be {@link #STATE_KEY_CALCULATED}.
- *
- * @throws InvalidOperationException if called prior to {@link #validateRound2PayloadReceived(JPAKERound2Payload)},
- * or if called multiple times.
- */
+ /// <summary>
+ /// Calculates and returns the key material.
+ /// A session key must be derived from this key material using a secure key derivation function (KDF).
+ /// The KDF used to derive the key is handled externally (i.e. not by JPAKEParticipant).
+ ///
+ /// The keying material will be identical for each participant if and only if
+ /// each participant's password is the same. i.e. If the participants do not
+ /// share the same password, then each participant will derive a different key.
+ /// Therefore, if you immediately start using a key derived from
+ /// the keying material, then you must handle detection of incorrect keys.
+ /// If you want to handle this detection explicitly, you can optionally perform
+ /// rounds 3 and 4. See JPAKEParticipant for details on how to execute
+ /// rounds 3 and 4.
+ ///
+ /// The keying material will be in the range <tt>[0, p-1]</tt>.
+ ///
+ /// ValidateRound2PayloadReceived(JPAKERound2Payload) must be called prior to this method.
+ ///
+ /// As a side effect, the internal password array is cleared, since it is no longer needed.
+ ///
+ /// After execution, the State state will be STATE_KEY_CALCULATED.
+ ///
+ /// Throws InvalidOperationException if called prior to ValidateRound2PayloadReceived(JPAKERound2Payload),
+ /// or if called multiple times.
+ /// </summary>
public BigInteger CalculateKeyingMaterial()
{
if (this.state >= STATE_KEY_CALCULATED)
@@ -408,47 +370,40 @@ namespace Org.BouncyCastle.Crypto.Agreement.Jpake
BigInteger s = JPAKEUtil.CalculateS(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.
- */
+ // 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.
Array.Clear(password, 0, password.Length);
this.password = null;
BigInteger keyingMaterial = JPAKEUtil.CalculateKeyingMaterial(p, q, gx4, x2, s, b);
- /*
- * Clear the ephemeral private key fields as well.
- * Note that we're relying on the garbage collector to do its job to clean these up.
- * The old objects will hang around in memory until the garbage collector destroys them.
- *
- * If the ephemeral private keys x1 and x2 are leaked,
- * the attacker might be able to brute-force the password.
- */
+ // Clear the ephemeral private key fields as well.
+ // Note that we're relying on the garbage collector to do its job to clean these up.
+ // The old objects will hang around in memory until the garbage collector destroys them.
+ //
+ // If the ephemeral private keys x1 and x2 are leaked,
+ // the attacker might be able to brute-force the password.
this.x1 = null;
this.x2 = null;
this.b = null;
- /*
- * Do not clear gx* yet, since those are needed by round 3.
- */
+ // Do not clear gx* yet, since those are needed by round 3.
this.state = STATE_KEY_CALCULATED;
return keyingMaterial;
}
- /**
- * Creates and returns the payload to send to the other participant during round 3.
- * <p>
- * See {@link JPAKEParticipant} for more details on round 3.
- * <p>
- * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_3_CREATED}.
- *
- * @param keyingMaterial The keying material as returned from {@link #calculateKeyingMaterial()}.
- * @throws InvalidOperationException if called prior to {@link #calculateKeyingMaterial()}, or multiple times
- */
+ /// <summary>
+ /// Creates and returns the payload to send to the other participant during round 3.
+ ///
+ /// See JPAKEParticipant for more details on round 3.
+ ///
+ /// After execution, the State state} will be STATE_ROUND_3_CREATED.
+ /// Throws InvalidOperationException if called prior to CalculateKeyingMaterial, or multiple
+ /// times.
+ /// </summary>
+ /// <param name="keyingMaterial">The keying material as returned from CalculateKeyingMaterial().</param>
public JPAKERound3Payload CreateRound3PayloadToSend(BigInteger keyingMaterial)
{
if (this.state >= STATE_ROUND_3_CREATED)
@@ -475,17 +430,16 @@ namespace Org.BouncyCastle.Crypto.Agreement.Jpake
return new JPAKERound3Payload(participantId, macTag);
}
- /**
- * Validates the payload received from the other participant during round 3.
- * <p>
- * See {@link JPAKEParticipant} for more details on round 3.
- * <p>
- * After execution, the {@link #getState() state} will be {@link #STATE_ROUND_3_VALIDATED}.
- *
- * @param keyingMaterial The keying material as returned from {@link #calculateKeyingMaterial()}.
- * @throws CryptoException if validation fails.
- * @throws InvalidOperationException if called prior to {@link #calculateKeyingMaterial()}, or multiple times
- */
+ /// <summary>
+ /// Validates the payload received from the other participant during round 3.
+ ///
+ /// See JPAKEParticipant for more details on round 3.
+ ///
+ /// After execution, the State state will be STATE_ROUND_3_VALIDATED.
+ /// Throws CryptoException if validation fails. Throws InvalidOperationException if called prior to
+ /// CalculateKeyingMaterial or multiple times
+ /// </summary>
+ /// <param name="keyingMaterial">The keying material as returned from CalculateKeyingMaterial().</param>
public void ValidateRound3PayloadReceived(JPAKERound3Payload round3PayloadReceived, BigInteger keyingMaterial)
{
if (this.state >= STATE_ROUND_3_VALIDATED)
@@ -511,9 +465,7 @@ namespace Org.BouncyCastle.Crypto.Agreement.Jpake
this.digest,
round3PayloadReceived.MacTag);
- /*
- * Clear the rest of the fields.
- */
+ // Clear the rest of the fields.
this.gx1 = null;
this.gx2 = null;
this.gx3 = null;
diff --git a/crypto/src/crypto/agreement/jpake/JPAKEPrimeOrderGroup.cs b/crypto/src/crypto/agreement/jpake/JPAKEPrimeOrderGroup.cs
index 1b0c514bb..3a142f713 100755
--- a/crypto/src/crypto/agreement/jpake/JPAKEPrimeOrderGroup.cs
+++ b/crypto/src/crypto/agreement/jpake/JPAKEPrimeOrderGroup.cs
@@ -4,62 +4,59 @@ using Org.BouncyCastle.Math;
namespace Org.BouncyCastle.Crypto.Agreement.Jpake
{
- /**
- * A pre-computed prime order group for use during a J-PAKE exchange.
- * <p>
- * Typically a Schnorr group is used. In general, J-PAKE can use any prime order group
- * that is suitable for public key cryptography, including elliptic curve cryptography.
- * <p>
- * See {@link JPAKEPrimeOrderGroups} for convenient standard groups.
- * <p>
- * NIST <a href="http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/DSA2_All.pdf">publishes</a>
- * many groups that can be used for the desired level of security.
- */
+ /// <summary>
+ /// A pre-computed prime order group for use during a J-PAKE exchange.
+ ///
+ /// Typically a Schnorr group is used. In general, J-PAKE can use any prime order group
+ /// that is suitable for public key cryptography, including elliptic curve cryptography.
+ ///
+ /// See JPAKEPrimeOrderGroups for convenient standard groups.
+ ///
+ /// NIST <a href="http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/DSA2_All.pdf">publishes</a>
+ /// many groups that can be used for the desired level of security.
+ /// </summary>
public class JPAKEPrimeOrderGroup
{
private readonly BigInteger p;
private readonly BigInteger q;
private readonly BigInteger g;
- /**
- * Constructs a new {@link JPAKEPrimeOrderGroup}.
- * <p>
- * In general, you should use one of the pre-approved groups from
- * {@link JPAKEPrimeOrderGroups}, rather than manually constructing one.
- * <p>
- * The following basic checks are performed:
- * <ul>
- * <li>p-1 must be evenly divisible by q</li>
- * <li>g must be in [2, p-1]</li>
- * <li>g^q mod p must equal 1</li>
- * <li>p must be prime (within reasonably certainty)</li>
- * <li>q must be prime (within reasonably certainty)</li>
- * </ul>
- * <p>
- * The prime checks are performed using {@link BigInteger#isProbablePrime(int)},
- * and are therefore subject to the same probability guarantees.
- * <p>
- * These checks prevent trivial mistakes.
- * However, due to the small uncertainties if p and q are not prime,
- * advanced attacks are not prevented.
- * Use it at your own risk.
- *
- * @throws NullReferenceException if any argument is null
- * @throws InvalidOperationException if any of the above validations fail
- */
+ /// <summary>
+ /// Constructs a new JPAKEPrimeOrderGroup.
+ ///
+ /// In general, you should use one of the pre-approved groups from
+ /// JPAKEPrimeOrderGroups, rather than manually constructing one.
+ ///
+ /// The following basic checks are performed:
+ ///
+ /// p-1 must be evenly divisible by q
+ /// g must be in [2, p-1]
+ /// g^q mod p must equal 1
+ /// p must be prime (within reasonably certainty)
+ /// q must be prime (within reasonably certainty)
+ ///
+ /// The prime checks are performed using BigInteger#isProbablePrime(int),
+ /// and are therefore subject to the same probability guarantees.
+ ///
+ /// These checks prevent trivial mistakes.
+ /// However, due to the small uncertainties if p and q are not prime,
+ /// advanced attacks are not prevented.
+ /// Use it at your own risk.
+ ///
+ /// Throws NullReferenceException if any argument is null. Throws
+ /// InvalidOperationException is any of the above validations fail.
+ /// </summary>
public JPAKEPrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g)
: this(p, q, g, false)
{
- /*
- * Don't skip the checks on user-specified groups.
- */
+ // Don't skip the checks on user-specified groups.
}
- /**
- * Internal package-private constructor used by the pre-approved
- * groups in {@link JPAKEPrimeOrderGroups}.
- * These pre-approved groups can avoid the expensive checks.
- */
+ /// <summary>
+ /// Constructor used by the pre-approved groups in JPAKEPrimeOrderGroups.
+ /// These pre-approved groups can avoid the expensive checks.
+ /// User-specified groups should not use this constructor.
+ /// </summary>
public JPAKEPrimeOrderGroup(BigInteger p, BigInteger q, BigInteger g, bool skipChecks)
{
JPAKEUtil.ValidateNotNull(p, "p");
@@ -80,10 +77,8 @@ namespace Org.BouncyCastle.Crypto.Agreement.Jpake
{
throw new ArgumentException("g^q mod p must equal 1");
}
- /*
- * Note these checks do not guarantee that p and q are prime.
- * We just have reasonable certainty that they are prime.
- */
+ // Note these checks do not guarantee that p and q are prime.
+ // We just have reasonable certainty that they are prime.
if (!p.IsProbablePrime(20))
{
throw new ArgumentException("p must be prime");
|