On Mon, 4 Aug 2025 19:59:50 GMT, Sebastian Stenzel <d...@openjdk.org> wrote:

>> `getEncoded` is the whole PKCS #8 encoding.
>> `getRawBytes` returns the content of the `privateKey` field inside the PKCS 
>> #8 encoding.
>> `getExpanded` is not related to encoding. It's what the underlying 
>> `NamedKEM` or `NamedSignature` will use.
>> 
>> For ML-KEM, `getRawBytes` might be any of the 3 CHOICEs: seed, expandedKey, 
>> or both. `getExpanded` is always the expanded format (defined in FIPS 203). 
>> There is a slight difference even if `getRawBytes` is using the expandedKey 
>> choice: it has the OCTET STRING header but `getExpanded` does not.
>> 
>> `engineTranslateKey` can re-encode the key depending on the 
>> "jdk.mlkem.pkcs8.encoding" security property. Therefore it works on the 
>> `getRawBytes` level.
>
> In X-Wing, the expanded decapsulation key is referred to as `sk_m`. I.e. 
> *without* the CHOICE structure. So in order to have 
> `NamedPKCS8Key.privKeyMaterial` contain the choice, I would have to do this:
> 
> 
> byte[] keyBytesWrappedInChoice = 
> KeyChoices.writeToChoice(KeyChoices.Type.EXPANDED_KEY, null, sk_m);
> PrivateKey key = NamedPKCS8Key.internalCreate("ML-KEM", "ML-KEM-768", 
> keyBytesWrappedInChoice, null);
> 
> 
> However, if I now call `keyFactory.translateKey(key)`, it'll throw:
> 
> 
> java.security.InvalidKeyException: key contains not enough info to translate
>       at 
> java.base/sun.security.util.KeyChoices.choiceToChoice(KeyChoices.java:220)
>       at 
> java.base/com.sun.crypto.provider.ML_KEM_Impls$KF.engineTranslateKey(ML_KEM_Impls.java:133)
>       at java.base/java.security.KeyFactory.translateKey(KeyFactory.java:475)
> 
> 
> in base64 `sk_m` has this value (test case 1 from [X-Wing test 
> vectors](https://datatracker.ietf.org/doc/html/draft-connolly-cfrg-xwing-kem-08#appendix-C)):
> 
> 
> IDjHPToyMBF3joBR7joyxgHNZdrAqPmpQIEj8GRIi+thihFD1Fqc+BbMlZuDnLsPH5y7DJWqXHsqhQNeiMRkT1VZjVF7psO12woyNCIYSHFQe8O/BspLfeOW/MFH4tONheMqoIKMUHvC28nEk4Q57YciB7y//iNoevxrdhG4/XrCetNairsm2RB0AQtsc1WhUUyluoExawtc3bmm2BmiGocA2PmbB4hBPVw8fXyhm4ACCJqKjKJ7BZBelLxh49fPLbaXxZYrC0s5O7Cbv/oujGxuk8K8NOpIFxZVSdota6ikQDe4ELd8Dhk0ppU3FjE0JhsjQshoNGtB2AkDgcDADDMb44giv+KWv8o1khgg52Q76KgrzlnMZdUn+ujHA1lK2FcYT+R52uyrJJec8WKCVtSPJdp+ajBrOaCoUlQMrRgMUMC0xnegLoubeWQBxdwUpSgloIjDG0RxVQRPCwgYczWfClLEaOaK/TlOiUisecKTeECk38gfr1IUvdocAtTO62klYLa4Z9fKO/uvXxwzHjap6uaWsJJeZ/GUMrCX+Helmdiu3DArkTgQl9kNIYgkapcOw1gKqxVDCtdHcntCp/fDy3sSDKaM1mZHdtmdZfMIbKW8sZiPHbyZqsJtZwEL0wjAzpeVnouGSCEvPSYuTfW3ThDLsKs+oFxI32S4EvgQNUd2vFd2kuUhmct6YDTLA9hh+Vs7jlEUYjtx1fAUIiO6F9tR1KWRskqkY8qWrWpJYBg61ySdKUq/kHEvhcieVqMGcId8DFpIUDhsCoIjmAQrabZyvTWb9ndKaboaa5kOFNGrEoA1iHovnOZgxhSQf/IXWncIZOJ0B+MSIYJ/OBgU2OrGvmq/28pxtHK1iSnBN5c2JXK/qhZdhkqdzHFhDbOyM7QOOyVnJuMXO3x+fXXPlCgrpVYivOZ5lhfJEuUQMPgm0abCeHScyGRSw2KXkXpg7icb/gWsTSedtEpGcTMie4BqeZaUZRYl
 
xQoGeRCeQPZvXIS7ajlPmBxge1S5DDCCw4Q9gUgCAXo6DNQ10ABGXTmba6kkUwFz+xREY1sapcykudONJ7eo8NUkerE0I/pGUErLZrBulhERusBpPuB9FIKXNdY6hEei9OxgfwKWfGMeUrtoUDOrv9hvViBycHXNP0UroNeTU2au3ycSwtkquVNHYtG94DOi8/Bu59ueXwEx4TZNrXNyW9NwknYF7TgZQBm55PVHurYtq1Cy4Wq2r5TLbFUe5DearAdyKZy746WLCOm29wyp7HRvIsSpTqlyYAla5PymyQov0lqbJexd9bAnXUhOByJqHXM0oou+JIpcVrJSQMuE39soR6iFHhB9icVUxjOKjlWr1zeu30EEzAhVD3JKk9gNrImWY+UJkXuWvfFcowE/EmIDDckeqHqrx8iVDsF0g0pLNYgTI6okoHMLccBHolui9abEBPcswpSRDuDOkDUbuESkSAqiXGRS9NClUTkKLToMyByJshhOHEhONaNrxlAxd4psk+aNscF84sAfABBjd/R84gU...

If you manually create an expanded-only key and then try to call`translateKey` 
on it but the security property is using the default value "seed", then of 
course the translation will not work.

Anyway, I don't think X-Wing implementation needs to touch that property. The 
X-Wing private key is always the 32-byte seed, and its "expanded" form can 
include the whole `expandDecapsulationKey` output, and then you can simply call 
internal `ML-KEM` methods on it.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/24969#discussion_r2252579592

Reply via email to