blob: 574d76f643eac39354477c5f0459a05251991b6e [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:
// Intel(R) Performance Primitives. Cryptography Primitives.
// EC over GF(p) Operations
//
// Context:
// ippsGFpECPointGetSize()
// ippsGFpECPointInit()
//
// ippsGFpECSetPointAtInfinity()
// ippsGFpECSetPoint()
// ippsGFpECSetPointRegular()
// ippsGFpECMakePoint()
// ippsGFpECSetPointRandom()
// ippsGFpECSetPointHash()
// ippsGFpECSetPointHash_rmf()
// ippsGFpECGetPoint()
// ippsGFpECGetPointRegular()
// ippsGFpECCpyPoint()
//
// ippsGFpECCmpPoint()
// ippsGFpECTstPoint()
// ippsGFpECNegPoint()
// ippsGFpECAddPoint()
// ippsGFpECMulPoint()
//
//
*/
#include "owndefs.h"
#include "owncp.h"
#include "pcpgfpecstuff.h"
#include "pcphash.h"
#include "pcphash_rmf.h"
IPPFUN(IppStatus, ippsGFpECPointGetSize,(const IppsGFpECState* pEC, int* pSizeInBytes))
{
IPP_BAD_PTR2_RET(pEC, pSizeInBytes);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
{
int elemLen = GFP_FELEN(GFP_PMA(ECP_GFP(pEC)));
*pSizeInBytes = sizeof(IppsGFpECPoint)
+elemLen*sizeof(BNU_CHUNK_T) /* X */
+elemLen*sizeof(BNU_CHUNK_T) /* Y */
+elemLen*sizeof(BNU_CHUNK_T);/* Z */
return ippStsNoErr;
}
}
IPPFUN(IppStatus, ippsGFpECPointInit,(const IppsGFpElement* pX, const IppsGFpElement* pY,
IppsGFpECPoint* pPoint, IppsGFpECState* pEC))
{
IPP_BAD_PTR2_RET(pPoint, pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
{
Ipp8u* ptr = (Ipp8u*)pPoint;
int elemLen = GFP_FELEN(GFP_PMA(ECP_GFP(pEC)));
ECP_POINT_ID(pPoint) = idCtxGFPPoint;
ECP_POINT_FLAGS(pPoint) = 0;
ECP_POINT_FELEN(pPoint) = elemLen;
ptr += sizeof(IppsGFpECPoint);
ECP_POINT_DATA(pPoint) = (BNU_CHUNK_T*)(ptr);
if(pX && pY)
return ippsGFpECSetPoint(pX, pY, pPoint, pEC);
else {
gfec_SetPointAtInfinity(pPoint);
return ippStsNoErr;
}
}
}
IPPFUN(IppStatus, ippsGFpECSetPointAtInfinity,(IppsGFpECPoint* pPoint, IppsGFpECState* pEC))
{
IPP_BAD_PTR2_RET(pPoint, pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
gfec_SetPointAtInfinity(pPoint);
return ippStsNoErr;
}
IPPFUN(IppStatus, ippsGFpECSetPoint,(const IppsGFpElement* pX, const IppsGFpElement* pY,
IppsGFpECPoint* pPoint,
IppsGFpECState* pEC))
{
IPP_BAD_PTR2_RET(pPoint, pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
IPP_BAD_PTR2_RET(pX, pY);
IPP_BADARG_RET( !GFPE_TEST_ID(pX), ippStsContextMatchErr );
IPP_BADARG_RET( !GFPE_TEST_ID(pY), ippStsContextMatchErr );
IPP_BADARG_RET( GFPE_ROOM(pX)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
IPP_BADARG_RET( GFPE_ROOM(pY)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
if(gfec_SetPoint(ECP_POINT_DATA(pPoint), GFPE_DATA(pX), GFPE_DATA(pY), pEC))
ECP_POINT_FLAGS(pPoint) = ECP_AFFINE_POINT | ECP_FINITE_POINT;
else
ECP_POINT_FLAGS(pPoint) = 0;
return ippStsNoErr;
}
IPPFUN(IppStatus, ippsGFpECSetPointRegular,(const IppsBigNumState* pX, const IppsBigNumState* pY,
IppsGFpECPoint* pPoint,
IppsGFpECState* pEC))
{
IPP_BAD_PTR2_RET(pPoint, pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
IPP_BAD_PTR2_RET(pX, pY);
pX = (IppsBigNumState*)( IPP_ALIGNED_PTR(pX, BN_ALIGNMENT) );
pY = (IppsBigNumState*)( IPP_ALIGNED_PTR(pY, BN_ALIGNMENT) );
IPP_BADARG_RET( !BN_VALID_ID(pX), ippStsContextMatchErr );
IPP_BADARG_RET( !BN_VALID_ID(pY), ippStsContextMatchErr );
IPP_BADARG_RET( !BN_POSITIVE(pX), ippStsOutOfRangeErr);
IPP_BADARG_RET( !BN_POSITIVE(pY), ippStsOutOfRangeErr);
{
IppsGFpState* pGF = ECP_GFP(pEC);
gsModEngine* pGFE = GFP_PMA(pGF);
int elemLen = GFP_FELEN(pGFE);
IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr )
IPP_BADARG_RET( BN_SIZE(pX) > elemLen, ippStsOutOfRangeErr);
IPP_BADARG_RET( BN_SIZE(pY) > elemLen, ippStsOutOfRangeErr);
IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=elemLen, ippStsOutOfRangeErr);
{
BNU_CHUNK_T* pointX = ECP_POINT_X(pPoint);
BNU_CHUNK_T* pointY = ECP_POINT_Y(pPoint);
BNU_CHUNK_T* pointZ = ECP_POINT_Z(pPoint);
cpGFpElementCopyPadd(pointX, elemLen, BN_NUMBER(pX), BN_SIZE(pX));
cpGFpElementCopyPadd(pointY, elemLen, BN_NUMBER(pY), BN_SIZE(pY));
cpGFpElementCopy(pointZ, MOD_MNT_R(pGFE), elemLen);
if( cpGFpSet(pointX, pointX, elemLen, pGFE) && cpGFpSet(pointY, pointY, elemLen, pGFE) )
ECP_POINT_FLAGS(pPoint) = ECP_AFFINE_POINT | ECP_FINITE_POINT;
else
gfec_SetPointAtInfinity(pPoint);
return ippStsNoErr;
}
}
}
IPPFUN(IppStatus, ippsGFpECGetPoint,(const IppsGFpECPoint* pPoint,
IppsGFpElement* pX, IppsGFpElement* pY,
IppsGFpECState* pEC))
{
IPP_BAD_PTR2_RET(pPoint, pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
///IPP_BADARG_RET( !IS_ECP_FINITE_POINT(pPoint), ippStsPointAtInfinity);
IPP_BADARG_RET( pX && !GFPE_TEST_ID(pX), ippStsContextMatchErr );
IPP_BADARG_RET( pY && !GFPE_TEST_ID(pY), ippStsContextMatchErr );
IPP_BADARG_RET( pX && GFPE_ROOM(pX)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
IPP_BADARG_RET( pY && GFPE_ROOM(pY)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
/* returns (X,Y) == (0,0) if Point is at infinity */
gfec_GetPoint((pX)? GFPE_DATA(pX):NULL, (pY)? GFPE_DATA(pY):NULL, pPoint, pEC);
return ippStsNoErr;
}
IPPFUN(IppStatus, ippsGFpECGetPointRegular,(const IppsGFpECPoint* pPoint,
IppsBigNumState* pX, IppsBigNumState* pY,
IppsGFpECState* pEC))
{
IppsGFpState* pGF;
gsModEngine* pGFE;
IPP_BAD_PTR2_RET(pPoint, pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
pGF = ECP_GFP(pEC);
pGFE = GFP_PMA(pGF);
if(pX) {
pX = (IppsBigNumState*)( IPP_ALIGNED_PTR(pX, BN_ALIGNMENT) );
IPP_BADARG_RET(!BN_VALID_ID(pX), ippStsContextMatchErr );
IPP_BADARG_RET(BN_ROOM(pX)*BNU_CHUNK_BITS<GFP_FEBITLEN(pGFE), ippStsOutOfRangeErr);
}
if(pY) {
pY = (IppsBigNumState*)( IPP_ALIGNED_PTR(pY, BN_ALIGNMENT) );
IPP_BADARG_RET(!BN_VALID_ID(pY), ippStsContextMatchErr );
IPP_BADARG_RET(BN_ROOM(pY)*BNU_CHUNK_BITS<GFP_FEBITLEN(pGFE), ippStsOutOfRangeErr);
}
{
int elmLen = GFP_FELEN(pGFE);
BNU_CHUNK_T* x = cpGFpGetPool(2, pGFE);
BNU_CHUNK_T* y = x + elmLen;
/* returns (X,Y) == (0,0) if Point is at infinity */
gfec_GetPoint((pX)? x:NULL, (pY)? y:NULL, pPoint, pEC);
/* convert into refular domain */
if(pX) {
GFP_METHOD(pGFE)->decode(x, x, pGFE);
ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)x, pX);
}
if(pY) {
GFP_METHOD(pGFE)->decode(y, y, pGFE);
ippsSet_BN(ippBigNumPOS, GFP_FELEN32(pGFE), (Ipp32u*)y, pY);
}
cpGFpReleasePool(2, pGFE);
return ippStsNoErr;
}
}
IPPFUN(IppStatus, ippsGFpECMakePoint,(const IppsGFpElement* pX, IppsGFpECPoint* pPoint, IppsGFpECState* pEC))
{
IPP_BAD_PTR3_RET(pX, pPoint, pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !GFP_IS_BASIC(GFP_PMA(ECP_GFP(pEC))), ippStsBadArgErr );
IPP_BADARG_RET( !GFPE_TEST_ID(pX), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
IPP_BADARG_RET( GFPE_ROOM(pX)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
return gfec_MakePoint(pPoint, GFPE_DATA(pX), pEC)? ippStsNoErr : ippStsQuadraticNonResidueErr;
}
IPPFUN(IppStatus, ippsGFpECSetPointRandom,(IppsGFpECPoint* pPoint, IppsGFpECState* pEC,
IppBitSupplier rndFunc, void* pRndParam,
Ipp8u* pScratchBuffer))
{
IppsGFpState* pGF;
gsModEngine* pGFE;
IPP_BAD_PTR3_RET(pPoint, pEC, pScratchBuffer);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
pGF = ECP_GFP(pEC);
pGFE = GFP_PMA(pGF);
IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr);
IPP_BAD_PTR2_RET(rndFunc, pRndParam);
{
int internal_err;
if( GFP_IS_BASIC(pGFE) ) {
BNU_CHUNK_T* pElm = cpGFpGetPool(1, pGFE);
do { /* get random X */
internal_err = NULL==cpGFpRand(pElm, pGFE, rndFunc, pRndParam);
} while( !internal_err && !gfec_MakePoint(pPoint, pElm, pEC) );
cpGFpReleasePool(1, pGFE);
/* R = [cofactor]R */
if(!internal_err)
gfec_MulPoint(pPoint, pPoint, ECP_COFACTOR(pEC), GFP_FELEN(pGFE), pEC, pScratchBuffer);
}
else {
/* number of bits and dwords being generated */
int generatedBits = ECP_ORDBITSIZE(pEC) + GFP_RAND_ADD_BITS;
int generatedLen = BITS_BNU_CHUNK(generatedBits);
/* allocate random exponent */
int poolElements = (generatedLen + GFP_PELEN(pGFE) -1) / GFP_PELEN(pGFE);
BNU_CHUNK_T* pExp = cpGFpGetPool(poolElements, pGFE);
int nsE;
/* setup copy of the base point */
IppsGFpECPoint G;
cpEcGFpInitPoint(&G, ECP_G(pEC),ECP_AFFINE_POINT|ECP_FINITE_POINT, pEC);
/* get random bits */
internal_err = ippStsNoErr != rndFunc((Ipp32u*)pExp, generatedBits, pRndParam);
if(!internal_err) {
/* reduce with respect to order value */
nsE = cpMod_BNU(pExp, generatedLen, MOD_MODULUS(ECP_MONT_R(pEC)), BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC)));
/* compute random point */
gfec_MulPoint(pPoint, &G, pExp, nsE, pEC, pScratchBuffer);
}
cpGFpReleasePool(poolElements, pGFE);
}
return internal_err? ippStsErr : ippStsNoErr;
}
}
IPPFUN(IppStatus, ippsGFpECCpyPoint,(const IppsGFpECPoint* pA,
IppsGFpECPoint* pR,
IppsGFpECState* pEC))
{
IPP_BAD_PTR3_RET(pA, pR, pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pA), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pR), ippStsContextMatchErr );
IPP_BADARG_RET( ECP_POINT_FELEN(pA)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
IPP_BADARG_RET( ECP_POINT_FELEN(pR)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
gfec_CopyPoint(pR, pA, GFP_FELEN(GFP_PMA(ECP_GFP(pEC))));
return ippStsNoErr;
}
IPPFUN(IppStatus, ippsGFpECCmpPoint,(const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ,
IppECResult* pResult,
IppsGFpECState* pEC))
{
IPP_BAD_PTR4_RET(pP, pQ, pResult, pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pP), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pQ), ippStsContextMatchErr );
IPP_BADARG_RET( ECP_POINT_FELEN(pP)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
IPP_BADARG_RET( ECP_POINT_FELEN(pQ)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
*pResult = gfec_ComparePoint(pP, pQ, pEC)? ippECPointIsEqual : ippECPointIsNotEqual;
return ippStsNoErr;
}
IPPFUN(IppStatus, ippsGFpECTstPoint,(const IppsGFpECPoint* pP,
IppECResult* pResult,
IppsGFpECState* pEC))
{
IPP_BAD_PTR3_RET(pP, pResult, pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pP), ippStsContextMatchErr );
IPP_BADARG_RET( ECP_POINT_FELEN(pP)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
if( gfec_IsPointAtInfinity(pP) )
*pResult = ippECPointIsAtInfinite;
else if( !gfec_IsPointOnCurve(pP, pEC) )
*pResult = ippECPointIsNotValid;
else
*pResult = ippECValid;
return ippStsNoErr;
}
IPPFUN(IppStatus, ippsGFpECTstPointInSubgroup,(const IppsGFpECPoint* pP,
IppECResult* pResult,
IppsGFpECState* pEC,
Ipp8u* pScratchBuffer))
{
IPP_BAD_PTR4_RET(pP, pResult, pEC, pScratchBuffer);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pP), ippStsContextMatchErr );
IPP_BADARG_RET( ECP_POINT_FELEN(pP)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
{
IppECResult tstResult;
ippsGFpECTstPoint(pP, &tstResult, pEC);
if(ippECValid==tstResult) {
IppsGFpECPoint T;
cpEcGFpInitPoint(&T, cpEcGFpGetPool(1, pEC),0, pEC);
gfec_MulPoint(&T, pP, MOD_MODULUS(ECP_MONT_R(pEC)), BITS_BNU_CHUNK(ECP_ORDBITSIZE(pEC)), pEC, pScratchBuffer);
tstResult = gfec_IsPointAtInfinity(&T)? ippECValid : ippECPointOutOfGroup;
cpEcGFpReleasePool(1, pEC);
}
*pResult = tstResult;
return ippStsNoErr;
}
}
IPPFUN(IppStatus, ippsGFpECNegPoint,(const IppsGFpECPoint* pP,
IppsGFpECPoint* pR,
IppsGFpECState* pEC))
{
IPP_BAD_PTR3_RET(pP, pR, pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pP), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pR), ippStsContextMatchErr );
IPP_BADARG_RET( ECP_POINT_FELEN(pP)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
IPP_BADARG_RET( ECP_POINT_FELEN(pR)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
gfec_NegPoint(pR, pP, pEC);
return ippStsNoErr;
}
IPPFUN(IppStatus, ippsGFpECAddPoint,(const IppsGFpECPoint* pP, const IppsGFpECPoint* pQ, IppsGFpECPoint* pR,
IppsGFpECState* pEC))
{
IPP_BAD_PTR4_RET(pP, pQ, pR, pEC);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pP), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pQ), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pR), ippStsContextMatchErr );
IPP_BADARG_RET( ECP_POINT_FELEN(pP)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
IPP_BADARG_RET( ECP_POINT_FELEN(pQ)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
IPP_BADARG_RET( ECP_POINT_FELEN(pR)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
if(pP==pQ)
gfec_DblPoint(pR, pP, pEC);
else
gfec_AddPoint(pR, pP, pQ, pEC);
return ippStsNoErr;
}
IPPFUN(IppStatus, ippsGFpECMulPoint,(const IppsGFpECPoint* pP,
const IppsBigNumState* pN,
IppsGFpECPoint* pR,
IppsGFpECState* pEC,
Ipp8u* pScratchBuffer))
{
IPP_BAD_PTR4_RET(pP, pR, pEC, pScratchBuffer);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pP), ippStsContextMatchErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pR), ippStsContextMatchErr );
IPP_BADARG_RET( ECP_POINT_FELEN(pP)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
IPP_BADARG_RET( ECP_POINT_FELEN(pR)!=GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsOutOfRangeErr);
IPP_BAD_PTR1_RET(pN);
pN = (IppsBigNumState*)( IPP_ALIGNED_PTR(pN, BN_ALIGNMENT) );
IPP_BADARG_RET(!BN_VALID_ID(pN), ippStsContextMatchErr );
IPP_BADARG_RET( BN_NEGATIVE(pN), ippStsBadArgErr );
IPP_BADARG_RET(BN_SIZE(pN)>2*GFP_FELEN(GFP_PMA(ECP_GFP(pEC))), ippStsSizeErr);
gfec_MulPoint(pR, pP, BN_NUMBER(pN), BN_SIZE(pN), pEC, pScratchBuffer);
return ippStsNoErr;
}
IPPFUN(IppStatus, ippsGFpECSetPointHash,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint,
IppsGFpECState* pEC, IppHashAlgId hashID,
Ipp8u* pScratchBuffer))
{
IppsGFpState* pGF;
gsModEngine* pGFE;
/* get algorithm id */
hashID = cpValidHashAlg(hashID);
IPP_BADARG_RET(ippHashAlg_Unknown==hashID, ippStsNotSupportedModeErr);
/* test message length */
IPP_BADARG_RET((msgLen<0), ippStsLengthErr);
/* test message pointer */
IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr);
IPP_BAD_PTR3_RET(pPoint, pEC, pScratchBuffer);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
pGF = ECP_GFP(pEC);
pGFE = GFP_PMA(pGF);
IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr);
{
int elemLen = GFP_FELEN(pGFE);
BNU_CHUNK_T* pModulus = GFP_MODULUS(pGFE);
Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/BYTESIZE];
int hashLen = cpHashAlgAttr[hashID].hashSize;
BNU_CHUNK_T hashVal[BITS_BNU_CHUNK(IPP_SHA512_DIGEST_BITSIZE)+1];
int hashValLen;
IppsHashState hashCtx;
ippsHashInit(&hashCtx, hashID);
{
BNU_CHUNK_T* pPoolElm = cpGFpGetPool(1, pGFE);
/* convert hdr => hdrStr */
BNU_CHUNK_T locHdr = (BNU_CHUNK_T)hdr;
Ipp8u hdrOctStr[sizeof(hdr/*locHdr*/)];
cpToOctStr_BNU(hdrOctStr, sizeof(hdrOctStr), &locHdr, 1);
/* compute md = hash(hrd||msg) */
ippsHashUpdate(hdrOctStr, sizeof(hdrOctStr), &hashCtx);
ippsHashUpdate(pMsg, msgLen, &hashCtx);
ippsHashFinal(md, &hashCtx);
/* convert hash into the integer */
hashValLen = cpFromOctStr_BNU(hashVal, md, hashLen);
hashValLen = cpMod_BNU(hashVal, hashValLen, pModulus, elemLen);
cpGFpSet(pPoolElm, hashVal, hashValLen, pGFE);
if( gfec_MakePoint(pPoint, pPoolElm, pEC)) {
/* set y-coordinate of the point (positive or negative) */
BNU_CHUNK_T* pY = ECP_POINT_Y(pPoint);
if(pY[0] & 1)
cpGFpNeg(pY, pY, pGFE);
/* update point if cofactor>1 */
gfec_MulPoint(pPoint, pPoint, ECP_COFACTOR(pEC), GFP_FELEN(pGFE), pEC, pScratchBuffer);
cpGFpReleasePool(1, pGFE);
return ippStsNoErr;
}
}
cpGFpReleasePool(1, pGFE);
return ippStsQuadraticNonResidueErr;
}
}
IPPFUN(IppStatus, ippsGFpECSetPointHash_rmf,(Ipp32u hdr, const Ipp8u* pMsg, int msgLen, IppsGFpECPoint* pPoint,
IppsGFpECState* pEC, const IppsHashMethod* pMethod,
Ipp8u* pScratchBuffer))
{
IppsGFpState* pGF;
gsModEngine* pGFE;
/* test method pointer */
IPP_BAD_PTR1_RET(pMethod);
/* test message length */
IPP_BADARG_RET((msgLen<0), ippStsLengthErr);
/* test message pointer */
IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr);
IPP_BAD_PTR3_RET(pPoint, pEC, pScratchBuffer);
pEC = (IppsGFpECState*)( IPP_ALIGNED_PTR(pEC, ECGFP_ALIGNMENT) );
IPP_BADARG_RET( !ECP_TEST_ID(pEC), ippStsContextMatchErr );
pGF = ECP_GFP(pEC);
pGFE = GFP_PMA(pGF);
IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr );
IPP_BADARG_RET( !ECP_POINT_TEST_ID(pPoint), ippStsContextMatchErr );
IPP_BADARG_RET( ECP_POINT_FELEN(pPoint)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr);
{
int elemLen = GFP_FELEN(pGFE);
BNU_CHUNK_T* pModulus = GFP_MODULUS(pGFE);
Ipp8u md[IPP_SHA512_DIGEST_BITSIZE/BYTESIZE];
int hashLen = pMethod->hashLen;
BNU_CHUNK_T hashVal[BITS_BNU_CHUNK(IPP_SHA512_DIGEST_BITSIZE)+1];
int hashValLen;
IppsHashState_rmf hashCtx;
ippsHashInit_rmf(&hashCtx, pMethod);
{
BNU_CHUNK_T* pPoolElm = cpGFpGetPool(1, pGFE);
/* convert hdr => hdrStr */
BNU_CHUNK_T locHdr = (BNU_CHUNK_T)hdr;
Ipp8u hdrOctStr[sizeof(hdr/*locHdr*/)];
cpToOctStr_BNU(hdrOctStr, sizeof(hdrOctStr), &locHdr, 1);
/* compute md = hash(hrd||msg) */
ippsHashUpdate_rmf(hdrOctStr, sizeof(hdrOctStr), &hashCtx);
ippsHashUpdate_rmf(pMsg, msgLen, &hashCtx);
ippsHashFinal_rmf(md, &hashCtx);
/* convert hash into the integer */
hashValLen = cpFromOctStr_BNU(hashVal, md, hashLen);
hashValLen = cpMod_BNU(hashVal, hashValLen, pModulus, elemLen);
cpGFpSet(pPoolElm, hashVal, hashValLen, pGFE);
if( gfec_MakePoint(pPoint, pPoolElm, pEC)) {
/* set y-coordinate of the point (positive or negative) */
BNU_CHUNK_T* pY = ECP_POINT_Y(pPoint);
if(pY[0] & 1)
cpGFpNeg(pY, pY, pGFE);
/* update point if cofactor>1 */
gfec_MulPoint(pPoint, pPoint, ECP_COFACTOR(pEC), GFP_FELEN(pGFE), pEC, pScratchBuffer);
cpGFpReleasePool(1, pGFE);
return ippStsNoErr;
}
}
cpGFpReleasePool(1, pGFE);
return ippStsQuadraticNonResidueErr;
}
}