@@ -149,6 +149,7 @@ protected Key engineDoPhase(Key key, boolean lastPhase)
149
149
return null ;
150
150
}
151
151
152
+ // Verify that x and y are integers in the interval [0, p - 1].
152
153
private static void validateCoordinate (BigInteger c , BigInteger mod )
153
154
throws InvalidKeyException {
154
155
if (c .compareTo (BigInteger .ZERO ) < 0 ) {
@@ -160,23 +161,37 @@ private static void validateCoordinate(BigInteger c, BigInteger mod)
160
161
}
161
162
}
162
163
163
- /*
164
- * Check whether a public key is valid.
165
- */
164
+ // Check whether a public key is valid, following the ECC
165
+ // Full Public-key Validation Routine (See section 5.6.2.3.3,
166
+ // NIST SP 800-56A Revision 3).
166
167
private static void validate (ECOperations ops , ECPublicKey key )
167
168
throws InvalidKeyException {
168
169
169
170
ECParameterSpec spec = key .getParams ();
170
171
171
- // ensure that integers are in proper range
172
+ // Note: Per the NIST 800-56A specification, it is required
173
+ // to verify that the public key is not the identity element
174
+ // (point of infinity). However, the point of infinity has no
175
+ // affine coordinates, although the point of infinity could
176
+ // be encoded. Per IEEE 1363.3-2013 (see section A.6.4.1),
177
+ // the point of inifinity is represented by a pair of
178
+ // coordinates (x, y) not on the curve. For EC prime finite
179
+ // field (q = p^m), the point of infinity is (0, 0) unless
180
+ // b = 0; in which case it is (0, 1).
181
+ //
182
+ // It means that this verification could be covered by the
183
+ // validation that the public key is on the curve. As will be
184
+ // verified in the following steps.
185
+
186
+ // Ensure that integers are in proper range.
172
187
BigInteger x = key .getW ().getAffineX ();
173
188
BigInteger y = key .getW ().getAffineY ();
174
189
175
190
BigInteger p = ops .getField ().getSize ();
176
191
validateCoordinate (x , p );
177
192
validateCoordinate (y , p );
178
193
179
- // ensure the point is on the curve
194
+ // Ensure the point is on the curve.
180
195
EllipticCurve curve = spec .getCurve ();
181
196
BigInteger rhs = x .modPow (BigInteger .valueOf (3 ), p ).add (curve .getA ()
182
197
.multiply (x )).add (curve .getB ()).mod (p );
@@ -185,7 +200,10 @@ private static void validate(ECOperations ops, ECPublicKey key)
185
200
throw new InvalidKeyException ("Point is not on curve" );
186
201
}
187
202
188
- // check the order of the point
203
+ // Check the order of the point.
204
+ //
205
+ // Compute nQ (using elliptic curve arithmetic), and verify that
206
+ // nQ is the the identity element.
189
207
ImmutableIntegerModuloP xElem = ops .getField ().getElement (x );
190
208
ImmutableIntegerModuloP yElem = ops .getField ().getElement (y );
191
209
AffinePoint affP = new AffinePoint (xElem , yElem );
@@ -195,7 +213,6 @@ private static void validate(ECOperations ops, ECPublicKey key)
195
213
if (!ops .isNeutral (product )) {
196
214
throw new InvalidKeyException ("Point has incorrect order" );
197
215
}
198
-
199
216
}
200
217
201
218
// see JCE spec
0 commit comments