Developer Reference for Intel® Integrated Performance Primitives Cryptography

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