RFR 8237218: Support NIST Curves verification in java implementation

Michael StJohns mstjohns at comcast.net
Fri Feb 28 20:18:03 UTC 2020


On 2/28/2020 3:05 PM, Michael StJohns wrote:
> Sorry - running behind on this thread.
>
> In ECUtil.decodePoint(),
>
> Since this code is open, I'm wondering if it might be useful to add 
> the checks specified in NIST SP800-186 Appendix D.1.  or SP800-56Ar1 
> 5.6.2.3 E.g.
>
>> D.1.2 Montgomery Curves
>> D.1.2.1 Partial Public Key Validation
>
>> Inputs:
>> 1. Montgomery curve MA,B defined over the prime field GF(p)
>>
>> 2. Point Q=(u, v) 1712
>> Output: ACCEPT or REJECT Q as an affine point on MA,B.
>> Process:
>> 1. If Q is the point at infinity ∅, output REJECT.
>> 2. Verify that both u and v are integers in the interval [0, p−1]. 
>> Output REJECT if  verification fails.
>> 3. Verify that (u, v) is a point on the MA,B by checking that (u, v) 
>> satisfies the defining equation v2 = u (u2 + A u + 1) where 
>> computations are carried out in GF(p). Output  REJECT if verification 
>> fails.
>> 4. Otherwise output ACCEPT.
>
>> D.1.2.2 Full Public Key Validation
>> Inputs:
>> 1. Montgomery curve MA,B defined over the prime field GF(p)
>> 2. Point Q
>> Output: ACCEPT or REJECT Q as a point on MA,B of order n.
>> Process:
>> 1. Perform partial public key validation on Q using the procedure of 
>> Appendix D.1.2.1.  Output REJECT if this procedure outputs REJECT.
>> 2. Verify that n Q = ∅. Output REJECT if verification fails.
>> 3. Otherwise output ACCEPT.
>
> This mainly ensures that the X/Y provided is actually a point on the 
> curve.   The threat to receiving a bad public key is more on the ECDH 
> side, but this appears to be the code that would need to be modified 
> so...
>
> Later, Mike
>
Here's the function I use in my application code - the last check 
(needed for full verification) uses BouncyCastle as I didn't have access 
to the internal methods in the SunEC provider.  Would have to be 
refactored slightly to be used in ECUtil.decodePoint().

   /**
    *  This function performs the checks described in NIST SP800-56A,
    *  section 5.6.2.5 over an ECPublicKey.  It throws a
    *  GeneralSecurityException if the key does not validate
    *
    * @param k the key to validate
    *
    * @throws InvalidKeyException if the key is invalid
    */
   public static void checkECPublicKey (ECPublicKey k)
     throws InvalidKeyException {

     // Step 0 - not in the SP document, but we don't support F2M
     // curves
     if (!((k.getParams().getCurve().getField()) instanceof ECFieldFp)) {
       throw new InvalidKeyException ("ECPublicKey is not on a Prime 
Curve - not supported");
     }

     ECPoint point = k.getW();
     // Step 1:
     if (point.equals(ECPoint.POINT_INFINITY)) {
       throw new InvalidKeyException ("ECPublic key is point at Infinity");
     }
     // Step 2:
     EllipticCurve curve = k.getParams().getCurve();
     BigInteger p = ((ECFieldFp)curve.getField()).getP();
     BigInteger x = point.getAffineX();
     BigInteger y = point.getAffineY();
     if (x.compareTo(BigInteger.ZERO) <= 0 || x.compareTo(p) >= 0)
       throw new InvalidKeyException ("ECPublicKey X out of Range");
     if (y.compareTo(BigInteger.ZERO) <= 0 || y.compareTo(p) >= 0)
       throw new InvalidKeyException ("ECPublicKey Y out of Range");

     // Step 3:
     BigInteger y2 = y.pow(2).mod(p);
     BigInteger x3 = x.pow(3);
     BigInteger ax = curve.getA().multiply(x);
     BigInteger sum = x3.add(ax).add(curve.getB()).mod(p);
     if (!y2.equals(sum))
       throw new InvalidKeyException ("ECPublicKey Point is not on Curve");
     // Step 4:  check nQ == INFINITY
     BigInteger n = k.getParams().getOrder();

     org.bouncycastle.math.ec.ECPoint bcPoint =
       //  EC5Util.convertPoint(k.getParams(), point, false); A/O 1.64
       EC5Util.convertPoint(k.getParams(), point);
     org.bouncycastle.math.ec.ECPoint testPoint =
       bcPoint.multiply(n);
     if (!testPoint.isInfinity())
       throw new InvalidKeyException ("ECPublicKey invalid order");


   }



More information about the security-dev mailing list