aboutsummaryrefslogtreecommitdiff
path: root/ext/ipp/sources/ippcp/src/pcpgfp.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ipp/sources/ippcp/src/pcpgfp.c')
-rw-r--r--ext/ipp/sources/ippcp/src/pcpgfp.c1165
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;
+ }
+ }
+}