Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to export ML-DSA key-pairs in seed format #2194

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

jakemas
Copy link
Contributor

@jakemas jakemas commented Feb 13, 2025

Issues:

Resolves #CryptoAlg-2918
#ACCP-130

Description of changes:

Support the ability to export ML-DSA key seeds. We modify the core algorithm implementation to store the seed used during key generation. This will allow the key pair to be reconstructed at a later stage from just the seed.

This is performed within ml_dsa_keypair, which has been modified to accept an addition argument seed that is a pointer to output array of ML_DSA_SEEDBYTES bytes.

int ml_dsa_keypair(ml_dsa_params *params, uint8_t *pk, uint8_t *sk, uint8_t *seed) {
- uint8_t seed[ML_DSA_SEEDBYTES];
  if (!RAND_bytes(seed, ML_DSA_SEEDBYTES)) {
    return -1;
  }
  ml_dsa_keypair_internal(params, pk, sk, seed);
- OPENSSL_cleanse(seed, sizeof(seed));
  return 0;
}

These changes bubble up to the ml_dsa.c definitions of keygen, that are now modified to support the provided buffer to store the seed:

int ml_dsa_44_keypair(uint8_t *public_key   /* OUT */,
                      uint8_t *private_key  /* OUT */,
+                     uint8_t *seed         /* OUT */) {
  ml_dsa_params params;
  ml_dsa_44_params_init(&params);
  return (ml_dsa_keypair(&params, public_key, private_key, seed) == 0);
}

We store the seed in the PQDSA_KEY struct during pkey_pqdsa_keygen:

struct pqdsa_key_st {
  const PQDSA *pqdsa;
  uint8_t *public_key;
  uint8_t *private_key;
+ uint8_t *seed;
};

To export, this PR supports:

  • EVP_marshal_private_key to export full format private key
  • EVP_marshal_private_key_v2 to export seed format private key
  • EVP_PKEY_get_raw_private_key to export raw format in full/seed form, depending on size provided (this could be a new API)

FIPS Compliance: I'm glad you're asking, yes this is compliant with FIPS, NIST have published PQC FAQs specifically to address this exact implementation: https://csrc.nist.gov/Projects/post-quantum-cryptography/faqs#Rdc7.

Performance Impact

Converting to seed-based storage for both public and private keys yields the following improvements:

ML-DSA-44: 99.17% (121x) reduction (3,840 bytes saved per key-pair).
ML-DSA-65: 99.46% (187x) reduction (5,952 bytes saved per key-pair).
ML-DSA-87: 99.57% (234x) reduction (7,456 bytes saved per key-pair).

Converting to seed-based storage for private keys yields the following improvements:

ML-DSA-44: 98.75% (80x) reduction (2,528 bytes saved per private key).
ML-DSA-65: 99.21% (126x) reduction (5,952 bytes saved per private key).
ML-DSA-87: 99.35% (153x) reduction (7,456 bytes saved per private key).

The proposed seed-based approach achieves an average storage reduction of 99.4% across all ML-DSA variants.

Call-outs:

Once we have alignment on the EVP API functionality, I will add documentation.

Testing:

Added new test suite Marshalv2ParseSeed for parsing as well as additional test for parsing seeds in RawFunctions

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license and the ISC license.

@codecov-commenter
Copy link

codecov-commenter commented Feb 13, 2025

Codecov Report

Attention: Patch coverage is 75.00000% with 23 lines in your changes missing coverage. Please review.

Project coverage is 79.03%. Comparing base (7518c78) to head (bb3f760).

Files with missing lines Patch % Lines
crypto/evp_extra/p_pqdsa_asn1.c 74.41% 11 Missing ⚠️
crypto/evp_extra/p_pqdsa_test.cc 70.58% 6 Missing and 4 partials ⚠️
crypto/fipsmodule/pqdsa/pqdsa.c 80.00% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #2194      +/-   ##
==========================================
- Coverage   79.04%   79.03%   -0.01%     
==========================================
  Files         612      612              
  Lines      106067   106144      +77     
  Branches    14985    14999      +14     
==========================================
+ Hits        83842    83893      +51     
- Misses      21571    21596      +25     
- Partials      654      655       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jakemas jakemas marked this pull request as ready for review February 13, 2025 22:07
@jakemas jakemas requested a review from a team as a code owner February 13, 2025 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants