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