- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Floating point exception (core dumped) when calling ippsECCPSignDSA.
It may bugs in the function.
Sample code:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "ippcp.h"
#define MAX_RETRY 20
#define RAND_SEED_BYTES 32
#define MAX_RAND_BITS 512
#define BYTES2U32LEN(n) ((n + sizeof(Ipp32u) - 1) / sizeof(Ipp32u))
void data_dump(char *prompt, unsigned char *data, int len)
{
int i;
int prev;
int curr;
fprintf(stderr, "[%s] [length = %d]\n", prompt, len);
prev = curr = 0;
for (i = 0; i < len; i++) {
if (i == (prev + 16)) {
i = prev;
curr = prev + 16;
fprintf(stderr, " | ");
for (; i < curr; i++)
if (isprint(data))
fprintf(stderr, "%c", data);
else
fprintf(stderr, " ");
fprintf(stderr, "\n");
prev = curr;
}
fprintf(stderr, "%02x ", data);
}
if (i != curr) {
curr = i;
for (; i < (prev + 16); i++)
fprintf(stderr, " ");
fprintf(stderr, " | ");
for (i = prev ; i < curr; i++) {
if (isprint(data))
fprintf(stderr, "%c", data);
else
fprintf(stderr, " ");
}
}
fprintf(stderr, "\n");
fflush(stderr);
}
static void RAND_bytes(Ipp8u *randData, int nBytes)
{
int i, round;
int *pRnd = (int *)randData;
round = (nBytes + sizeof(int) - 1) / sizeof(int);
for(i = 0; i < round; i++){
*pRnd = rand();
pRnd++;
}
#ifdef DUMP
data_dump("Random", randData, nBytes);
#endif
return;
}
static IppsPRNGState* newRandCtx()
{
IppsPRNGState *pRndCtx = NULL;
int rndCtxSize, bnCtxSize;
IppStatus ret;
IppsBigNumState* bnTmp;
Ipp8u tmpSeed[RAND_SEED_BYTES] = {0};
ippsPRNGGetSize(&rndCtxSize);
if(rndCtxSize & 0x07)
rndCtxSize = ((rndCtxSize >> 3) + 1) << 3;
pRndCtx = (IppsPRNGState*)malloc(rndCtxSize);
if(!pRndCtx){
return NULL;
}
ret = ippsPRNGInit(MAX_RAND_BITS, pRndCtx);
if(ippStsNoErr != ret){
fprintf(stderr, "ippsPRNGInit fial: %s\n", ippcpGetStatusString(ret));
free(pRndCtx);
pRndCtx = NULL;
return NULL;
}
ippsBigNumGetSize(BYTES2U32LEN(RAND_SEED_BYTES), &bnCtxSize);
bnTmp = (IppsBigNumState*) malloc(bnCtxSize);
if(bnTmp){
RAND_bytes(tmpSeed, RAND_SEED_BYTES);
ippsBigNumInit(BYTES2U32LEN(RAND_SEED_BYTES), bnTmp);
ippsSetOctString_BN(tmpSeed, RAND_SEED_BYTES, bnTmp);
ippsPRNGSetSeed(bnTmp, pRndCtx);
free(bnTmp);
return pRndCtx;
}else{
free(pRndCtx);
return NULL;
}
}
static int genECCKey(IppsBigNumState* priKey, IppsECCPPointState* pubKey, const IppsECCPState* pCtx)
{
IppStatus ret = -1;
IppsPRNGState *pRndCtx;
int i;
pRndCtx = newRandCtx();
if(!pRndCtx)
return -1;
for(i = 0; i < MAX_RETRY; i++){
ret = ippsECCPGenKeyPair(priKey, pubKey, pCtx, ippsPRNGen, pRndCtx);
if(ippStsNoErr == ret)
break;
}
free(pRndCtx);
return ret;
}
int ec_sign_verify_test()
{
int prilen, publen;
int bnSize, bnCtxSize;
int ret = -1, nSize;
IppECResult nResult;
unsigned char digst[32];
IppsBigNumState *pPrivate = NULL, *pDigst = NULL, *pSignR = NULL, *pSignS = NULL;
IppsECCPPointState* pPublic = NULL;
IppsECCPState* pCtx;
//init ECC CTX
ippsECCPGetSizeStd256r1(&nSize);
pCtx = (IppsECCPState*)malloc(nSize);
if(pCtx){
ippsECCPInitStd256r1(pCtx);
ippsECCPSetStd256r1(pCtx);
ippsECCPBindGxyTblStd256r1(pCtx);
}else
goto testEnd;
//generate public & private key
bnSize = BYTES2U32LEN(32);
ippsBigNumGetSize(bnSize, &bnCtxSize);
prilen = bnCtxSize;
ippsECCPPointGetSize(256, &publen);
pPrivate = (IppsBigNumState*)malloc(prilen);
pPublic = (IppsECCPPointState*)malloc(publen);
if(!pPrivate || !pPublic)
goto testEnd;
ippsBigNumInit(bnSize, pPrivate);
ippsECCPPointInit(256, pPublic);
fprintf(stderr, "Calling genECCKey to generate ECC key pair ...\n");
ret = genECCKey(pPrivate, pPublic, pCtx);
if(ippStsNoErr != ret)
goto testEnd;
fprintf(stderr, "Generate ECC key pair suceed !\n");
#ifdef DUMP
data_dump("Private Key", pPrivate, prilen);
data_dump("Public Key", pPublic, publen);
#endif
//get random digest
pDigst = (IppsBigNumState*)malloc(bnCtxSize);
ippsBigNumInit(bnSize, pDigst);
RAND_bytes(digst, 32);
ippsSetOctString_BN(digst, 32, pDigst);
#ifdef DUMP
data_dump("Digest", pDigst, bnCtxSize);
#endif
//do signature
pSignR = (IppsBigNumState*)malloc(bnCtxSize);
pSignS = (IppsBigNumState*)malloc(bnCtxSize);
if(!pSignR || !pSignS)
goto testEnd;
ippsBigNumInit(bnSize, pSignR);
ippsBigNumInit(bnSize, pSignS);
fprintf(stderr, "Calling ippsECCPSignDSA to do signature ...\n");
ret = ippsECCPSignDSA(pDigst, pPrivate, pSignR, pSignS, pCtx);
fprintf(stderr, "ippsECCPSignDSA return: %d, It means: %s\n", ret, ippsECCGetResultString(ret));
if(ret)
goto testEnd;
#ifdef DUMP
data_dump("SignR", pSignR, bnCtxSize);
data_dump("SignS", pSignS, bnCtxSize);
#endif
//do verify
ret = ippsECCPSetKeyPair(NULL, pPublic, ippTrue, pCtx);
fprintf(stderr, "ippsECCPSetKeyPair return: %d, It means: %s\n", ret, ippsECCGetResultString(ret));
if(ret)
goto testEnd;
ret = ippsECCPVerifyDSA(pDigst, pSignR, pSignS, &nResult, pCtx);
fprintf(stderr, "ippsECCPSignDSA return: %d, It means: %s\n", ret, ippsECCGetResultString(ret));
fprintf(stderr, "ippsECCPSignDSA result: %d, It means: %s\n", nResult, ippsECCGetResultString(nResult));
testEnd:
if(pCtx)
free(pCtx);
if(pPrivate)
free(pPrivate);
if(pPublic)
free(pPublic);
if(pDigst)
free(pDigst);
if(pSignR)
free(pSignR);
if(pSignS)
free(pSignS);
return ret;
}
int main()
{
srand(time(NULL));
ec_sign_verify_test();
return 0;
}
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The problem resolved.
before calling ippsECCPSignDSA
it must set an Ephemeral EC key pair to the ECC context.
The keys can be generated and set up by the functions ECCPGenKeyPair and ECCPSetKeyPair with only
requirement that the key regPrivKey be different from the key ephPrivKey.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks for sharing this. kinrong.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
hi kinrong,
the right sequence of calls is described in the manual, the corrected code (that works fine) is below.
Calling genECCKey to generate ECC key pair ...
Generate ECC key pair suceed !
Calling ippsECCPSignDSA to do signature ...
ippsECCPSignDSA return: 0, It means: Validation pass successfully
ippsECCPSetKeyPair return: 0, It means: Validation pass successfully
ippsECCPSignDSA return: 0, It means: Validation pass successfully
ippsECCPSignDSA result: 0, It means: Validation pass successfully
Press any key to continue . . .
The root of the problem – incorrect sequence of IPP calls
regards, Igor
#include <stdlib.h> #include <stdio.h> #include <ctype.h> #include <time.h> #include "ippcp.h" #define MAX_RETRY 20 #define RAND_SEED_BYTES 32 #define MAX_RAND_BITS 512 #define BYTES2U32LEN(n) ((n + sizeof(Ipp32u) - 1) / sizeof(Ipp32u)) void data_dump(char *prompt, unsigned char *data, int len) { int i; int prev; int curr; fprintf(stderr, "[%s] [length = %d]\n", prompt, len); prev = curr = 0; for (i = 0; i < len; i++) { if (i == (prev + 16)) { i = prev; curr = prev + 16; fprintf(stderr, " | "); for (; i < curr; i++) if (isprint(data)) fprintf(stderr, "%c", data); else fprintf(stderr, " "); fprintf(stderr, "\n"); prev = curr; } fprintf(stderr, "%02x ", data); } if (i != curr) { curr = i; for (; i < (prev + 16); i++) fprintf(stderr, " "); fprintf(stderr, " | "); for (i = prev ; i < curr; i++) { if (isprint(data)) fprintf(stderr, "%c", data); else fprintf(stderr, " "); } } fprintf(stderr, "\n"); fflush(stderr); } static void RAND_bytes(Ipp8u *randData, int nBytes) { int i, round; int *pRnd = (int *)randData; round = (nBytes + sizeof(int) - 1) / sizeof(int); for(i = 0; i < round; i++){ *pRnd = rand(); pRnd++; } #ifdef DUMP data_dump("Random", randData, nBytes); #endif return; } static IppsPRNGState* newRandCtx() { IppsPRNGState *pRndCtx = NULL; int rndCtxSize, bnCtxSize; IppStatus ret; IppsBigNumState* bnTmp; Ipp8u tmpSeed[RAND_SEED_BYTES] = {0}; ippsPRNGGetSize(&rndCtxSize); if(rndCtxSize & 0x07) rndCtxSize = ((rndCtxSize >> 3) + 1) << 3; pRndCtx = (IppsPRNGState*)malloc(rndCtxSize); if(!pRndCtx){ return NULL; } ret = ippsPRNGInit(MAX_RAND_BITS, pRndCtx); if(ippStsNoErr != ret){ fprintf(stderr, "ippsPRNGInit fial: %s\n", ippcpGetStatusString(ret)); free(pRndCtx); pRndCtx = NULL; return NULL; } ippsBigNumGetSize(BYTES2U32LEN(RAND_SEED_BYTES), &bnCtxSize); bnTmp = (IppsBigNumState*) malloc(bnCtxSize); if(bnTmp){ RAND_bytes(tmpSeed, RAND_SEED_BYTES); ippsBigNumInit(BYTES2U32LEN(RAND_SEED_BYTES), bnTmp); ippsSetOctString_BN(tmpSeed, RAND_SEED_BYTES, bnTmp); ippsPRNGSetSeed(bnTmp, pRndCtx); free(bnTmp); return pRndCtx; }else{ free(pRndCtx); return NULL; } } static int genECCKey(IppsBigNumState* priKey, IppsECCPPointState* pubKey, const IppsECCPState* pCtx) { IppStatus ret = -1; IppsPRNGState *pRndCtx; int i; pRndCtx = newRandCtx(); if(!pRndCtx) return -1; for(i = 0; i < MAX_RETRY; i++){ ret = ippsECCPGenKeyPair(priKey, pubKey, pCtx, ippsPRNGen, pRndCtx); if(ippStsNoErr == ret) break; } free(pRndCtx); return ret; } int ec_sign_verify_test() { int prilen, publen; int bnSize, bnCtxSize; int ret = -1, nSize; IppECResult nResult; unsigned char digst[32]; IppsBigNumState *pPrivate = NULL, *pDigst = NULL, *pSignR = NULL, *pSignS = NULL; IppsECCPPointState* pPublic = NULL; IppsECCPState* pCtx; /* gres */IppsBigNumState *pPrivateE = NULL; /* gres */IppsECCPPointState* pPublicE = NULL; //init ECC CTX ippsECCPGetSizeStd256r1(&nSize); pCtx = (IppsECCPState*)malloc(nSize); if(pCtx){ ippsECCPInitStd256r1(pCtx); ippsECCPSetStd256r1(pCtx); ippsECCPBindGxyTblStd256r1(pCtx); }else goto testEnd; //generate public & private key bnSize = BYTES2U32LEN(32); ippsBigNumGetSize(bnSize, &bnCtxSize); prilen = bnCtxSize; ippsECCPPointGetSize(256, &publen); pPrivate = (IppsBigNumState*)malloc(prilen); pPublic = (IppsECCPPointState*)malloc(publen); /* gres */ pPrivateE = (IppsBigNumState*)malloc(prilen); /* gres */ pPublicE = (IppsECCPPointState*)malloc(publen); if(!pPrivate || !pPublic /* gres */ || !pPrivateE || !pPublicE) goto testEnd; ippsBigNumInit(bnSize, pPrivate); ippsECCPPointInit(256, pPublic); ippsBigNumInit(bnSize, pPrivateE); ippsECCPPointInit(256, pPublicE); fprintf(stderr, "Calling genECCKey to generate ECC key pair ...\n"); ret = genECCKey(pPrivate, pPublic, pCtx); /* gres: ephemeral keys */ genECCKey(pPrivateE, pPublicE, pCtx); if(ippStsNoErr != ret) goto testEnd; fprintf(stderr, "Generate ECC key pair suceed !\n"); #ifdef DUMP data_dump("Private Key", pPrivate, prilen); data_dump("Public Key", pPublic, publen); #endif //get random digest pDigst = (IppsBigNumState*)malloc(bnCtxSize); ippsBigNumInit(bnSize, pDigst); RAND_bytes(digst, 32); ippsSetOctString_BN(digst, 32, pDigst); #ifdef DUMP data_dump("Digest", pDigst, bnCtxSize); #endif //do signature pSignR = (IppsBigNumState*)malloc(bnCtxSize); pSignS = (IppsBigNumState*)malloc(bnCtxSize); if(!pSignR || !pSignS) goto testEnd; ippsBigNumInit(bnSize, pSignR); ippsBigNumInit(bnSize, pSignS); fprintf(stderr, "Calling ippsECCPSignDSA to do signature ...\n"); /* gres set ephemeral keys: */ ippsECCPSetKeyPair(pPrivateE, pPublicE, ippFalse, pCtx); ret = ippsECCPSignDSA(pDigst, pPrivate, pSignR, pSignS, pCtx); fprintf(stderr, "ippsECCPSignDSA return: %d, It means: %s\n", ret, ippsECCGetResultString(ret)); if(ret) goto testEnd; #ifdef DUMP data_dump("SignR", pSignR, bnCtxSize); data_dump("SignS", pSignS, bnCtxSize); #endif //do verify ret = ippsECCPSetKeyPair(NULL, pPublic, ippTrue, pCtx); fprintf(stderr, "ippsECCPSetKeyPair return: %d, It means: %s\n", ret, ippsECCGetResultString(ret)); if(ret) goto testEnd; ret = ippsECCPVerifyDSA(pDigst, pSignR, pSignS, &nResult, pCtx); fprintf(stderr, "ippsECCPSignDSA return: %d, It means: %s\n", ret, ippsECCGetResultString(ret)); fprintf(stderr, "ippsECCPSignDSA result: %d, It means: %s\n", nResult, ippsECCGetResultString(nResult)); testEnd: if(pCtx) free(pCtx); if(pPrivate) free(pPrivate); if(pPublic) free(pPublic); if(pPrivateE) /* gres */ free(pPrivateE); if(pPublicE) /* gres */ free(pPublicE); if(pDigst) free(pDigst); if(pSignR) free(pSignR); if(pSignS) free(pSignS); return ret; } int main() { srand(time(NULL)); ec_sign_verify_test(); return 0; }
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
thanks for you,this is important to me

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page