@Test
public void testComputeSharedSecretWithWycheproofVectors() throws Exception {

  JSONObject json =
      WycheproofTestUtil.readJson("../wycheproof/testvectors/x25519_test.json");
  int errors = 0;
  int cntSkippedTests = 0;
  JSONArray testGroups = json.getJSONArray("testGroups");
  for (int i = 0; i < testGroups.length(); i++) {
    JSONObject group = testGroups.getJSONObject(i);
    JSONArray tests = group.getJSONArray("tests");
    String curve = group.getString("curve");
    for (int j = 0; j < tests.length(); j++) {
      JSONObject testcase = tests.getJSONObject(j);
      String tcId =
          String.format(
              "testcase %d (%s)", testcase.getInt("tcId"), testcase.getString("comment"));
      String result = testcase.getString("result");
      String hexPubKey = testcase.getString("public");
      String hexPrivKey = testcase.getString("private");
      String expectedSharedSecret = testcase.getString("shared");
      if (!curve.equals("curve25519")) {
        System.out.printf("Skipping %s, unknown curve name: %s", tcId, curve);
        cntSkippedTests++;
        continue;
      }
      try {
        String sharedSecret =
            Hex.encode(X25519.computeSharedSecret(Hex.decode(hexPrivKey), Hex.decode(hexPubKey)));
        if (result.equals("invalid")) {
          System.out.printf(
              "FAIL %s: accepting invalid parameters, shared secret: %s%n", tcId, sharedSecret);
          errors++;
        } else if (!expectedSharedSecret.equals(sharedSecret)) {
          System.out.printf(
              "FAIL %s: incorrect shared secret, computed: %s, expected: %s%n",
              tcId, sharedSecret, expectedSharedSecret);
          errors++;
        }
      } catch (GeneralSecurityException ex) {
        if (result.equals("valid")) {
          System.out.printf("FAIL %s, exception %s%n", tcId, ex);
          errors++;
        }
      } catch (Exception ex) {
        // Other exceptions typically indicate that something is wrong with the implementation.
        System.out.printf("FAIL %s, exception %s%n", tcId, ex);
        errors++;
      }
    }
  }
  System.out.printf("Number of tests skipped: %d", cntSkippedTests);
  assertEquals(0, errors);
}