/* Copyright (c) 2014, Google Inc.
 *
 * Permission to use, copy, modify, and/or distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#include <stdio.h>
#include <string.h>

#include <vector>

#include <openssl/bn.h>
#include <openssl/bytestring.h>
#include <openssl/crypto.h>
#include <openssl/ec_key.h>
#include <openssl/err.h>
#include <openssl/mem.h>
#include <openssl/obj.h>


namespace bssl {

// kECKeyWithoutPublic is an ECPrivateKey with the optional publicKey field
// omitted.
static const uint8_t kECKeyWithoutPublic[] = {
  0x30, 0x31, 0x02, 0x01, 0x01, 0x04, 0x20, 0xc6, 0xc1, 0xaa, 0xda, 0x15, 0xb0,
  0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb, 0x24, 0x1a, 0xff, 0x2e,
  0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77,
  0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07,
};

// kECKeySpecifiedCurve is the above key with P-256's parameters explicitly
// spelled out rather than using a named curve.
static const uint8_t kECKeySpecifiedCurve[] = {
    0x30, 0x82, 0x01, 0x22, 0x02, 0x01, 0x01, 0x04, 0x20, 0xc6, 0xc1, 0xaa,
    0xda, 0x15, 0xb0, 0x76, 0x61, 0xf8, 0x14, 0x2c, 0x6c, 0xaf, 0x0f, 0xdb,
    0x24, 0x1a, 0xff, 0x2e, 0xfe, 0x46, 0xc0, 0x93, 0x8b, 0x74, 0xf2, 0xbc,
    0xc5, 0x30, 0x52, 0xb0, 0x77, 0xa0, 0x81, 0xfa, 0x30, 0x81, 0xf7, 0x02,
    0x01, 0x01, 0x30, 0x2c, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01,
    0x01, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
    0x30, 0x5b, 0x04, 0x20, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
    0x04, 0x20, 0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb,
    0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
    0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b, 0x03, 0x15,
    0x00, 0xc4, 0x9d, 0x36, 0x08, 0x86, 0xe7, 0x04, 0x93, 0x6a, 0x66, 0x78,
    0xe1, 0x13, 0x9d, 0x26, 0xb7, 0x81, 0x9f, 0x7e, 0x90, 0x04, 0x41, 0x04,
    0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5,
    0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0,
    0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2,
    0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16,
    0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
    0x37, 0xbf, 0x51, 0xf5, 0x02, 0x21, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
    0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xbc,
    0xe6, 0xfa, 0xad, 0xa7, 0x17, 0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc,
    0x63, 0x25, 0x51, 0x02, 0x01, 0x01,
};

// kECKeyMissingZeros is an ECPrivateKey containing a degenerate P-256 key where
// the private key is one. The private key is incorrectly encoded without zero
// padding.
static const uint8_t kECKeyMissingZeros[] = {
  0x30, 0x58, 0x02, 0x01, 0x01, 0x04, 0x01, 0x01, 0xa0, 0x0a, 0x06, 0x08, 0x2a,
  0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04,
  0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6, 0xe5, 0x63,
  0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, 0xf4, 0xa1,
  0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f,
  0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57,
  0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
};

// kECKeyMissingZeros is an ECPrivateKey containing a degenerate P-256 key where
// the private key is one. The private key is encoded with the required zero
// padding.
static const uint8_t kECKeyWithZeros[] = {
  0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
  0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0xa1,
  0x44, 0x03, 0x42, 0x00, 0x04, 0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47,
  0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d,
  0xeb, 0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96, 0x4f, 0xe3,
  0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e,
  0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68,
  0x37, 0xbf, 0x51, 0xf5,
};

// DecodeECPrivateKey decodes |in| as an ECPrivateKey structure and returns the
// result or nullptr on error.
static ScopedEC_KEY DecodeECPrivateKey(const uint8_t *in, size_t in_len) {
  CBS cbs;
  CBS_init(&cbs, in, in_len);
  ScopedEC_KEY ret(EC_KEY_parse_private_key(&cbs, NULL));
  if (!ret || CBS_len(&cbs) != 0) {
    return nullptr;
  }
  return ret;
}

// EncodeECPrivateKey encodes |key| as an ECPrivateKey structure into |*out|. It
// returns true on success or false on error.
static bool EncodeECPrivateKey(std::vector<uint8_t> *out, const EC_KEY *key) {
  ScopedCBB cbb;
  uint8_t *der;
  size_t der_len;
  if (!CBB_init(cbb.get(), 0) ||
      !EC_KEY_marshal_private_key(cbb.get(), key, EC_KEY_get_enc_flags(key)) ||
      !CBB_finish(cbb.get(), &der, &der_len)) {
    return false;
  }
  out->assign(der, der + der_len);
  OPENSSL_free(der);
  return true;
}

static bool Testd2i_ECPrivateKey() {
  ScopedEC_KEY key = DecodeECPrivateKey(kECKeyWithoutPublic,
                                        sizeof(kECKeyWithoutPublic));
  if (!key) {
    fprintf(stderr, "Failed to parse private key.\n");
    ERR_print_errors_fp(stderr);
    return false;
  }

  std::vector<uint8_t> out;
  if (!EncodeECPrivateKey(&out, key.get())) {
    fprintf(stderr, "Failed to serialize private key.\n");
    ERR_print_errors_fp(stderr);
    return false;
  }

  if (std::vector<uint8_t>(kECKeyWithoutPublic,
                           kECKeyWithoutPublic + sizeof(kECKeyWithoutPublic)) !=
      out) {
    fprintf(stderr, "Serialisation of key doesn't match original.\n");
    return false;
  }

  const EC_POINT *pub_key = EC_KEY_get0_public_key(key.get());
  if (pub_key == NULL) {
    fprintf(stderr, "Public key missing.\n");
    return false;
  }

  ScopedBIGNUM x(BN_new());
  ScopedBIGNUM y(BN_new());
  if (!x || !y) {
    return false;
  }
  if (!EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(key.get()),
                                           pub_key, x.get(), y.get(), NULL)) {
    fprintf(stderr, "Failed to get public key in affine coordinates.\n");
    return false;
  }
  ScopedString x_hex(BN_bn2hex(x.get()));
  ScopedString y_hex(BN_bn2hex(y.get()));
  if (!x_hex || !y_hex) {
    return false;
  }
  if (0 != strcmp(
          x_hex.get(),
          "c81561ecf2e54edefe6617db1c7a34a70744ddb261f269b83dacfcd2ade5a681") ||
      0 != strcmp(
          y_hex.get(),
          "e0e2afa3f9b6abe4c698ef6495f1be49a3196c5056acb3763fe4507eec596e88")) {
    fprintf(stderr, "Incorrect public key: %s %s\n", x_hex.get(), y_hex.get());
    return false;
  }

  return true;
}

static bool TestZeroPadding() {
  // Check that the correct encoding round-trips.
  ScopedEC_KEY key = DecodeECPrivateKey(kECKeyWithZeros,
                                        sizeof(kECKeyWithZeros));
  std::vector<uint8_t> out;
  if (!key || !EncodeECPrivateKey(&out, key.get())) {
    ERR_print_errors_fp(stderr);
    return false;
  }

  if (std::vector<uint8_t>(kECKeyWithZeros,
                           kECKeyWithZeros + sizeof(kECKeyWithZeros)) != out) {
    fprintf(stderr, "Serialisation of key was incorrect.\n");
    return false;
  }

  // Keys without leading zeros also parse, but they encode correctly.
  key = DecodeECPrivateKey(kECKeyMissingZeros, sizeof(kECKeyMissingZeros));
  if (!key || !EncodeECPrivateKey(&out, key.get())) {
    ERR_print_errors_fp(stderr);
    return false;
  }

  if (std::vector<uint8_t>(kECKeyWithZeros,
                           kECKeyWithZeros + sizeof(kECKeyWithZeros)) != out) {
    fprintf(stderr, "Serialisation of key was incorrect.\n");
    return false;
  }

  return true;
}

static bool TestSpecifiedCurve() {
  // Test keys with specified curves may be decoded.
  ScopedEC_KEY key =
      DecodeECPrivateKey(kECKeySpecifiedCurve, sizeof(kECKeySpecifiedCurve));
  if (!key) {
    ERR_print_errors_fp(stderr);
    return false;
  }

  // The group should have been interpreted as P-256.
  if (EC_GROUP_get_curve_name(EC_KEY_get0_group(key.get())) !=
      NID_X9_62_prime256v1) {
    fprintf(stderr, "Curve name incorrect.\n");
    return false;
  }

  // Encoding the key should still use named form.
  std::vector<uint8_t> out;
  if (!EncodeECPrivateKey(&out, key.get())) {
    ERR_print_errors_fp(stderr);
    return false;
  }
  if (std::vector<uint8_t>(kECKeyWithoutPublic,
                           kECKeyWithoutPublic + sizeof(kECKeyWithoutPublic)) !=
      out) {
    fprintf(stderr, "Serialisation of key was incorrect.\n");
    return false;
  }

  return true;
}

static bool TestSetAffine(const int nid) {
  ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
  if (!key) {
    return false;
  }

  const EC_GROUP *const group = EC_KEY_get0_group(key.get());

  if (!EC_KEY_generate_key(key.get())) {
    fprintf(stderr, "EC_KEY_generate_key failed with nid %d\n", nid);
    ERR_print_errors_fp(stderr);
    return false;
  }

  if (!EC_POINT_is_on_curve(group, EC_KEY_get0_public_key(key.get()),
                            nullptr)) {
    fprintf(stderr, "generated point is not on curve with nid %d", nid);
    ERR_print_errors_fp(stderr);
    return false;
  }

  ScopedBIGNUM x(BN_new());
  ScopedBIGNUM y(BN_new());
  if (!EC_POINT_get_affine_coordinates_GFp(group,
                                           EC_KEY_get0_public_key(key.get()),
                                           x.get(), y.get(), nullptr)) {
    fprintf(stderr, "EC_POINT_get_affine_coordinates_GFp failed with nid %d\n",
            nid);
    ERR_print_errors_fp(stderr);
    return false;
  }

  ScopedEC_POINT point(EC_POINT_new(group));
  if (!point) {
    return false;
  }

  if (!EC_POINT_set_affine_coordinates_GFp(group, point.get(), x.get(), y.get(),
                                           nullptr)) {
    fprintf(stderr, "EC_POINT_set_affine_coordinates_GFp failed with nid %d\n",
            nid);
    ERR_print_errors_fp(stderr);
    return false;
  }

  // Subtract one from |y| to make the point no longer on the curve.
  if (!BN_sub(y.get(), y.get(), BN_value_one())) {
    return false;
  }

  ScopedEC_POINT invalid_point(EC_POINT_new(group));
  if (!invalid_point) {
    return false;
  }

  if (EC_POINT_set_affine_coordinates_GFp(group, invalid_point.get(), x.get(),
                                          y.get(), nullptr)) {
    fprintf(stderr,
            "EC_POINT_set_affine_coordinates_GFp succeeded with invalid "
            "coordinates with nid %d\n",
            nid);
    ERR_print_errors_fp(stderr);
    return false;
  }

  return true;
}

static bool TestArbitraryCurve() {
  // Make a P-256 key and extract the affine coordinates.
  ScopedEC_KEY key(EC_KEY_new_by_curve_name(NID_X9_62_prime256v1));
  if (!key || !EC_KEY_generate_key(key.get())) {
    return false;
  }

  // Make an arbitrary curve which is identical to P-256.
  static const uint8_t kP[] = {
      0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  };
  static const uint8_t kA[] = {
      0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
  };
  static const uint8_t kB[] = {
      0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, 0xb3, 0xeb, 0xbd,
      0x55, 0x76, 0x98, 0x86, 0xbc, 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53,
      0xb0, 0xf6, 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b,
  };
  static const uint8_t kX[] = {
      0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, 0xf8, 0xbc, 0xe6,
      0xe5, 0x63, 0xa4, 0x40, 0xf2, 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb,
      0x33, 0xa0, 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96,
  };
  static const uint8_t kY[] = {
      0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb,
      0x4a, 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31,
      0x5e, 0xce, 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5,
  };
  static const uint8_t kOrder[] = {
      0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
      0xff, 0xff, 0xff, 0xff, 0xff, 0xbc, 0xe6, 0xfa, 0xad, 0xa7, 0x17,
      0x9e, 0x84, 0xf3, 0xb9, 0xca, 0xc2, 0xfc, 0x63, 0x25, 0x51,
  };
  ScopedBN_CTX ctx(BN_CTX_new());
  ScopedBIGNUM p(BN_bin2bn(kP, sizeof(kP), nullptr));
  ScopedBIGNUM a(BN_bin2bn(kA, sizeof(kA), nullptr));
  ScopedBIGNUM b(BN_bin2bn(kB, sizeof(kB), nullptr));
  ScopedBIGNUM gx(BN_bin2bn(kX, sizeof(kX), nullptr));
  ScopedBIGNUM gy(BN_bin2bn(kY, sizeof(kY), nullptr));
  ScopedBIGNUM order(BN_bin2bn(kOrder, sizeof(kOrder), nullptr));
  ScopedBIGNUM cofactor(BN_new());
  if (!ctx || !p || !a || !b || !gx || !gy || !order || !cofactor ||
      !BN_set_word(cofactor.get(), 1)) {
    return false;
  }

  ScopedEC_GROUP group(
      EC_GROUP_new_curve_GFp(p.get(), a.get(), b.get(), ctx.get()));
  if (!group) {
    return false;
  }
  ScopedEC_POINT generator(EC_POINT_new(group.get()));
  if (!generator ||
      !EC_POINT_set_affine_coordinates_GFp(group.get(), generator.get(),
                                           gx.get(), gy.get(), ctx.get()) ||
      !EC_GROUP_set_generator(group.get(), generator.get(), order.get(),
                              cofactor.get())) {
    return false;
  }

  // |group| should not have a curve name.
  if (EC_GROUP_get_curve_name(group.get()) != NID_undef) {
    return false;
  }

  // Copy |key| to |key2| using |group|.
  ScopedEC_KEY key2(EC_KEY_new());
  ScopedEC_POINT point(EC_POINT_new(group.get()));
  ScopedBIGNUM x(BN_new()), y(BN_new());
  if (!key2 || !point || !x || !y ||
      !EC_KEY_set_group(key2.get(), group.get()) ||
      !EC_KEY_set_private_key(key2.get(), EC_KEY_get0_private_key(key.get())) ||
      !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(key.get()),
                                           EC_KEY_get0_public_key(key.get()),
                                           x.get(), y.get(), nullptr) ||
      !EC_POINT_set_affine_coordinates_GFp(group.get(), point.get(), x.get(),
                                           y.get(), nullptr) ||
      !EC_KEY_set_public_key(key2.get(), point.get())) {
    fprintf(stderr, "Could not copy key.\n");
    return false;
  }

  // The key must be valid according to the new group too.
  if (!EC_KEY_check_key(key2.get())) {
    fprintf(stderr, "Copied key is not valid.\n");
    return false;
  }

  return true;
}

static bool TestAddingEqualPoints(int nid) {
  ScopedEC_KEY key(EC_KEY_new_by_curve_name(nid));
  if (!key) {
    return false;
  }

  const EC_GROUP *const group = EC_KEY_get0_group(key.get());

  if (!EC_KEY_generate_key(key.get())) {
    fprintf(stderr, "EC_KEY_generate_key failed with nid %d\n", nid);
    ERR_print_errors_fp(stderr);
    return false;
  }

  ScopedEC_POINT p1(EC_POINT_new(group));
  ScopedEC_POINT p2(EC_POINT_new(group));
  ScopedEC_POINT double_p1(EC_POINT_new(group));
  ScopedEC_POINT p1_plus_p2(EC_POINT_new(group));
  if (!p1 || !p2 || !double_p1 || !p1_plus_p2) {
    return false;
  }

  if (!EC_POINT_copy(p1.get(), EC_KEY_get0_public_key(key.get())) ||
      !EC_POINT_copy(p2.get(), EC_KEY_get0_public_key(key.get()))) {
    fprintf(stderr, "EC_POINT_COPY failed with nid %d\n", nid);
    ERR_print_errors_fp(stderr);
    return false;
  }

  ScopedBN_CTX ctx(BN_CTX_new());
  if (!ctx) {
    return false;
  }

  if (!EC_POINT_dbl(group, double_p1.get(), p1.get(), ctx.get()) ||
      !EC_POINT_add(group, p1_plus_p2.get(), p1.get(), p2.get(), ctx.get())) {
    fprintf(stderr, "Point operation failed with nid %d\n", nid);
    ERR_print_errors_fp(stderr);
    return false;
  }

  if (EC_POINT_cmp(group, double_p1.get(), p1_plus_p2.get(), ctx.get()) != 0) {
    fprintf(stderr, "A+A != 2A for nid %d", nid);
    return false;
  }

  return true;
}

static bool ForEachCurve(bool (*test_func)(int nid)) {
  const size_t num_curves = EC_get_builtin_curves(nullptr, 0);
  std::vector<EC_builtin_curve> curves(num_curves);
  EC_get_builtin_curves(curves.data(), num_curves);

  for (const auto& curve : curves) {
    if (!test_func(curve.nid)) {
      fprintf(stderr, "Test failed for %s\n", curve.comment);
      return false;
    }
  }

  return true;
}

}  // namespace bssl

int main(void) {
  CRYPTO_library_init();

  if (!bssl::Testd2i_ECPrivateKey() ||
      !bssl::TestZeroPadding() ||
      !bssl::TestSpecifiedCurve() ||
      !bssl::ForEachCurve(bssl::TestSetAffine) ||
      !bssl::ForEachCurve(bssl::TestAddingEqualPoints) ||
      !bssl::TestArbitraryCurve()) {
    fprintf(stderr, "failed\n");
    return 1;
  }

  printf("PASS\n");
  return 0;
}
