diff options
Diffstat (limited to 'ext/ipp/sources/ippcp/src/pcpgfp.c')
-rw-r--r-- | ext/ipp/sources/ippcp/src/pcpgfp.c | 1165 |
1 files changed, 1165 insertions, 0 deletions
diff --git a/ext/ipp/sources/ippcp/src/pcpgfp.c b/ext/ipp/sources/ippcp/src/pcpgfp.c new file mode 100644 index 0000000..693efe8 --- /dev/null +++ b/ext/ipp/sources/ippcp/src/pcpgfp.c @@ -0,0 +1,1165 @@ +/*############################################################################ + # 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. + ############################################################################*/ + +/* +// Intel(R) Performance Primitives. Cryptography Primitives. +// Operations over GF(p). +// +// Context: +// ippsGFpGetSize() +// ippsGFpInitArbitrary() +// ippsGFpInitFixed() +// ippsGFpInit() +// +// ippsGFpElementGetSize() +// ippsGFpElementInit() +// +// ippsGFpSetElement() +// ippsGFpSetElementRegular() +// ippsGFpSetElementOctString() +// ippsGFpSetElementRandom() +// ippsGFpSetElementHash() +// ippsGFpSetElementHash_rmf +// ippsGFpCpyElement() +// ippsGFpGetElement() +// ippsGFpGetElementOctString() +// +// ippsGFpCmpElement() +// ippsGFpIsZeroElement() +// ippsGFpIsUnityElement() +// +// ippsGFpSetPolyTerm() +// ippsGFpGetPolyTerm() +// +// ippsGFpConj() +// ippsGFpNeg() +// ippsGFpInv() +// ippsGFpSqrt() +// ippsGFpAdd() +// ippsGFpSub() +// ippsGFpMul() +// ippsGFpSqr() +// ippsGFpExp() +// ippsGFpMultiExp() +// +// ippsGFpAdd_GFpE() +// ippsGFpSub_GFpE() +// ippsGFpMul_GFpE() +// +// +*/ +#include "owndefs.h" +#include "owncp.h" + +#include "pcpgfpstuff.h" +#include "pcpgfpxstuff.h" +#include "pcphash.h" +#include "pcphash_rmf.h" +#include "pcptool.h" + +//gres: temporary excluded: #include <assert.h> + + +/* +// size of GFp engine context (Montgomery) +*/ +int cpGFpGetSize(int feBitSize, int peBitSize, int numpe) +{ + int ctxSize = 0; + int elemLen = BITS_BNU_CHUNK(feBitSize); + int pelmLen = BITS_BNU_CHUNK(peBitSize); + + /* size of GFp engine */ + ctxSize = sizeof(gsModEngine) + + elemLen*sizeof(BNU_CHUNK_T) /* modulus */ + + elemLen*sizeof(BNU_CHUNK_T) /* mont_R */ + + elemLen*sizeof(BNU_CHUNK_T) /* mont_R^2 */ + + elemLen*sizeof(BNU_CHUNK_T) /* half of modulus */ + + elemLen*sizeof(BNU_CHUNK_T) /* quadratic non-residue */ + + pelmLen*sizeof(BNU_CHUNK_T)*numpe; /* pool */ + + ctxSize += sizeof(IppsGFpState); /* size of IppsGFPState */ + return ctxSize; +} + +IPPFUN(IppStatus, ippsGFpGetSize,(int feBitSize, int* pSize)) +{ + IPP_BAD_PTR1_RET(pSize); + IPP_BADARG_RET((feBitSize < 2) || (feBitSize > GFP_MAX_BITSIZE), ippStsSizeErr); + + *pSize = cpGFpGetSize(feBitSize, feBitSize+BITSIZE(BNU_CHUNK_T), GFP_POOL_SIZE) + + GFP_ALIGNMENT; + return ippStsNoErr; +} + + +/* +// init GFp engine context (Montgomery) +*/ +static void cpGFEInit(gsModEngine* pGFE, int modulusBitSize, int peBitSize, int numpe) +{ + int modLen = BITS_BNU_CHUNK(modulusBitSize); + int pelmLen = BITS_BNU_CHUNK(peBitSize); + + Ipp8u* ptr = (Ipp8u*)pGFE; + + /* clear whole context */ + PaddBlock(0, ptr, sizeof(gsModEngine)); + ptr += sizeof(gsModEngine); + + GFP_PARENT(pGFE) = NULL; + GFP_EXTDEGREE(pGFE) = 1; + GFP_FEBITLEN(pGFE) = modulusBitSize; + GFP_FELEN(pGFE) = modLen; + GFP_FELEN32(pGFE) = BITS2WORD32_SIZE(modulusBitSize); + GFP_PELEN(pGFE) = pelmLen; + //GFP_METHOD(pGFE) = method; + GFP_MODULUS(pGFE) = (BNU_CHUNK_T*)(ptr); ptr += modLen*sizeof(BNU_CHUNK_T); + GFP_MNT_R(pGFE) = (BNU_CHUNK_T*)(ptr); ptr += modLen*sizeof(BNU_CHUNK_T); + GFP_MNT_RR(pGFE) = (BNU_CHUNK_T*)(ptr); ptr += modLen*sizeof(BNU_CHUNK_T); + GFP_HMODULUS(pGFE) = (BNU_CHUNK_T*)(ptr); ptr += modLen*sizeof(BNU_CHUNK_T); + GFP_QNR(pGFE) = (BNU_CHUNK_T*)(ptr); ptr += modLen*sizeof(BNU_CHUNK_T); + GFP_POOL(pGFE) = (BNU_CHUNK_T*)(ptr);/* ptr += modLen*sizeof(BNU_CHUNK_T);*/ + GFP_MAXPOOL(pGFE) = numpe; + GFP_USEDPOOL(pGFE) = 0; + + cpGFpElementPadd(GFP_MODULUS(pGFE), modLen, 0); + cpGFpElementPadd(GFP_MNT_R(pGFE), modLen, 0); + cpGFpElementPadd(GFP_MNT_RR(pGFE), modLen, 0); + cpGFpElementPadd(GFP_HMODULUS(pGFE), modLen, 0); + cpGFpElementPadd(GFP_QNR(pGFE), modLen, 0); +} + +static void cpGFEqnr(gsModEngine* pGFE) +{ + BNU_CHUNK_T* pQnr = GFP_QNR(pGFE); + + int elemLen = GFP_FELEN(pGFE); + BNU_CHUNK_T* e = cpGFpGetPool(3, pGFE); + BNU_CHUNK_T* t = e+elemLen; + BNU_CHUNK_T* p1 = t+elemLen; + //gres: temporary excluded: assert(NULL!=e); + + cpGFpElementCopyPadd(p1, elemLen, GFP_MNT_R(pGFE), elemLen); + + /* (modulus-1)/2 */ + cpLSR_BNU(e, GFP_MODULUS(pGFE), elemLen, 1); + + /* find a non-square g, where g^{(modulus-1)/2} = -1 */ + cpGFpElementCopy(pQnr, p1, elemLen); + do { + cpGFpAdd(pQnr, pQnr, p1, pGFE); + cpGFpExp(t, pQnr, e, elemLen, pGFE); + cpGFpNeg(t, t, pGFE); + } while( !GFP_EQ(p1, t, elemLen) ); + + cpGFpReleasePool(3, pGFE); +} + +static void cpGFESet(gsModEngine* pGFE, const BNU_CHUNK_T* pPrime, int primeBitSize, const gsModMethod* method) +{ + int primeLen = BITS_BNU_CHUNK(primeBitSize); + + /* arithmetic methods */ + GFP_METHOD(pGFE) = method; + + /* store modulus */ + COPY_BNU(GFP_MODULUS(pGFE), pPrime, primeLen); + + /* montgomery factor */ + GFP_MNT_FACTOR(pGFE) = gsMontFactor(GFP_MODULUS(pGFE)[0]); + + /* montgomery identity (R) */ + ZEXPAND_BNU(GFP_MNT_R(pGFE), 0, primeLen); + GFP_MNT_R(pGFE)[primeLen] = 1; + cpMod_BNU(GFP_MNT_R(pGFE), primeLen+1, GFP_MODULUS(pGFE), primeLen); + + /* montgomery domain converter (RR) */ + ZEXPAND_BNU(GFP_MNT_RR(pGFE), 0, primeLen); + COPY_BNU(GFP_MNT_RR(pGFE)+primeLen, GFP_MNT_R(pGFE), primeLen); + cpMod_BNU(GFP_MNT_RR(pGFE), 2*primeLen, GFP_MODULUS(pGFE), primeLen); + + /* half of modulus */ + cpLSR_BNU(GFP_HMODULUS(pGFE), GFP_MODULUS(pGFE), primeLen, 1); + + /* set qnr value */ + cpGFEqnr(pGFE); +} + +IppStatus cpGFpInitGFp(int primeBitSize, IppsGFpState* pGF) +{ + IPP_BADARG_RET((primeBitSize< IPP_MIN_GF_BITSIZE) || (primeBitSize> IPP_MAX_GF_BITSIZE), ippStsSizeErr); + IPP_BAD_PTR1_RET(pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + + { + Ipp8u* ptr = (Ipp8u*)pGF; + + GFP_ID(pGF) = idCtxGFP; + GFP_PMA(pGF) = (gsModEngine*)(ptr+sizeof(IppsGFpState)); + cpGFEInit(GFP_PMA(pGF), primeBitSize, primeBitSize+BITSIZE(BNU_CHUNK_T), GFP_POOL_SIZE); + + return ippStsNoErr; + } +} + +IppStatus cpGFpSetGFp(const BNU_CHUNK_T* pPrime, int primeBitSize, const IppsGFpMethod* method, IppsGFpState* pGF) +{ + cpGFESet(GFP_PMA(pGF), pPrime, primeBitSize, method->arith); + return ippStsNoErr; +} + +/*F* +// Name: ippsGFpInitFixed +// +// Purpose: initializes prime finite field GF(p) +// +// Returns: Reason: +// ippStsNullPtrErr NULL == method +// NULL == pGF +// +// ippStsBadArgErr method != ippsGFpMethod_pXXX() any fixed prime method +// primeBitSize != sizeof modulus defined by fixed method +// +// ippStsNoErr no error +// +// Parameters: +// primeBitSize length of prime in bits +// method pointer to the basic arithmetic metods +// pGF pointer to Finite Field context is being initialized +*F*/ +IPPFUN(IppStatus, ippsGFpInitFixed,(int primeBitSize, const IppsGFpMethod* method, IppsGFpState* pGF)) +{ + IPP_BAD_PTR2_RET(method, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + + /* test method is prime based */ + IPP_BADARG_RET(cpID_Prime!=(method->modulusID & cpID_Prime), ippStsBadArgErr); + /* test if method is not prime based arbitrary */ + IPP_BADARG_RET(!method->modulus, ippStsBadArgErr); + /* size of the underlying prime must be equal to primeBitSize parameter*/ + IPP_BADARG_RET(method->modulusBitDeg!=primeBitSize, ippStsBadArgErr); + + { + /* init GF */ + IppStatus sts = cpGFpInitGFp(primeBitSize, pGF); + + /* set up GF engine */ + if(ippStsNoErr==sts) { + gsModEngine* pGFE = GFP_PMA(pGF); + cpGFESet(pGFE, method->modulus, primeBitSize, method->arith); + } + + return sts; + } +} + +/*F* +// Name: ippsGFpInitArbitrary +// +// Purpose: initializes prime finite field GF(p) +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pPrime +// NULL == pGF +// +// ippStsSizeErr !(IPP_MIN_GF_BITSIZE <= primeBitSize <=IPP_MAX_GF_BITSIZE) +// +// ippStsContextMatchErr incorrect pPrime context ID +// +// ippStsBadArgErr prime <0 +// bitsize(prime) != primeBitSize +// prime <IPP_MIN_GF_CHAR +// prime is even +// +// ippStsNoErr no error +// +// Parameters: +// pPrimeBN pointer to the prime context +// primeBitSize length of prime in bits +// pGF pointer to Finite Field context is being initialized +*F*/ +IPPFUN(IppStatus, ippsGFpInitArbitrary,(const IppsBigNumState* pPrimeBN, int primeBitSize, IppsGFpState* pGF)) +{ + IPP_BAD_PTR1_RET(pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + + IPP_BADARG_RET((primeBitSize< IPP_MIN_GF_BITSIZE) || (primeBitSize> IPP_MAX_GF_BITSIZE), ippStsSizeErr); + + IPP_BAD_PTR1_RET(pPrimeBN); + pPrimeBN = (IppsBigNumState*)( IPP_ALIGNED_PTR(pPrimeBN, BN_ALIGNMENT) ); + IPP_BADARG_RET(!BN_VALID_ID(pPrimeBN), ippStsContextMatchErr); + IPP_BADARG_RET(BN_SIGN(pPrimeBN)!= IppsBigNumPOS, ippStsBadArgErr); /* prime is negative */ + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pPrimeBN),BN_SIZE(pPrimeBN)) != primeBitSize, ippStsBadArgErr); /* primeBitSize == bitsize(prime) */ + IPP_BADARG_RET((BN_SIZE(pPrimeBN)==1) && (BN_NUMBER(pPrimeBN)[0]<IPP_MIN_GF_CHAR), ippStsBadArgErr); /* prime < 3 */ + IPP_BADARG_RET(0==(BN_NUMBER(pPrimeBN)[0] & 1), ippStsBadArgErr); /* prime is even */ + + { + /* init GF */ + IppStatus sts = cpGFpInitGFp(primeBitSize, pGF); + + /* set up GF engine */ + if(ippStsNoErr==sts) { + gsModEngine* pGFE = GFP_PMA(pGF); + cpGFESet(pGFE, BN_NUMBER(pPrimeBN), primeBitSize, ippsGFpMethod_pArb()->arith); + } + + return sts; + } +} + +/*F* +// Name: ippsGFpInit +// +// Purpose: initializes prime finite field GF(p) +// +// Returns: Reason: +// ippStsNullPtrErr NULL == method +// NULL == pGF +// +// ippStsSizeErr !(IPP_MIN_GF_BITSIZE <= primeBitSize <=IPP_MAX_GF_BITSIZE +// +// ippStsContextMatchErr invalid pPrime->idCtx +// +// ippStsBadArgErr method != ippsGFpMethod_pXXX() or != ippsGFpMethod_pArb() +// prime != method->modulus +// prime <0 +// bitsize(prime) != primeBitSize +// prime <IPP_MIN_GF_CHAR +// prime is even +// +// ippStsNoErr no error +// +// Parameters: +// pPrimeBN pointer to the data representation Finite Field element +// primeBitSize length of Finite Field data representation array +// method pointer to Finite Field Element context +// pGF pointer to Finite Field context is being initialized +*F*/ +IPPFUN(IppStatus, ippsGFpInit,(const IppsBigNumState* pPrimeBN, int primeBitSize, const IppsGFpMethod* method, IppsGFpState* pGF)) +{ + IPP_BADARG_RET(!pPrimeBN && !method, ippStsNullPtrErr); + + IPP_BADARG_RET((primeBitSize< IPP_MIN_GF_BITSIZE) || (primeBitSize> IPP_MAX_GF_BITSIZE), ippStsSizeErr); + + /* use ippsGFpInitFixed() if NULL==pPrimeBN */ + if(!pPrimeBN) + return ippsGFpInitFixed(primeBitSize, method, pGF); + + /* use ippsGFpInitArbitrary() if NULL==method */ + if(!method) + return ippsGFpInitArbitrary(pPrimeBN, primeBitSize, pGF); + + /* test parameters if both pPrimeBN and method are defined */ + else { + IppStatus sts; + + /* test input prime */ + pPrimeBN = (IppsBigNumState*)( IPP_ALIGNED_PTR(pPrimeBN, BN_ALIGNMENT) ); + IPP_BADARG_RET(!BN_VALID_ID(pPrimeBN), ippStsContextMatchErr); + IPP_BADARG_RET(BN_SIGN(pPrimeBN)!= IppsBigNumPOS, ippStsBadArgErr); /* prime is negative */ + IPP_BADARG_RET(BITSIZE_BNU(BN_NUMBER(pPrimeBN),BN_SIZE(pPrimeBN)) != primeBitSize, ippStsBadArgErr); /* primeBitSize == bitsize(prime) */ + IPP_BADARG_RET((BN_SIZE(pPrimeBN)==1) && (BN_NUMBER(pPrimeBN)[0]<IPP_MIN_GF_CHAR), ippStsBadArgErr); /* prime < 3 */ + IPP_BADARG_RET(0==(BN_NUMBER(pPrimeBN)[0] & 1), ippStsBadArgErr); /* prime is even */ + + /* test if method is prime based */ + IPP_BADARG_RET(cpID_Prime!=(method->modulusID & cpID_Prime), ippStsBadArgErr); + + /* test if size of the prime is matched to method's prime */ + IPP_BADARG_RET(method->modulusBitDeg && (primeBitSize!=method->modulusBitDeg), ippStsBadArgErr); + + /* if method assumes fixed prime value */ + if(method->modulus) { + int primeLen = BITS_BNU_CHUNK(primeBitSize); + IPP_BADARG_RET(cpCmp_BNU(BN_NUMBER(pPrimeBN), primeLen, method->modulus, primeLen), ippStsBadArgErr); + } + + /* init GF */ + sts = cpGFpInitGFp(primeBitSize, pGF); + + /* set up GF and find quadratic nonresidue */ + if(ippStsNoErr==sts) { + gsModEngine* pGFE = GFP_PMA(pGF); + cpGFESet(pGFE, BN_NUMBER(pPrimeBN), primeBitSize, method->arith); + } + + return sts; + } +} + +IPPFUN(IppStatus, ippsGFpScratchBufferSize,(int nExponents, int ExpBitSize, const IppsGFpState* pGF, int* pBufferSize)) +{ + IPP_BAD_PTR2_RET(pGF, pBufferSize); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + + IPP_BADARG_RET( 0>=nExponents ||nExponents>IPP_MAX_EXPONENT_NUM, ippStsBadArgErr); + IPP_BADARG_RET( 0>=ExpBitSize, ippStsBadArgErr); + + { + int elmDataSize = GFP_FELEN(GFP_PMA(pGF))*sizeof(BNU_CHUNK_T); + + /* get window_size */ + int w = (nExponents==1)? cpGFpGetOptimalWinSize(ExpBitSize) : /* use optimal window size, if single-scalar operation */ + nExponents; /* or pseudo-oprimal if multi-scalar operation */ + + /* number of table entries */ + int nPrecomputed = 1<<w; + + *pBufferSize = elmDataSize*nPrecomputed + (CACHE_LINE_SIZE-1); + + return ippStsNoErr; + } +} + +IPPFUN(IppStatus, ippsGFpElementGetSize,(const IppsGFpState* pGF, int* pElementSize)) +{ + IPP_BAD_PTR2_RET(pElementSize, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + + *pElementSize = sizeof(IppsGFpElement) + +GFP_FELEN(GFP_PMA(pGF))*sizeof(BNU_CHUNK_T); + return ippStsNoErr; +} + + +IPPFUN(IppStatus, ippsGFpElementInit,(const Ipp32u* pA, int nsA, IppsGFpElement* pR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR2_RET(pR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + + IPP_BADARG_RET(0>nsA, ippStsSizeErr); + + { + int elemLen = GFP_FELEN(GFP_PMA(pGF)); + + Ipp8u* ptr = (Ipp8u*)pR; + ptr += sizeof(IppsGFpElement); + cpGFpElementConstruct(pR, (BNU_CHUNK_T*)ptr, elemLen); + return ippsGFpSetElement(pA, nsA, pR, pGF); + } +} + +/*F* +// Name: ippsGFpSetElement +// +// Purpose: Set GF Element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGF +// NULL == pElm +// NULL == pDataA && nsA>0 +// +// ippStsContextMatchErr invalid pGF->idCtx +// invalid pElm->idCtx +// +// ippStsSizeErr pDataA && !(0<=nsA && nsA<GFP_FELEN32()) +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// BNU representation of pDataA[i]..pDataA[i+GFP_FELEN32()-1] >= modulus +// +// ippStsNoErr no error +// +// Parameters: +// pDataA pointer to the data representation Finite Field element +// nsA length of Finite Field data representation array +// pElm pointer to Finite Field Element context +// pGF pointer to Finite Field context +*F*/ +IPPFUN(IppStatus, ippsGFpSetElement,(const Ipp32u* pDataA, int nsA, IppsGFpElement* pElm, IppsGFpState* pGF)) +{ + IPP_BAD_PTR2_RET(pElm, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElm), ippStsContextMatchErr ); + + IPP_BADARG_RET( !pDataA && (0<nsA), ippStsNullPtrErr); + IPP_BADARG_RET( pDataA && !(0<=nsA && nsA<=GFP_FELEN32(GFP_PMA(pGF))), ippStsSizeErr ); + IPP_BADARG_RET( GFPE_ROOM(pElm)!=GFP_FELEN(GFP_PMA(pGF)), ippStsOutOfRangeErr ); + + { + IppStatus sts = ippStsNoErr; + + gsModEngine* pGFE = GFP_PMA(pGF); + int elemLen = GFP_FELEN(pGFE); + BNU_CHUNK_T* pTmp = cpGFpGetPool(1, pGFE); + //gres: temporary excluded: assert(NULL!=pTmp); + + ZEXPAND_BNU(pTmp, 0, elemLen); + if(pDataA && nsA) + cpGFpxCopyToChunk(pTmp, pDataA, nsA, pGFE); + + if(!cpGFpxSet(GFPE_DATA(pElm), pTmp, elemLen, pGFE)) + sts = ippStsOutOfRangeErr; + + cpGFpReleasePool(1, pGFE); + return sts; + } +} + +IPPFUN(IppStatus, ippsGFpSetElementRegular,(const IppsBigNumState* pBN, IppsGFpElement* pElm, IppsGFpState* pGF)) +{ + IPP_BAD_PTR1_RET(pBN); + pBN = (IppsBigNumState*)( IPP_ALIGNED_PTR(pBN, BN_ALIGNMENT) ); + IPP_BADARG_RET( !BN_VALID_ID(pBN), ippStsContextMatchErr ); + IPP_BADARG_RET( !BN_POSITIVE(pBN), ippStsOutOfRangeErr); + + return ippsGFpSetElement((Ipp32u*)BN_NUMBER(pBN), BITS2WORD32_SIZE( BITSIZE_BNU(BN_NUMBER((pBN)),BN_SIZE((pBN)))), pElm, pGF); +} + +/*F* +// Name: ippsGFpSetElementOctString +// +// Purpose: Set GF Element +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGF +// NULL == pElm +// NULL == pStr && strSize>0 +// +// ippStsContextMatchErr invalid pGF->idCtx +// invalid pElm->idCtx +// +// ippStsSizeErr pDataA && !(0<=nsA && nsA<GFP_FELEN32()) +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// BNU representation of pStr[] >= modulus +// +// ippStsNoErr no error +// +// Parameters: +// pDataA pointer to the data representation Finite Field element +// nsA length of Finite Field data representation array +// pElm pointer to Finite Field Element context +// pGF pointer to Finite Field context +*F*/ +IPPFUN(IppStatus, ippsGFpSetElementOctString,(const Ipp8u* pStr, int strSize, IppsGFpElement* pElm, IppsGFpState* pGF)) +{ + IPP_BAD_PTR2_RET(pElm, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElm), ippStsContextMatchErr ); + + IPP_BADARG_RET( (!pStr && 0<strSize), ippStsNullPtrErr); + IPP_BADARG_RET(!(0<strSize && strSize<=(int)(GFP_FELEN32(GFP_PMA(pGF))*sizeof(Ipp32u))), ippStsSizeErr ); + + IPP_BADARG_RET( GFPE_ROOM(pElm)!=GFP_FELEN(GFP_PMA(pGF)), ippStsOutOfRangeErr); + + { + gsModEngine* pGFE = GFP_PMA(pGF); + gsModEngine* pBasicGFE = cpGFpBasic(pGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFE); + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicSize = BITS2WORD8_SIZE(BITSIZE_BNU(GFP_MODULUS(pBasicGFE),GFP_FELEN(pBasicGFE))); + + BNU_CHUNK_T* pDataElm = GFPE_DATA(pElm); + + int deg, error; + /* set element to zero */ + cpGFpElementPadd(pDataElm, GFP_FELEN(pGFE), 0); + + /* convert oct string to element (from low to high) */ + for(deg=0, error=0; deg<basicDeg && !error; deg++) { + int size = IPP_MIN(strSize, basicSize); + error = NULL == cpGFpSetOctString(pDataElm, pStr, size, pBasicGFE); + + pDataElm += basicElemLen; + strSize -= size; + pStr += size; + } + + return error? ippStsOutOfRangeErr : ippStsNoErr; + } +} + + +/*F* +// Name: ippsGFpSetElementRandom +// +// Purpose: Set GF Element Random +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGF +// NULL == pElm +// NULL == rndFunc +// +// ippStsContextMatchErr invalid pGF->idCtx +// invalid pElm->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsErr internal error caused by call of rndFunc() +// +// ippStsNoErr no error +// +// Parameters: +// pDataA pointer to the data representation Finite Field element +// nsA length of Finite Field data representation array +// pElm pointer to Finite Field Element context +// pGF pointer to Finite Field context +*F*/ +IPPFUN(IppStatus, ippsGFpSetElementRandom,(IppsGFpElement* pElm, IppsGFpState* pGF, + IppBitSupplier rndFunc, void* pRndParam)) +{ + IPP_BAD_PTR3_RET(pElm, pGF, rndFunc); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElm), ippStsContextMatchErr ); + + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( GFPE_ROOM(pElm)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + return cpGFpxRand(GFPE_DATA(pElm), pGFE, rndFunc, pRndParam)? ippStsNoErr : ippStsErr; + } +} + +IPPFUN(IppStatus, ippsGFpCpyElement, (const IppsGFpElement* pElmA, IppsGFpElement* pElmR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR3_RET(pElmA, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + cpGFpElementCopy(GFPE_DATA(pElmR), GFPE_DATA(pElmA), GFP_FELEN(pGFE)); + return ippStsNoErr; + } +} + +IPPFUN(IppStatus, ippsGFpGetElement, (const IppsGFpElement* pElm, Ipp32u* pDataA, int nsA, IppsGFpState* pGF)) +{ + IPP_BAD_PTR3_RET(pElm, pDataA, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElm), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( GFPE_ROOM(pElm)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + IPP_BADARG_RET( !(0<nsA && nsA>=GFP_FELEN32(pGFE)), ippStsSizeErr ); + + { + int elemLen = GFP_FELEN(pGFE); + BNU_CHUNK_T* pTmp = cpGFpGetPool(1, pGFE); + //gres: temporary excluded: assert(NULL!=pTmp); + + cpGFpxGet(pTmp, elemLen, GFPE_DATA(pElm), pGFE); + cpGFpxCopyFromChunk(pDataA, pTmp, pGFE); + + cpGFpReleasePool(1, pGFE); + return ippStsNoErr; + } + } +} + +IPPFUN(IppStatus, ippsGFpGetElementOctString,(const IppsGFpElement* pElm, Ipp8u* pStr, int strSize, IppsGFpState* pGF)) +{ + IPP_BAD_PTR3_RET(pStr, pElm, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElm), ippStsContextMatchErr ); + IPP_BADARG_RET( 0>=strSize, ippStsSizeErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( GFPE_ROOM(pElm)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + { + gsModEngine* pBasicGFE = cpGFpBasic(pGFE); + int basicDeg = cpGFpBasicDegreeExtension(pGFE); + int basicElemLen = GFP_FELEN(pBasicGFE); + int basicSize = BITS2WORD8_SIZE(BITSIZE_BNU(GFP_MODULUS(pBasicGFE),GFP_FELEN(pBasicGFE))); + + BNU_CHUNK_T* pDataElm = GFPE_DATA(pElm); + int deg; + for(deg=0; deg<basicDeg; deg++) { + int size = IPP_MIN(strSize, basicSize); + cpGFpGetOctString(pStr, size, pDataElm, pBasicGFE); + + pDataElm += basicElemLen; + pStr += size; + strSize -= size; + } + + return ippStsNoErr; + } + } +} + +IPPFUN(IppStatus, ippsGFpCmpElement,(const IppsGFpElement* pElmA, const IppsGFpElement* pElmB, + int* pResult, + const IppsGFpState* pGF)) +{ + IPP_BAD_PTR4_RET(pElmA, pElmB, pResult, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmB), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmB)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + { + int flag = cpGFpElementCmp(GFPE_DATA(pElmA), GFPE_DATA(pElmB), GFP_FELEN(pGFE)); + if( GFP_IS_BASIC(pGFE) ) + *pResult = (0==flag)? IPP_IS_EQ : (0<flag)? IPP_IS_GT : IPP_IS_LT; + else + *pResult = (0==flag)? IPP_IS_EQ : IPP_IS_NE; + return ippStsNoErr; + } + } +} + +IPPFUN(IppStatus, ippsGFpIsZeroElement,(const IppsGFpElement* pElmA, + int* pResult, + const IppsGFpState* pGF)) +{ + IPP_BAD_PTR3_RET(pElmA, pResult, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + { + int flag = GFP_IS_ZERO(GFPE_DATA(pElmA), GFP_FELEN(pGFE)); + *pResult = (1==flag)? IPP_IS_EQ : IPP_IS_NE; + return ippStsNoErr; + } + } +} + +IPPFUN(IppStatus, ippsGFpIsUnityElement,(const IppsGFpElement* pElmA, + int* pResult, + const IppsGFpState* pGF)) +{ + IPP_BAD_PTR3_RET(pElmA, pResult, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + { + gsModEngine* pBasicGFE = cpGFpBasic(pGFE); + int basicElmLen = GFP_FELEN(pBasicGFE); + BNU_CHUNK_T* pUnity = GFP_MNT_R(pBasicGFE); + + int elmLen = GFP_FELEN(pGFE); + int flag; + + FIX_BNU(pUnity, basicElmLen); + FIX_BNU(GFPE_DATA(pElmA), elmLen); + + flag = (basicElmLen==elmLen) && (0 == cpGFpElementCmp(GFPE_DATA(pElmA), pUnity, elmLen)); + *pResult = (1==flag)? IPP_IS_EQ : IPP_IS_NE; + return ippStsNoErr; + } + } +} + +IPPFUN(IppStatus, ippsGFpConj,(const IppsGFpElement* pElmA, + IppsGFpElement* pElmR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR3_RET(pElmA, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + IPP_BADARG_RET( 2!=GFP_EXTDEGREE(pGFE), ippStsBadArgErr ) + + cpGFpxConj(GFPE_DATA(pElmR), GFPE_DATA(pElmA), pGFE); + return ippStsNoErr; + } +} + +IPPFUN(IppStatus, ippsGFpNeg,(const IppsGFpElement* pElmA, + IppsGFpElement* pElmR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR3_RET(pElmA, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + GFP_METHOD(pGFE)->neg(GFPE_DATA(pElmR), GFPE_DATA(pElmA), pGFE); + return ippStsNoErr; + } +} + + +IPPFUN(IppStatus, ippsGFpInv,(const IppsGFpElement* pElmA, + IppsGFpElement* pElmR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR3_RET(pElmA, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + IPP_BADARG_RET( GFP_IS_ZERO(GFPE_DATA(pElmA),GFP_FELEN(pGFE)), ippStsDivByZeroErr ); + + return NULL != cpGFpxInv(GFPE_DATA(pElmR), GFPE_DATA(pElmA), pGFE)? ippStsNoErr : ippStsBadArgErr; + } +} + + +IPPFUN(IppStatus, ippsGFpSqrt,(const IppsGFpElement* pElmA, + IppsGFpElement* pElmR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR3_RET(pElmA, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr ) + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + return cpGFpSqrt(GFPE_DATA(pElmR), GFPE_DATA(pElmA), pGFE)? ippStsNoErr : ippStsQuadraticNonResidueErr; + } +} + + +IPPFUN(IppStatus, ippsGFpAdd,(const IppsGFpElement* pElmA, const IppsGFpElement* pElmB, + IppsGFpElement* pElmR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR4_RET(pElmA, pElmB, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmB), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmB)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + GFP_METHOD(pGFE)->add(GFPE_DATA(pElmR), GFPE_DATA(pElmA), GFPE_DATA(pElmB), pGFE); + return ippStsNoErr; + } +} + + +IPPFUN(IppStatus, ippsGFpSub,(const IppsGFpElement* pElmA, const IppsGFpElement* pElmB, + IppsGFpElement* pElmR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR4_RET(pElmA, pElmB, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmB), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmB)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + GFP_METHOD(pGFE)->sub(GFPE_DATA(pElmR), GFPE_DATA(pElmA), GFPE_DATA(pElmB), pGFE); + return ippStsNoErr; + } +} + +IPPFUN(IppStatus, ippsGFpMul,(const IppsGFpElement* pElmA, const IppsGFpElement* pElmB, + IppsGFpElement* pElmR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR4_RET(pElmA, pElmB, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmB), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmB)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + GFP_METHOD(pGFE)->mul(GFPE_DATA(pElmR), GFPE_DATA(pElmA), GFPE_DATA(pElmB),pGFE); + return ippStsNoErr; + } +} + +IPPFUN(IppStatus, ippsGFpSqr,(const IppsGFpElement* pElmA, + IppsGFpElement* pElmR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR3_RET(pElmA, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + GFP_METHOD(pGFE)->sqr(GFPE_DATA(pElmR), GFPE_DATA(pElmA), pGFE); + return ippStsNoErr; + } +} + +IPPFUN(IppStatus, ippsGFpAdd_PE,(const IppsGFpElement* pElmA, const IppsGFpElement* pParentElmB, + IppsGFpElement* pElmR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR4_RET(pElmA, pParentElmB, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pParentElmB), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( GFP_IS_BASIC(pGFE), ippStsBadArgErr ) + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + IPP_BADARG_RET( (GFPE_ROOM(pParentElmB)!=GFP_FELEN(GFP_PARENT(pGFE))), ippStsOutOfRangeErr); + + cpGFpxAdd_GFE(GFPE_DATA(pElmR), GFPE_DATA(pElmA), GFPE_DATA(pParentElmB), pGFE); + return ippStsNoErr; + } +} + +IPPFUN(IppStatus, ippsGFpSub_PE,(const IppsGFpElement* pElmA, const IppsGFpElement* pParentElmB, + IppsGFpElement* pElmR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR4_RET(pElmA, pParentElmB, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pParentElmB), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( GFP_IS_BASIC(pGFE), ippStsBadArgErr ) + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + IPP_BADARG_RET( (GFPE_ROOM(pParentElmB)!=GFP_FELEN(GFP_PARENT(pGFE))), ippStsOutOfRangeErr); + + cpGFpxSub_GFE(GFPE_DATA(pElmR), GFPE_DATA(pElmA), GFPE_DATA(pParentElmB), pGFE); + return ippStsNoErr; + } +} + +IPPFUN(IppStatus, ippsGFpMul_PE,(const IppsGFpElement* pElmA, const IppsGFpElement* pParentElmB, + IppsGFpElement* pElmR, IppsGFpState* pGF)) +{ + IPP_BAD_PTR4_RET(pElmA, pParentElmB, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pParentElmB), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( GFP_IS_BASIC(pGFE), ippStsBadArgErr ) + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + IPP_BADARG_RET( (GFPE_ROOM(pParentElmB)!=GFP_FELEN(GFP_PARENT(pGFE))), ippStsOutOfRangeErr); + + cpGFpxMul_GFE(GFPE_DATA(pElmR), GFPE_DATA(pElmA), GFPE_DATA(pParentElmB), pGFE); + return ippStsNoErr; + } +} + +IPPFUN(IppStatus, ippsGFpExp,(const IppsGFpElement* pElmA, const IppsBigNumState* pE, + IppsGFpElement* pElmR, IppsGFpState* pGF, + Ipp8u* pScratchBuffer)) +{ + IPP_BAD_PTR4_RET(pElmA, pE, pElmR, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + + pE = (IppsBigNumState*)( IPP_ALIGNED_PTR(pE, BN_ALIGNMENT) ); + IPP_BADARG_RET( !BN_VALID_ID(pE), ippStsContextMatchErr ); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + + cpGFpxExp(GFPE_DATA(pElmR), GFPE_DATA(pElmA), BN_NUMBER(pE), BN_SIZE(pE), pGFE, pScratchBuffer); + return ippStsNoErr; + } +} + +IPPFUN(IppStatus, ippsGFpMultiExp,(const IppsGFpElement* const ppElmA[], const IppsBigNumState* const ppE[], int nItems, + IppsGFpElement* pElmR, IppsGFpState* pGF, + Ipp8u* pScratchBuffer)) +{ + IPP_BAD_PTR2_RET(ppElmA, ppE); + + if(nItems==1) + return ippsGFpExp(ppElmA[0], ppE[0], pElmR, pGF, pScratchBuffer); + + else { + /* test number of exponents */ + IPP_BADARG_RET(1>nItems || nItems>IPP_MAX_EXPONENT_NUM, ippStsBadArgErr); + + IPP_BAD_PTR2_RET(pElmR, pGF); + + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr ); + IPP_BADARG_RET( !GFPE_TEST_ID(pElmR), ippStsContextMatchErr ); + { + int n; + + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + /* test all ppElmA[] and ppE[] pairs */ + for(n=0; n<nItems; n++) { + const IppsGFpElement* pElmA = ppElmA[n]; + const IppsBigNumState* pE = ppE[n]; + IPP_BAD_PTR2_RET(pElmA, pE); + + IPP_BADARG_RET( !GFPE_TEST_ID(pElmA), ippStsContextMatchErr ); + pE = (IppsBigNumState*)( IPP_ALIGNED_PTR(pE, BN_ALIGNMENT) ); + IPP_BADARG_RET( !BN_VALID_ID(pE), ippStsContextMatchErr ); + + IPP_BADARG_RET( (GFPE_ROOM(pElmA)!=GFP_FELEN(pGFE)) || (GFPE_ROOM(pElmR)!=GFP_FELEN(pGFE)), ippStsOutOfRangeErr); + } + + if(NULL==pScratchBuffer) { + mod_mul mulF = GFP_METHOD(pGFE)->mul; + + BNU_CHUNK_T* pTmpR = cpGFpGetPool(1, pGFE); + //gres: temporary excluded: assert(NULL!=pTmpR); + + cpGFpxExp(GFPE_DATA(pElmR), GFPE_DATA(ppElmA[0]), BN_NUMBER(ppE[0]), BN_SIZE(ppE[0]), pGFE, 0); + for(n=1; n<nItems; n++) { + cpGFpxExp(pTmpR, GFPE_DATA(ppElmA[n]), BN_NUMBER(ppE[n]), BN_SIZE(ppE[n]), pGFE, 0); + mulF(GFPE_DATA(pElmR), GFPE_DATA(pElmR), pTmpR, pGFE); + } + + cpGFpReleasePool(1, pGFE); + } + + else { + const BNU_CHUNK_T* ppAdata[IPP_MAX_EXPONENT_NUM]; + const BNU_CHUNK_T* ppEdata[IPP_MAX_EXPONENT_NUM]; + int nsEdataLen[IPP_MAX_EXPONENT_NUM]; + for(n=0; n<nItems; n++) { + ppAdata[n] = GFPE_DATA(ppElmA[n]); + ppEdata[n] = BN_NUMBER(ppE[n]); + nsEdataLen[n] = BN_SIZE(ppE[n]); + } + cpGFpxMultiExp(GFPE_DATA(pElmR), ppAdata, ppEdata, nsEdataLen, nItems, pGFE, pScratchBuffer); + } + + return ippStsNoErr; + } + } +} + +/*F* +// Name: ippsGFpSetElementHash +// +// Purpose: Set GF Element Hash of the Message +// +// Returns: Reason: +// ippStsNullPtrErr NULL == pGF +// NULL == pElm +// NULL == pMsg if msgLen>0 +// +// ippStsNotSupportedModeErr hashID is not supported +// +// ippStsContextMatchErr invalid pGF->idCtx +// invalid pElm->idCtx +// +// ippStsOutOfRangeErr GFPE_ROOM() != GFP_FELEN() +// +// ippStsNoErr no error +// +// Parameters: +// pMsg pointer to the message is beinh hashed +// msgLen length of the message above +// pElm pointer to Finite Field Element context +// pGF pointer to Finite Field context +// hashID applied hash algothith ID +*F*/ +IPPFUN(IppStatus, ippsGFpSetElementHash,(const Ipp8u* pMsg, int msgLen, IppsGFpElement* pElm, IppsGFpState* pGF, IppHashAlgId hashID)) +{ + /* get algorithm id */ + hashID = cpValidHashAlg(hashID); + IPP_BADARG_RET(ippHashAlg_Unknown==hashID, ippStsNotSupportedModeErr); + + /* test message length and pointer */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + IPP_BAD_PTR2_RET(pElm, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr); + IPP_BADARG_RET( !GFPE_TEST_ID(pElm), ippStsContextMatchErr); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr); + IPP_BADARG_RET( GFPE_ROOM(pElm)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + { + Ipp8u md[MAX_HASH_SIZE]; + BNU_CHUNK_T hashVal[(MAX_HASH_SIZE*8)/BITSIZE(BNU_CHUNK_T)+1]; /* +1 to meet cpMod_BNU() implementtaion specific */ + IppStatus sts = ippsHashMessage(pMsg, msgLen, md, hashID); + + if(ippStsNoErr==sts) { + int elemLen = GFP_FELEN(pGFE); + int hashLen = cpHashAlgAttr[hashID].hashSize; + int hashValLen = cpFromOctStr_BNU(hashVal, md, hashLen); + hashValLen = cpMod_BNU(hashVal, hashValLen, GFP_MODULUS(pGFE), elemLen); + cpGFpSet(GFPE_DATA(pElm), hashVal, hashValLen, pGFE); + } + + return sts; + } + } +} + +IPPFUN(IppStatus, ippsGFpSetElementHash_rmf,(const Ipp8u* pMsg, int msgLen, IppsGFpElement* pElm, IppsGFpState* pGF, const IppsHashMethod* pMethod)) +{ + /* test method pointer */ + IPP_BAD_PTR1_RET(pMethod); + + /* test message length and pointer */ + IPP_BADARG_RET((msgLen<0), ippStsLengthErr); + IPP_BADARG_RET((msgLen && !pMsg), ippStsNullPtrErr); + + IPP_BAD_PTR2_RET(pElm, pGF); + pGF = (IppsGFpState*)( IPP_ALIGNED_PTR(pGF, GFP_ALIGNMENT) ); + IPP_BADARG_RET( !GFP_TEST_ID(pGF), ippStsContextMatchErr); + IPP_BADARG_RET( !GFPE_TEST_ID(pElm), ippStsContextMatchErr); + { + gsModEngine* pGFE = GFP_PMA(pGF); + IPP_BADARG_RET( !GFP_IS_BASIC(pGFE), ippStsBadArgErr); + IPP_BADARG_RET( GFPE_ROOM(pElm)!=GFP_FELEN(pGFE), ippStsOutOfRangeErr); + + { + Ipp8u md[MAX_HASH_SIZE]; + BNU_CHUNK_T hashVal[(MAX_HASH_SIZE*8)/BITSIZE(BNU_CHUNK_T)+1]; /* +1 to meet cpMod_BNU() implementtaion specific */ + IppStatus sts = ippsHashMessage_rmf(pMsg, msgLen, md, pMethod); + + if(ippStsNoErr==sts) { + int elemLen = GFP_FELEN(pGFE); + int hashLen = pMethod->hashLen; + int hashValLen = cpFromOctStr_BNU(hashVal, md, hashLen); + hashValLen = cpMod_BNU(hashVal, hashValLen, GFP_MODULUS(pGFE), elemLen); + cpGFpSet(GFPE_DATA(pElm), hashVal, hashValLen, pGFE); + } + + return sts; + } + } +} |