8264606: More comment for ECDH public key validation

Reviewed-by: wetmore
This commit is contained in:
Xue-Lei Andrew Fan 2021-04-02 15:23:23 +00:00
parent 885916eda0
commit 177bc84fe8

View File

@ -149,6 +149,7 @@ public final class ECDHKeyAgreement extends KeyAgreementSpi {
return null; return null;
} }
// Verify that x and y are integers in the interval [0, p - 1].
private static void validateCoordinate(BigInteger c, BigInteger mod) private static void validateCoordinate(BigInteger c, BigInteger mod)
throws InvalidKeyException{ throws InvalidKeyException{
if (c.compareTo(BigInteger.ZERO) < 0) { if (c.compareTo(BigInteger.ZERO) < 0) {
@ -160,15 +161,29 @@ public final class ECDHKeyAgreement extends KeyAgreementSpi {
} }
} }
/* // Check whether a public key is valid, following the ECC
* Check whether a public key is valid. // Full Public-key Validation Routine (See section 5.6.2.3.3,
*/ // NIST SP 800-56A Revision 3).
private static void validate(ECOperations ops, ECPublicKey key) private static void validate(ECOperations ops, ECPublicKey key)
throws InvalidKeyException { throws InvalidKeyException {
ECParameterSpec spec = key.getParams(); ECParameterSpec spec = key.getParams();
// ensure that integers are in proper range // Note: Per the NIST 800-56A specification, it is required
// to verify that the public key is not the identity element
// (point of infinity). However, the point of infinity has no
// affine coordinates, although the point of infinity could
// be encoded. Per IEEE 1363.3-2013 (see section A.6.4.1),
// the point of inifinity is represented by a pair of
// coordinates (x, y) not on the curve. For EC prime finite
// field (q = p^m), the point of infinity is (0, 0) unless
// b = 0; in which case it is (0, 1).
//
// It means that this verification could be covered by the
// validation that the public key is on the curve. As will be
// verified in the following steps.
// Ensure that integers are in proper range.
BigInteger x = key.getW().getAffineX(); BigInteger x = key.getW().getAffineX();
BigInteger y = key.getW().getAffineY(); BigInteger y = key.getW().getAffineY();
@ -176,7 +191,7 @@ public final class ECDHKeyAgreement extends KeyAgreementSpi {
validateCoordinate(x, p); validateCoordinate(x, p);
validateCoordinate(y, p); validateCoordinate(y, p);
// ensure the point is on the curve // Ensure the point is on the curve.
EllipticCurve curve = spec.getCurve(); EllipticCurve curve = spec.getCurve();
BigInteger rhs = x.modPow(BigInteger.valueOf(3), p).add(curve.getA() BigInteger rhs = x.modPow(BigInteger.valueOf(3), p).add(curve.getA()
.multiply(x)).add(curve.getB()).mod(p); .multiply(x)).add(curve.getB()).mod(p);
@ -185,7 +200,10 @@ public final class ECDHKeyAgreement extends KeyAgreementSpi {
throw new InvalidKeyException("Point is not on curve"); throw new InvalidKeyException("Point is not on curve");
} }
// check the order of the point // Check the order of the point.
//
// Compute nQ (using elliptic curve arithmetic), and verify that
// nQ is the the identity element.
ImmutableIntegerModuloP xElem = ops.getField().getElement(x); ImmutableIntegerModuloP xElem = ops.getField().getElement(x);
ImmutableIntegerModuloP yElem = ops.getField().getElement(y); ImmutableIntegerModuloP yElem = ops.getField().getElement(y);
AffinePoint affP = new AffinePoint(xElem, yElem); AffinePoint affP = new AffinePoint(xElem, yElem);
@ -195,7 +213,6 @@ public final class ECDHKeyAgreement extends KeyAgreementSpi {
if (!ops.isNeutral(product)) { if (!ops.isNeutral(product)) {
throw new InvalidKeyException("Point has incorrect order"); throw new InvalidKeyException("Point has incorrect order");
} }
} }
// see JCE spec // see JCE spec