EC weirdness

Michael StJohns mstjohns at
Thu Jul 19 19:36:30 UTC 2018

On 7/16/2018 4:42 PM, Adam Petcher wrote:
> I think the reason for the hard-coded curves is largely historical, 
> and I don't know of a security-related reason for it (other than the 
> prevention of insecure parameters). Though it has the additional 
> benefit that it simplifies the interface a lot, because the 
> implementation for a curve is not completely determined by the domain 
> parameters. 

Actually - they are.  An ECGenParameterSpec  (basically a named curve) 
is turned into an ECParameterSpec  (the actual curve and G stuff) which 
is turned into an AlgorithmSpecification of type (SunEC, EC) which 
strangely tries to do a reverse lookup of the parameter spec to get a 
name for the curve.   (That's not exactly it, but its close in spirit).

> The implementation may also need to know which optimized finite field 
> implementation, precomputed tables, etc to use. Looking up all of 
> these things at once can be a lot simpler than trying to specify them 
> over an interface.

Nope - that's not it.  The underlying C code mostly uses generic bignum 
operations on the curve parameters rather than pre-computed things.

My guess is that there were some dependencies on named curves in the EC 
library and the EC related stuff in the PKCS11 library.

> I'm trying to figure out if your problem motivates support for 
> arbitrary base points, or if there is another way to get what you 
> want. Is the base point a secret in your scheme? Either way, can you 
> implement your scheme using KeyAgreement (e.g. using the "base point" 
> as the public key and a random integer as the private key)? What if 
> ECDH KeyAgreement supported three-party Diffie-Hellman, or you extract 
> a point from generateSecret()? Would that help?

In the scheme, G' is secret.  This is basically the EC version of  Two key pairs generated on P-256' 
(e.g. same curve params, but with G'), can use ECDH to get to the same 
shared secret.   If your key pair wasn't generated with G', then you 
can't get to the same secret with someone who's key pair was.

This is sort of an IOT experiment - I don't want to have to do an 
explicit authorization via a certificate binding a public key.  I can 
generate a group G', and have all the various devices generate a key 
pair using that G'.   The ability to get a pairwise shared secret with 
another device proves the membership in the group to that other device 
and vice versa.

The problem with using ECDH is that generic ECDH operations throw away 
the Y coordinate.  I can do xG' -> X'  using the SunEC ECDH, but what I 
actually get as a result is the scalar X'.x.

I've been trying to avoid using external libraries, but I'll probably 
end up using the BC point math stuff to make this work.

I may do a bit more archeology and see whether there are actual 
dependencies on the build in curve data (e.g. PKCS11).  If not, I may 
try and provide a patch refactoring out that limitation and doing a more 
thorough separation of the math from the packaging.

Later, Mike

> On 7/13/2018 9:30 PM, Michael StJohns wrote:
>> Hi -
>> Every so often I run into some rather strange things in the way the 
>> Sun EC classes were built.  Most recently, I was trying to use the 
>> SunEC provider to do a PACE like protocol.  Basically, the idea was 
>> to be able to generate public key points on the P-256 curve, but with 
>> a different base point G (knowledge of G' or having a public key 
>> generated from G' would allow you to do a valid ECDH operation, keys 
>> with disjoint points would not).
>> I was able to generate a normal key pair using ECGenParameterSpec 
>> with a name, so I grabbed the ECParameterSpec from the public key, 
>> made a copy of most of the stuff (curve, cofactor), but substituted 
>> the public point W from the key pair I'd just generated, and passed 
>> that in as G to the new parameter spec.  I tried to initialize the 
>> KPG with my *almost* P-256 spec, and it failed with "unsupported curve".
>> Looking into the code and tracing through 
>> to the native code, I'm once again 
>> surprised that all of the curves are hard coded into the C native 
>> code, rather than being passed in as data from the Java code.
>> Is there a good security reason for hard coding the curves at the C 
>> level that I'm missing?
>> This comes under the heading of unexpected behavior rather than a bug 
>> per se I think.   Although - I'd *really* like to be able to pass a 
>> valid ECParameterSpec in to the generation process and get whatever 
>> keys are appropriate for that curve and base point.
>> Later, Mike

More information about the security-dev mailing list