JCA design for RFC 7748

Michael StJohns mstjohns at comcast.net
Mon Aug 7 21:52:28 UTC 2017


On 8/7/2017 4:37 PM, Adam Petcher wrote:
> I'm working on the Java implementation of RFC 7748 (Diffie-Hellman 
> with X25519 and X448). I know some of you have been anxious to talk 
> about how this would fit into JCA, and I appreciate your patience 
> while I learned enough about JCA and existing crypto implementations 
> to develop this API proposal. This API/design proposal is for RFC 7748 
> only, and it does not include the API for RFC 8032 (EdDSA).

So you're expecting yet another set of APIs to cover those as well? 
Rather than one API to cover all of the new curves?  Seems to be a bit 
short sighted.

> Of course, I expect many of the decisions that we make for RFC 7748 
> will also impact RFC 8032.
>
> First off, I think it is important to separate RFC 7748 from the 
> existing ECDH API and implementation. RFC 7748 is a different standard,

It's still an elliptic curve.  Note that there is already a worked 
example here - F2m vs Fp curves.

> it uses different encodings and algorithms,

 From a JCA point of view, the public key gets encoded as an 
SubjectPublicKeyInfo and the private key gets encoded as a PKCS8 - 
that's for lots and lots of compatibility reasons.  The public point of 
the public key might be encoded (inside the SPKI) as little endian OCTET 
STRING array vs a  big endian ASN1 INTEGER, but its still just an 
integer internally.

The algorithms are Key Agreement and Signature - those are at least what 
JCA will see them as.  The actual KeyAgreement.getInstance("name") is of 
course going to be different than KeyAgreement.getInstance("ECDH") for 
example.


> and it has different properties.

Details please?  Or do you mean that you can't use a given type of key 
for both key agreement and signature?

> Further, this separation will reduce the probability of programming 
> errors (e.g. accidentally interpreting a Weierstrass point as an RFC 
> 7748 point).

Um.  What?   It actually won't.

> So I propose that we use distinct algorithm names for RFC 7748,
Yes.

> and that we don't use any of the existing EC classes like 
> EllipticCurve and ECPoint with RFC 7748.
No.   (My opinion but...) It's *hard* to add new meta classes for keys.  
Just considering the EC stuff you have ECKey, ECPublicKey, ECPrivateKey, 
EllipticCurve, ECPublicKeySpec, ECPrivateKeySpec, ECPoint, 
ECParameterSpec, ECGenParameterSpec, EllipticCurve and ECField (with 
ECFieldF2M and ECFieldF2P being the differentiator for all of the 
various keys within this space).

>
> We can achieve this separation without duplicating a lot of code if we 
> start with some simplifying assumptions. My goal is to remove 
> functionality that nobody needs in order to simplify the design and 
> API. If I am simplifying away something that you think you will need, 
> please let me know.

There's a difference with what you do with the public API vs what you do 
with the plugin provider.    Throwing away all of the "functionality 
that nobody needs" will probably come back to bite those who come later 
with something that looks *almost* like what you did, but needs just one 
more parameter than you were kind enough to leave behind.

>
> A) We don't need to expose actual curve parameters over the API. 
> Curves can be specified using names (e.g. "X25519") or OIDs. The 
> underlying implementation will likely support arbitrary Montgomery 
> curves, but the JCA application will only be able to use the supported 
> named curves.

Strangely, this hasn't turned out all that well.  There needs to be a 
name, OID in the public space (primarily for the encodings and PKIX 
stuff) and to be honest - you really want the parameters in public space 
as well (the ECParameterSpec and its ilk) so that a given key can be 
used with different providers or even to play around internally with new 
curves before giving them a name.

> B) We don't need direct interoperability between different providers 
> using opaque key representations. We can communicate with other 
> providers using X509/PKCS8 encoding, or by using KeyFactory and key 
> specs.
I don't actually understand that statement.  Keys of different providers 
generally don't interoperate anyways, but you can mostly take an 
"encoded" one and create a new one in a new provider via the 
Keyfactory.  KeySpecs provide you with a way of manually building a key 
- and that turns out to be VERY necessary, especially when you're 
dealing with adapting hardware modules to the JCA.

>
> These two assumptions greatly simplify the API. We won't need classes 
> that mirror ECParameterSpec, EllipticCurve, ECPoint, ECField, 
> ECPublicKey, etc. for X25519/X448.

That assumption holds only if your various other assumptions hold. My 
opinion is that they probably don't.  (BTW - I'm pretty sure, given that 
every single asymmetric JCA crypto api takes a PublicKey or PrivateKey 
you're going to need to mirror those classes at least; you'll also need 
a ParameterSpec and a GenParameterSpec class with whatever underlying 
supporting classes are required to deal with KeyFactory's)

>
> Now that the motivation and assumptions are out of the way, here is a 
> description of the proposed JCA API:

I'd suggest getting agreement on the above before proceeding.

Later, Mike




More information about the security-dev mailing list