メインコンテンツまでスキップ

6. Private Key Format

この節では PKIX における ML-KEM の RFC 原文を保持し, algorithm identifiers, SubjectPublicKeyInfo, private key formats, ASN.1 objects, security considerations, examples を含めます.

6.  Private Key Format

   [FIPS203] specifies two formats for an ML-KEM private key: a 64-octet
   seed and an (expanded) private key, which is referred to as the
   decapsulation key.  The expanded private key (and public key) is
   computed from the seed using ML-KEM.KeyGen_internal(d,z) (algorithm
   16) using the first 32 octets as _d_ and the remaining 32 octets as
   _z_. If the expanded private key is generated without exporting the
   seed, ML-KEM.KeyGen() (algorithm 19) is used; it combines seed
   generation with ML-KEM.KeyGen_internal(d,z).

   A key pair is generated by sampling 64 octets uniformly at random for
   the seed (private key) from a cryptographically secure pseudorandom
   number generator (CSPRNG).  The public key can then be computed using
   ML-KEM.KeyGen_internal(d,z) as described earlier.

   "Asymmetric Key Packages" [RFC5958] describes how to encode a private
   key in a structure that both identifies which algorithm the private
   key is for and allows for the public key and additional attributes
   about the key to be included as well.  For illustration, the ASN.1
   structure OneAsymmetricKey is replicated below.

     OneAsymmetricKey ::= SEQUENCE {
       version                  Version,
       privateKeyAlgorithm      SEQUENCE {
       algorithm                PUBLIC-KEY.&id({PublicKeySet}),
       parameters               PUBLIC-KEY.&Params({PublicKeySet}
                                  {@privateKeyAlgorithm.algorithm})
                                     OPTIONAL}
       privateKey               OCTET STRING (CONTAINING
                                  PUBLIC-KEY.&PrivateKey({PublicKeySet}
                                    {@privateKeyAlgorithm.algorithm})),
       attributes           [0] Attributes OPTIONAL,
       ...,
       [[2: publicKey       [1] BIT STRING (CONTAINING
                                  PUBLIC-KEY.&Params({PublicKeySet}
                                    {@privateKeyAlgorithm.algorithm})
                                    OPTIONAL ]],
       ...
     }

   For ML-KEM private keys, the privateKey field in OneAsymmetricKey
   contains one of the following DER-encoded CHOICE structures.  The
   seed format is a fixed 64-byte OCTET STRING (66 bytes total with the
   0x8040 tag and length) for all security levels, while the expandedKey
   and both formats vary in size by security level:

     ML-KEM-512-PrivateKey ::= CHOICE {
       seed [0] OCTET STRING (SIZE (64)),
       expandedKey OCTET STRING (SIZE (1632)),
       both SEQUENCE {
         seed OCTET STRING (SIZE (64)),
         expandedKey OCTET STRING (SIZE (1632))
         }
       }

     ML-KEM-768-PrivateKey ::= CHOICE {
       seed [0] OCTET STRING (SIZE (64)),
       expandedKey OCTET STRING (SIZE (2400)),
       both SEQUENCE {
         seed OCTET STRING (SIZE (64)),
         expandedKey OCTET STRING (SIZE (2400))
         }
       }

     ML-KEM-1024-PrivateKey ::= CHOICE {
       seed [0] OCTET STRING (SIZE (64)),
       expandedKey OCTET STRING (SIZE (3168)),
       both SEQUENCE {
         seed OCTET STRING (SIZE (64)),
         expandedKey OCTET STRING (SIZE (3168))
         }
       }

   The CHOICE allows three representations of the private key:

   *  The seed format (tag [0]) contains just the 64-byte seed value
      from which both the expanded private key and public key can be
      derived using ML-KEM.KeyGen_internal(d,z) (algorithm 16) using the
      first 32 octets as _d_ and the remaining 32 octets as _z_.

   *  The expandedKey format contains the expanded private key that was
      derived from the seed.  If the seed is not exported, both the
      expanded private key and public key can be derived using ML-
      KEM.KeyGen() (algorithm 16).

   *  The both format contains both the seed and expanded private key,
      allowing for interoperability; some may want to use and retain the
      seed and others may only support expanded private keys.

   The privateKeyAlgorithm field uses the AlgorithmIdentifier structure
   with the appropriate OID as defined in Section 3.

   The publicKey field contains the byte stream of the public key.  If
   present, the publicKey field will hold the encoded public key as
   defined in Section 4.

   Note that while the private key can be stored in multiple formats,
   the seed-only format is RECOMMENDED, as it is the most compact
   representation.  Both the expanded private key and the public key can
   be deterministically derived from the seed using ML-
   KEM.KeyGen_internal(d,z) (algorithm 16) using the first 32 octets as
   _d_ and the remaining 32 octets as _z_.  Alternatively, the public
   key can be extracted from the expanded private key.  While the
   publicKey field and expandedKey format are technically redundant when
   using the seed-only format, they MAY be included to enable key pair
   consistency checks during import operations.

   When parsing the private key, the ASN.1 tag explicitly indicates
   which variant of CHOICE is present.  Implementations should use the
   context-specific tag IMPLICIT [0] (raw value 0x80) for seed, OCTET
   STRING (0x04) for expandedKey, and SEQUENCE (0x30) for both to parse
   the private key, rather than any other heuristic like length of the
   enclosing OCTET STRING.

   Appendix C.1 contains examples for ML-KEM private keys encoded using
   the textual encoding defined in [RFC7468].