Signing/Verification Using the Elliptic Curve Cryptography Functions over a Prime Finite Field¶
Use of ECCPSignDSA, ECCPVerifyDSA
#include <iostream>
#include <vector>
#include <string>
using namespace std;
#include "ippcp.h"
static IppsECCPState* newStd_256_ECP(void)
{
int ctxSize;
ippsECCPGetSize(256, &ctxSize);
IppsECCPState* pCtx = (IppsECCPState*)( new Ipp8u [ctxSize] );
ippsECCPInit(256, pCtx);
ippsECCPSetStd(IppECCPStd256r1, pCtx);
return pCtx;
}
static IppsECCPPointState* newECP_256_Point(void)
{
int ctxSize;
ippsECCPPointGetSize(256, &ctxSize);
IppsECCPPointState* pPoint = (IppsECCPPointState*)( new Ipp8u [ctxSize] );
ippsECCPPointInit(256, pPoint);
return pPoint;
}
static IppsBigNumState* newBN(int len, const Ipp32u* pData)
{
int ctxSize;
ippsBigNumGetSize(len, &ctxSize);
IppsBigNumState* pBN = (IppsBigNumState*)( new Ipp8u [ctxSize] );
ippsBigNumInit(len, pBN);
if(pData)
ippsSet_BN(IppsBigNumPOS, len, pData, pBN);
return pBN;
}
IppsPRNGState* newPRNG(void)
{
int ctxSize;
ippsPRNGGetSize(&ctxSize);
IppsPRNGState* pCtx = (IppsPRNGState*)( new Ipp8u [ctxSize] );
ippsPRNGInit(160, pCtx);
return pCtx;
}
int main(void)
{
// define standard 256-bit EC
IppsECCPState* pECP = newStd_256_ECP();
// extract or use any other way to get order(ECP)
const Ipp32u secp256r1_r[] = {0xFC632551, 0xF3B9CAC2, 0xA7179E84, 0xBCE6FAAD
0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0xFFFFFFFF};
const int ordSize = sizeof(secp256r1_r)/sizeof(Ipp32u);
IppsBigNumState* pECPorder = newBN(ordSize, secp256r1_r);
// define a message to be signed; let it be random, for example
IppsPRNGState* pRandGen = newPRNG(); // 'external' PRNG
Ipp32u tmpData[ordSize];
ippsPRNGen(tmpData, 256, pRandGen);
IppsBigNumState* pRandMsg = newBN(ordSize, tmpData); // random 256-bit message
IppsBigNumState* pMsg = newBN(ordSize, 0); // msg to be signed
ippsMod_BN(pRandMsg, pECPorder, pMsg);
// declare Signer's regular and ephemeral key pair
IppsBigNumState* regPrivate = newBN(ordSize, 0);
IppsBigNumState* ephPrivate = newBN(ordSize, 0);
// define Signer's ephemeral key pair
IppsECCPPointState* regPublic = newECP_256_Point();
IppsECCPPointState* ephPublic = newECP_256_Point();
// generate regular & ephemeral key pairs, should be different each other
ippsECCPGenKeyPair(regPrivate, regPublic, pECP, ippsPRNGen, pRandGen);
ippsECCPGenKeyPair(ephPrivate, ephPublic, pECP, ippsPRNGen, pRandGen);
//
// signature
//
// set ephemeral key pair
ippsECCPSetKeyPair(ephPrivate, ephPublic, ippFalse, pECP);
// compure signature
IppsBigNumState* signX = newBN(ordSize, 0);
IppsBigNumState* signY = newBN(ordSize, 0);
ippsECCPSignDSA(pMsg, regPrivate, signX, signY, pECP);
//
// verification
//
ippsECCPSetKeyPair(NULL, regPublic, ippTrue, pECP);
IppECResult eccResult;
ippsECCPVerifyDSA(pMsg, signX,signY, &eccResult, pECP);
if(ippECValid == eccResult)
cout << "signature verificatioin passed" <<endl;
else
cout << "signature verificatioin failed" <<endl;
delete [] (Ipp8u*)signX;
delete [] (Ipp8u*)signY;
delete [] (Ipp8u*)ephPublic;
delete [] (Ipp8u*)regPublic;
delete [] (Ipp8u*)ephPrivate;
delete [] (Ipp8u*)regPrivate;
delete [] (Ipp8u*)pRandMsg;
delete [] (Ipp8u*)pMsg;
delete [] (Ipp8u*)pRandGen;
delete [] (Ipp8u*)pECPorder;
delete [] (Ipp8u*)pECP;
return 0;
}