/* ksdk_port.h
 *
 * Copyright (C) 2006-2016 wolfSSL Inc.
 *
 * This file is part of wolfSSL.
 *
 * wolfSSL is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * wolfSSL is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
 */

#ifndef _KSDK_PORT_H_
#define _KSDK_PORT_H_

#include <wolfssl/wolfcrypt/settings.h>
#ifdef USE_FAST_MATH
# include <wolfssl/wolfcrypt/tfm.h>
#else
# include <wolfssl/wolfcrypt/integer.h>
#endif
#include <wolfssl/wolfcrypt/ecc.h>
#include <wolfssl/wolfcrypt/curve25519.h>
#include <wolfssl/wolfcrypt/ed25519.h>


/* API to init required hardware */
int
ksdk_port_init(void);

/* software algorithm, by wolfcrypt */
#if defined(FREESCALE_LTC_TFM)
int
wolfcrypt_mp_mul(mp_int * A, mp_int * B, mp_int * C);
int
wolfcrypt_mp_mod(mp_int * a, mp_int * b, mp_int * c);
int
wolfcrypt_mp_mulmod(mp_int * a, mp_int * b, mp_int * c, mp_int * d);
int
wolfcrypt_mp_mod(mp_int * a, mp_int * b, mp_int * c);
int
wolfcrypt_mp_invmod(mp_int * a, mp_int * b, mp_int * c);
int
wolfcrypt_mp_exptmod(mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
#endif /* FREESCALE_LTC_TFM */

#if defined(FREESCALE_LTC_ECC)
/**================= Use KSDK 1.3 LTC Driver - Dec 29, 2016 =================**/
// #include "fsl_ltc.h"
# include "fsl_ltc_driver.h"
/**==========================================================================**/

typedef enum _fsl_ltc_ecc_coordinate_system {
    kLTC_Weierstrass = 0U, /*!< Point coordinates on an elliptic curve in Weierstrass form */
    kLTC_Curve25519  = 1U, /*!< Point coordinates on an Curve25519 elliptic curve in Montgomery form */
    kLTC_Ed25519     = 2U, /*!< Point coordinates on an Ed25519 elliptic curve in twisted Edwards form */
} fsl_ltc_ecc_coordinate_system_t;

int
wc_ecc_point_add(ecc_point * mG, ecc_point * mQ, ecc_point * mR, mp_int * m);

# ifdef HAVE_CURVE25519

/** ===================Modified return type from status_t to ltc_status_t -
 * ltc_pkha_ecc_point_t * to (ltc_pkha_ecc_point *) Dec 29, 2016
 * ===========================================================================**/
int
wc_curve25519(ECPoint * q, byte * n, const ECPoint * p, fsl_ltc_ecc_coordinate_system_t type);
const ECPoint *
wc_curve25519_GetBasePoint(void);
/*status_t*/ ltc_status_t
LTC_PKHA_Curve25519ToWeierstrass(const /*ltc_pkha_ecc_point_t */ ltc_pkha_ecc_point * ltcPointIn,
  /* ltc_pkha_ecc_point_t */ ltc_pkha_ecc_point *                                     ltcPointOut);
/*status_t*/ ltc_status_t
LTC_PKHA_WeierstrassToCurve25519(const ltc_pkha_ecc_point * ltcPointIn,
  ltc_pkha_ecc_point *                                      ltcPointOut);
/*status_t*/ ltc_status_t
LTC_PKHA_Curve25519ComputeY(ltc_pkha_ecc_point * ltcPoint);
# endif // ifdef HAVE_CURVE25519

# ifdef HAVE_ED25519

/** ===================Modified return type from status_t to ltc_status_t - Dec 29, 2016
 *        ltc_pkha_ecc_point_t* to ltc_pkha_ecc_point *
 *      =========================================================================================**/
/*status_t*/ ltc_status_t
LTC_PKHA_Ed25519ToWeierstrass(const ltc_pkha_ecc_point * ltcPointIn, ltc_pkha_ecc_point * ltcPointOut);
/*status_t*/ ltc_status_t
LTC_PKHA_WeierstrassToEd25519(const ltc_pkha_ecc_point * ltcPointIn, ltc_pkha_ecc_point * ltcPointOut);
/*status_t*/ ltc_status_t
LTC_PKHA_Ed25519_PointMul(const ltc_pkha_ecc_point * ltcPointIn,
  const uint8_t *                                    N,
  size_t                                             sizeN,
  ltc_pkha_ecc_point *                               ltcPointOut,
  fsl_ltc_ecc_coordinate_system_t                    typeOut);
const /*ltc_pkha_ecc_point_t*/ ltc_pkha_ecc_point *
LTC_PKHA_Ed25519_BasePoint(void);
/*status_t*/ ltc_status_t
LTC_PKHA_Ed25519_PointDecompress(const uint8_t * pubkey, size_t pubKeySize, ltc_pkha_ecc_point * ltcPointOut);
/*status_t*/ ltc_status_t
LTC_PKHA_sc_reduce(uint8_t * a);
/*status_t*/ ltc_status_t
LTC_PKHA_sc_muladd(uint8_t * s, const uint8_t * a, const uint8_t * b, const uint8_t * c);
/*status_t*/ ltc_status_t
LTC_PKHA_SignatureForVerify(uint8_t * rcheck, const unsigned char * a, const unsigned char * b, ed25519_key * key);
/*status_t*/ ltc_status_t
LTC_PKHA_Ed25519_Compress(const ltc_pkha_ecc_point * ltcPointIn, uint8_t * p);
# endif // ifdef HAVE_ED25519

#endif /* FREESCALE_LTC_ECC */

#endif /* _KSDK_PORT_H_ */
