/*******************************************************************************
* Copyright 2016-2018 Intel Corporation
* All Rights Reserved.
*
* If this  software was obtained  under the  Intel Simplified  Software License,
* the following terms apply:
*
* The source code,  information  and material  ("Material") contained  herein is
* owned by Intel Corporation or its  suppliers or licensors,  and  title to such
* Material remains with Intel  Corporation or its  suppliers or  licensors.  The
* Material  contains  proprietary  information  of  Intel or  its suppliers  and
* licensors.  The Material is protected by  worldwide copyright  laws and treaty
* provisions.  No part  of  the  Material   may  be  used,  copied,  reproduced,
* modified, published,  uploaded, posted, transmitted,  distributed or disclosed
* in any way without Intel's prior express written permission.  No license under
* any patent,  copyright or other  intellectual property rights  in the Material
* is granted to  or  conferred  upon  you,  either   expressly,  by implication,
* inducement,  estoppel  or  otherwise.  Any  license   under such  intellectual
* property rights must be express and approved by Intel in writing.
*
* Unless otherwise agreed by Intel in writing,  you may not remove or alter this
* notice or  any  other  notice   embedded  in  Materials  by  Intel  or Intel's
* suppliers or licensors in any way.
*
*
* If this  software  was obtained  under the  Apache License,  Version  2.0 (the
* "License"), the following terms apply:
*
* 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.
*******************************************************************************/

/*
//     Intel(R) Integrated Performance Primitives. Cryptography Primitives.
// 
//     Context:
//        ippsGFpECPrivateKey()
//
*/

#include "owndefs.h"
#include "owncp.h"
#include "pcpgfpecstuff.h"

/*F*
//    Name: ippsGFpECPrivateKey
//
// Purpose: Generate random private key
//
// Returns:                Reason:
//    ippStsNullPtrErr        NULL == pEC
//                            NULL == pPrivate
//
//    ippStsContextMatchErr   illegal pEC->idCtx
//                            pEC->subgroup == NULL
//                            illegal pPrivate->idCtx
//
//    ippStsSizeErr           BN_ROOM(pPrivate)*BITSIZE(BNU_CHUNK_T)<ECP_ORDBITSIZE(pEC)
//
//    ippStsNoErr             no errors
//
// Parameters:
//    pPrivate    pointer to the resultant private key
//    pEC         pointer to the EC context
//    rndFunc     Specified Random Generator
//    pRndParam   Pointer to the Random Generator context
//
*F*/
IPPFUN(IppStatus, ippsGFpECPrivateKey, (IppsBigNumState* pPrivate, IppsGFpECState* pEC,
                                        IppBitSupplier rndFunc, void* pRndParam))
{
   IPP_BAD_PTR2_RET(pEC, rndFunc);

   /* use aligned EC context */
   pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
   IPP_BADARG_RET(!ECP_TEST_ID(pEC), ippStsContextMatchErr);
   IPP_BADARG_RET(!ECP_SUBGROUP(pEC), ippStsContextMatchErr);

   /* test private key */
   IPP_BAD_PTR1_RET(pPrivate);
   pPrivate = (IppsBigNumState*)( IPP_ALIGNED_PTR(pPrivate, ALIGN_VAL) );
   IPP_BADARG_RET(!BN_VALID_ID(pPrivate), ippStsContextMatchErr);
   IPP_BADARG_RET((BN_ROOM(pPrivate)*BITSIZE(BNU_CHUNK_T)<ECP_ORDBITSIZE(pEC)), ippStsSizeErr);

   {
      /* generate random private key X:  0 < X < R */
      BNU_CHUNK_T* pOrder = MOD_MODULUS(ECP_MONT_R(pEC));
      int orderBitLen = ECP_ORDBITSIZE(pEC);
      int orderLen = BITS_BNU_CHUNK(orderBitLen);

      BNU_CHUNK_T* pX = BN_NUMBER(pPrivate);
      int nsX = BITS_BNU_CHUNK(orderBitLen);
      BNU_CHUNK_T xMask = MASK_BNU_CHUNK(orderBitLen);

      IppStatus sts;
      do {
         sts = rndFunc((Ipp32u*)pX, orderBitLen, pRndParam);
         if(ippStsNoErr!=sts)
            break;
         pX[nsX-1] &= xMask;
      } while( (1 == cpEqu_BNU_CHUNK(pX, nsX, 0)) ||
               (0 <= cpCmp_BNU(pX, nsX, pOrder, orderLen)) );

      /* set up private */
      if(ippStsNoErr==sts) {
         BN_SIGN(pPrivate) = ippBigNumPOS;
         FIX_BNU(pX, nsX);
         BN_SIZE(pPrivate) = nsX;
      }

      return sts;
   }
}
