Overview | Package | Class | Tree | Deprecated | Index | Help
| Bouncy Castle Cryptography Library 1.84
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD

## org.bouncycastle.crypto.agreement.ecjpake
Class ECJPAKEParticipant

    java.lang.Object
      org.bouncycastle.crypto.agreement.ecjpake.ECJPAKEParticipant

public class ECJPAKEParticipant
extends java.lang.Object

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 "J-PAKE: Authenticated Key Exchange Without PKI."

The J-PAKE protocol is symmetric. There is no notion of a client or server, but rather just two participants. An instance of `ECJPAKEParticipant` represents one participant, and is the primary interface for executing the exchange.

To execute an exchange, construct a `ECJPAKEParticipant` 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(ECJPAKERound1Payload)` - use the payload received from the other participant `createRound2PayloadToSend()` - and send the payload to the other participant `validateRound2PayloadReceived(ECJPAKERound2Payload)` - use the payload received from the other participant `calculateKeyingMaterial()` `createRound3PayloadToSend(BigInteger)` - and send the payload to the other participant `validateRound3PayloadReceived(ECJPAKERound3Payload, 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 NIST SP 800-56A Revision 3, Section 5.9.1 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 `ECJPAKEParticipant` should be constructed for each new J-PAKE exchange).

Field Summary
`static int` | `STATE_INITIALIZED`
`static int` | `STATE_KEY_CALCULATED`
`static int` | `STATE_ROUND_1_CREATED`
`static int` | `STATE_ROUND_1_VALIDATED`
`static int` | `STATE_ROUND_2_CREATED`
`static int` | `STATE_ROUND_2_VALIDATED`
`static int` | `STATE_ROUND_3_CREATED`
`static int` | `STATE_ROUND_3_VALIDATED`

Constructor Summary
`ECJPAKEParticipant(java.lang.String participantId, char[] password)` Convenience constructor for a new `ECJPAKEParticipant` that uses the `ECJPAKECurves.NIST_P256` elliptic curve, a SHA-256 digest, and a default `SecureRandom` implementation.
`ECJPAKEParticipant(java.lang.String participantId, char[] password, ECJPAKECurve curve)` Convenience constructor for a new `ECJPAKEParticipant` that uses a SHA-256 digest and a default `SecureRandom` implementation.
`ECJPAKEParticipant(java.lang.String participantId, char[] password, ECJPAKECurve curve, Digest digest, java.security.SecureRandom random)` Construct a new `ECJPAKEParticipant`.

Method Summary
`java.math.BigInteger` | `calculateKeyingMaterial()` Calculates and returns the key material.
`ECJPAKERound1Payload` | `createRound1PayloadToSend()` Creates and returns the payload to send to the other participant during round 1.
`ECJPAKERound2Payload` | `createRound2PayloadToSend()` Creates and returns the payload to send to the other participant during round 2.
`ECJPAKERound3Payload` | `createRound3PayloadToSend(java.math.BigInteger keyingMaterial)` Creates and returns the payload to send to the other participant during round 3.
`int` | `getState()` Gets the current state of this participant.
`void` | `validateRound1PayloadReceived(ECJPAKERound1Payload round1PayloadReceived)` Validates the payload received from the other participant during round 1.
`void` | `validateRound2PayloadReceived(ECJPAKERound2Payload round2PayloadReceived)` Validates the payload received from the other participant during round 2.
`void` | `validateRound3PayloadReceived(ECJPAKERound3Payload round3PayloadReceived, java.math.BigInteger keyingMaterial)` Validates the payload received from the other participant during round 3.

Methods inherited from class java.lang.Object
`clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

Field Detail

### STATE_INITIALIZED

    public static final int STATE_INITIALIZED

See Also:
  Constant Field Values

### STATE_ROUND_1_CREATED

    public static final int STATE_ROUND_1_CREATED

See Also:
  Constant Field Values

### STATE_ROUND_1_VALIDATED

    public static final int STATE_ROUND_1_VALIDATED

See Also:
  Constant Field Values

### STATE_ROUND_2_CREATED

    public static final int STATE_ROUND_2_CREATED

See Also:
  Constant Field Values

### STATE_ROUND_2_VALIDATED

    public static final int STATE_ROUND_2_VALIDATED

See Also:
  Constant Field Values

### STATE_KEY_CALCULATED

    public static final int STATE_KEY_CALCULATED

See Also:
  Constant Field Values

### STATE_ROUND_3_CREATED

    public static final int STATE_ROUND_3_CREATED

See Also:
  Constant Field Values

### STATE_ROUND_3_VALIDATED

    public static final int STATE_ROUND_3_VALIDATED

See Also:
  Constant Field Values

Constructor Detail

### ECJPAKEParticipant

    public ECJPAKEParticipant(java.lang.String participantId,
                              char[] password)

  Convenience constructor for a new `ECJPAKEParticipant` that uses the `ECJPAKECurves.NIST_P256` elliptic curve, a SHA-256 digest, and a default `SecureRandom` implementation.

  After construction, the `state` will be `STATE_INITIALIZED`.

Parameters:
  `participantId` - unique identifier of this participant. The two participants in the exchange must NOT share the same id.
  `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.
Throws:
  `java.lang.NullPointerException` - if any argument is null
  `java.lang.IllegalArgumentException` - if password is empty

### ECJPAKEParticipant

    public ECJPAKEParticipant(java.lang.String participantId,
                              char[] password,
                              ECJPAKECurve curve)

  Convenience constructor for a new `ECJPAKEParticipant` that uses a SHA-256 digest and a default `SecureRandom` implementation.

  After construction, the `state` will be `STATE_INITIALIZED`.

Parameters:
  `participantId` - unique identifier of this participant. The two participants in the exchange must NOT share the same id.
  `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.
  `curve` - elliptic curve See `ECJPAKECurves` for standard curves.
Throws:
  `java.lang.NullPointerException` - if any argument is null
  `java.lang.IllegalArgumentException` - if password is empty

### ECJPAKEParticipant

    public ECJPAKEParticipant(java.lang.String participantId,
                              char[] password,
                              ECJPAKECurve curve,
                              Digest digest,
                              java.security.SecureRandom random)

  Construct a new `ECJPAKEParticipant`.

  After construction, the `state` will be `STATE_INITIALIZED`.

Parameters:
  `participantId` - unique identifier of this participant. The two participants in the exchange must NOT share the same id.
  `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.
  `curve` - elliptic curve. See `ECJPAKECurves` for standard curves
  `digest` - digest to use during zero knowledge proofs and key confirmation (SHA-256 or stronger preferred)
  `random` - source of secure random data for x1 and x2, and for the zero knowledge proofs
Throws:
  `java.lang.NullPointerException` - if any argument is null
  `java.lang.IllegalArgumentException` - if password is empty

Method Detail

### getState

    public int getState()

  Gets the current state of this participant. See the STATE_* constants for possible values.

### createRound1PayloadToSend

    public ECJPAKERound1Payload createRound1PayloadToSend()

  Creates and returns the payload to send to the other participant during round 1.

  After execution, the `state` will be `STATE_ROUND_1_CREATED`.

### validateRound1PayloadReceived

    public void validateRound1PayloadReceived(ECJPAKERound1Payload round1PayloadReceived)
                                       throws CryptoException

  Validates the payload received from the other participant during round 1.

  Must be called prior to `createRound2PayloadToSend()`.

  After execution, the `state` will be `STATE_ROUND_1_VALIDATED`.

  Throws:
    `CryptoException` - if validation fails.
    `java.lang.IllegalStateException` - if called multiple times.

### createRound2PayloadToSend

    public ECJPAKERound2Payload createRound2PayloadToSend()

  Creates and returns the payload to send to the other participant during round 2.

  `validateRound1PayloadReceived(ECJPAKERound1Payload)` must be called prior to this method.

  After execution, the `state` will be `STATE_ROUND_2_CREATED`.

  Throws:
    `java.lang.IllegalStateException` - if called prior to `validateRound1PayloadReceived(ECJPAKERound1Payload)`, or multiple times

### validateRound2PayloadReceived

    public void validateRound2PayloadReceived(ECJPAKERound2Payload round2PayloadReceived)
                                       throws CryptoException

  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` will be `STATE_ROUND_2_VALIDATED`.

  Throws:
    `CryptoException` - if validation fails.
    `java.lang.IllegalStateException` - if called prior to `validateRound1PayloadReceived(ECJPAKERound1Payload)`, or multiple times

### calculateKeyingMaterial

    public java.math.BigInteger calculateKeyingMaterial()

  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 `ECJPAKEParticipant`).

  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 `ECJPAKEParticipant` for details on how to execute rounds 3 and 4.

  The keying material will be in the range [0, n-1].

  `validateRound2PayloadReceived(ECJPAKERound2Payload)` 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` will be `STATE_KEY_CALCULATED`.

  Throws:
    `java.lang.IllegalStateException` - if called prior to `validateRound2PayloadReceived(ECJPAKERound2Payload)`, or if called multiple times.

### createRound3PayloadToSend

    public ECJPAKERound3Payload createRound3PayloadToSend(java.math.BigInteger keyingMaterial)

  Creates and returns the payload to send to the other participant during round 3.

  See `ECJPAKEParticipant` for more details on round 3.

  After execution, the `state` will be `STATE_ROUND_3_CREATED`.

  Parameters:
    `keyingMaterial` - The keying material as returned from `calculateKeyingMaterial()`.
  Throws:
    `java.lang.IllegalStateException` - if called prior to `calculateKeyingMaterial()`, or multiple times

### validateRound3PayloadReceived

    public void validateRound3PayloadReceived(ECJPAKERound3Payload round3PayloadReceived,
                                              java.math.BigInteger keyingMaterial)
                                       throws CryptoException

  Validates the payload received from the other participant during round 3.

  See `ECJPAKEParticipant` for more details on round 3.

  After execution, the `state` will be `STATE_ROUND_3_VALIDATED`.

  Parameters:
    `round3PayloadReceived` - The round 3 payload received from the other participant.
    `keyingMaterial` - The keying material as returned from `calculateKeyingMaterial()`.
  Throws:
    `CryptoException` - if validation fails.
    `java.lang.IllegalStateException` - if called prior to `calculateKeyingMaterial()`, or multiple times

Overview | Package | Class | Tree | Deprecated | Index | Help
| Bouncy Castle Cryptography Library 1.84
PREV CLASS NEXT CLASS | FRAMES NO FRAMES
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD