Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8349164

Switch to latest ML-DSA private key encoding

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Unresolved
    • Icon: P2 P2
    • 24-pool, 25
    • security-libs
    • None
    • behavioral
    • minimal
    • ML-DSA is new in JDK 24.
    • File or wire format
    • Implementation

      Summary

      Update the ML-DSA private key encoding to align with Section 6 of draft-ietf-lamps-dilithium-certificates-8. Specifically, the privateKey field in OneAsymmetricKey will follow the DER-encoded CHOICE structure as defined: it must contain one of the three permitted alternatives described in the draft.

      Problem

      When ML-DSA was initially implemented in OpenJDK, earlier versions of draft-ietf-lamps-dilithium-certificates stated that "A fully populated ML-DSA private key consists of 6 parameters. The size necessary to hold all private key elements is 32+32+32+32*[(k+l)*ceiling(log(2*eta+1))+13*k] bytes", this matches the private key defined in NIST FIPS 204 — specifically, the private key part of the return value from the ML-DSA.KeyGen function, as defined in Section 5.1 of FIPS 204.

      In the final revision of the draft, the private key format has been formally defined as a DER-encoded ASN.1 CHOICE. For ML-DSA-44, for example:

      ML-DSA-44-PrivateKey ::= CHOICE {
          seed [0] OCTET STRING (SIZE (32)),
          expandedKey OCTET STRING (SIZE (2560)),
          both SEQUENCE {
              seed OCTET STRING (SIZE (32)),
              expandedKey OCTET STRING (SIZE (2560))
          }
      }

      Similar structures are defined for ML-DSA-65 and ML-DSA-87.

      Our current implementation corresponds to the second choice, expandedKey OCTET STRING. To comply with the updated specification, we must update our implementation to support the other two choices as well.

      Solution

      Update the ML-DSA private key encoding to support the new CHOICE structure. A new security or system property will control which of the three CHOICE options is used by the JDK.

      When KeyPairGenerator::generateKey or KeyFactory::translateKey is invoked, the returned ML-DSA private key will be encoded using the selected format.

      Note: If KeyFactory::translateKey is used to convert a key that lacks a seed into a format that includes the seed, the operation will fail and an InvalidKeyException will be thrown.

      Specification

      A new security property, jdk.mldsa.pkcs8.encoding, is introduced to control the encoding format of ML-DSA private keys in PKCS #8.

      The following entry is added to the java.security file:

      #
      # The privateKey field for newly created ML-DSA private keys in PKCS #8
      #
      # The draft-ietf-lamps-dilithium-certificates specification defines three formats
      # for an ML-DSA private key: a 32-byte seed, an expanded private key,
      # or a sequence containing both.
      #
      # Valid values for this property are "seed", "expandedKey", and "both"
      # (case-insensitive). The default is "seed".
      #
      # This property determines the encoding format used when a new keypair is
      # generated using a KeyPairGenerator, as well as the output of the translateKey
      # method on an existing key using a KeyFactory.
      #
      # If a system property of the same name is also specified, it supersedes the
      # security property value defined here.
      #
      # Note: This property is currently used by the SUN provider in the JDK
      # Reference implementation. It is not guaranteed to be supported by other
      # SE implementations.
      #
      #jdk.mldsa.pkcs8.encoding = seed

            weijun Weijun Wang
            weijun Weijun Wang
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: