/*************************************************************************
* Copyright (C) 2019 Intel 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.
*************************************************************************/

#ifndef _IFMA_RSA_ARITH_H_
#define _IFMA_RSA_ARITH_H_

/*
 * RSA kernels implemented with AVX512_IFMA256 ISA
 */

#include "owncp.h"

#if (_IPP32E >= _IPP32E_K1)

/* Almost Montgomery Multiplication / Squaring */
/* clang-format off */
#define ifma256_amm52x20 OWNAPI(ifma256_amm52x20)
  IPP_OWN_DECL(void, ifma256_amm52x20, (Ipp64u out[20], const Ipp64u a[20], const Ipp64u b[20], const Ipp64u m[20], Ipp64u k0))
#define ifma256_ams52x20 OWNAPI(ifma256_ams52x20)
  IPP_OWN_DECL(void, ifma256_ams52x20, (Ipp64u out[20], const Ipp64u a[20], const Ipp64u m[20], Ipp64u k0))
#define ifma256_amm52x30 OWNAPI(ifma256_amm52x30)
  IPP_OWN_DECL(void, ifma256_amm52x30, (Ipp64u out[32], const Ipp64u a[32], const Ipp64u b[32], const Ipp64u m[32], Ipp64u k0))
#define ifma256_ams52x30 OWNAPI(ifma256_ams52x30)
  IPP_OWN_DECL(void, ifma256_ams52x30, (Ipp64u out[32], const Ipp64u a[32], const Ipp64u m[32], Ipp64u k0))
#define ifma256_amm52x40 OWNAPI(ifma256_amm52x40)
  IPP_OWN_DECL(void, ifma256_amm52x40, (Ipp64u out[40], const Ipp64u a[40], const Ipp64u b[40], const Ipp64u m[40], Ipp64u k0))
#define ifma256_ams52x40 OWNAPI(ifma256_ams52x40)
  IPP_OWN_DECL(void, ifma256_ams52x40, (Ipp64u out[40], const Ipp64u a[40], const Ipp64u m[40], Ipp64u k0))
/* clang-format on */

/*
 * Dual Almost Montgomery Multiplication / Squaring
 * (two independent operations and data arrays)
 */
/* clang-format off */
#define ifma256_amm52x20_dual OWNAPI(ifma256_amm52x20_dual)
  IPP_OWN_DECL(void, ifma256_amm52x20_dual, (Ipp64u out[2][20], const Ipp64u a[2][20], const Ipp64u b[2][20], const Ipp64u m[2][20], const Ipp64u k0[2]))
#define ifma256_ams52x20_dual OWNAPI(ifma256_ams52x20_dual)
  IPP_OWN_DECL(void, ifma256_ams52x20_dual, (Ipp64u out[2][20], const Ipp64u a[2][20], const Ipp64u m[2][20], const Ipp64u k0[2]))
#define ifma256_amm52x30_dual OWNAPI(ifma256_amm52x30_dual)
  IPP_OWN_DECL(void, ifma256_amm52x30_dual, (Ipp64u out[2][32], const Ipp64u a[2][32], const Ipp64u b[2][32], const Ipp64u m[2][32], const Ipp64u k0[2]))
#define ifma256_ams52x30_dual OWNAPI(ifma256_ams52x30_dual)
  IPP_OWN_DECL(void, ifma256_ams52x30_dual, (Ipp64u out[2][32], const Ipp64u a[2][32], const Ipp64u m[2][32], const Ipp64u k0[2]))
#define ifma256_amm52x40_dual OWNAPI(ifma256_amm52x40_dual)
  IPP_OWN_DECL(void, ifma256_amm52x40_dual, (Ipp64u out[2][40], const Ipp64u a[2][40], const Ipp64u b[2][40], const Ipp64u m[2][40], const Ipp64u k0[2]))
#define ifma256_ams52x40_dual OWNAPI(ifma256_ams52x40_dual)
  IPP_OWN_DECL(void, ifma256_ams52x40_dual, (Ipp64u out[2][40], const Ipp64u a[2][40], const Ipp64u m[2][40], const Ipp64u k0[2]))
/* clang-format on */

/* Exponentiation */
#define ifma256_exp52x20 OWNAPI(ifma256_exp52x20)
/* clang-format off */
IPP_OWN_DECL (void, ifma256_exp52x20, (Ipp64u* out,
                                       const Ipp64u* base,
                                       const Ipp64u* exp,
                                       const Ipp64u* modulus,
                                       const Ipp64u* toMont,
                                       const Ipp64u k0))

/* Dual exponentiation */
#define ifma256_exp52x20_dual OWNAPI(ifma256_exp52x20_dual)
IPP_OWN_DECL (void, ifma256_exp52x20_dual, (Ipp64u out [2][20],
                                            const Ipp64u base [2][20],
                                            const Ipp64u* exp [2], // 2x16
                                            const Ipp64u modulus[2][20],
                                            const Ipp64u toMont [2][20],
                                            const Ipp64u k0 [2]))

#define ifma256_exp52x30_dual OWNAPI(ifma256_exp52x30_dual)
IPP_OWN_DECL (void, ifma256_exp52x30_dual, (Ipp64u out [2][32],
                                            const Ipp64u base [2][32],
                                            const Ipp64u* exp [2], // 2x24
                                            const Ipp64u modulus[2][32],
                                            const Ipp64u toMont [2][32],
                                            const Ipp64u k0 [2]))

#define ifma256_exp52x40_dual OWNAPI(ifma256_exp52x40_dual)
IPP_OWN_DECL (void, ifma256_exp52x40_dual, (Ipp64u out [2][40],
                                            const Ipp64u base [2][40],
                                            const Ipp64u* exp [2], // 2x32
                                            const Ipp64u modulus[2][40],
                                            const Ipp64u toMont [2][40],
                                            const Ipp64u k0 [2]))

/* clang-format on */

#endif // #if(_IPP32E>=_IPP32E_K1)
#endif // #ifndef _IFMA_RSA_ARITH_H_
