/* Copyright (c) 2016, 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. */

#if !defined(__STDC_FORMAT_MACROS)
#define __STDC_FORMAT_MACROS
#endif

#include <openssl/base.h>

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

#include <openssl/bn.h>
#include <openssl/mem.h>

#include "../bn/internal.h"
#include "../test/file_test.h"
#include "p256-x86_64.h"


// Disable tests if BORINGSSL_SHARED_LIBRARY is defined. These tests need access
// to internal functions.
#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \
    !defined(OPENSSL_SMALL) && !defined(BORINGSSL_SHARED_LIBRARY)

static bool TestSelectW5() {
  // Fill a table with some garbage input.
  P256_POINT table[16];
  for (size_t i = 0; i < 16; i++) {
    memset(table[i].X, 3 * i, sizeof(table[i].X));
    memset(table[i].Y, 3 * i + 1, sizeof(table[i].Y));
    memset(table[i].Z, 3 * i + 2, sizeof(table[i].Z));
  }

  for (int i = 0; i <= 16; i++) {
    P256_POINT val;
    ecp_nistz256_select_w5(&val, table, i);

    P256_POINT expected;
    if (i == 0) {
      memset(&expected, 0, sizeof(expected));
    } else {
      expected = table[i-1];
    }

    if (memcmp(&val, &expected, sizeof(P256_POINT)) != 0) {
      fprintf(stderr, "ecp_nistz256_select_w5(%d) gave the wrong value.\n", i);
      return false;
    }
  }

  return true;
}

static bool TestSelectW7() {
  // Fill a table with some garbage input.
  P256_POINT_AFFINE table[64];
  for (size_t i = 0; i < 64; i++) {
    memset(table[i].X, 2 * i, sizeof(table[i].X));
    memset(table[i].Y, 2 * i + 1, sizeof(table[i].Y));
  }

  for (int i = 0; i <= 64; i++) {
    P256_POINT_AFFINE val;
    ecp_nistz256_select_w7(&val, table, i);

    P256_POINT_AFFINE expected;
    if (i == 0) {
      memset(&expected, 0, sizeof(expected));
    } else {
      expected = table[i-1];
    }

    if (memcmp(&val, &expected, sizeof(P256_POINT_AFFINE)) != 0) {
      fprintf(stderr, "ecp_nistz256_select_w7(%d) gave the wrong value.\n", i);
      return false;
    }
  }

  return true;
}

static bool GetFieldElement(FileTest *t, BN_ULONG out[P256_LIMBS],
                            const char *name) {
  std::vector<uint8_t> bytes;
  if (!t->GetBytes(&bytes, name)) {
    return false;
  }

  if (bytes.size() != BN_BYTES * P256_LIMBS) {
    t->PrintLine("Invalid length: %s", name);
    return false;
  }

  // |byte| contains bytes in big-endian while |out| should contain |BN_ULONG|s
  // in little-endian.
  memset(out, 0, P256_LIMBS * sizeof(BN_ULONG));
  for (size_t i = 0; i < bytes.size(); i++) {
    out[P256_LIMBS - 1 - (i / BN_BYTES)] <<= 8;
    out[P256_LIMBS - 1 - (i / BN_BYTES)] |= bytes[i];
  }

  return true;
}

static std::string FieldElementToString(const BN_ULONG a[P256_LIMBS]) {
  std::string ret;
  for (size_t i = P256_LIMBS-1; i < P256_LIMBS; i--) {
    char buf[2 * BN_BYTES + 1];
    BIO_snprintf(buf, sizeof(buf), BN_HEX_FMT2, a[i]);
    ret += buf;
  }
  return ret;
}

static bool ExpectFieldElementsEqual(FileTest *t, const char *message,
                                     const BN_ULONG expected[P256_LIMBS],
                                     const BN_ULONG actual[P256_LIMBS]) {
  if (memcmp(expected, actual, sizeof(BN_ULONG) * P256_LIMBS) == 0) {
    return true;
  }

  t->PrintLine("%s", message);
  t->PrintLine("Expected: %s", FieldElementToString(expected).c_str());
  t->PrintLine("Actual:   %s", FieldElementToString(actual).c_str());
  return false;
}

static bool PointToAffine(P256_POINT_AFFINE *out, const P256_POINT *in) {
  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,
  };

  bssl::UniquePtr<BIGNUM> x(BN_new()), y(BN_new()), z(BN_new());
  bssl::UniquePtr<BIGNUM> p(BN_bin2bn(kP, sizeof(kP), nullptr));
  if (!x || !y || !z || !p ||
      !bn_set_words(x.get(), in->X, P256_LIMBS) ||
      !bn_set_words(y.get(), in->Y, P256_LIMBS) ||
      !bn_set_words(z.get(), in->Z, P256_LIMBS)) {
    return false;
  }

  // Coordinates must be fully-reduced.
  if (BN_cmp(x.get(), p.get()) >= 0 ||
      BN_cmp(y.get(), p.get()) >= 0 ||
      BN_cmp(z.get(), p.get()) >= 0) {
    return false;
  }

  memset(out, 0, sizeof(P256_POINT_AFFINE));

  if (BN_is_zero(z.get())) {
    // The point at infinity is represented as (0, 0).
    return true;
  }

  bssl::UniquePtr<BN_CTX> ctx(BN_CTX_new());
  bssl::UniquePtr<BN_MONT_CTX> mont(BN_MONT_CTX_new());
  if (!ctx || !mont ||
      !BN_MONT_CTX_set(mont.get(), p.get(), ctx.get()) ||
      // Invert Z.
      !BN_from_montgomery(z.get(), z.get(), mont.get(), ctx.get()) ||
      !BN_mod_inverse(z.get(), z.get(), p.get(), ctx.get()) ||
      !BN_to_montgomery(z.get(), z.get(), mont.get(), ctx.get()) ||
      // Convert (X, Y, Z) to (X/Z^2, Y/Z^3).
      !BN_mod_mul_montgomery(x.get(), x.get(), z.get(), mont.get(),
                             ctx.get()) ||
      !BN_mod_mul_montgomery(x.get(), x.get(), z.get(), mont.get(),
                             ctx.get()) ||
      !BN_mod_mul_montgomery(y.get(), y.get(), z.get(), mont.get(),
                             ctx.get()) ||
      !BN_mod_mul_montgomery(y.get(), y.get(), z.get(), mont.get(),
                             ctx.get()) ||
      !BN_mod_mul_montgomery(y.get(), y.get(), z.get(), mont.get(),
                             ctx.get())) {
    return false;
  }

  memcpy(out->X, x->d, sizeof(BN_ULONG) * x->top);
  memcpy(out->Y, y->d, sizeof(BN_ULONG) * y->top);
  return true;
}

static bool ExpectPointsEqual(FileTest *t, const char *message,
                              const P256_POINT_AFFINE *expected,
                              const P256_POINT *point) {
  // There are multiple representations of the same |P256_POINT|, so convert to
  // |P256_POINT_AFFINE| and compare.
  P256_POINT_AFFINE affine;
  if (!PointToAffine(&affine, point)) {
    t->PrintLine("%s", message);
    t->PrintLine("Could not convert to affine: (%s, %s, %s)",
                 FieldElementToString(point->X).c_str(),
                 FieldElementToString(point->Y).c_str(),
                 FieldElementToString(point->Z).c_str());
    return false;
  }

  if (memcmp(expected, &affine, sizeof(P256_POINT_AFFINE)) != 0) {
    t->PrintLine("%s", message);
    t->PrintLine("Expected: (%s, %s)",
                 FieldElementToString(expected->X).c_str(),
                 FieldElementToString(expected->Y).c_str());
    t->PrintLine("Actual:   (%s, %s)", FieldElementToString(affine.X).c_str(),
                 FieldElementToString(affine.Y).c_str());
    return false;
  }

  return true;
}

static bool TestNegate(FileTest *t) {
  BN_ULONG a[P256_LIMBS], b[P256_LIMBS];
  if (!GetFieldElement(t, a, "A") ||
      !GetFieldElement(t, b, "B")) {
    return false;
  }

  // Test that -A = B.
  BN_ULONG ret[P256_LIMBS];
  ecp_nistz256_neg(ret, a);
  if (!ExpectFieldElementsEqual(t, "ecp_nistz256_neg(A) was incorrect.", b,
                                ret)) {
    return false;
  }

  memcpy(ret, a, sizeof(ret));
  ecp_nistz256_neg(ret, ret);
  if (!ExpectFieldElementsEqual(
          t, "In-place ecp_nistz256_neg(A) was incorrect.", b, ret)) {
    return false;
  }

  // Test that -B = A.
  ecp_nistz256_neg(ret, b);
  if (!ExpectFieldElementsEqual(t, "ecp_nistz256_neg(B) was incorrect.", a,
                                ret)) {
    return false;
  }

  memcpy(ret, b, sizeof(ret));
  ecp_nistz256_neg(ret, ret);
  if (!ExpectFieldElementsEqual(
          t, "In-place ecp_nistz256_neg(B) was incorrect.", a, ret)) {
    return false;
  }

  return true;
}

static bool TestMulMont(FileTest *t) {
  BN_ULONG a[P256_LIMBS], b[P256_LIMBS], result[P256_LIMBS];
  if (!GetFieldElement(t, a, "A") ||
      !GetFieldElement(t, b, "B") ||
      !GetFieldElement(t, result, "Result")) {
    return false;
  }

  BN_ULONG ret[P256_LIMBS];
  ecp_nistz256_mul_mont(ret, a, b);
  if (!ExpectFieldElementsEqual(t, "ecp_nistz256_mul_mont(A, B) was incorrect.",
                                result, ret)) {
    return false;
  }

  ecp_nistz256_mul_mont(ret, b, a);
  if (!ExpectFieldElementsEqual(t, "ecp_nistz256_mul_mont(B, A) was incorrect.",
                                result, ret)) {
    return false;
  }

  memcpy(ret, a, sizeof(ret));
  ecp_nistz256_mul_mont(ret, ret, b);
  if (!ExpectFieldElementsEqual(
          t, "ecp_nistz256_mul_mont(ret = A, B) was incorrect.", result, ret)) {
    return false;
  }

  memcpy(ret, a, sizeof(ret));
  ecp_nistz256_mul_mont(ret, b, ret);
  if (!ExpectFieldElementsEqual(
          t, "ecp_nistz256_mul_mont(B, ret = A) was incorrect.", result, ret)) {
    return false;
  }

  memcpy(ret, b, sizeof(ret));
  ecp_nistz256_mul_mont(ret, a, ret);
  if (!ExpectFieldElementsEqual(
          t, "ecp_nistz256_mul_mont(A, ret = B) was incorrect.", result, ret)) {
    return false;
  }

  memcpy(ret, b, sizeof(ret));
  ecp_nistz256_mul_mont(ret, ret, a);
  if (!ExpectFieldElementsEqual(
          t, "ecp_nistz256_mul_mont(ret = B, A) was incorrect.", result, ret)) {
    return false;
  }

  if (memcmp(a, b, sizeof(a)) == 0) {
    ecp_nistz256_sqr_mont(ret, a);
    if (!ExpectFieldElementsEqual(t, "ecp_nistz256_sqr_mont(A) was incorrect.",
                                  result, ret)) {
      return false;
    }

    memcpy(ret, a, sizeof(ret));
    ecp_nistz256_sqr_mont(ret, ret);
    if (!ExpectFieldElementsEqual(
            t, "ecp_nistz256_sqr_mont(ret = A) was incorrect.", result, ret)) {
      return false;
    }
  }

  return true;
}

static bool TestFromMont(FileTest *t) {
  BN_ULONG a[P256_LIMBS], result[P256_LIMBS];
  if (!GetFieldElement(t, a, "A") ||
      !GetFieldElement(t, result, "Result")) {
    return false;
  }

  BN_ULONG ret[P256_LIMBS];
  ecp_nistz256_from_mont(ret, a);
  if (!ExpectFieldElementsEqual(t, "ecp_nistz256_from_mont(A) was incorrect.",
                                result, ret)) {
    return false;
  }

  memcpy(ret, a, sizeof(ret));
  ecp_nistz256_from_mont(ret, ret);
  if (!ExpectFieldElementsEqual(
          t, "ecp_nistz256_from_mont(ret = A) was incorrect.", result, ret)) {
    return false;
  }

  return true;
}

static bool TestPointAdd(FileTest *t) {
  P256_POINT a, b;
  P256_POINT_AFFINE result;
  if (!GetFieldElement(t, a.X, "A.X") ||
      !GetFieldElement(t, a.Y, "A.Y") ||
      !GetFieldElement(t, a.Z, "A.Z") ||
      !GetFieldElement(t, b.X, "B.X") ||
      !GetFieldElement(t, b.Y, "B.Y") ||
      !GetFieldElement(t, b.Z, "B.Z") ||
      !GetFieldElement(t, result.X, "Result.X") ||
      !GetFieldElement(t, result.Y, "Result.Y")) {
    return false;
  }

  P256_POINT ret;
  ecp_nistz256_point_add(&ret, &a, &b);
  if (!ExpectPointsEqual(t, "ecp_nistz256_point_add(A, B) was incorrect.",
                         &result, &ret)) {
    return false;
  }

  ecp_nistz256_point_add(&ret, &b, &a);
  if (!ExpectPointsEqual(t, "ecp_nistz256_point_add(B, A) was incorrect.",
                         &result, &ret)) {
    return false;
  }

  memcpy(&ret, &a, sizeof(ret));
  ecp_nistz256_point_add(&ret, &ret, &b);
  if (!ExpectPointsEqual(t, "ecp_nistz256_point_add(ret = A, B) was incorrect.",
                         &result, &ret)) {
    return false;
  }

  memcpy(&ret, &a, sizeof(ret));
  ecp_nistz256_point_add(&ret, &b, &ret);
  if (!ExpectPointsEqual(t, "ecp_nistz256_point_add(B, ret = A) was incorrect.",
                         &result, &ret)) {
    return false;
  }

  memcpy(&ret, &b, sizeof(ret));
  ecp_nistz256_point_add(&ret, &a, &ret);
  if (!ExpectPointsEqual(t, "ecp_nistz256_point_add(ret = A, B) was incorrect.",
                         &result, &ret)) {
    return false;
  }

  memcpy(&ret, &b, sizeof(ret));
  ecp_nistz256_point_add(&ret, &ret, &a);
  if (!ExpectPointsEqual(t, "ecp_nistz256_point_add(ret = B, A) was incorrect.",
                         &result, &ret)) {
    return false;
  }

  P256_POINT_AFFINE a_affine, b_affine, infinity;
  memset(&infinity, 0, sizeof(infinity));
  if (!PointToAffine(&a_affine, &a) ||
      !PointToAffine(&b_affine, &b)) {
    return false;
  }

  // ecp_nistz256_point_add_affine does not work when a == b unless doubling the
  // point at infinity.
  if (memcmp(&a_affine, &b_affine, sizeof(a_affine)) != 0 ||
      memcmp(&a_affine, &infinity, sizeof(a_affine)) == 0) {
    ecp_nistz256_point_add_affine(&ret, &a, &b_affine);
    if (!ExpectPointsEqual(t,
                           "ecp_nistz256_point_add_affine(A, B) was incorrect.",
                           &result, &ret)) {
      return false;
    }

    memcpy(&ret, &a, sizeof(ret));
    ecp_nistz256_point_add_affine(&ret, &ret, &b_affine);
    if (!ExpectPointsEqual(
            t, "ecp_nistz256_point_add_affine(ret = A, B) was incorrect.",
            &result, &ret)) {
      return false;
    }

    ecp_nistz256_point_add_affine(&ret, &b, &a_affine);
    if (!ExpectPointsEqual(t,
                           "ecp_nistz256_point_add_affine(B, A) was incorrect.",
                           &result, &ret)) {
      return false;
    }

    memcpy(&ret, &b, sizeof(ret));
    ecp_nistz256_point_add_affine(&ret, &ret, &a_affine);
    if (!ExpectPointsEqual(
            t, "ecp_nistz256_point_add_affine(ret = B, A) was incorrect.",
            &result, &ret)) {
      return false;
    }
  }

  if (memcmp(&a, &b, sizeof(a)) == 0) {
    ecp_nistz256_point_double(&ret, &a);
    if (!ExpectPointsEqual(t, "ecp_nistz256_point_double(A) was incorrect.",
                           &result, &ret)) {
      return false;
    }

    ret = a;
    ecp_nistz256_point_double(&ret, &ret);
    if (!ExpectPointsEqual(
            t, "In-place ecp_nistz256_point_double(A) was incorrect.", &result,
            &ret)) {
      return false;
    }
  }

  return true;
}

int main(int argc, char **argv) {
  if (argc != 2) {
    fprintf(stderr, "%s TEST_FILE\n", argv[0]);
    return 1;
  }

  if (!TestSelectW5() ||
      !TestSelectW7()) {
    return 1;
  }

  return FileTestMain([](FileTest *t, void *) -> bool {
    if (t->GetParameter() == "Negate") {
      return TestNegate(t);
    }
    if (t->GetParameter() == "MulMont") {
      return TestMulMont(t);
    }
    if (t->GetParameter() == "FromMont") {
      return TestFromMont(t);
    }
    if (t->GetParameter() == "PointAdd") {
      return TestPointAdd(t);
    }

    t->PrintLine("Unknown test type: %s", t->GetParameter().c_str());
    return false;
  }, nullptr, argv[1]);
}

#else

int main() {
  printf("PASS\n");
  return 0;
}

#endif
