blob: e895dda8601477d7ce6e8f98034e7e4f6ccafba1 [file] [log] [blame]
/*############################################################################
# Copyright 1999-2018 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.
############################################################################*/
/*
//
// Purpose:
// Cryptography Primitive.
// EC over Prime Finite Field (EC Point operations)
//
// Contents:
// ippsECCPSetPoint()
// ippsECCPSetPointAtInfinity()
// ippsECCPGetPoint()
//
// ippsECCPCheckPoint()
// ippsECCPComparePoint()
//
// ippsECCPNegativePoint()
// ippsECCPAddPoint()
// ippsECCPMulPointScalar()
//
//
*/
#include "owndefs.h"
#include "owncp.h"
#include "pcpeccp.h"
/*F*
// Name: ippsECCPSetPoint
//
// Purpose: Converts regular affine coordinates EC point (pX,pY)
// into internal presentation - montgomery projective.
//
// Returns: Reason:
// ippStsNullPtrErr NULL == pECC
// NULL == pPoint
// NULL == pX
// NULL == pY
//
// ippStsContextMatchErr illegal pECC->idCtx
// illegal pX->idCtx
// illegal pY->idCtx
// illegal pPoint->idCtx
//
// ippStsOutOfECErr point out-of EC
//
// ippStsNoErr no errors
//
// Parameters:
// pX pointer to the regular affine coordinate X
// pY pointer to the regular affine coordinate Y
// pPoint pointer to the EC Point context
// pECC pointer to the ECCP context
//
// Note:
// if B==0 and (x,y)=(0,y) then point at Infinity will be set up
// if B!=0 and (x,y)=(0,0) then point at Infinity will be set up
// else point with requested coordinates (x,y) wil be set up
// There are no check validation inside!
//
*F*/
IPPFUN(IppStatus, ippsECCPSetPoint,(const IppsBigNumState* pX,
const IppsBigNumState* pY,
IppsECCPPointState* pPoint,
IppsECCPState* pEC))
{
/* test pEC */
IPP_BAD_PTR1_RET(pEC);
/* use aligned EC context */
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET(!ECP_TEST_ID(pEC), ippStsContextMatchErr);
/* test pX and pY */
IPP_BAD_PTR2_RET(pX,pY);
pX = (IppsBigNumState*)( IPP_ALIGNED_PTR(pX, ALIGN_VAL) );
pY = (IppsBigNumState*)( IPP_ALIGNED_PTR(pY, ALIGN_VAL) );
IPP_BADARG_RET(!BN_VALID_ID(pX), ippStsContextMatchErr);
IPP_BADARG_RET(!BN_VALID_ID(pY), ippStsContextMatchErr);
{
IppStatus sts;
IppsGFpState* pGF = ECP_GFP(pEC);
gsModEngine* pGFE = GFP_PMA(pGF);
int elemLen = GFP_FELEN(pGFE);
IppsGFpElement elmX, elmY;
cpGFpElementConstruct(&elmX, cpGFpGetPool(1, pGFE), elemLen);
cpGFpElementConstruct(&elmY, cpGFpGetPool(1, pGFE), elemLen);
do {
BNU_CHUNK_T* pData = BN_NUMBER(pX);
int ns = BN_SIZE(pX);
sts = ippsGFpSetElement((Ipp32u*)pData, BITS2WORD32_SIZE(BITSIZE_BNU(pData, ns)), &elmX, pGF);
if(ippStsNoErr!=sts) break;
pData = BN_NUMBER(pY);
ns = BN_SIZE(pY);
sts = ippsGFpSetElement((Ipp32u*)pData, BITS2WORD32_SIZE(BITSIZE_BNU(pData, ns)), &elmY, pGF);
if(ippStsNoErr!=sts) break;
sts = ippsGFpECSetPoint(&elmX, &elmY, pPoint, pEC);
} while(0);
cpGFpReleasePool(2, pGFE);
return sts;
}
}
/*F*
// Name: ippsECCPSetPointAtInfinity
//
// Purpose: Set point at Infinity
//
// Returns: Reason:
// ippStsNullPtrErr NULL == pECC
// NULL == pPoint
//
// ippStsContextMatchErr illegal pECC->idCtx
// illegal pPoint->idCtx
//
// ippStsNoErr no errors
//
// Parameters:
// pPoint pointer to the EC Point context
// pECC pointer to the ECCP context
//
*F*/
IPPFUN(IppStatus, ippsECCPSetPointAtInfinity,(IppsECCPPointState* pPoint, IppsECCPState* pEC))
{
return ippsGFpECSetPointAtInfinity(pPoint, pEC);
}
/*F*
// Name: ippsECCPGetPoint
//
// Purpose: Converts internal presentation EC point - montgomery projective
// into regular affine coordinates EC point (pX,pY)
//
// Returns: Reason:
// ippStsNullPtrErr NULL == pECC
// NULL == pPoint
//
// ippStsContextMatchErr illegal pECC->idCtx
// illegal pPoint->idCtx
// NULL != pX, illegal pX->idCtx
// NULL != pY, illegal pY->idCtx
//
// ippStsNoErr no errors
//
// Parameters:
// pX pointer to the regular affine coordinate X
// pY pointer to the regular affine coordinate Y
// pLength pointer to the length of coordinates
// pPoint pointer to the EC Point context
// pECC pointer to the ECCP context
//
*F*/
IPPFUN(IppStatus, ippsECCPGetPoint,(IppsBigNumState* pX, IppsBigNumState* pY,
const IppsECCPPointState* pPoint,
IppsECCPState* pEC))
{
/* test pEC */
IPP_BAD_PTR1_RET(pEC);
/* use aligned EC context */
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET(!ECP_TEST_ID(pEC), ippStsContextMatchErr);
/* test pX and pY */
if(pX) {
pX = (IppsBigNumState*)( IPP_ALIGNED_PTR(pX, ALIGN_VAL) );
IPP_BADARG_RET(!BN_VALID_ID(pX), ippStsContextMatchErr);
}
if(pY) {
pY = (IppsBigNumState*)( IPP_ALIGNED_PTR(pY, ALIGN_VAL) );
IPP_BADARG_RET(!BN_VALID_ID(pY), ippStsContextMatchErr);
}
{
IppStatus sts;
IppsGFpState* pGF = ECP_GFP(pEC);
gsModEngine* pGFE = GFP_PMA(pGF);
int elemLen = GFP_FELEN(pGFE);
mod_decode decode = GFP_METHOD(pGFE)->decode; /* gf decode method */
IppsGFpElement elmX, elmY;
cpGFpElementConstruct(&elmX, cpGFpGetPool(1, pGFE), elemLen);
cpGFpElementConstruct(&elmY, cpGFpGetPool(1, pGFE), elemLen);
do {
sts = ippsGFpECGetPoint(pPoint, pX? &elmX:NULL, pY? &elmY:NULL, pEC);
if(ippStsNoErr!=sts) break;
if(pX) {
decode(elmX.pData, elmX.pData, pGFE);
sts = ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)elmX.pData, pX);
if(ippStsNoErr!=sts) break;
}
if(pY) {
decode(elmY.pData, elmY.pData, pGFE);
sts = ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)elmY.pData, pY);
if(ippStsNoErr!=sts) break;
}
} while(0);
cpGFpReleasePool(2, pGFE);
return sts;
}
}
/*F*
// Name: ippsECCPCheckPoint
//
// Purpose: Check EC point:
// - is point lie on EC
// - is point at infinity
//
// Returns: Reason:
// ippStsNullPtrErr NULL == pECC
// NULL == pP
// NULL == pResult
//
// ippStsContextMatchErr illegal pECC->idCtx
// illegal pP->idCtx
//
// ippStsNoErr no errors
//
// Parameters:
// pPoint pointer to the EC Point context
// pECC pointer to the ECCP context
// pResult pointer to the result:
// ippECValid
// ippECPointIsNotValid
// ippECPointIsAtInfinite
//
*F*/
IPPFUN(IppStatus, ippsECCPCheckPoint,(const IppsECCPPointState* pP,
IppECResult* pResult,
IppsECCPState* pEC))
{
return ippsGFpECTstPoint(pP, pResult, pEC);
}
/*F*
// Name: ippsECCPComparePoint
//
// Purpose: Compare two EC points
//
// Returns: Reason:
// ippStsNullPtrErr NULL == pECC
// NULL == pP
// NULL == pQ
// NULL == pResult
//
// ippStsContextMatchErr illegal pECC->idCtx
// illegal pP->idCtx
// illegal pQ->idCtx
//
// ippStsNoErr no errors
//
// Parameters:
// pP pointer to the EC Point context
// pQ pointer to the EC Point context
// pECC pointer to the ECCP context
// pResult pointer to the result:
// ippECPointIsEqual
// ippECPointIsNotEqual
//
*F*/
IPPFUN(IppStatus, ippsECCPComparePoint,(const IppsECCPPointState* pP,
const IppsECCPPointState* pQ,
IppECResult* pResult,
IppsECCPState* pEC))
{
return ippsGFpECCmpPoint(pP, pQ, pResult, pEC);
}
/*F*
// Name: ippsECCPNegativePoint
//
// Purpose: Perforn EC point operation: R = -P
//
// Returns: Reason:
// ippStsNullPtrErr NULL == pECC
// NULL == pP
// NULL == pR
//
// ippStsContextMatchErr illegal pECC->idCtx
// illegal pP->idCtx
// illegal pR->idCtx
//
// ippStsNoErr no errors
//
// Parameters:
// pP pointer to the source EC Point context
// pR pointer to the resultant EC Point context
// pECC pointer to the ECCP context
//
*F*/
IPPFUN(IppStatus, ippsECCPNegativePoint, (const IppsECCPPointState* pP,
IppsECCPPointState* pR,
IppsECCPState* pEC))
{
return ippsGFpECNegPoint(pP, pR, pEC);
}
/*F*
// Name: ippsECCPAddPoint
//
// Purpose: Perforn EC point operation: R = P+Q
//
// Returns: Reason:
// ippStsNullPtrErr NULL == pECC
// NULL == pP
// NULL == pQ
// NULL == pR
//
// ippStsContextMatchErr illegal pECC->idCtx
// illegal pP->idCtx
// illegal pQ->idCtx
// illegal pR->idCtx
//
// ippStsNoErr no errors
//
// Parameters:
// pP pointer to the source EC Point context
// pQ pointer to the source EC Point context
// pR pointer to the resultant EC Point context
// pECC pointer to the ECCP context
//
*F*/
IPPFUN(IppStatus, ippsECCPAddPoint,(const IppsECCPPointState* pP,
const IppsECCPPointState* pQ,
IppsECCPPointState* pR,
IppsECCPState* pEC))
{
return ippsGFpECAddPoint(pP, pQ, pR, pEC);
}
/*F*
// Name: ippsECCPMulPointScalar
//
// Purpose: Perforn EC point operation: R = k*P
//
// Returns: Reason:
// ippStsNullPtrErr NULL == pECC
// NULL == pP
// NULL == pK
// NULL == pR
//
// ippStsContextMatchErr illegal pECC->idCtx
// illegal pP->idCtx
// illegal pK->idCtx
// illegal pR->idCtx
//
// ippStsNoErr no errors
//
// Parameters:
// pP pointer to the source EC Point context
// pK pointer to the source BigNum multiplier context
// pR pointer to the resultant EC Point context
// pECC pointer to the ECCP context
//
*F*/
IPPFUN(IppStatus, ippsECCPMulPointScalar,(const IppsECCPPointState* pP,
const IppsBigNumState* pK,
IppsECCPPointState* pR,
IppsECCPState* pEC))
{
/* use aligned EC context */
IPP_BAD_PTR1_RET(pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET(!ECP_TEST_ID(pEC), ippStsContextMatchErr);
return ippsGFpECMulPoint(pP, pK, pR, pEC, (Ipp8u*)ECP_SBUFFER(pEC));
}