net.i2p.data

## Class PublicKey

- java.lang.Object
- - net.i2p.data.SimpleDataStructure
  - - net.i2p.data.PublicKey

- All Implemented Interfaces:
    DataStructure
  Direct Known Subclasses:
    NextSessionKey

      public class PublicKey
      extends SimpleDataStructure

  Cryptographic public key for asymmetric encryption in I2P.

  PublicKey provides the encryption component of I2P's asymmetric cryptography:

  - Default Algorithm: ElGamal 2048-bit (256 bytes)
  - Modern Support: Variable length and type support since 0.9.38
  - Key Structure: Contains only public exponent
  - Constants: Prime numbers defined in crypto specification

  Supported Algorithms:

  - ElGamal 2048: Legacy algorithm, 256-byte keys
  - ECIES X25519: Modern elliptic curve, 32-byte keys
  - Unknown Types: Forward-compatible support for future algorithms

  Key Format:

  - ElGamal: 256-byte public exponent only
  - Elliptic Curve: Variable length based on curve parameters
  - Type Encoding: Algorithm type stored with key data
  - Validation: Length and format checking per algorithm

  Usage:

  - Encryption: Encrypt messages for corresponding `PrivateKey`
  - Key Exchange: Participate in ElGamal key exchange
  - Identity: Part of `Destination` cryptographic identity
  - Verification: Public key validation and distribution

  Performance Features:

  - LRU Caching: Frequently used keys cached for efficiency
  - Factory Methods: Static creation methods for cache access
  - Efficient Storage: Optimized byte representation
  - Fast Comparison: Optimized equals() and hashCode()

  Security Considerations:

  - Algorithm Choice: Prefer modern algorithms (X25519)
  - Key Validation: Verify key parameters before use
  - Key Distribution: Safely transmit public keys
  - Size Limits: Currently limited to 256 bytes maximum

  Migration Path:

  - Legacy: ElGamal 2048-bit for backward compatibility
  - Modern: ECIES X25519 for better performance
  - Future: Extensible design for new algorithms

  Implementation Notes:

  - Size Limitation: Support for keys >256 bytes not yet implemented
  - Cache Index: First 4 bytes used for LRU cache lookup
  - Type Safety: Algorithm type validation on creation

  Thread Safety:

  - Immutable Data: Key data cannot be modified after creation
  - Thread-Safe Cache: Static factory methods are thread-safe
  - Safe Sharing: Instances can be safely shared between threads

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static int` | `KEYSIZE_BYTES`

    - ### Fields inherited from class net.i2p.data.SimpleDataStructure

      `_data`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `PublicKey()`
    `PublicKey(byte[] data)`
    `PublicKey(EncType type)`
    `PublicKey(EncType type, byte[] data)`
    `PublicKey(int typeCode, byte[] data)` Unknown type only.
    `PublicKey(String base64Data)` Constructs from base64.

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `static void` | `clearCache()` Clears the public key cache.
    `static PublicKey` | `create(byte[] data, int off)` Pull from cache or return new.
    `static PublicKey` | `create(InputStream in)` Pull from cache or return new.
    `boolean` | `equals(Object obj)` Warning - this returns true for two different classes with the same size and same data, e.g.
    `byte[]` | `getPadding(KeyCertificate kcert)` Get the portion of this (type 0) PK that is really padding based on the Key Cert type given, if any
    `EncType` | `getType()` Gets the encryption type of this public key.
    `int` | `getUnknownTypeCode()` Gets the type code for unknown encryption types.
    `int` | `hashCode()` We assume the data has enough randomness in it, so use the first 4 bytes for speed.
    `int` | `length()` The legal length of the byte array in this data structure
    `String` | `toString()`
    `(package private) PublicKey` | `toTypedKey(KeyCertificate kcert)` Up-convert this from an untyped (type 0) PK to a typed PK based on the Key Cert given.

    - ### Methods inherited from class net.i2p.data.SimpleDataStructure

      `calculateHash, fromBase64, fromByteArray, getData, read, readBytes, setData, toBase64, toByteArray, writeBytes`

    - ### Methods inherited from class java.lang.Object

      `clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

- - ### Field Detail

    - #### KEYSIZE_BYTES

          public static final int KEYSIZE_BYTES

  - ### Constructor Detail

    - #### PublicKey

          public PublicKey()

    - #### PublicKey

          public PublicKey(byte[] data)

      Parameters:
        `data` - must be non-null

    - #### PublicKey

          public PublicKey(EncType type)

      Parameters:
        `type` - if null, type is unknown

    - #### PublicKey

          public PublicKey(EncType type,
                           byte[] data)

      Parameters:
        `type` - if null, type is unknown
        `data` - must be non-null

    - #### PublicKey

          public PublicKey(int typeCode,
                           byte[] data)

      Unknown type only.
      Parameters:
        `typeCode` - must not match a known type. 1-255
        `data` - must be non-null

    - #### PublicKey

          public PublicKey(String base64Data)
                    throws DataFormatException

      Constructs from base64. ElGamal only.
      Parameters:
        `base64Data` - a string of base64 data (the output of .toBase64() called on a prior instance of PublicKey
      Throws:
        `DataFormatException`

  - ### Method Detail

    - #### clearCache

          public static void clearCache()

      Clears the public key cache.

    - #### create

          public static PublicKey create(byte[] data,
                                         int off)

      Pull from cache or return new. ELGAMAL_2048 only! Deprecated - used only by deprecated Destination.readBytes(data, off)
      Throws:
        `DataFormatException` - if not enough bytes

    - #### create

          public static PublicKey create(InputStream in)
                                  throws IOException

      Pull from cache or return new. ELGAMAL_2048 only!
      Throws:
        `IOException`

    - #### equals

          public boolean equals(Object obj)

      Description copied from class: `SimpleDataStructure`
      Warning - this returns true for two different classes with the same size and same data, e.g. SessionKey and SessionTag, but you wouldn't put them in the same Set, would you?
      Overrides:
        `equals` in class `SimpleDataStructure`

    - #### getPadding

          public byte[] getPadding(KeyCertificate kcert)

      Get the portion of this (type 0) PK that is really padding based on the Key Cert type given, if any
      Returns:
        trailing padding length > 0 or null if no padding or type is unknown
      Throws:
        `IllegalArgumentException` - if this is already typed to a different type

    - #### getType

          public EncType getType()

      Gets the encryption type of this public key.
      Returns:
        null if unknown

    - #### getUnknownTypeCode

          public int getUnknownTypeCode()

      Gets the type code for unknown encryption types. Only valid if getType() returns null

    - #### hashCode

          public int hashCode()

      Description copied from class: `SimpleDataStructure`
      We assume the data has enough randomness in it, so use the first 4 bytes for speed. If this is not the case, override in the extending class.
      Overrides:
        `hashCode` in class `SimpleDataStructure`

    - #### length

          public int length()

      Description copied from class: `SimpleDataStructure`
      The legal length of the byte array in this data structure
      Specified by:
        `length` in class `SimpleDataStructure`

    - #### toString

          public String toString()

      Overrides:
        `toString` in class `SimpleDataStructure`

    - #### toTypedKey

          PublicKey toTypedKey(KeyCertificate kcert)

      Up-convert this from an untyped (type 0) PK to a typed PK based on the Key Cert given. The type of the returned key will be null if the kcert sigtype is null.
      Throws:
        `IllegalArgumentException` - if this is already typed to a different type