Visible to Intel only — GUID: GUID-F081E06F-16F5-4EC2-9DC8-FBB5ED313165
Introducing Intel® Cryptography Primitives Library
Getting Help and Support
Notational Conventions
Getting Started with Intel® Cryptography Primitives Library
Theory of Operation
Linking Your Application with Intel® Cryptography Primitives Library
Using Custom Library Tool for Intel® Cryptography Primitives Library
Programming with Intel® Cryptography Primitives Library in the Microsoft* Visual Studio* IDE
Performance Test Tool (perfsys) Command Line Options
Preview Features
Intel® Cryptography Primitives Library API Reference
Notices and Disclaimers
Related Products
Overview
Symmetric Cryptography Primitive Functions
One-Way Hash Primitives
Data Authentication Primitive Functions
Public Key Cryptography Functions
Finite Field Arithmetic
Mitigation for Frequency Throttling Side-Channel Attack
Multi-buffer Cryptography Functions
Support Functions and Classes
Deprecated Functions
Bibliography
AESGetSize
AESInit
AESSetKey
AESPack, AESUnpack
AESEncryptECB
AESDecryptECB
AESEncryptCBC
AESDecryptCBC
AESEncryptCBC_CS
AESDecryptCBC_CS
AESEncryptCFB
AES_EncryptCFB16_MB
AESDecryptCFB
AESEncryptOFB
AESDecryptOFB
AESEncryptCTR
AESDecryptCTR
AESEncryptXTS_Direct, AESDecryptXTS_Direct
Example of Using AES Functions
RSA_GetSizePublicKey, RSA_GetSizePrivateKeyType1, RSA_GetSizePrivateKeyType2
RSA_InitPublicKey, RSA_InitPrivateKeyType1, RSA_InitPrivateKeyType2
RSA_SetPublicKey, RSA_SetPrivateKeyType1, RSA_SetPrivateKeyType2
RSA_GetPublicKey, RSA_GetPrivateKeyType1, RSA_GetPrivateKeyType2
RSA_GetBufferSizePublicKey, RSA_GetBufferSizePrivateKey
RSA_MB_GetBufferSizePublicKey, RSA_MB_GetBufferSizePrivateKey
RSA_GenerateKeys
RSA_ValidateKeys
DLPGetSize
DLPInit
DLPPack, DLPUnpack
DLPSet
DLPGet
DLPSetDP
DLPGetDP
DLPGenKeyPair
DLPPublicKey
DLPValidateKeyPair
DLPSetKeyPair
DLPGenerateDSA
DLPValidateDSA
DLPSignDSA
DLPVerifyDSA
Example of Using Discrete-logarithm Based Primitive Functions
DLPGenerateDH
DLPValidateDH
DLPSharedSecretDH
DLGetResultString
GFpECESGetSize_SM2
GFpECESInit_SM2
GFpECESSetKey_SM2
GFpECESStart_SM2
GFpECESEncrypt_SM2
GFpECESDecrypt_SM2
GFpECESFinal_SM2
GFpECESGetBufferSize_SM2
GFpECEncryptSM2_Ext_EncMsgSize
GFpECDecryptSM2_Ext_DecMsgSize
GFpECEncryptSM2_Ext
GFpECDecryptSM2_Ext
GFpECMessageRepresentationSM2
GFpECUserIDHashSM2
GFpECKeyExchangeSM2_GetSize
GFpECKeyExchangeSM2_Init
GFpECKeyExchangeSM2_Setup
GFpECKeyExchangeSM2_SharedKey
GFpECKeyExchangeSM2_Confirm
GFpECGetSize
GFpECInit
GFpECSet
GFpECSetSubgroup
GFpECInitStd
GFpECGet
GFpECGetSubgroup
GFpECScratchBufferSize
GFpECVerify
GFpECPointGetSize
GFpECPointInit
GFpECSetPointAtInfinity
GFpECSetPoint, GFpECSetPointREgular
GFpECSetPointOctString
GFpECSetPointRandom
GFpECMakePoint
GFpECSetPointHash, GFpECSetPointHashBackCompatible, GFpECSetPointHash_rmf, GFpECSetPointHashBackCompatible_rmf
GFpECGetPoint , GFpECGetPointRegular
GFpECGetPointOctString
GFpECTstPoint
GFpECTstPointInSubgroup
GFpECCpyPoint
GFpECCmpPoint
GFpECNegPoint
GFpECAddPoint
GFpECMulPoint
GFpECPrivateKey, GFpECPublicKey, GFpECTstKeyPair
GFpECPublicKey
GFpECTstKeyPair
GFpECPSharedSecretDH, GFpECPSharedSecretDHC
GFpECSharedSecretDHC
GFpECPSignDSA, GFpECPSignNR, GFpECPSignSM2
GFpECPVerifyDSA, GFpECPVerifyNR, GFpECPVerifySM2
GFpECSignNR
GFpECVerifyNR
GFpECSignSM2
GFpECVerifySM2
GFpInit
GFpMethod
GFpGetSize
GFpxInitBinomial
GFpxInit
GFpxMethod
GFpxGetSize
GFpScratchBufferSize
GFpElementGetSize
GFpElementInit
GFpSetElement
GFpSetElementOctString
GFpSetElementRandom
GFpSetElementHash
GFpCpyElement
GFpGetElement
GFpGetElementOctString
GFpCmpElement
GFpIsZeroElement
GFpIsUnityElement
GFpConj
GFpNeg
GFpInv
GFpSqrt
GFpAdd
GFpSub
GFpMul
GFpSqr
GFpExp
GFpMultiExp
GFpAdd_PE
GFpSub_PE
GFpMul_PE
RSA Algorithm Functions (MBX)
NIST Recommended Elliptic Curve Functions
Montgomery Curve25519 Elliptic Curve Functions
Edwards Curve25519 Elliptic Curve Functions
SM2 Elliptic Curve Functions
SM3 Hash Functions
SM4 Algorithm Functions
SM4 XTS Algorithm Functions
SM4 CCM Algorithm Functions
SM4 GCM Algorithm Functions
Modular Exponentiation
Visible to Intel only — GUID: GUID-F081E06F-16F5-4EC2-9DC8-FBB5ED313165
BigNumber Class
The section presents source code of the BigNumber class.
Declarations
Contents of the header file (xsample_bignum.h) declaring the BigNumber class are presented below:
#if !defined _BIGNUMBER_H_
#define _BIGNUMBER_H_
#include "ippcp.h"
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
class BigNumber
{
public:
BigNumber(Ipp32u value=0);
BigNumber(Ipp32s value);
BigNumber(const IppsBigNumState* pBN);
BigNumber(const Ipp32u* pData, int length=1, IppsBigNumSGN sgn=IppsBigNumPOS);
BigNumber(const BigNumber& bn);
BigNumber(const char *s);
virtual ~BigNumber();
// set value
void Set(const Ipp32u* pData, int length=1, IppsBigNumSGN sgn=IppsBigNumPOS);
// conversion to IppsBigNumState
friend IppsBigNumState* BN(const BigNumber& bn) {return bn.m_pBN;}
operator IppsBigNumState* () const { return m_pBN; }
// some useful constants
static const BigNumber& Zero();
static const BigNumber& One();
static const BigNumber& Two();
// arithmetic operators probably need
BigNumber& operator = (const BigNumber& bn);
BigNumber& operator += (const BigNumber& bn);
BigNumber& operator -= (const BigNumber& bn);
BigNumber& operator *= (Ipp32u n);
BigNumber& operator *= (const BigNumber& bn);
BigNumber& operator /= (const BigNumber& bn);
BigNumber& operator %= (const BigNumber& bn);
friend BigNumber operator + (const BigNumber& a, const BigNumber& b);
friend BigNumber operator - (const BigNumber& a, const BigNumber& b);
friend BigNumber operator * (const BigNumber& a, const BigNumber& b);
friend BigNumber operator * (const BigNumber& a, Ipp32u);
friend BigNumber operator % (const BigNumber& a, const BigNumber& b);
friend BigNumber operator / (const BigNumber& a, const BigNumber& b);
// modulo arithmetic
BigNumber Modulo(const BigNumber& a) const;
BigNumber ModAdd(const BigNumber& a, const BigNumber& b) const;
BigNumber ModSub(const BigNumber& a, const BigNumber& b) const;
BigNumber ModMul(const BigNumber& a, const BigNumber& b) const;
BigNumber InverseAdd(const BigNumber& a) const;
BigNumber InverseMul(const BigNumber& a) const;
// comparisons
friend bool operator < (const BigNumber& a, const BigNumber& b);
friend bool operator > (const BigNumber& a, const BigNumber& b);
friend bool operator == (const BigNumber& a, const BigNumber& b);
friend bool operator != (const BigNumber& a, const BigNumber& b);
friend bool operator <= (const BigNumber& a, const BigNumber& b) {return !(a>b);}
friend bool operator >= (const BigNumber& a, const BigNumber& b) {return !(a<b);}
// easy tests
bool IsOdd() const;
bool IsEven() const { return !IsOdd(); }
// size of BigNumber
int MSB() const;
int LSB() const;
int BitSize() const { return MSB()+1; }
int DwordSize() const { return (BitSize()+31)>>5;}
friend int Bit(const vector<Ipp32u>& v, int n);
// conversion and output
void num2hex( string& s ) const; // convert to hex string
void num2vec( vector<Ipp32u>& v ) const; // convert to 32-bit word vector
friend ostream& operator << (ostream& os, const BigNumber& a);
protected:
bool create(const Ipp32u* pData, int length, IppsBigNumSGN sgn=IppsBigNumPOS);
int compare(const BigNumber& ) const;
IppsBigNumState* m_pBN;
};
// convert bit size into 32-bit words
#define BITSIZE_WORD(n) ((((n)+31)>>5))
#endif // _BIGNUMBER_H_
Definitions
C++ definitions for the BigNumber class methods are given below. For the declarations to be included, see the preceding Declarations section.
#include "xsample_bignum.h"
//////////////////////////////////////////////////////////////////////
//
// BigNumber
//
//////////////////////////////////////////////////////////////////////
BigNumber::~BigNumber()
{
delete [] (Ipp8u*)m_pBN;
}
bool BigNumber::create(const Ipp32u* pData, int length, IppsBigNumSGN sgn)
{
int size;
ippsBigNumGetSize(length, &size);
m_pBN = (IppsBigNumState*)( new Ipp8u[size] );
if(!m_pBN)
return false;
ippsBigNumInit(length, m_pBN);
if(pData)
ippsSet_BN(sgn, length, pData, m_pBN);
return true;
}
// constructors
//
BigNumber::BigNumber(Ipp32u value)
{
create(&value, 1, IppsBigNumPOS);
}
BigNumber::BigNumber(Ipp32s value)
{
Ipp32s avalue = abs(value);
create((Ipp32u*)&avalue, 1, (value<0)? IppsBigNumNEG : IppsBigNumPOS);
}
BigNumber::BigNumber(const IppsBigNumState* pBN)
{
IppsBigNumSGN bnSgn;
int bnBitLen;
Ipp32u* bnData;
ippsRef_BN(&bnSgn, &bnBitLen, &bnData, pBN);
create(bnData, BITSIZE_WORD(bnBitLen), bnSgn);
}
BigNumber::BigNumber(const Ipp32u* pData, int length, IppsBigNumSGN sgn)
{
create(pData, length, sgn);
}
static char HexDigitList[] = "0123456789ABCDEF";
BigNumber::BigNumber(const char* s)
{
bool neg = '-' == s[0];
if(neg) s++;
bool hex = ('0'==s[0]) && (('x'==s[1]) || ('X'==s[1]));
int dataLen;
Ipp32u base;
if(hex) {
s += 2;
base = 0x10;
dataLen = (int)(strlen(s) + 7)/8;
}
else {
base = 10;
dataLen = (int)(strlen(s) + 9)/10;
}
create(0, dataLen);
*(this) = Zero();
while(*s) {
char tmp[2] = {s[0],0};
Ipp32u digit = (Ipp32u)strcspn(HexDigitList, tmp);
*this = (*this) * base + BigNumber( digit );
s++;
}
if(neg)
(*this) = Zero()- (*this);
}
BigNumber::BigNumber(const BigNumber& bn)
{
IppsBigNumSGN bnSgn;
int bnBitLen;
Ipp32u* bnData;
ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn);
create(bnData, BITSIZE_WORD(bnBitLen), bnSgn);
}
// set value
//
void BigNumber::Set(const Ipp32u* pData, int length, IppsBigNumSGN sgn)
{
ippsSet_BN(sgn, length, pData, BN(*this));
}
// constants
//
const BigNumber& BigNumber::Zero()
{
static const BigNumber zero(0);
return zero;
}
const BigNumber& BigNumber::One()
{
static const BigNumber one(1);
return one;
}
const BigNumber& BigNumber::Two()
{
static const BigNumber two(2);
return two;
}
// arithmetic operators
//
BigNumber& BigNumber::operator =(const BigNumber& bn)
{
if(this != &bn) { // prevent self copy
IppsBigNumSGN bnSgn;
int bnBitLen;
Ipp32u* bnData;
ippsRef_BN(&bnSgn, &bnBitLen, &bnData, bn);
delete (Ipp8u*)m_pBN;
create(bnData, BITSIZE_WORD(bnBitLen), bnSgn);
}
return *this;
}
BigNumber& BigNumber::operator += (const BigNumber& bn)
{
int aBitLen;
ippsRef_BN(NULL, &aBitLen, NULL, *this);
int bBitLen;
ippsRef_BN(NULL, &bBitLen, NULL, bn);
int rBitLen = IPP_MAX(aBitLen, bBitLen) + 1;
BigNumber result(0, BITSIZE_WORD(rBitLen));
ippsAdd_BN(*this, bn, result);
*this = result;
return *this;
}
BigNumber& BigNumber::operator -= (const BigNumber& bn)
{
int aBitLen;
ippsRef_BN(NULL, &aBitLen, NULL, *this);
int bBitLen;
ippsRef_BN(NULL, &bBitLen, NULL, bn);
int rBitLen = IPP_MAX(aBitLen, bBitLen);
BigNumber result(0, BITSIZE_WORD(rBitLen));
ippsSub_BN(*this, bn, result);
*this = result;
return *this;
}
BigNumber& BigNumber::operator *= (const BigNumber& bn)
{
int aBitLen;
ippsRef_BN(NULL, &aBitLen, NULL, *this);
int bBitLen;
ippsRef_BN(NULL, &bBitLen, NULL, bn);
int rBitLen = aBitLen + bBitLen;
BigNumber result(0, BITSIZE_WORD(rBitLen));
ippsMul_BN(*this, bn, result);
*this = result;
return *this;
}
BigNumber& BigNumber::operator *= (Ipp32u n)
{
int aBitLen;
ippsRef_BN(NULL, &aBitLen, NULL, *this);
BigNumber result(0, BITSIZE_WORD(aBitLen+32));
BigNumber bn(n);
ippsMul_BN(*this, bn, result);
*this = result;
return *this;
}
BigNumber& BigNumber::operator %= (const BigNumber& bn)
{
BigNumber remainder(bn);
ippsMod_BN(BN(*this), BN(bn), BN(remainder));
*this = remainder;
return *this;
}
BigNumber& BigNumber::operator /= (const BigNumber& bn)
{
BigNumber quotient(*this);
BigNumber remainder(bn);
ippsDiv_BN(BN(*this), BN(bn), BN(quotient), BN(remainder));
*this = quotient;
return *this;
}
BigNumber operator + (const BigNumber& a, const BigNumber& b )
{
BigNumber r(a);
return r += b;
}
BigNumber operator - (const BigNumber& a, const BigNumber& b )
{
BigNumber r(a);
return r -= b;
}
BigNumber operator * (const BigNumber& a, const BigNumber& b )
{
BigNumber r(a);
return r *= b;
}
BigNumber operator * (const BigNumber& a, Ipp32u n)
{
BigNumber r(a);
return r *= n;
}
BigNumber operator / (const BigNumber& a, const BigNumber& b )
{
BigNumber q(a);
return q /= b;
}
BigNumber operator % (const BigNumber& a, const BigNumber& b )
{
BigNumber r(b);
ippsMod_BN(BN(a), BN(b), BN(r));
return r;
}
// modulo arithmetic
//
BigNumber BigNumber::Modulo(const BigNumber& a) const
{
return a % *this;
}
BigNumber BigNumber::InverseAdd(const BigNumber& a) const
{
BigNumber t = Modulo(a);
if(t==BigNumber::Zero())
return t;
else
return *this - t;
}
BigNumber BigNumber::InverseMul(const BigNumber& a) const
{
BigNumber r(*this);
ippsModInv_BN(BN(a), BN(*this), BN(r));
return r;
}
BigNumber BigNumber::ModAdd(const BigNumber& a, const BigNumber& b) const
{
BigNumber r = this->Modulo(a+b);
return r;
}
BigNumber BigNumber::ModSub(const BigNumber& a, const BigNumber& b) const
{
BigNumber r = this->Modulo(a + this->InverseAdd(b));
return r;
}
BigNumber BigNumber::ModMul(const BigNumber& a, const BigNumber& b) const
{
BigNumber r = this->Modulo(a*b);
return r;
}
// comparison
//
int BigNumber::compare(const BigNumber &bn) const
{
Ipp32u result;
BigNumber tmp = *this - bn;
ippsCmpZero_BN(BN(tmp), &result);
return (result==IS_ZERO)? 0 : (result==GREATER_THAN_ZERO)? 1 : -1;
}
bool operator < (const BigNumber &a, const BigNumber &b) { return a.compare(b) < 0; }
bool operator > (const BigNumber &a, const BigNumber &b) { return a.compare(b) > 0; }
bool operator == (const BigNumber &a, const BigNumber &b) { return 0 == a.compare(b);}
bool operator != (const BigNumber &a, const BigNumber &b) { return 0 != a.compare(b);}
// easy tests
//
bool BigNumber::IsOdd() const
{
Ipp32u* bnData;
ippsRef_BN(NULL, NULL, &bnData, *this);
return bnData[0]&1;
}
// size of BigNumber
//
int BigNumber::LSB() const
{
if( *this == BigNumber::Zero() )
return 0;
vector<Ipp32u> v;
num2vec(v);
int lsb = 0;
vector<Ipp32u>::iterator i;
for(i=v.begin(); i!=v.end(); i++) {
Ipp32u x = *i;
if(0==x)
lsb += 32;
else {
while(0==(x&1)) {
lsb++;
x >>= 1;
}
break;
}
}
return lsb;
}
int BigNumber::MSB() const
{
if( *this == BigNumber::Zero() )
return 0;
vector<Ipp32u> v;
num2vec(v);
int msb = (int)v.size()*32 -1;
vector<Ipp32u>::reverse_iterator i;
for(i=v.rbegin(); i!=v.rend(); i++) {
Ipp32u x = *i;
if(0==x)
msb -=32;
else {
while(!(x&0x80000000)) {
msb--;
x <<= 1;
}
break;
}
}
return msb;
}
int Bit(const vector<Ipp32u>& v, int n)
{
return 0 != ( v[n>>5] & (1<<(n&0x1F)) );
}
// conversions and output
//
void BigNumber::num2vec( vector<Ipp32u>& v ) const
{
int bnBitLen;
Ipp32u* bnData;
ippsRef_BN(NULL, &bnBitLen, &bnData, *this);
int len = BITSIZE_WORD(bnBitLen);;
for(int n=0; n<len; n++)
v.push_back( bnData[n] );
}
void BigNumber::num2hex( string& s ) const
{
IppsBigNumSGN bnSgn;
int bnBitLen;
Ipp32u* bnData;
ippsRef_BN(&bnSgn, &bnBitLen, &bnData, *this);
int len = BITSIZE_WORD(bnBitLen);
s.append(1, (bnSgn==ippBigNumNEG)? '-' : ' ');
s.append(1, '0');
s.append(1, 'x');
for(int n=len; n>0; n--) {
Ipp32u x = bnData[n-1];
for(int nd=8; nd>0; nd--) {
char c = HexDigitList[(x>>(nd-1)*4)&0xF];
s.append(1, c);
}
}
}
ostream& operator << ( ostream &os, const BigNumber& a)
{
string s;
a.num2hex(s);
os << s.c_str();
return os;
}