Class SM9KeyExchange

java.lang.Object
org.bouncycastle.crypto.agreement.SM9KeyExchange

public class SM9KeyExchange extends Object
The SM9 key exchange protocol (GM/T 0044.3-2016).

Usage per party: construct with your own key-exchange private key (derived under the KGC's published hid), the peer's identity, and whether you are the initiator (user A) or responder (user B). Call generateEphemeral(SecureRandom) to produce your R value, exchange R values, then call calculateKey(int, ECPoint) with the peer's R to obtain the shared key. The optional key-confirmation tags are then available via getResponderConfirmation() (S_B) and getInitiatorConfirmation() (S_A).

  • Constructor Details

  • Method Details

    • generateEphemeral

      public ECPoint generateEphemeral(SecureRandom random)
      Generate this party's ephemeral value R = [r]Q_peer (a G1 point) and retain the ephemeral scalar r. Q_peer = [H1(peerIdentity||hid, N)]P1 + P_pub-e, using the hid this party's own key was derived under - both parties' keys come from the same KGC, which publishes the hid it chose.
    • calculateKey

      public byte[] calculateKey(int klenBits, ECPoint peerR)
      Compute the shared key of klenBits bits from the peer's ephemeral value peerR. Must be called after generateEphemeral(SecureRandom).
    • getResponderConfirmation

      public byte[] getResponderConfirmation()
      S_B = Hash(0x82 || g1 || Hash(g2||g3||IDA||IDB||RA||RB)): the confirmation the responder sends to (and the initiator checks against) the initiator.

      The returned tag is a secret authenticator; a received value must be compared against it with Arrays.constantTimeAreEqual(byte[], byte[]), not Arrays.equals, to avoid a timing side channel.

    • getInitiatorConfirmation

      public byte[] getInitiatorConfirmation()
      S_A = Hash(0x83 || g1 || Hash(g2||g3||IDA||IDB||RA||RB)): the confirmation the initiator sends to (and the responder checks against) the responder.

      The returned tag is a secret authenticator; a received value must be compared against it with Arrays.constantTimeAreEqual(byte[], byte[]), not Arrays.equals, to avoid a timing side channel.