• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * @license
3  * Copyright 2016 Google Inc. All rights reserved.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.security.wycheproof;
18 
19 import com.google.security.wycheproof.WycheproofRunner.ExcludedTest;
20 import com.google.security.wycheproof.WycheproofRunner.ProviderType;
21 import java.math.BigInteger;
22 import java.security.GeneralSecurityException;
23 import java.security.InvalidKeyException;
24 import java.security.KeyFactory;
25 import java.security.KeyPair;
26 import java.security.KeyPairGenerator;
27 import java.security.NoSuchAlgorithmException;
28 import java.security.interfaces.ECPrivateKey;
29 import java.security.interfaces.ECPublicKey;
30 import java.security.spec.ECFieldFp;
31 import java.security.spec.ECGenParameterSpec;
32 import java.security.spec.ECParameterSpec;
33 import java.security.spec.ECPoint;
34 import java.security.spec.ECPrivateKeySpec;
35 import java.security.spec.ECPublicKeySpec;
36 import java.security.spec.EllipticCurve;
37 import java.security.spec.InvalidKeySpecException;
38 import java.security.spec.X509EncodedKeySpec;
39 import javax.crypto.KeyAgreement;
40 import junit.framework.TestCase;
41 
42 /**
43  * Testing ECDH.
44  *
45  * <p><b>Defense in depth</b>: The tests for ECDH assume that a attacker has control over all
46  * aspects of the public key in an exchange. That means that the attacker can potentially send weak
47  * or invalid public keys. For example, invalid public keys can contain points not on the curve,
48  * curves that have been deliberately chosen so that DLs are easy to compute as well as orders or
49  * cofactors that are wrong. It is expected that implementations validate the inputs of a key
50  * agreement and that in no case information about the private key is leaked.
51  *
52  * <p><b>References:</b> Ingrid Biehl, Bernd Meyer, Volker Müller, "Differential Fault Attacks on
53  * Elliptic Curve Cryptosystems", Crypto '00, pp. 131-164
54  *
55  * <p>Adrian Antipa, Daniel Brown, Alfred Menezes, Rene Struik, and Scott Vanstone, "Validation of
56  * Elliptic Curve Public Keys", PKC 2003, https://www.iacr.org/archive/pkc2003/25670211/25670211.pdf
57  *
58  * <p># <b>Bugs:</b> CVE-2015-7940: BouncyCastle before 1.51 does not validate a point is on the
59  * curve. BouncyCastle v.1.52 checks that the public key point is on the public key curve but does
60  * not check whether public key and private key use the same curve. BouncyCastle v.1.53 is still
61  * vulnerable to attacks with modified public keys. An attacker can change the order of the curve
62  * used by the public key. ECDHC would then reduce the private key modulo this order, which can be
63  * used to find the private key.
64  *
65  * <p>SunEC had similar problem. CVE ?
66  *
67  * @author bleichen@google.com (Daniel Bleichenbacher)
68  */
69 // TODO(bleichen): Stuff we haven't implemented:
70 //   - timing attacks
71 // Stuff we are delaying because there are more important bugs:
72 //   - testWrongOrder using BouncyCastle with ECDHWithSHA1Kdf throws
73 //     java.lang.UnsupportedOperationException: KDF can only be used when algorithm is known
74 //     Not sure if that is expected or another bug.
75 // CVEs for ECDH we haven't used anywhere.
76 //   - CVE-2014-3470: OpenSSL anonymous ECDH denial of service: triggered by NULL value in
77 //     certificate.
78 //   - CVE-2014-3572: OpenSSL downgrades ECDHE to ECDH
79 //   - CVE-2011-3210: OpenSSL was not thread safe
80 public class EcdhTest extends TestCase {
81 
82   static final String[] ECDH_VARIANTS = {
83     // Raw ECDH. The shared secret is the x-coordinate of the ECDH computation.
84     // The tests below assume that this variant is implemenented.
85     "ECDH",
86     // ECDHC is a variant described in P1363 7.2.2 ECSVDP-DHC.
87     // BouncyCastle implements this variant.
88     "ECDHC",
89     // A variant with an explicit key derivation function.
90     // This is implemented by BouncyCastle.
91     "ECDHWITHSHA1KDF",
92   };
93 
94   /** ECDH test vectors */
95   public static class EcdhTestVector {
96     final String curvename;
97     final String pub; // hexadecimal representation of the X509 encoding
98     final BigInteger s; // private key
99     final String shared; // hexadecimal representation of the shared secret
100 
EcdhTestVector(String curvename, String pub, BigInteger s, String shared)101     public EcdhTestVector(String curvename, String pub, BigInteger s, String shared) {
102       this.curvename = curvename;
103       this.pub = pub;
104       this.s = s;
105       this.shared = shared;
106     }
107 
getPublicKey()108     public ECPublicKey getPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
109       KeyFactory kf = KeyFactory.getInstance("EC");
110       byte[] encoded = TestUtil.hexToBytes(pub);
111       return (ECPublicKey) kf.generatePublic(new X509EncodedKeySpec(encoded));
112     }
113 
getPrivateKey()114     public ECPrivateKey getPrivateKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
115       KeyFactory kf = KeyFactory.getInstance("EC");
116       ECPrivateKeySpec spec = new ECPrivateKeySpec(s, EcUtil.getCurveSpecRef(curvename));
117       return (ECPrivateKey) kf.generatePrivate(spec);
118     }
119   }
120 
121   public static final EcdhTestVector[] ECDH_TEST_VECTORS = {
122       // vectors with normal ECDH values
123       new EcdhTestVector(
124           "secp224r1",
125           "304e301006072a8648ce3d020106052b81040021033a00049c08bb3788a5cb8d"
126               + "22591f2520791cdaf61765a84f0419d28ff8fb2dcb5d51e5714d8740420d0945"
127               + "187f97be42872bae9bf3f5b1857a475f",
128           new BigInteger("8af784fe9cebd363df85f598dcc2ab82b2ca725360dadb77b3708032", 16),
129           "c1921af3d06d813ccb009e363a647836d30b3f9c211c26e64a3bb0b6"),
130       new EcdhTestVector(
131           "secp256r1",
132           "3059301306072a8648ce3d020106082a8648ce3d030107034200044b3b0a5231"
133               + "76309f259498c55e3a9be45c9fb65ad4e60d6064e04b89c1bd0a1835039219c1"
134               + "22b89e2b539bb16d3afced502137f02944c374863137035fd3f1ae",
135           new BigInteger("051a995be2a8499e2c9331b3b5f3c012048bb02a1a6f044ed93d9bd295fcec16", 16),
136           "33befba428b295b9a0123d3a848d91d1e9a5266959e036d1a25e28d83d06421f"),
137       new EcdhTestVector(
138           "secp384r1",
139           "3076301006072a8648ce3d020106052b8104002203620004c1d31b771bb123f4"
140               + "fb2b789a2880c57a68b3bbfa7da3d80b8325b73428bd2a4e79b55b57ac454f52"
141               + "8ac02b62d54dfc315b9ba04363e94b825767951a9338f5d1db4c6d3f0e9a15bc"
142               + "9b834fc11a01e4b310c22aba73766fd769ea684fbad5d9d2",
143           new BigInteger("ff65a2bf5e1347e2286fb29273fb118a76996038bea2fcfd2032e8663f7588e5"
144                   + "3130d195b161eba39085abbc3e24bcef", 16),
145           "dbd85b2caaca6d69460c94bd9f99b3bd51404788a58334a18709a882050fe1bf"
146               + "a4dd74de6e4368c1243443e5f64b60c7"),
147       new EcdhTestVector(
148           "secp521r1",
149           "30819b301006072a8648ce3d020106052b81040023038186000401ca6ec5476b"
150               + "ae3cf0f28f370ac3a9a0de2091418a590978bf87a6f1aeadebde98925e8fb42c"
151               + "d03d57ff9aeb9890646067a3095874828a392b80a88880e5f456e4d000493581"
152               + "376d20d711a487e0106a3fc047b91803ed154e274b26d858cf2f55e356b45765"
153               + "2101b925b7d36b542d2a3e33e01404fb4f944c3b8ef276b6f5082e591135",
154           new BigInteger("01f362c182f1eaae2920578a2f30c228e28b996e74d4bd799621300d5f2e6c69"
155                   + "30204f00476732c95a79ae527503621edf633dbb87400740f54adc4430706221"
156                   + "2f68", 16),
157           "0107b9c99c80e2bc834e10c44afe2d611aafe8aad0eb80384aefbd9bb8196ea3"
158               + "b5797bedac39de3362532c9b04aeb98a3e60034c3d2dcb4a43b8f8b44e9528d3"
159               + "eeb8"),
160       new EcdhTestVector(
161           "brainpoolp256r1",
162           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
163               + "01022100a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d"
164               + "1f6e5377304404207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6c"
165               + "e94a4b44f330b5d9042026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7"
166               + "e1ce6bccdc18ff8c07b60441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27"
167               + "e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745"
168               + "132ded8e545c1d54c72f046997022100a9fb57dba1eea9bc3e660a909d838d71"
169               + "8c397aa3b561a6f7901e0e82974856a7020101034200048178776ff8332108da"
170               + "d4fa59bce3111133a30e33fa7f96d0211ec9fa4904dcca084de67f52fd720ccd"
171               + "ada5c49305200a6028793a83cbe692c08237ecd0572fa2",
172           new BigInteger("143be522a9d0420f6bd19b95ce3a5e19c61970c31f13448276546625e607e7c9", 16),
173           "3658b819481f00f74cfd76b9dcf82867c3c3186f948cbc75bf296c6d332aedf0"),
174       // vectors with extreme values for the shared secret
175       new EcdhTestVector(
176           "secp256r1",
177           "3059301306072a8648ce3d020106082a8648ce3d03010703420004983f80374a"
178               + "4730f9decd7221fa3ebb527d44f459b6c6afcf7de7069481400a748fb8733ba0"
179               + "8e01cd53d54af45975554d0dbd6d5f0acf0fd95692606347cace7e",
180           new BigInteger("56556c546751dee664ae71baa0189a2e69b1e1f8939a49ed7cc35d7ea98fbcc7", 16),
181           "0000000000000000000000000000000000000000000000000000000000000000"),
182       new EcdhTestVector(
183           "secp384r1",
184           "3076301006072a8648ce3d020106052b8104002203620004d64af08419f8a0aa"
185               + "5d830a2b0f42e6a27a3c17e0e98f64a1e7e10c6a41a308832dcd9a493db0cd43"
186               + "7e47063c1db6c967494c8460f03bf95ff619b7c7499e1bc08fd759fc44c4af3d"
187               + "03de541a719baf996b4f91a9af5bf08fa671af0899f91359",
188           new BigInteger("ee383acde7e5b3e6c246833e183c4272a1714a13097b4b57bc2eeecdccbd69b6"
189                   + "cff435215a3c92b5d4e0b2c36444a7fa", 16),
190           "0000000000000000000000000000000000000000000000000000000000000000"
191               + "00000000000000000000000000000000"),
192       new EcdhTestVector(
193           "secp384r1",
194           "3076301006072a8648ce3d020106052b81040022036200041c1ed3f66b6ae370"
195               + "411ac30fda63c784c5cbc3951a7cfe567d8bfa3ea535a2eb8c192d349e69ea2a"
196               + "39eb5013a5cf383cf91c82e81eee1a9bc97386e340e65b2b2d8cf2633b919a82"
197               + "10a638b8e2345cda054ce96efcaeee20dcce82d13d40eb6a",
198           new BigInteger("98f230ef0c0ab02c78179ba9ea3e1c8d16c3ec276665c432b9040b803dfff657"
199                   + "a6c77512b6a602d416785016c3cd3da7", 16),
200           "0000000000000000000000000000000000000000000000000000000000000000"
201               + "00000000000000000000000000000002"),
202       new EcdhTestVector(
203           "secp384r1",
204           "3076301006072a8648ce3d020106052b8104002203620004d10b0df120b1324d"
205               + "8b76ee43065e4f4be63f68cf5b381ae79046920108a8f21cf8097bf313225b74"
206               + "1125eb5a66105ee445961b28ad1843613775c063a85319f1353d8bf2a217210e"
207               + "309f2c7c27b57d42fdc042abb00b37a0f3118cf74b4174f0",
208           new BigInteger("5b8e9af3c17fa0d683f3bc94f8685f33c0b616281f91b466cac9da0a0e085ba6"
209                   + "f48aafcdb4fc13d55f1a33ac436f82bb", 16),
210           "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
211               + "ffffffff0000000000000000fffffffe"),
212       new EcdhTestVector(
213           "secp521r1",
214           "30819b301006072a8648ce3d020106052b810400230381860004008269c7d0ff"
215               + "febadbf5bdfa2adf0f378d0844268e5acb57d0157fe688488cef91256e15939d"
216               + "311aaf6479e29ef14de3981c3a5768c7b66693e956fa515d4a0c847c0054a32b"
217               + "4a8f615ba5550f204ebf1f7f02f7252b5ae564361eec468adf4d59caa4c4b424"
218               + "a30761d805d521c2e1f1dfde385e9146624cb2b84f94888730acbfbf1294",
219           new BigInteger("019ad2de5943f5112021a3215cee84c4e8d40e188641419a5b7958636f1843d0"
220                   + "cbda4747aad69fd806b333b82b095d0f10bda8dbeca7ee9f67d09caffb4869e4"
221                   + "1172", 16),
222           "0000000000000000000000000000000000000000000000000000000000000000"
223               + "0000000000000000000000000000000000000000000000000000000000000000"
224               + "0000"),
225       new EcdhTestVector(
226           "secp521r1",
227           "30819b301006072a8648ce3d020106052b810400230381860004003b0d698705"
228               + "0fad0f76ac1ac7a1c7e91e24addf821c06ae0844a3f1b6338c111a32a94a5369"
229               + "fdf8fd1cc137314c7d7a99dfabba1cc92f10026e45388714fe453ed50015e59a"
230               + "c4bab161635e0df0f5553ee6112fc60f744ffc607965975c0843f7a893441c4f"
231               + "e5e6e290426dd219ecbc159f39302b52b37b69a890e9fc4cf70eba39bbf6",
232           new BigInteger("0147492d3019808024569dc81b0e6aef9f27bfd43e009e8b4b6b0512b220490e"
233                   + "08f98324b16d3ed91a54d391f92973f5376c66b9f8a9cbf893b0900968fd8d6e"
234                   + "5e7d", 16),
235           "0000000000000000000000000000000000000000000000000000000000000000"
236               + "0000000000000000000000000000000000000000000000000000000000000000"
237               + "0001"),
238       new EcdhTestVector(
239           "secp521r1",
240           "30819b301006072a8648ce3d020106052b81040023038186000401bb2936bfc5"
241               + "8f1e9819d62ed2a38a0ce618f000546fe8af4983d8dbbda7b7ae914a656ac540"
242               + "7c153f6edacb170fd2129d126d987d5032c7a31540bb6a4e93f8af15015c23ce"
243               + "1263e691903cd2c859d883c980fada91b764aef7e5a20fb22bcf5949e62c8082"
244               + "c8245bcf8686a6a39b7ef2eec49b1a047b73aeb06e3793c1d01fa24fd156",
245           new BigInteger("5a5f98ceb2f856685c51ba714d5e1db06d1e6542a8d02b9c13efeeb1f3e6613d"
246                   + "8ef83e49748cb63aad268ba68c9295c507dac125f51ba75c82f6029dcc14d4ab"
247                   + "16", 16),
248           "0000000000000000000000000000000000000000000000000000000000000000"
249               + "0000000000000000000000000000000000000000000000000000000000000000"
250               + "0002"),
251       new EcdhTestVector(
252           "secp521r1",
253           "30819b301006072a8648ce3d020106052b81040023038186000401ce7a5356fd"
254               + "002ff3d9a193dd910795b56f8bd2f975367d982d27e04b4e0935425fdef6b3e1"
255               + "6fac26a898a757ddbfb01a45236a8a06ead9db3dff644ed87a7f09310000c862"
256               + "7374a123b1c0fdf7efaaee362fa7fdeb1c56bd787e81484d21a818ff49552704"
257               + "af2d2fe714a1576299ff6d3745349cdb463e8c003641c13c870391cfd360",
258           new BigInteger("c5dd96d1f0aa141f184d0a749809dc0749a0629b9b7d99d1cbe40c14204d70c7"
259                   + "f63413756040a4c2a67551df6723c4b784ace44d7e35f46233c78b2c7548594b"
260                   + "3d", 16),
261           "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
262               + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
263               + "fffd"),
264       new EcdhTestVector(
265           "secp521r1",
266           "30819b301006072a8648ce3d020106052b81040023038186000400d4574ad46e"
267               + "42824b7738f0ed19f0dbec65e743ed6a1798e8168546713a929c97cb8b2f3c20"
268               + "928bed9fad88319ef216e42c7a82707befead2b21000e06e6ca37709004848c1"
269               + "34a7fa6d0f8cd9aa237b84ffa02cb3bc8d84b8022153a3e01248dfc87403e8f3"
270               + "f1b70b52b7eabffd01fe1b4101fa901494a2067e2321a47e87cce45eecfd",
271           new BigInteger("01ac34343b1814a092e48f1c60de0bacced8c328246f103428ab0ce6611807e6"
272                   + "90022dbc6bc558265b917dc513152cd1661b30e3b62a2cc2bf9f909e3fd51918"
273                   + "de5b", 16),
274           "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
275               + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
276               + "fffe"),
277       new EcdhTestVector(
278           "brainpoolp256r1",
279           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
280               + "01022100a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d"
281               + "1f6e5377304404207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6c"
282               + "e94a4b44f330b5d9042026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7"
283               + "e1ce6bccdc18ff8c07b60441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27"
284               + "e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745"
285               + "132ded8e545c1d54c72f046997022100a9fb57dba1eea9bc3e660a909d838d71"
286               + "8c397aa3b561a6f7901e0e82974856a70201010342000498703a894131de3f81"
287               + "5836bdb1d5a03e59fbf50ffde6575ee690e9ebf6a32e785ad50d1eb00062a9b8"
288               + "176ba32f06f3908f82a3ddd9da10eafcac61f57a180bcb",
289           new BigInteger("17617237e4ec2629d798a81ca086c1a73494e70619dd7b77cb7360174de82107", 16),
290           "0000000000000000000000000000000000000000000000000000000000000001"),
291       new EcdhTestVector(
292           "brainpoolp256r1",
293           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
294               + "01022100a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d"
295               + "1f6e5377304404207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6c"
296               + "e94a4b44f330b5d9042026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7"
297               + "e1ce6bccdc18ff8c07b60441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27"
298               + "e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745"
299               + "132ded8e545c1d54c72f046997022100a9fb57dba1eea9bc3e660a909d838d71"
300               + "8c397aa3b561a6f7901e0e82974856a702010103420004055f1b89b08c1c4a0f"
301               + "96ff15dd284bdad79b90636ce73c461cb6da001e19638c07490bed6a644e944a"
302               + "c3e8684c4d5cf469a3f5b039690cba52dc0dccb095e61e",
303           new BigInteger("7988ceedd4ce4f516f083261dc0dbb4d59c71b058bf00876135fb1d5e72a1cea", 16),
304           "0000000000000000000000000000000000000000000000000000000000000002"),
305       new EcdhTestVector(
306           "brainpoolp256r1",
307           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
308               + "01022100a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d"
309               + "1f6e5377304404207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6c"
310               + "e94a4b44f330b5d9042026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7"
311               + "e1ce6bccdc18ff8c07b60441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27"
312               + "e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745"
313               + "132ded8e545c1d54c72f046997022100a9fb57dba1eea9bc3e660a909d838d71"
314               + "8c397aa3b561a6f7901e0e82974856a70201010342000424f99dbc3d8f4989f2"
315               + "43662e67de0f8d03d0f84031caa553f4a3ccc1c999de1e43530fcd456a5d83d5"
316               + "11aedc8bda7c2b18cc509cabe47e76d46501fd82ebbfae",
317           new BigInteger("844649c38c375c5f4959b129c6510e54f71a60b91d1b09a7b1a8dd0e954da186", 16),
318           "a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5376"),
319       // vectors with extreme values for the public key
320       new EcdhTestVector(
321           "secp256r1",
322           "3059301306072a8648ce3d020106082a8648ce3d030107034200040000000000"
323               + "00000000000000000000000000000000000000000000000000000066485c780e"
324               + "2f83d72433bd5d84a06bb6541c2af31dae871728bf856a174f93f4",
325           new BigInteger("2e0a2c5159af006f28f5b51e55ce9270f17a431ebefee2d95bf2f954c3c460c5", 16),
326           "bb4b8e7b1b5d766d7e6d3de41e0ab0703cadcca4e039f310e3ed0004e2c1ba67"),
327       new EcdhTestVector(
328           "secp384r1",
329           "3076301006072a8648ce3d020106052b81040022036200040000000000000000"
330               + "0000000000000000000000000000000000000000000000000000000000000000"
331               + "00000000000000003cf99ef04f51a5ea630ba3f9f960dd593a14c9be39fd2bd2"
332               + "15d3b4b08aaaf86bbf927f2c46e52ab06fb742b8850e521e",
333           new BigInteger("b0a8c4804a2b9769216a51b51ece43391cf3f66c383a748d54f1c15f27bbf041"
334                   + "a3b9470a6d49f8abe9e6b4db6bd7c59f", 16),
335           "6598237fdfd3f38e00c3c58a3045b9d54c510f0f5523293af1966635f2ddf963"
336               + "87b12065ad8e1a5b72618e6441c72841"),
337       new EcdhTestVector(
338           "secp384r1",
339           "3076301006072a8648ce3d020106052b8104002203620004ffffffffffffffff"
340               + "fffffffffffffffffffffffffffffffffffffffffffffffeffffffff00000000"
341               + "00000000fffffffe732152442fb6ee5c3e6ce1d920c059bc623563814d79042b"
342               + "903ce60f1d4487fccd450a86da03f3e6ed525d02017bfdb3",
343           new BigInteger("135b5751b27de8fe0e34d452ad81c4ca90def546275c349f467aabd24e039b75"
344                   + "28c473bc5732cb96921d01e6ca11739a", 16),
345           "ef5ceb524843eb0277f574b278b09f82670dbcdacbe51a646441a45ebdfa4976"
346               + "1fb3b534bfccd957edb99e9a4e329467"),
347       new EcdhTestVector(
348           "secp521r1",
349           "30819b301006072a8648ce3d020106052b810400230381860004000000000000"
350               + "0000000000000000000000000000000000000000000000000000000000000000"
351               + "0000000000000000000000000000000000000000000000000000000000d20ec9"
352               + "fea6b577c10d26ca1bb446f40b299e648b1ad508aad068896fee3f8e614bc630"
353               + "54d5772bf01a65d412e0bcaa8e965d2f5d332d7f39f846d440ae001f4f87",
354           new BigInteger("7ca82bb7bdd0ab3805e1d25ce49f71780e93a0314f579a474d0b0f81812c8365"
355                   + "bc3917eb00208a1cfdb44cdc53f112930560e86bcad563d0bd4ff951f2c41454"
356                   + "f6", 16),
357           "00d6283f6a7b59628920dd3afe97a5021c79e26c71adf5c0774cedaaf5b25b92"
358               + "ed2776cfefbe95e467a15032c221064ff19b1207183f0ca0c594b6a83ca0e3f3"
359               + "2250"),
360       new EcdhTestVector(
361           "secp521r1",
362           "30819b301006072a8648ce3d020106052b810400230381860004000000000000"
363               + "0000000000000000000000000000000000000000000000000000000000000000"
364               + "000000000000000000000000000000000000000000000000000000010010e59b"
365               + "e93c4f269c0269c79e2afd65d6aeaa9b701eacc194fb3ee03df47849bf550ec6"
366               + "36ebee0ddd4a16f1cd9406605af38f584567770e3f272d688c832e843564",
367           new BigInteger("011cf3abed354498f6922af2ddc9d74b2bb829bee79cc272c7b154f16a720c29"
368                   + "429bb354bb034549e33be5b84ffb6da99a0c28bb37fa44f78cce5feb871370e1"
369                   + "2c93", 16),
370           "00e51b94872c9cb3831bac48e9e4cbc6b4eafdc09ce51f43d0ff118b5d429f20"
371               + "b88261dbfc9636ecf081cdcf1b1336425a39841cf1ff742bc3d5553a709cd0a7"
372               + "3a13"),
373       new EcdhTestVector(
374           "secp521r1",
375           "30819b301006072a8648ce3d020106052b81040023038186000401ffffffffff"
376               + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
377               + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffd0010e59b"
378               + "e93c4f269c0269c79e2afd65d6aeaa9b701eacc194fb3ee03df47849bf550ec6"
379               + "36ebee0ddd4a16f1cd9406605af38f584567770e3f272d688c832e843564",
380           new BigInteger("011c2b1a82cd320924e757b4259e5f7c0455efe3f05d316c9705b5071fdbd59e"
381                   + "db59ee938b95a67727ca01ffe5155baf5eff83ae5ec4a56770a50475b017a762"
382                   + "30cf", 16),
383           "000adf30396bda59d36fc307a4f43f594806f3a46373f3e4af6516e67f99d981"
384               + "1c0496f49527895fa7738423f6429318f54afa6841cb4692e15016fe49fc7c82"
385               + "509d"),
386       new EcdhTestVector(
387           "secp521r1",
388           "30819b301006072a8648ce3d020106052b81040023038186000401ffffffffff"
389               + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
390               + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffe00d9254f"
391               + "df800496acb33790b103c5ee9fac12832fe546c632225b0f7fce3da4574b1a87"
392               + "9b623d722fa8fc34d5fc2a8731aad691a9a8bb8b554c95a051d6aa505acf",
393           new BigInteger("01e1603fe7e275673aeb8b3f105f4058e073b4c37d2f0ae2bd66b189454e1b41"
394                   + "c442c3f35f085eae3aa37eefffe76736440f9b3fd2e3931d468b6d90e560bc0f"
395                   + "35f5", 16),
396           "0158694585e55f1289e410fdeeed82940b3029dd8207dcb4de407278a6328d5e"
397               + "b904262419f1ef2ecacb415872f0c9d64df82b1241cd780bd0abc9e26ceebadf"
398               + "44e7"),
399       new EcdhTestVector(
400           "brainpoolp256r1",
401           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
402               + "01022100a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d"
403               + "1f6e5377304404207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6c"
404               + "e94a4b44f330b5d9042026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7"
405               + "e1ce6bccdc18ff8c07b60441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27"
406               + "e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745"
407               + "132ded8e545c1d54c72f046997022100a9fb57dba1eea9bc3e660a909d838d71"
408               + "8c397aa3b561a6f7901e0e82974856a702010103420004000000000000000000"
409               + "000000000000000000000000000000000000000000000109e0e9e8d98fb89da2"
410               + "a32b2c7618b26bb99b920f02a5e831a142e6c8673110cd",
411           new BigInteger("61c2be000b5888035bfde07d532b36d91cc347f556d87c7a01397f4cde29c6e4", 16),
412           "3db56c93e51a0b5b17a8009be010be6eecca6b7e0b587753cb8bc850869a710d"),
413       new EcdhTestVector(
414           "brainpoolp256r1",
415           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
416               + "01022100a9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d"
417               + "1f6e5377304404207d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6c"
418               + "e94a4b44f330b5d9042026dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7"
419               + "e1ce6bccdc18ff8c07b60441048bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27"
420               + "e1e3bd23c23a4453bd9ace3262547ef835c3dac4fd97f8461a14611dc9c27745"
421               + "132ded8e545c1d54c72f046997022100a9fb57dba1eea9bc3e660a909d838d71"
422               + "8c397aa3b561a6f7901e0e82974856a702010103420004a9fb57dba1eea9bc3e"
423               + "660a909d838d726e3bf623d52620282013481d1f6e537613a0346db14d55d1bc"
424               + "c27079b68864ac32885b5bdfc3c9db6f85a35d3df4c39b",
425           new BigInteger("8527b0540fc10b025a6e0892439c59a889a52e57a0f81b4df41442869c524873", 16),
426           "a01ed9d4f5a0884db2a232dd5369d6014bfe1f2f6a6d05a757e7a078b71a1f54"),
427   };
428 
429   /** Test vectors */
430   public static class EcPublicKeyTestVector {
431     final String comment;
432     final String encoded; // hexadecimal representation of the X509 encoding
433     final BigInteger p; // characteristic of the field
434     final BigInteger n; // order of the subgroup
435     final BigInteger a; // parameter a of the Weierstrass representation
436     final BigInteger b; // parameter b of the Weierstrass represnetation
437     final BigInteger gx; // x-coordinate of the generator
438     final BigInteger gy; // y-coordainat of the generator
439     final Integer h; // cofactor: may be null
440     final BigInteger pubx; // x-coordinate of the public point
441     final BigInteger puby; // y-coordinate of the public point
442 
EcPublicKeyTestVector( String comment, String encoded, BigInteger p, BigInteger n, BigInteger a, BigInteger b, BigInteger gx, BigInteger gy, Integer h, BigInteger pubx, BigInteger puby)443     public EcPublicKeyTestVector(
444         String comment,
445         String encoded,
446         BigInteger p,
447         BigInteger n,
448         BigInteger a,
449         BigInteger b,
450         BigInteger gx,
451         BigInteger gy,
452         Integer h,
453         BigInteger pubx,
454         BigInteger puby) {
455       this.comment = comment;
456       this.encoded = encoded;
457       this.p = p;
458       this.n = n;
459       this.a = a;
460       this.b = b;
461       this.gx = gx;
462       this.gy = gy;
463       this.h = h;
464       this.pubx = pubx;
465       this.puby = puby;
466     }
467 
468     /**
469      * Returns this key as ECPublicKeySpec or null if the key cannot be represented as
470      * ECPublicKeySpec. The later happens for example if the order of cofactor are not positive.
471      */
getSpec()472     public ECPublicKeySpec getSpec() {
473       try {
474         ECFieldFp fp = new ECFieldFp(p);
475         EllipticCurve curve = new EllipticCurve(fp, a, b);
476         ECPoint g = new ECPoint(gx, gy);
477         // ECParameterSpec requires that the cofactor h is specified.
478         if (h == null) {
479           return null;
480         }
481         ECParameterSpec params = new ECParameterSpec(curve, g, n, h);
482         ECPoint pubPoint = new ECPoint(pubx, puby);
483         ECPublicKeySpec pub = new ECPublicKeySpec(pubPoint, params);
484         return pub;
485       } catch (Exception ex) {
486         System.out.println(comment + " throws " + ex.toString());
487         return null;
488       }
489     }
490 
getX509EncodedKeySpec()491     public X509EncodedKeySpec getX509EncodedKeySpec() {
492       return new X509EncodedKeySpec(TestUtil.hexToBytes(encoded));
493     }
494   }
495 
496   public static final EcPublicKeyTestVector EC_VALID_PUBLIC_KEY =
497       new EcPublicKeyTestVector(
498           "unmodified",
499           "3059301306072a8648ce3d020106082a8648ce3d03010703420004cdeb39edd0"
500               + "3e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b84"
501               + "29598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8",
502           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
503           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16),
504           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
505           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
506           new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16),
507           new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16),
508           1,
509           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
510           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16));
511 
512   public static final EcPublicKeyTestVector[] EC_MODIFIED_PUBLIC_KEYS = {
513       // Modified keys
514       new EcPublicKeyTestVector(
515           "public point not on curve",
516           "3059301306072a8648ce3d020106082a8648ce3d03010703420004cdeb39edd0"
517               + "3e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b84"
518               + "29598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebaca",
519           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
520           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16),
521           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
522           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
523           new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16),
524           new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16),
525           1,
526           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
527           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebaca", 16)),
528       new EcPublicKeyTestVector(
529           "public point = (0,0)",
530           "3059301306072a8648ce3d020106082a8648ce3d030107034200040000000000"
531               + "0000000000000000000000000000000000000000000000000000000000000000"
532               + "000000000000000000000000000000000000000000000000000000",
533           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
534           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16),
535           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
536           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
537           new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16),
538           new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16),
539           1,
540           new BigInteger("0"),
541           new BigInteger("0")),
542       new EcPublicKeyTestVector(
543           "order = 1",
544           "308201133081cc06072a8648ce3d02013081c0020101302c06072a8648ce3d01"
545               + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff"
546               + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff"
547               + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53"
548               + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d"
549               + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33"
550               + "576b315ececbb6406837bf51f502010102010103420004cdeb39edd03e2b1a11"
551               + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b"
552               + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8",
553           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
554           new BigInteger("01", 16),
555           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
556           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
557           new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16),
558           new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16),
559           1,
560           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
561           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)),
562       new EcPublicKeyTestVector(
563           "order = 26959946660873538060741835960514744168612397095220107664918121663170",
564           "3082012f3081e806072a8648ce3d02013081dc020101302c06072a8648ce3d01"
565               + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff"
566               + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff"
567               + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53"
568               + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d"
569               + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33"
570               + "576b315ececbb6406837bf51f5021d00ffffffff00000000ffffffffffffffff"
571               + "bce6faada7179e84f3b9cac202010103420004cdeb39edd03e2b1a11a5e134ec"
572               + "99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b49bbb85c"
573               + "3303ddb1553c3b761c2caacca71606ba9ebac8",
574           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
575           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2", 16),
576           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
577           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
578           new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16),
579           new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16),
580           1,
581           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
582           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)),
583       new EcPublicKeyTestVector(
584           "generator = (0,0)",
585           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
586               + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff"
587               + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff"
588               + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53"
589               + "b0f63bce3c3e27d2604b04410400000000000000000000000000000000000000"
590               + "0000000000000000000000000000000000000000000000000000000000000000"
591               + "00000000000000000000000000022100ffffffff00000000ffffffffffffffff"
592               + "bce6faada7179e84f3b9cac2fc63255102010103420004cdeb39edd03e2b1a11"
593               + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b"
594               + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8",
595           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
596           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16),
597           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
598           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
599           new BigInteger("0"),
600           new BigInteger("0"),
601           1,
602           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
603           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)),
604       new EcPublicKeyTestVector(
605           "generator not on curve",
606           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
607               + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff"
608               + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff"
609               + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53"
610               + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d"
611               + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33"
612               + "576b315ececbb6406837bf51f7022100ffffffff00000000ffffffffffffffff"
613               + "bce6faada7179e84f3b9cac2fc63255102010103420004cdeb39edd03e2b1a11"
614               + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b"
615               + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8",
616           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
617           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16),
618           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
619           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
620           new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16),
621           new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f7", 16),
622           1,
623           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
624           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)),
625       new EcPublicKeyTestVector(
626           "cofactor = 2",
627           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
628               + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff"
629               + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff"
630               + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53"
631               + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d"
632               + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33"
633               + "576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffff"
634               + "bce6faada7179e84f3b9cac2fc63255102010203420004cdeb39edd03e2b1a11"
635               + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b"
636               + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8",
637           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
638           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16),
639           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
640           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
641           new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16),
642           new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16),
643           2,
644           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
645           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)),
646       new EcPublicKeyTestVector(
647           "cofactor = None",
648           "308201303081e906072a8648ce3d02013081dd020101302c06072a8648ce3d01"
649               + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff"
650               + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff"
651               + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53"
652               + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d"
653               + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33"
654               + "576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffff"
655               + "bce6faada7179e84f3b9cac2fc63255103420004cdeb39edd03e2b1a11a5e134"
656               + "ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b49bbb8"
657               + "5c3303ddb1553c3b761c2caacca71606ba9ebac8",
658           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
659           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16),
660           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
661           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
662           new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16),
663           new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16),
664           null,
665           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
666           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)),
667       new EcPublicKeyTestVector(
668           "modified prime",
669           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
670               + "01022100fd091059a6893635f900e9449d63f572b2aebc4cff7b4e5e33f1b200"
671               + "e8bbc1453044042002f6efa55976c9cb06ff16bb629c0a8d4d5143b40084b1a1"
672               + "cc0e4dff17443eb704205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53"
673               + "b0f63bce3c3e27d2604b0441040000000000000000000006597fa94b1fd90000"
674               + "000000000000000000000000021b8c7dd77f9a95627922eceefea73f028f1ec9"
675               + "5ba9b8fa95a3ad24bdf9fff414022100ffffffff00000000ffffffffffffffff"
676               + "bce6faada7179e84f3b9cac2fc63255102010103420004000000000000000000"
677               + "0006597fa94b1fd90000000000000000000000000000021b8c7dd77f9a956279"
678               + "22eceefea73f028f1ec95ba9b8fa95a3ad24bdf9fff414",
679           new BigInteger("fd091059a6893635f900e9449d63f572b2aebc4cff7b4e5e33f1b200e8bbc145", 16),
680           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16),
681           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
682           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
683           new BigInteger("06597fa94b1fd9000000000000000000000000000002", 16),
684           new BigInteger("1b8c7dd77f9a95627922eceefea73f028f1ec95ba9b8fa95a3ad24bdf9fff414", 16),
685           1,
686           new BigInteger("06597fa94b1fd9000000000000000000000000000002", 16),
687           new BigInteger("1b8c7dd77f9a95627922eceefea73f028f1ec95ba9b8fa95a3ad24bdf9fff414", 16)),
688       new EcPublicKeyTestVector(
689           "using secp224r1",
690           "304e301006072a8648ce3d020106052b81040021033a0004074f56dc2ea648ef"
691               + "89c3b72e23bbd2da36f60243e4d2067b70604af1c2165cec2f86603d60c8a611"
692               + "d5b84ba3d91dfe1a480825bcc4af3bcf",
693           new BigInteger("ffffffffffffffffffffffffffffffff000000000000000000000001", 16),
694           new BigInteger("ffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d", 16),
695           new BigInteger("fffffffffffffffffffffffffffffffefffffffffffffffffffffffe", 16),
696           new BigInteger("b4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", 16),
697           new BigInteger("b70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", 16),
698           new BigInteger("bd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", 16),
699           1,
700           new BigInteger("074f56dc2ea648ef89c3b72e23bbd2da36f60243e4d2067b70604af1", 16),
701           new BigInteger("c2165cec2f86603d60c8a611d5b84ba3d91dfe1a480825bcc4af3bcf", 16)),
702       new EcPublicKeyTestVector(
703           "a = 0",
704           "308201143081cd06072a8648ce3d02013081c1020101302c06072a8648ce3d01"
705               + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff"
706               + "ffffffff30250401000420f104880c3980129c7efa19b6b0cb04e547b8d0fc0b"
707               + "95f4946496dd4ac4a7c440044104cdeb39edd03e2b1a11a5e134ec99d5f25f21"
708               + "673d403f3ecb47bd1fa676638958ea58493b8429598c0b49bbb85c3303ddb155"
709               + "3c3b761c2caacca71606ba9ebac8022100ffffffff00000000ffffffffffffff"
710               + "ffbce6faada7179e84f3b9cac2fc63255102010103420004cdeb39edd03e2b1a"
711               + "11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c"
712               + "0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8",
713           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
714           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16),
715           new BigInteger("0"),
716           new BigInteger("f104880c3980129c7efa19b6b0cb04e547b8d0fc0b95f4946496dd4ac4a7c440", 16),
717           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
718           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16),
719           1,
720           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
721           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)),
722       new EcPublicKeyTestVector(
723           "new curve with generator of order 3 that is also on secp256r1",
724           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
725               + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff"
726               + "ffffffff3044042046dc879a5c2995d0e6f682468ea95791b7bbd0225cfdb251"
727               + "3fb10a737afece170420bea6c109251bfe4acf2eeda7c24c4ab70a1473335dec"
728               + "28b244d4d823d15935e2044104701c05255026aa4630b78fc6b769e388059ab1"
729               + "443cbdd1f8348bedc3be589dc34cfdab998ad27738ae382aa013986ade0f4859"
730               + "2a9a1ae37ca61d25ec5356f1bd022100ffffffff00000000ffffffffffffffff"
731               + "bce6faada7179e84f3b9cac2fc63255102010103420004701c05255026aa4630"
732               + "b78fc6b769e388059ab1443cbdd1f8348bedc3be589dc3b3025465752d88c851"
733               + "c7d55fec679521f0b7a6d665e51c8359e2da13aca90e42",
734           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
735           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16),
736           new BigInteger("46dc879a5c2995d0e6f682468ea95791b7bbd0225cfdb2513fb10a737afece17", 16),
737           new BigInteger("bea6c109251bfe4acf2eeda7c24c4ab70a1473335dec28b244d4d823d15935e2", 16),
738           new BigInteger("701c05255026aa4630b78fc6b769e388059ab1443cbdd1f8348bedc3be589dc3", 16),
739           new BigInteger("4cfdab998ad27738ae382aa013986ade0f48592a9a1ae37ca61d25ec5356f1bd", 16),
740           1,
741           new BigInteger("701c05255026aa4630b78fc6b769e388059ab1443cbdd1f8348bedc3be589dc3", 16),
742           new BigInteger("b3025465752d88c851c7d55fec679521f0b7a6d665e51c8359e2da13aca90e42", 16)),
743       // Invalid keys
744       new EcPublicKeyTestVector(
745           "order = -1157920892103562487626974469494075735299969552241357603"
746               + "42422259061068512044369",
747           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
748               + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff"
749               + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff"
750               + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53"
751               + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d"
752               + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33"
753               + "576b315ececbb6406837bf51f50221ff00000000ffffffff0000000000000000"
754               + "4319055258e8617b0c46353d039cdaaf02010103420004cdeb39edd03e2b1a11"
755               + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b"
756               + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8",
757           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
758           new BigInteger(
759               "-115792089210356248762697446949407573529996955224135760342422259061068512044369"),
760           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
761           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
762           new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16),
763           new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16),
764           1,
765           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
766           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)),
767       new EcPublicKeyTestVector(
768           "order = 0",
769           "308201133081cc06072a8648ce3d02013081c0020101302c06072a8648ce3d01"
770               + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff"
771               + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff"
772               + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53"
773               + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d"
774               + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33"
775               + "576b315ececbb6406837bf51f502010002010103420004cdeb39edd03e2b1a11"
776               + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b"
777               + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8",
778           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
779           new BigInteger("0"),
780           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
781           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
782           new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16),
783           new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16),
784           1,
785           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
786           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)),
787       new EcPublicKeyTestVector(
788           "cofactor = -1",
789           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
790               + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff"
791               + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff"
792               + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53"
793               + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d"
794               + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33"
795               + "576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffff"
796               + "bce6faada7179e84f3b9cac2fc6325510201ff03420004cdeb39edd03e2b1a11"
797               + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b"
798               + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8",
799           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
800           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16),
801           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
802           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
803           new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16),
804           new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16),
805           -1,
806           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
807           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)),
808       new EcPublicKeyTestVector(
809           "cofactor = 0",
810           "308201333081ec06072a8648ce3d02013081e0020101302c06072a8648ce3d01"
811               + "01022100ffffffff00000001000000000000000000000000ffffffffffffffff"
812               + "ffffffff30440420ffffffff00000001000000000000000000000000ffffffff"
813               + "fffffffffffffffc04205ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53"
814               + "b0f63bce3c3e27d2604b0441046b17d1f2e12c4247f8bce6e563a440f277037d"
815               + "812deb33a0f4a13945d898c2964fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33"
816               + "576b315ececbb6406837bf51f5022100ffffffff00000000ffffffffffffffff"
817               + "bce6faada7179e84f3b9cac2fc63255102010003420004cdeb39edd03e2b1a11"
818               + "a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958ea58493b8429598c0b"
819               + "49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8",
820           new BigInteger("ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", 16),
821           new BigInteger("ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", 16),
822           new BigInteger("ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", 16),
823           new BigInteger("5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", 16),
824           new BigInteger("6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", 16),
825           new BigInteger("4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", 16),
826           0,
827           new BigInteger("cdeb39edd03e2b1a11a5e134ec99d5f25f21673d403f3ecb47bd1fa676638958", 16),
828           new BigInteger("ea58493b8429598c0b49bbb85c3303ddb1553c3b761c2caacca71606ba9ebac8", 16)),
829   };
830 
831   /** Checks that key agreement using ECDH works. */
832   @ExcludedTest(
833       providers = {ProviderType.BOUNCY_CASTLE},
834       comment = "KeyPairGenerator.EC is removed")
testBasic()835   public void testBasic() throws Exception {
836     KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
837     ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256r1");
838     keyGen.initialize(ecSpec);
839     KeyPair keyPairA = keyGen.generateKeyPair();
840     KeyPair keyPairB = keyGen.generateKeyPair();
841 
842     KeyAgreement kaA = KeyAgreement.getInstance("ECDH");
843     KeyAgreement kaB = KeyAgreement.getInstance("ECDH");
844     kaA.init(keyPairA.getPrivate());
845     kaB.init(keyPairB.getPrivate());
846     kaA.doPhase(keyPairB.getPublic(), true);
847     kaB.doPhase(keyPairA.getPublic(), true);
848     byte[] kAB = kaA.generateSecret();
849     byte[] kBA = kaB.generateSecret();
850     assertEquals(TestUtil.bytesToHex(kAB), TestUtil.bytesToHex(kBA));
851   }
852 
853   @ExcludedTest(
854       providers = {ProviderType.BOUNCY_CASTLE},
855       comment = "KeyAgreement.ECDH is removed")
testVectors()856   public void testVectors() throws Exception {
857     KeyAgreement ka = KeyAgreement.getInstance("ECDH");
858     for (EcdhTestVector t : ECDH_TEST_VECTORS) {
859       try {
860         ka.init(t.getPrivateKey());
861         ka.doPhase(t.getPublicKey(), true);
862         byte[] shared = ka.generateSecret();
863         assertEquals("Curve:" + t.curvename, TestUtil.bytesToHex(shared), t.shared);
864       } catch (NoSuchAlgorithmException | InvalidKeySpecException ex) {
865         // Skipped, because the provider does not support the curve.
866       }
867     }
868   }
869 
870   @ExcludedTest(
871       providers = {ProviderType.BOUNCY_CASTLE},
872       comment = "KeyFactory.EC is removed")
testDecode()873   public void testDecode() throws Exception {
874     KeyFactory kf = KeyFactory.getInstance("EC");
875     ECPublicKey key1 = (ECPublicKey) kf.generatePublic(EC_VALID_PUBLIC_KEY.getSpec());
876     ECPublicKey key2 = (ECPublicKey) kf.generatePublic(EC_VALID_PUBLIC_KEY.getX509EncodedKeySpec());
877     ECParameterSpec params1 = key1.getParams();
878     ECParameterSpec params2 = key2.getParams();
879     assertEquals(params1.getCofactor(), params2.getCofactor());
880     assertEquals(params1.getCurve(), params2.getCurve());
881     assertEquals(params1.getGenerator(), params2.getGenerator());
882     assertEquals(params1.getOrder(), params2.getOrder());
883     assertEquals(key1.getW(), key2.getW());
884   }
885 
886   /**
887    * This test modifies the order of group in the public key. A severe bug would be an
888    * implementation that leaks information whether the private key is larger than the order given in
889    * the public key. Also a severe bug would be to reduce the private key modulo the order given in
890    * the public key parameters.
891    */
892   @SuppressWarnings("InsecureCryptoUsage")
testModifiedPublic(String algorithm)893   public void testModifiedPublic(String algorithm) throws Exception {
894     KeyAgreement ka;
895     try {
896       ka = KeyAgreement.getInstance(algorithm);
897     } catch (NoSuchAlgorithmException ex) {
898       System.out.println("testWrongOrder: " + algorithm + " not supported");
899       return;
900     }
901     KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
902     keyGen.initialize(EcUtil.getNistP256Params());
903     ECPrivateKey priv = (ECPrivateKey) keyGen.generateKeyPair().getPrivate();
904     KeyFactory kf = KeyFactory.getInstance("EC");
905     ECPublicKey validKey = (ECPublicKey) kf.generatePublic(EC_VALID_PUBLIC_KEY.getSpec());
906     ka.init(priv);
907     ka.doPhase(validKey, true);
908     String expected = TestUtil.bytesToHex(ka.generateSecret());
909     for (EcPublicKeyTestVector test : EC_MODIFIED_PUBLIC_KEYS) {
910       try {
911         X509EncodedKeySpec spec = test.getX509EncodedKeySpec();
912         ECPublicKey modifiedKey = (ECPublicKey) kf.generatePublic(spec);
913         ka.init(priv);
914         ka.doPhase(modifiedKey, true);
915         String shared = TestUtil.bytesToHex(ka.generateSecret());
916         // The implementation did not notice that the public key was modified.
917         // This is not nice, but at the moment we only fail the test if the
918         // modification was essential for computing the shared secret.
919         //
920         // BouncyCastle v.1.53 fails this test, for ECDHC with modified order.
921         // This implementation reduces the product s*h modulo the order given
922         // in the public key. An attacker who can modify the order of the public key
923         // and who can learn whether such a modification changes the shared secret is
924         // able to learn the private key with a simple binary search.
925         assertEquals("algorithm:" + algorithm + " test:" + test.comment, expected, shared);
926       } catch (GeneralSecurityException ex) {
927         // OK, since the public keys have been modified.
928         System.out.println("testModifiedPublic:" + test.comment + " throws " + ex.toString());
929       }
930     }
931   }
932 
933   /**
934    * This is a similar test as testModifiedPublic. However, this test uses test vectors
935    * ECPublicKeySpec
936    */
937   @SuppressWarnings("InsecureCryptoUsage")
testModifiedPublicSpec(String algorithm)938   public void testModifiedPublicSpec(String algorithm) throws Exception {
939     KeyAgreement ka;
940     try {
941       ka = KeyAgreement.getInstance(algorithm);
942     } catch (NoSuchAlgorithmException ex) {
943       System.out.println("testWrongOrder: " + algorithm + " not supported");
944       return;
945     }
946     KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
947     keyGen.initialize(EcUtil.getNistP256Params());
948     ECPrivateKey priv = (ECPrivateKey) keyGen.generateKeyPair().getPrivate();
949     KeyFactory kf = KeyFactory.getInstance("EC");
950     ECPublicKey validKey = (ECPublicKey) kf.generatePublic(EC_VALID_PUBLIC_KEY.getSpec());
951     ka.init(priv);
952     ka.doPhase(validKey, true);
953     String expected = TestUtil.bytesToHex(ka.generateSecret());
954     for (EcPublicKeyTestVector test : EC_MODIFIED_PUBLIC_KEYS) {
955       ECPublicKeySpec spec = test.getSpec();
956       if (spec == null) {
957         // The constructor of EcPublicKeySpec performs some very minor validity checks.
958         // spec == null if one of these validity checks fails. Of course such a failure is OK.
959         continue;
960       }
961       try {
962         ECPublicKey modifiedKey = (ECPublicKey) kf.generatePublic(spec);
963         ka.init(priv);
964         ka.doPhase(modifiedKey, true);
965         String shared = TestUtil.bytesToHex(ka.generateSecret());
966         // The implementation did not notice that the public key was modified.
967         // This is not nice, but at the moment we only fail the test if the
968         // modification was essential for computing the shared secret.
969         //
970         // BouncyCastle v.1.53 fails this test, for ECDHC with modified order.
971         // This implementation reduces the product s*h modulo the order given
972         // in the public key. An attacker who can modify the order of the public key
973         // and who can learn whether such a modification changes the shared secret is
974         // able to learn the private key with a simple binary search.
975         assertEquals("algorithm:" + algorithm + " test:" + test.comment, expected, shared);
976       } catch (GeneralSecurityException ex) {
977         // OK, since the public keys have been modified.
978         System.out.println("testModifiedPublic:" + test.comment + " throws " + ex.toString());
979       }
980     }
981   }
982 
testModifiedPublic()983   public void testModifiedPublic() throws Exception {
984     testModifiedPublic("ECDH");
985     testModifiedPublic("ECDHC");
986   }
987 
testModifiedPublicSpec()988   public void testModifiedPublicSpec() throws Exception {
989     testModifiedPublicSpec("ECDH");
990     testModifiedPublicSpec("ECDHC");
991   }
992 
993   @SuppressWarnings("InsecureCryptoUsage")
testDistinctCurves(String algorithm, ECPrivateKey priv, ECPublicKey pub)994   public void testDistinctCurves(String algorithm, ECPrivateKey priv, ECPublicKey pub)
995       throws Exception {
996     KeyAgreement kaA;
997     try {
998       kaA = KeyAgreement.getInstance(algorithm);
999     } catch (NoSuchAlgorithmException ex) {
1000       System.out.println("Algorithm not supported: " + algorithm);
1001       return;
1002     }
1003     byte[] shared;
1004     try {
1005       kaA.init(priv);
1006       kaA.doPhase(pub, true);
1007       shared = kaA.generateSecret();
1008     } catch (InvalidKeyException ex) {
1009       // This is expected.
1010       return;
1011     }
1012     // Printing some information to determine what might have gone wrong:
1013     // E.g., if the generated secret is the same as the x-coordinate of the public key
1014     // then it is likely that the ECDH computation was using a fake group with small order.
1015     // Such a situation is probably exploitable.
1016     // This probably is exploitable. If the curve of the private key was used for the ECDH
1017     // then the generated secret and the x-coordinate of the public key are likely
1018     // distinct.
1019     EllipticCurve pubCurve = pub.getParams().getCurve();
1020     EllipticCurve privCurve = priv.getParams().getCurve();
1021     ECPoint pubW = pub.getW();
1022     System.out.println("testDistinctCurves: algorithm=" + algorithm);
1023     System.out.println(
1024         "Private key: a="
1025             + privCurve.getA()
1026             + " b="
1027             + privCurve.getB()
1028             + " p"
1029             + EcUtil.getModulus(privCurve));
1030     System.out.println("        s =" + priv.getS());
1031     System.out.println(
1032         "Public key: a="
1033             + pubCurve.getA()
1034             + " b="
1035             + pubCurve.getB()
1036             + " p"
1037             + EcUtil.getModulus(pubCurve));
1038     System.out.println("        w = (" + pubW.getAffineX() + ", " + pubW.getAffineY() + ")");
1039     System.out.println(
1040         "          = ("
1041             + pubW.getAffineX().toString(16)
1042             + ", "
1043             + pubW.getAffineY().toString(16)
1044             + ")");
1045     System.out.println("generated shared secret:" + TestUtil.bytesToHex(shared));
1046     fail("Generated secret with distinct Curves using " + algorithm);
1047   }
1048 
1049   /**
1050    * This test modifies the order of group in the public key. A severe bug would be an
1051    * implementation that leaks information whether the private key is larger than the order given in
1052    * the public key. Also a severe bug would be to reduce the private key modulo the order given in
1053    * the public key parameters.
1054    */
1055   // TODO(bleichen): This can be merged with testModifiedPublic once this is fixed.
1056   @SuppressWarnings("InsecureCryptoUsage")
testWrongOrder(String algorithm, ECParameterSpec spec)1057   public void testWrongOrder(String algorithm, ECParameterSpec spec) throws Exception {
1058     KeyAgreement ka;
1059     try {
1060       ka = KeyAgreement.getInstance(algorithm);
1061     } catch (NoSuchAlgorithmException ex) {
1062       System.out.println("testWrongOrder: " + algorithm + " not supported");
1063       return;
1064     }
1065     KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
1066     ECPrivateKey priv;
1067     ECPublicKey pub;
1068     try {
1069       keyGen.initialize(spec);
1070       priv = (ECPrivateKey) keyGen.generateKeyPair().getPrivate();
1071       pub = (ECPublicKey) keyGen.generateKeyPair().getPublic();
1072     } catch (GeneralSecurityException ex) {
1073       // This is OK, since not all provider support Brainpool curves
1074       System.out.println("testWrongOrder: could not generate keys for curve");
1075       return;
1076     }
1077     // Get the shared secret for the unmodified keys.
1078     ka.init(priv);
1079     ka.doPhase(pub, true);
1080     byte[] shared = ka.generateSecret();
1081     // Generate a modified public key.
1082     ECParameterSpec modifiedParams =
1083         new ECParameterSpec(
1084             spec.getCurve(), spec.getGenerator(), spec.getOrder().shiftRight(16), 1);
1085     ECPublicKeySpec modifiedPubSpec = new ECPublicKeySpec(pub.getW(), modifiedParams);
1086     KeyFactory kf = KeyFactory.getInstance("EC");
1087     ECPublicKey modifiedPub;
1088     try {
1089       modifiedPub = (ECPublicKey) kf.generatePublic(modifiedPubSpec);
1090     } catch (GeneralSecurityException ex) {
1091       // The provider does not support non-standard curves or did a validity check.
1092       // Both would be correct.
1093       System.out.println("testWrongOrder: can't modify order.");
1094       return;
1095     }
1096     byte[] shared2;
1097     try {
1098       ka.init(priv);
1099       ka.doPhase(modifiedPub, true);
1100       shared2 = ka.generateSecret();
1101     } catch (GeneralSecurityException ex) {
1102       // This is the expected behavior
1103       System.out.println("testWrongOrder:" + ex.toString());
1104       return;
1105     }
1106     // TODO(bleichen): Getting here is already a bug and we might flag this later.
1107     // At the moment we are only interested in really bad behavior of a library, that potentially
1108     // leaks the secret key. This is the case when the shared secrets are different, since this
1109     // suggests that the implementation reduces the multiplier modulo the given order of the curve
1110     // or some other behaviour that is dependent on the private key.
1111     // An attacker who can check whether a DH computation was done correctly or incorrectly because
1112     // of modular reduction, can determine the private key, either by a binary search or by trying
1113     // to guess the private key modulo some small "order".
1114     // BouncyCastle v.1.53 fails this test, and leaks the private key.
1115     System.out.println(
1116         "Generated shared secret with a modified order:"
1117             + algorithm
1118             + "\n"
1119             + "expected:"
1120             + TestUtil.bytesToHex(shared)
1121             + " computed:"
1122             + TestUtil.bytesToHex(shared2));
1123     assertEquals(
1124         "Algorithm:" + algorithm, TestUtil.bytesToHex(shared), TestUtil.bytesToHex(shared2));
1125   }
1126 
testWrongOrderEcdh()1127   public void testWrongOrderEcdh() throws Exception {
1128     testWrongOrder("ECDH", EcUtil.getNistP256Params());
1129     testWrongOrder("ECDH", EcUtil.getBrainpoolP256r1Params());
1130   }
1131 
testWrongOrderEcdhc()1132   public void testWrongOrderEcdhc() throws Exception {
1133     testWrongOrder("ECDHC", EcUtil.getNistP256Params());
1134     testWrongOrder("ECDHC", EcUtil.getBrainpoolP256r1Params());
1135   }
1136 }
1137