Bouncy Castle Cryptography Library 1.87

org.bouncycastle.crypto.params
Class SM9EncPrivateKeyParameters

java.lang.Object
  extended byorg.bouncycastle.crypto.params.AsymmetricKeyParameter
      extended byorg.bouncycastle.crypto.params.SM9EncPrivateKeyParameters
All Implemented Interfaces:
CipherParameters, javax.security.auth.Destroyable

public class SM9EncPrivateKeyParameters
extends AsymmetricKeyParameter
implements javax.security.auth.Destroyable

A user's SM9 encryption private key de = [t2]P2, a point of G2 (GM/T 0044.4-2016). Carries the master public key and the user's identity, both needed to decapsulate/decrypt (the identity is part of the KDF input), and the hid the KGC derived the key under, which the key exchange relies on to form the peer's Q point.

A key additionally records which usage it was derived for - KEM/decryption (SM9EncMasterPrivateKeyParameters.generateUserKey(byte[], byte)), which can be declared further for one of the two (see below), or key exchange (SM9EncMasterPrivateKeyParameters.generateExchangeKey(byte[])) - and the consumers enforce it: the key exchange evaluates the pairing e(R, de) on a peer-supplied point R, so a key that also decapsulates would hand any exchange peer the very pairing oracle on de that the KEM's security argument assumes is unavailable. Keeping the two usages on separate keys (distinct hid, or distinct master keys as the GM/T 0044.5 examples do) is what makes sharing the master key sound.

A key rebuilt from its encoding (fromEncoded(byte[], org.bouncycastle.crypto.params.SM9EncMasterPublicKeyParameters, byte[], byte) / fromEncodedExchangeKey(byte[], org.bouncycastle.crypto.params.SM9EncMasterPublicKeyParameters, byte[])) carries the usage the importer names - the point encoding itself does not record which usage the KGC derived it for - so an importer must claim the usage the key was actually derived under. The rest of what it carries is checked: the point is refused unless it is the key the KGC derives for the identity and hid under the master public key it is imported with. Where the KGC derives an identity's exchange key and its KEM / decryption key under one hid, the two are the same point, and the usage is the one thing that check cannot tell. A declaration for the KEM or for decryption is not recorded by the encoding either: getEncoded() writes the point alone, so the importer declares the usage again when it rebuilds the key, or the rebuilt key is declared for neither.

Usage warning: one identity's key should be used for the KEM or for public-key encryption, but not for both. A deployment needing both has its KGC publish a separate hid for each function. A KEM / decryption key can be declared for one of the two when it is derived or imported (SM9EncMasterPrivateKeyParameters.generateUserKey(byte[], byte, int), fromEncoded(byte[], SM9EncMasterPublicKeyParameters, byte[], byte, int)), and is then refused for the other on every use, its first included. One declared for neither is held to the first of the two it is used for, and refused for the other - see recordUsage(int).


Field Summary
static int USAGE_DECRYPTION
          The use of a key for public-key decryption (GM/T 0044.4-2016, clause 7): a usage a key can be declared for, and one recordUsage(int) checks.
static int USAGE_KEM
          The use of a key for KEM decapsulation (GM/T 0044.4-2016, clause 6): a usage a key can be declared for, and one recordUsage(int) checks.
static int USAGE_KEY_EXCHANGE
          The usage of a key-exchange key (GM/T 0044.3-2016), as SM9EncMasterPrivateKeyParameters.generateExchangeKey(byte[]) derives and fromEncodedExchangeKey(byte[], org.bouncycastle.crypto.params.SM9EncMasterPublicKeyParameters, byte[]) imports one.
static int USAGE_UNSPECIFIED
          The usage of a KEM / decryption key declared for neither of the two when it was derived or imported: it is held to the first of them it is used for - see recordUsage(int).
 
Method Summary
 void destroy()
          Destroy this object, dropping its reference to the private point de and zeroizing the identity.
static SM9EncPrivateKeyParameters fromEncoded(byte[] enc, SM9EncMasterPublicKeyParameters masterPublicKey, byte[] identity, byte hid)
          Rebuild a KEM / decryption user key from its bare point encoding.
static SM9EncPrivateKeyParameters fromEncoded(byte[] enc, SM9EncMasterPublicKeyParameters masterPublicKey, byte[] identity, byte hid, int usage)
          Rebuild a KEM / decryption user key from its bare point encoding, as fromEncoded(byte[], SM9EncMasterPublicKeyParameters, byte[], byte) does, declared for one of the two.
static SM9EncPrivateKeyParameters fromEncodedExchangeKey(byte[] enc, SM9EncMasterPublicKeyParameters masterPublicKey, byte[] identity)
          Rebuild a key-exchange user key from its bare point encoding, under SM9EncMasterPrivateKeyParameters.HID_EXCHANGE - the import path for an exchange party that received its key from the KGC rather than deriving it in-process via SM9EncMasterPrivateKeyParameters.generateExchangeKey(byte[]).
static SM9EncPrivateKeyParameters fromEncodedExchangeKey(byte[] enc, SM9EncMasterPublicKeyParameters masterPublicKey, byte[] identity, byte hid)
          Rebuild a key-exchange user key from its bare point encoding under an explicit hid, for a KGC whose published exchange hid is not SM9EncMasterPrivateKeyParameters.HID_EXCHANGE (the official English edition's GM/T 0044.5 Annex B example runs the exchange under 0x03).
 byte[] getEncoded()
          The user's encryption private key point de of G2 in uncompressed form (0x04 || x || y, 129 bytes).
 byte getHid()
          The private-key generation function identifier hid this key was derived under - the KGC's published choice, not sensitive.
 byte[] getIdentity()
          The identity this key was derived for.
 SM9EncMasterPublicKeyParameters getMasterPublicKey()
           
 SM9G2Point getPrivatePoint()
          The private point de.
 int getUsage()
          The usage this key was derived or imported for: USAGE_KEY_EXCHANGE for a key-exchange key, USAGE_KEM or USAGE_DECRYPTION for a KEM / decryption key declared for one of the two, and USAGE_UNSPECIFIED for one declared for neither.
 boolean isDestroyed()
           
 boolean isExchangeKey()
          Whether this key was derived for the key exchange (SM9EncMasterPrivateKeyParameters.generateExchangeKey(byte[])) rather than for KEM / decryption.
 void recordUsage(int usage)
          Record that this key is being handed over for - USAGE_KEM or USAGE_DECRYPTION - refusing it if it may not be used for that.
 
Methods inherited from class org.bouncycastle.crypto.params.AsymmetricKeyParameter
isPrivate
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

USAGE_UNSPECIFIED

public static final int USAGE_UNSPECIFIED
The usage of a KEM / decryption key declared for neither of the two when it was derived or imported: it is held to the first of them it is used for - see recordUsage(int).

See Also:
Constant Field Values

USAGE_KEM

public static final int USAGE_KEM
The use of a key for KEM decapsulation (GM/T 0044.4-2016, clause 6): a usage a key can be declared for, and one recordUsage(int) checks.

See Also:
Constant Field Values

USAGE_DECRYPTION

public static final int USAGE_DECRYPTION
The use of a key for public-key decryption (GM/T 0044.4-2016, clause 7): a usage a key can be declared for, and one recordUsage(int) checks.

See Also:
Constant Field Values

USAGE_KEY_EXCHANGE

public static final int USAGE_KEY_EXCHANGE
The usage of a key-exchange key (GM/T 0044.3-2016), as SM9EncMasterPrivateKeyParameters.generateExchangeKey(byte[]) derives and fromEncodedExchangeKey(byte[], org.bouncycastle.crypto.params.SM9EncMasterPublicKeyParameters, byte[]) imports one.

See Also:
Constant Field Values
Method Detail

getPrivatePoint

public SM9G2Point getPrivatePoint()
The private point de. A consumer that decapsulates or decrypts with it calls recordUsage(int) first, as SM9KEMExtractor and SM9Engine do when they are handed the key.

Throws:
java.lang.IllegalStateException - if this key has been destroyed.

getMasterPublicKey

public SM9EncMasterPublicKeyParameters getMasterPublicKey()

getHid

public byte getHid()
The private-key generation function identifier hid this key was derived under - the KGC's published choice, not sensitive.


isExchangeKey

public boolean isExchangeKey()
Whether this key was derived for the key exchange (SM9EncMasterPrivateKeyParameters.generateExchangeKey(byte[])) rather than for KEM / decryption. SM9KeyExchange accepts only exchange keys; SM9KEMExtractor and SM9 decryption accept only non-exchange keys.


getUsage

public int getUsage()
The usage this key was derived or imported for: USAGE_KEY_EXCHANGE for a key-exchange key, USAGE_KEM or USAGE_DECRYPTION for a KEM / decryption key declared for one of the two, and USAGE_UNSPECIFIED for one declared for neither.


recordUsage

public void recordUsage(int usage)
Record that this key is being handed over for - USAGE_KEM or USAGE_DECRYPTION - refusing it if it may not be used for that. The KEM and decryption entry points (SM9KEMExtractor, SM9Engine and the provider services built on them) call this when they are handed the key, so the use is recorded then, before the operation itself runs and whether or not it goes on to succeed. A call made only to find out whether a use would be accepted records that use as well.

A key declared for one of the two when it was derived or imported is refused for the other, on its first use as on every later one. Beyond that, a key is held to the first of the two it is used for, and refused for the other. The key is recognised by its value - its point and identity - rather than by this object, so the same key rebuilt from its encoding, or derived again, is held to the same use, whatever usage that object was declared for. Setting Properties.SM9_ALLOW_MULTI_USE to "true" turns this second check off, and nothing is recorded while it is set; a declared usage still holds. A destroyed key is not checked against the record of its value and adds nothing to it, whether it was destroyed before its first use or since: it can no longer be used for either function, which the operation it is handed to reports.

The record is kept in memory by the copy of this library in use, and is not kept across a restart: an application that loads the library once, as most do, keeps one record for its JVM, while one that loads a separate copy through each of several class loaders keeps a separate record for each copy. Nor is a key remembered for as long as the process runs: its record lasts while a key object of its value that has been handed over, and not destroyed since, is in use, and while it is among the 1024 keys most recently handed over. A key rebuilt for each use, among more than 1024 keys in use, can be forgotten between two of its uses, and its next use is then taken as its first; a key declared for one of the two is refused for the other however often it is rebuilt. The check therefore guards against a key being put to both uses by mistake within one application; it does not replace using a separate key for each function.

Parameters:
usage - the use about to be made of this key.
Throws:
java.lang.IllegalArgumentException - if usage is neither of the two, if this is a key-exchange key, if this key was declared for the other, or if this key has been used for the other.

getIdentity

public byte[] getIdentity()
The identity this key was derived for. Synchronized with destroy(), which zeroes the array in place: the flag is set before the clear, but reading a byte the clear has already written does not order the reader after the flag, so an unsynchronized copy could return a partly zeroed identity with the flag still reading false.


getEncoded

public byte[] getEncoded()
The user's encryption private key point de of G2 in uncompressed form (0x04 || x || y, 129 bytes). The master public key, identity and hid are not part of this encoding; supply them via fromEncoded(byte[], org.bouncycastle.crypto.params.SM9EncMasterPublicKeyParameters, byte[], byte) to rebuild a usable key (the identity is part of the decryption KDF input, the hid drives the key exchange's Q-point computation).


fromEncoded

public static SM9EncPrivateKeyParameters fromEncoded(byte[] enc,
                                                     SM9EncMasterPublicKeyParameters masterPublicKey,
                                                     byte[] identity,
                                                     byte hid)
Rebuild a KEM / decryption user key from its bare point encoding. For a key the KGC derived for the key exchange use fromEncodedExchangeKey(byte[], org.bouncycastle.crypto.params.SM9EncMasterPublicKeyParameters, byte[]) instead - the usage is the importer's claim (see the class note), and the consumers enforce whichever is claimed.

The hid is the KGC's published choice and may be any one byte except SM9EncMasterPrivateKeyParameters.HID_EXCHANGE, as where the key is derived: a point formed under SM9EncMasterPrivateKeyParameters.HID_EXCHANGE is that identity's exchange key, so claiming the KEM / decryption usage for it here is the one combination of usage and hid that names two different keys at once. The claim is checked against the hid rather than left to stand alone.

The point itself is checked against the master public key, identity and hid, by the KGC's own relation e([H1(ID || hid, N)]P1 + P_pub-e, de) = e(P_pub-e, P2), which holds exactly when de = [ke * (H1(ID || hid, N) + ke)^-1]P2 for the ke behind that P_pub-e. The encoding is the point alone, and the other three arrive beside it: a point paired with another master public key, or filed under another identity or hid, is refused with an IllegalArgumentException rather than imported as a key it is not. The check costs a pairing, several times what decoding the point costs, G2 subgroup check included, and on a master public key's first use a second, e(P_pub-e, P2), which the master public key then keeps.


fromEncoded

public static SM9EncPrivateKeyParameters fromEncoded(byte[] enc,
                                                     SM9EncMasterPublicKeyParameters masterPublicKey,
                                                     byte[] identity,
                                                     byte hid,
                                                     int usage)
Rebuild a KEM / decryption user key from its bare point encoding, as fromEncoded(byte[], SM9EncMasterPublicKeyParameters, byte[], byte) does, declared for one of the two. A key declared for USAGE_KEM or USAGE_DECRYPTION is refused for the other on every use, its first included; USAGE_UNSPECIFIED declares neither - see recordUsage(int).

Parameters:
enc - the encoding getEncoded() writes.
masterPublicKey - the encryption master public key the key was derived under.
identity - the identity the key was derived for.
hid - the hid the KGC derived the key under.
usage - USAGE_KEM, USAGE_DECRYPTION or USAGE_UNSPECIFIED.
Returns:
the rebuilt key.

fromEncodedExchangeKey

public static SM9EncPrivateKeyParameters fromEncodedExchangeKey(byte[] enc,
                                                                SM9EncMasterPublicKeyParameters masterPublicKey,
                                                                byte[] identity)
Rebuild a key-exchange user key from its bare point encoding, under SM9EncMasterPrivateKeyParameters.HID_EXCHANGE - the import path for an exchange party that received its key from the KGC rather than deriving it in-process via SM9EncMasterPrivateKeyParameters.generateExchangeKey(byte[]). The point is checked as fromEncoded(byte[], org.bouncycastle.crypto.params.SM9EncMasterPublicKeyParameters, byte[], byte) checks it.


fromEncodedExchangeKey

public static SM9EncPrivateKeyParameters fromEncodedExchangeKey(byte[] enc,
                                                                SM9EncMasterPublicKeyParameters masterPublicKey,
                                                                byte[] identity,
                                                                byte hid)
Rebuild a key-exchange user key from its bare point encoding under an explicit hid, for a KGC whose published exchange hid is not SM9EncMasterPrivateKeyParameters.HID_EXCHANGE (the official English edition's GM/T 0044.5 Annex B example runs the exchange under 0x03). The point is checked as fromEncoded(byte[], org.bouncycastle.crypto.params.SM9EncMasterPublicKeyParameters, byte[], byte) checks it.


destroy

public void destroy()
Destroy this object, dropping its reference to the private point de and zeroizing the identity.

As the point's coordinates are immutable they cannot be zeroized in place; destruction drops the reference and marks the key destroyed, after which getPrivatePoint(), getEncoded() and getIdentity() throw IllegalStateException. The master public key remains available.

Specified by:
destroy in interface javax.security.auth.Destroyable

isDestroyed

public boolean isDestroyed()
Specified by:
isDestroyed in interface javax.security.auth.Destroyable

Bouncy Castle Cryptography Library 1.87