Skip to content

ML-KEM and ML-DSA private key ASN.1 encoding format does not comply with IETF draft #1969

Description

@bukodi

Description:
The ASN.1 encoding of the ML-DSA and ML-KEM private keys generated by the Bouncy Castle library does not comply with the IETF draft specifications.

According to Chapter 6 of the Dilithium IETF draft [1], the 'privateKey' component of the OneAsymmetricKey sequence should contain the raw octet string encoding of the 32-octet seed. However, the BC library generates an OCTET STRING that contains another OCTET STRING, which in turn contains the 32-octet seed. This additional OCTET STRING tag affects the import and export operations of both ML-KEM and ML-DSA private keys for all key sizes.

(Used Bouncy Castle version :1.79)

Reproduction steps for ML-DSA-44 key export:

  1. The IETF draft [1] Appendix C.1 provides an example ML-DSA-44 private key with seed 000102...1e1f:

    -----BEGIN PRIVATE KEY-----
    MDICAQAwCwYJYIZIAWUDBAMRBCAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRob
    HB0eHw==
    -----END PRIVATE KEY-----
    

    Decoded by online tool: https://lapo.it/asn1js/#MDICAQAwCwYJYIZIAWUDBAMRBCAAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB0eHw

  2. Generate the same key pair with the BC library and export the private key in PKCS#8 format:

        KeyPairGenerator kpg = KeyPairGenerator.getInstance(MLDSAParameterSpec.ml_dsa_44.getName(), "BC");
        kpg.initialize(MLDSAParameterSpec.ml_dsa_44, new FixedSecureRandom( new byte[] {
                0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
        }));
        KeyPair kp = kpg.generateKeyPair();
    
        StringWriter sw = new StringWriter();
        try( JcaPEMWriter pemWriter = new JcaPEMWriter(sw) ) {
            pemWriter.writeObject( new JcaMiscPEMGenerator(kp.getPrivate()));;
        };
        System.out.println("Private key PEM: \n" + sw);

The output is:

 -----BEGIN PRIVATE KEY-----
 MDQCAQAwCwYJYIZIAWUDBAMRBCIEIAABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZ
 GhscHR4f
 -----END PRIVATE KEY-----

Decoded by online tool: https://lapo.it/asn1js/#MDQCAQAwCwYJYIZIAWUDBAMRBCIEIAABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4f

References:
[1] https://datatracker.ietf.org/doc/draft-ietf-lamps-dilithium-certificates/06/
[2] https://datatracker.ietf.org/doc/draft-ietf-lamps-kyber-certificates/07/

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions