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;
}