/******************************************************************************
 *
 *  Copyright 2006-2015 Broadcom Corporation
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at:
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 ******************************************************************************/

/*******************************************************************************
 *
 *  This file contains simple pairing algorithms using Elliptic Curve
 *  Cryptography for private public key
 *
 ******************************************************************************/
#include "p_256_ecc_pp.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "p_256_multprecision.h"

elliptic_curve_t curve;
elliptic_curve_t curve_p256;

static void p_256_init_point(Point* q) { memset(q, 0, sizeof(Point)); }

static void p_256_copy_point(Point* q, Point* p) {
  memcpy(q, p, sizeof(Point));
}

// q=2q
static void ECC_Double(Point* q, Point* p, uint32_t keyLength) {
  uint32_t t1[KEY_LENGTH_DWORDS_P256];
  uint32_t t2[KEY_LENGTH_DWORDS_P256];
  uint32_t t3[KEY_LENGTH_DWORDS_P256];
  uint32_t* x1;
  uint32_t* x3;
  uint32_t* y1;
  uint32_t* y3;
  uint32_t* z1;
  uint32_t* z3;

  if (multiprecision_iszero(p->z, keyLength)) {
    multiprecision_init(q->z, keyLength);
    return;  // return infinity
  }

  x1 = p->x;
  y1 = p->y;
  z1 = p->z;
  x3 = q->x;
  y3 = q->y;
  z3 = q->z;

  multiprecision_mersenns_squa_mod(t1, z1, keyLength);      // t1=z1^2
  multiprecision_sub_mod(t2, x1, t1, keyLength);            // t2=x1-t1
  multiprecision_add_mod(t1, x1, t1, keyLength);            // t1=x1+t1
  multiprecision_mersenns_mult_mod(t2, t1, t2, keyLength);  // t2=t2*t1
  multiprecision_lshift_mod(t3, t2, keyLength);
  multiprecision_add_mod(t2, t3, t2, keyLength);  // t2=3t2

  multiprecision_mersenns_mult_mod(z3, y1, z1, keyLength);  // z3=y1*z1
  multiprecision_lshift_mod(z3, z3, keyLength);

  multiprecision_mersenns_squa_mod(y3, y1, keyLength);  // y3=y1^2
  multiprecision_lshift_mod(y3, y3, keyLength);
  multiprecision_mersenns_mult_mod(t3, y3, x1, keyLength);  // t3=y3*x1=x1*y1^2
  multiprecision_lshift_mod(t3, t3, keyLength);
  multiprecision_mersenns_squa_mod(y3, y3, keyLength);  // y3=y3^2=y1^4
  multiprecision_lshift_mod(y3, y3, keyLength);

  multiprecision_mersenns_squa_mod(x3, t2, keyLength);      // x3=t2^2
  multiprecision_lshift_mod(t1, t3, keyLength);             // t1=2t3
  multiprecision_sub_mod(x3, x3, t1, keyLength);            // x3=x3-t1
  multiprecision_sub_mod(t1, t3, x3, keyLength);            // t1=t3-x3
  multiprecision_mersenns_mult_mod(t1, t1, t2, keyLength);  // t1=t1*t2
  multiprecision_sub_mod(y3, t1, y3, keyLength);            // y3=t1-y3
}

// q=q+p,     zp must be 1
static void ECC_Add(Point* r, Point* p, Point* q, uint32_t keyLength) {
  uint32_t t1[KEY_LENGTH_DWORDS_P256];
  uint32_t t2[KEY_LENGTH_DWORDS_P256];
  uint32_t* x1;
  uint32_t* x2;
  uint32_t* x3;
  uint32_t* y1;
  uint32_t* y2;
  uint32_t* y3;
  uint32_t* z1;
  uint32_t* z2;
  uint32_t* z3;

  x1 = p->x;
  y1 = p->y;
  z1 = p->z;
  x2 = q->x;
  y2 = q->y;
  z2 = q->z;
  x3 = r->x;
  y3 = r->y;
  z3 = r->z;

  // if Q=infinity, return p
  if (multiprecision_iszero(z2, keyLength)) {
    p_256_copy_point(r, p);
    return;
  }

  // if P=infinity, return q
  if (multiprecision_iszero(z1, keyLength)) {
    p_256_copy_point(r, q);
    return;
  }

  multiprecision_mersenns_squa_mod(t1, z1, keyLength);      // t1=z1^2
  multiprecision_mersenns_mult_mod(t2, z1, t1, keyLength);  // t2=t1*z1
  multiprecision_mersenns_mult_mod(t1, x2, t1, keyLength);  // t1=t1*x2
  multiprecision_mersenns_mult_mod(t2, y2, t2, keyLength);  // t2=t2*y2

  multiprecision_sub_mod(t1, t1, x1, keyLength);  // t1=t1-x1
  multiprecision_sub_mod(t2, t2, y1, keyLength);  // t2=t2-y1

  if (multiprecision_iszero(t1, keyLength)) {
    if (multiprecision_iszero(t2, keyLength)) {
      ECC_Double(r, q, keyLength);
      return;
    } else {
      multiprecision_init(z3, keyLength);
      return;  // return infinity
    }
  }

  multiprecision_mersenns_mult_mod(z3, z1, t1, keyLength);  // z3=z1*t1
  multiprecision_mersenns_squa_mod(y3, t1, keyLength);      // t3=t1^2
  multiprecision_mersenns_mult_mod(z1, y3, t1, keyLength);  // t4=t3*t1
  multiprecision_mersenns_mult_mod(y3, y3, x1, keyLength);  // t3=t3*x1
  multiprecision_lshift_mod(t1, y3, keyLength);             // t1=2*t3
  multiprecision_mersenns_squa_mod(x3, t2, keyLength);      // x3=t2^2
  multiprecision_sub_mod(x3, x3, t1, keyLength);            // x3=x3-t1
  multiprecision_sub_mod(x3, x3, z1, keyLength);            // x3=x3-t4
  multiprecision_sub_mod(y3, y3, x3, keyLength);            // t3=t3-x3
  multiprecision_mersenns_mult_mod(y3, y3, t2, keyLength);  // t3=t3*t2
  multiprecision_mersenns_mult_mod(z1, z1, y1, keyLength);  // t4=t4*t1
  multiprecision_sub_mod(y3, y3, z1, keyLength);
}

// Computing the Non-Adjacent Form of a positive integer
static void ECC_NAF(uint8_t* naf, uint32_t* NumNAF, uint32_t* k,
                    uint32_t keyLength) {
  uint32_t sign;
  int i = 0;
  int j;
  uint32_t var;

  while ((var = multiprecision_most_signbits(k, keyLength)) >= 1) {
    if (k[0] & 0x01)  // k is odd
    {
      sign = (k[0] & 0x03);  // 1 or 3

      // k = k-naf[i]
      if (sign == 1)
        k[0] = k[0] & 0xFFFFFFFE;
      else {
        k[0] = k[0] + 1;
        if (k[0] == 0)  // overflow
        {
          j = 1;
          do {
            k[j]++;
          } while (k[j++] == 0);  // overflow
        }
      }
    } else
      sign = 0;

    multiprecision_rshift(k, k, keyLength);
    naf[i / 4] |= (sign) << ((i % 4) * 2);
    i++;
  }

  *NumNAF = i;
}

// Binary Non-Adjacent Form for point multiplication
void ECC_PointMult_Bin_NAF(Point* q, Point* p, uint32_t* n,
                           uint32_t keyLength) {
  uint32_t sign;
  uint8_t naf[256 / 4 + 1];
  uint32_t NumNaf;
  Point minus_p;
  Point r;
  uint32_t* modp;

  if (keyLength == KEY_LENGTH_DWORDS_P256) {
    modp = curve_p256.p;
  } else {
    modp = curve.p;
  }

  p_256_init_point(&r);
  multiprecision_init(p->z, keyLength);
  p->z[0] = 1;

  // initialization
  p_256_init_point(q);

  // -p
  multiprecision_copy(minus_p.x, p->x, keyLength);
  multiprecision_sub(minus_p.y, modp, p->y, keyLength);

  multiprecision_init(minus_p.z, keyLength);
  minus_p.z[0] = 1;

  // NAF
  memset(naf, 0, sizeof(naf));
  ECC_NAF(naf, &NumNaf, n, keyLength);

  for (int i = NumNaf - 1; i >= 0; i--) {
    p_256_copy_point(&r, q);
    ECC_Double(q, &r, keyLength);
    sign = (naf[i / 4] >> ((i % 4) * 2)) & 0x03;

    if (sign == 1) {
      p_256_copy_point(&r, q);
      ECC_Add(q, &r, p, keyLength);
    } else if (sign == 3) {
      p_256_copy_point(&r, q);
      ECC_Add(q, &r, &minus_p, keyLength);
    }
  }

  multiprecision_inv_mod(minus_p.x, q->z, keyLength);
  multiprecision_mersenns_squa_mod(q->z, minus_p.x, keyLength);
  multiprecision_mersenns_mult_mod(q->x, q->x, q->z, keyLength);
  multiprecision_mersenns_mult_mod(q->z, q->z, minus_p.x, keyLength);
  multiprecision_mersenns_mult_mod(q->y, q->y, q->z, keyLength);
}

bool ECC_ValidatePoint(const Point& pt) {
  const size_t kl = KEY_LENGTH_DWORDS_P256;
  p_256_init_curve(kl);

  // Ensure y^2 = x^3 + a*x + b (mod p); a = -3

  // y^2 mod p
  uint32_t y2_mod[kl] = {0};
  multiprecision_mersenns_squa_mod(y2_mod, (uint32_t*)pt.y, kl);

  // Right hand side calculation
  uint32_t rhs[kl] = {0};
  multiprecision_mersenns_squa_mod(rhs, (uint32_t*)pt.x, kl);
  uint32_t three[kl] = {0};
  three[0] = 3;
  multiprecision_sub_mod(rhs, rhs, three, kl);
  multiprecision_mersenns_mult_mod(rhs, rhs, (uint32_t*)pt.x, kl);
  multiprecision_add_mod(rhs, rhs, curve_p256.b, kl);

  return multiprecision_compare(rhs, y2_mod, kl) == 0;
}
