Part I. 开发指南

内容参考官方文档

《Intel® Integrated Performance Primitives Cryptography Developer Guide, Intel Integrated Performance Primitives 2018》

1. Getting Started

路径说明

  1. 默认的Intel IPP密码库安装路径<install_dir>为C:/Program files (x86)/IntelSWTools/compilers_and_libraries_2018.x.xxx/<target_os
  2. 默认的Intel IPP密码库主文件目录<ipp cryptography directory>为<install_dir>/ippcp/.

添加环境变量

  1. 环境变量(执行如下文件)

    1. <install_dir>\ipp\bin\ippvars.bat
    2. <install_dir>\ippcp\bin\ippcpvars.bat
  2. 手动添加Path
    1. <install_dir>\redist\ ia32_win\ipp
    2. <install_dir>\redist\ intel64_win\ippcp

然后分别运行

  1. <install_dir>\ippcp\tools\ia32\perfsys\ps_ippcp.exe
  2. <install_dir>\ippcp\tools\intel64\perfsys\ps_ippcp.exe

检测这两个程序是否能正常运行;正常运行则设置正确。

2. Theory of Operation

默认的接口函数是一个分派接口而已,它会根据CPU型号去分配对于的真正实现的库。根据CPU型号实现的库和函数会以该CPU标识为前缀。

比如ippsSHA256Update()是一般的接口,内含很多版本。在64-bit 应用的第二代Core处理器会调用e9_ippsSHA256Update(),在64-bit 应用的支持SSE4.2的处理器上会调用y8_ippsSHA256Update()。

表 CPU型号的前缀标识表

3. Linking Your Application

Intel IPP密码库支持四种链接方式:单线程静态库、单线程动态库、多线程静态库、多线程动态库。

  1. 单线程库已带,安装后路径为

<ipp cryptography directory>/lib/<arch>

  1. 多线程库需单独下载,安装后路径为

<ipp cryptography directory>/lib/<arch>/threaded

库名

单线程

多线程

静态库

ippcpmt.lib

ippcpmt.lib

动态库

ippcp.lib

ippcp.lib

4. Programming in the VS* IDE

1. VS IDE添加路径

最好把IPP的相关路径也添加进去,因为有很多需要IPP。

工具 → 选项 → 环境很解决方案 → VC目录,添加对应平台的include文件和lib文件。

  1. include

    1. <install_dir>\ipp\include
    2. <install_dir>\ippcp\include
  2. Lib
    1. <install_dir>\ipp\lib\<arch>_win,<arch> 为ia32或者intel64
    2. <install_dir>\ippcp\lib\<arch>_win,<arch> 为ia32或者intel64
  3. bin(是否需要添加,因为环境变量已经添加)
    1. <install_dir>\redist\<arch>_win\ipp,<arch> 为ia32或intel64
    2. <install_dir>\redist\<arch>_win\ippcp,<arch> 为ia32或intel64

2. 工程添加库

项目 → 属性 → 配置属性 → 链接器 → 输入 → 附加依赖性,添加需要的lib文件。例如动态链接需要ippcp.lib,静态链接需要ippcpmt.lib。

附录A Performance Test Tool

  1. <install_dir>\ippcp\tools\ia32\perfsys\ps_ippcp.exe
  2. <install_dir>\ippcp\tools\intel64\perfsys\ps_ippcp.exe

附录B Threading and OpenMP

如果应用层已经采用多线程来调用 IPP 密码库,则底层最好使用单线程密码库。否则,应用层和底层IPP密码库都使用多线程的话,会出现Nested parallelization,从而导致效率降低。

Part II. 开发参考手册

1. Overview

1.1 Function Context Structures

两种上下文:

  1. Spec为后缀,表示函数操作时不做更改
  2. State为后缀,表示函数操作时要做更改

2. Symmetric Cryptography

2.1加解密步骤

其中<Alg>指具体的密码算法,<Mode>指ECB、CBC、OFB、CFB、CTR模式。

执行步骤:

步骤1. 获取ctx大小:ipps<Alg>GetSize(int* pSize);其中<Alg>指具体的密码算法。

步骤2. 内存分配:pCtx = malloc(Size),分配Size字节内存给密码算法的pCtx;

步骤3. 初始化(密钥扩展):ipps<Alg>Init,需指定密钥。

步骤4. 加解密:调用ipps<Alg>Encrypt<Mode>或者ipps<Alg>Decrypt<Mode>,这里要设定IV,且IV在执行后会变化。

步骤5. 反初始化(数据清除):调用ipps<Alg>Init,但让key置为NULL。

步骤6. 内存释放:free(pCtx)。

注:

1. 还有个ipps<Alg>SetKey用于重新设定密钥,功能与ipps<Alg>Init类似;两者差异未知,猜测可能Init涉及一些别的特殊操作。

2.2 支持的密码算法和工作模式

表X 支持的密码算法和工作模式

模式算法

AES

TDES/DES

SM4

ARCFour

ECB

Y

Y

Y

RC4为流密码

CBC

Y

Y

Y

CFB

Y

Y

Y

OFB

Y

Y

Y

CTR

Y

Y

Y

CCM

Y

X

Y(2018版)

GCM

Y

X

X

XTS

Y

X

X

SIV

Y

X

X

补充说明

  1. TDES = DES加密(K1) → DES解密(K2) → DES加密(K1) 。
  2. ARCFour即RC4算法。
  3. CCM、GCM、SIV为认证加密模式;XTS为磁盘加密模式。

2.3 函数说明

2.3.1 获取上下文大小GetSize

IppStatus ippsAESGetSize(int* pSize);

IppStatus ippsDESGetSize(int* pSize);

IppStatus ippsSMS4GetSize(int* pSize);

IppStatus ippsARCFourGetSize(int* pSize);

参数说明

  1. pSize:OUT,CTX大小,单位字节。

2.3.2 初始化和反初始化Init

IppStatus ippsAESInit(const Ipp8u* pKey, int keylen, IppsAESSpec* pCtx, int ctxSize);

IppStatus ippsDESInit(const Ipp8u* pKey, IppsDESSpec* pCtx);

IppStatus ippsSMS4Init(const Ipp8u* pKey, int keyLen, IppsSMS4Spec* pCtx, int ctxSize);

IppStatus ippsARCFourInit(const Ipp8u* pKey, int keyLen, IppsARCFourState* pCtx);

参数说明

  1. pKey:IN,密钥。
  2. keyLen:IN,密钥字节长度。
  3. pCtx:OUT,密码算法上下文。
  4. ctxSize:IN,CTX大小,单位字节。

补充说明

  1. SM4的密钥长度必须是16。RC4密钥长度为1—256字节。
  2. 将pKey设置为NULL则执行反初始化。
  3. TDES需要对三个密钥各执行ippsDESInit以初始化三个IppsDESSpec*。

2.3.3 重置密钥SetKey

AESSM4有重置密钥函数

IppStatus ippsAESSetKey(const Ipp8u* pKey, int keylen, IppsAESSpec* pCtx);

IppStatus ippsSMS4SetKey(const Ipp8u* pKey, int keyLen, IppsSMS4Spec* pCtx);

参数说明

  1. pKey:IN,密钥。
  2. keyLen:IN,密钥字节长度。
  3. pCtx:OUT,密码算法上下文。

补充说明

  1. pCtx必须是已经Init了的才能调用此函数。

2.3.4 上下文导入导出Pack/Unpack

SM4无上下文导入导出。

IppStatus ippsAESPack (const IppsAESSpec* pCtx, Ipp8u* pBuffer, int bufSize);

IppStatus ippsAESUnpack (const Ipp8u* pBuffer, IppsAESSpec* pCtx, int ctxSize);

IppStatus ippsDESPack (const IppsDESSpec* pCtx, Ipp8u* pBuffer);

IppStatus ippsDESUnpack (const Ipp8u* pBuffer, IppsDESSpec* pCtx);

IppStatus ippsARCFourPack (const IppsARCFourState* pCtx, Ipp8u* pBuffer);

IppStatus ippsARCFourUnpack (const Ipp8u* pBuffer, IppsARCFourState* pCtx);

参数说明

A)导出/Pack

  1. pCtx:IN,上下文。
  2. pBuffer:OUT,导出缓冲区。
  3. bufSize:IN,有的函数无。

B)导入/Unpack

  1. pBuffer:IN,导入缓冲区。
  2. pCtx:OUT,上下文。
  3. ctxSize:IN,上下文。

备注:

  1. 无论缓冲区pBuffer字节大小还是上下文pCtx字节大小,都调用ipps***GetSize获得。
  2. SM4无上下文导入导出。
  3. AES有bufSize和ctxSize是因为AES的密钥有三种长度,使得其buf和ctx不定长。

2.3.5 AES加解密

IppStatus ippsAESEncryptECB(       const Ipp8u *pSrc, Ipp8u *pDst, int srclen, const IppsAESSpec* pCtx);

IppStatus ippsAESDecryptECB(        const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx);

IppStatus ippsAESEncryptCBC(       const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESDecryptCBC(       const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESEncryptCFB(        const Ipp8u* pSrc, Ipp8u* pDst, int srcLen, int cfbBlkSize, const IppsAESSpec* pCtx, const Ipp8u *pIV);

IppStatus ippsAESDecryptCFB( const Ipp8u* pSrc, Ipp8u* pDst, int srclen, int cfbBlkSize, const IppsAESSpec* pCtx, const Ipp8u*pIV);

IppStatus ippsAESEncryptOFB (      const Ipp8u* pSrc, Ipp8u* pDst, int srclen, int ofbBlkSize, const IppsAESSpec* pCtx, Ipp8u* pIV);

IppStatus ippsAESDecryptOFB (       const Ipp8u* pSrc, Ipp8u* pDst, int srclen, int ofbBlkSize, const IppsAESSpec* pCtx, Ipp8u* pIV);

IppStatus ippsAESEncryptCTR(       const Ipp8u* pSrc, Ipp8u* pDst, int srcLen,const IppsAESSpec* pCtx, Ipp8u* pCtrValue , int ctrNumBitSize);

IppStatus ippsAESDecryptCTR(       const Ipp8u* pSrc, Ipp8u* pDst, int srcLen,const IppsAESSpec* pCtx, Ipp8u* pCtrValue, int ctrNumBitSize);

以下是在2018版中发现的新增接口,CBC的CS模式,2017版无。

IppStatus ippsAESEncryptCBC_CS1 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESEncryptCBC_CS2 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESEncryptCBC_CS3 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESDecryptCBC_CS1 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESDecryptCBC_CS2 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

IppStatus ippsAESDecryptCBC_CS3 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsAESSpec* pCtx, const Ipp8u* pIV);

表X 参数列表

AES

pSrc

pDst

srcLen

pCtx

pIV

其它

ECB

Y

Y

Y

Y

CBC

Y

Y

Y

Y

Y

CBC_CS1

Y

Y

Y

Y

Y

CBC_CS2

Y

Y

Y

Y

Y

CBC_CS3

Y

Y

Y

Y

Y

CFB

Y

Y

Y

Y

Y

cfbBlkSize

OFB

Y

Y

Y

Y

Y

ofbBlkSize

CTR

Y

Y

Y

Y

pCtrValue

ctrNumBitSize

参数说明

  1. pSrc:IN,加密时为明文,解密时为密文。
  2. srclen:IN,Src的字节长度。
  3. pDst:OUT,加密时为密文,解密时为明文。长度等于srclen。
  4. pCtx:IO,密码算法上下文。
  5. pIV:IO,初始化向量,长度同分组大小,调用后会改变。ECB无。
  6. pCtrValue:IO,CTR的计数器,相当于其它模式的初始化向量。
  7. ctrNumBitSize:IN,计数器中有效的计数比特长度(从右端计)。
  8. cfbBlkSize/ ofbBlkSize:CFB/OFB每拍输出的密钥流字节数,小于分组大小。

备注1CBC_CS采用密文偷取技术,使得数据多次加密时使用不便。因此,建议这种模式下一次性输入完毕明文/密文。

备注2srcLen长度说明。

表X srcLen说明

AES

srcLen

ECB

16 | srcLen

CBC

16 | srcLen

CFB

cfbBlkSize | srcLen

OFB

ofbBlkSize | srcLen

CTR

任意长度。

但非最后一次调用时都要求16 | srcLen

CTRsrcLen长度的进一步说明

若srcLen不是16的整数倍,则生成的多余的密钥流会被丢弃。下次再送入数据时,会用新的CTR值加密作为密钥流。

例如,第1次送入33字节,第二次再送入31字节。第一次生成48字节密钥流,前33字节密钥流用于加密,后15字节密钥流丢弃;第二次重新产生32字节,前31字节密钥流用于加密,后1字节密钥流丢弃。这样一来,由于第一次加密时丢弃了15字节密钥流,就导致了其加密结果和我们期望的结果不一致。

2.3.6 AES其它模式

AES加密认证涉及CCM、GCM、SIV,详情参见官方文档。本文档略。

AES磁盘加密涉及XTS模式,详情参见官方文档。本文档略。

2.3.7 TDES加解密

IppStatus ippsTDESEncryptECB(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec * pCtx3, IppsCPPadding padding);

IppStatus ippsTDESDecryptECB(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec * pCtx3, IppsCPPadding padding);

IppStatus ippsTDESEncryptCBC(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec * pCtx3, const Ipp8u *pIV, IppsCPPadding padding);

IppStatus ippsTDESDecryptCBC(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec * pCtx3, const Ipp8u *pIV, IppsCPPadding padding);

IppStatus ippsTDESEncryptCFB(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, int cfbBlkSize, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec *pCtx3, const Ipp8u *pIV, IppsCPPadding padding);

IppStatus ippsTDESDecryptCFB(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, int cfbBlkSize, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec *pCtx3, const Ipp8u *pIV, IppsCPPadding padding);

IppStatus ippsTDESEncryptOFB (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, int ofbBlkSize, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec *pCtx3, Ipp8u* pIV);

IppStatus ippsTDESDecryptOFB (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, int ofbBlkSize, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec *pCtx3, Ipp8u* pIV);

IppStatus ippsTDESEncryptCTR(const Ipp8u *pSrc, Ipp8u *pDst, int srclen, const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec *pCtx3,Ipp8u *pCtrValue, int ctrNumBitSize);

IppStatus ippsTDESDecryptCTR(const Ipp8u *pSrc, Ipp8u *pDst, int srcLen,const IppsDESSpec *pCtx1, const IppsDESSpec *pCtx2, const IppsDESSpec *pCtx3, Ipp8u *pCtrValue, int ctrNumBitSize);

表X 参数列表

TDES

pSrc

pDst

srcLen

pCtx1-3

pIV

padding

其它

ECB

Y

Y

Y

Y

Y

CBC

Y

Y

Y

Y

Y

Y

CFB

Y

Y

Y

Y

Y

Y

cfbBlkSize

OFB

Y

Y

Y

Y

Y

ofbBlkSize

CTR

Y

Y

Y

Y

pCtrValue

ctrNumBitSize

参数说明

  1. pSrc:IN,加密时为明文,解密时为密文。
  2. srclen:IN,Src的字节长度。
  3. pDst:OUT,加密时为密文,解密时为明文。长度等于srclen。
  4. pCtx1,pCtx2,pCtx3:IO,密码算法上下文,三个密钥对应三个上下文。
  5. pIV:IO,初始化向量,长度同分组大小,调用后会改变。ECB无。
  6. padding:IN,目前好像只支持IppsPaddingNONE(不填充)。具体待查。
  7. pCtrValue:IO,CTR的计数器,相当于其它模式的初始化向量。
  8. ctrNumBitSize:IN,计数器中有效的计数比特长度(从右端计)。
  9. cfbBlkSize/ ofbBlkSize:CFB/OFB每拍输出的密钥流字节数,小于分组大小。

备注:

  1. padding:具体待查。

2.3.8 SM4加解密

IppStatus ippsSMS4EncryptECB(const Ipp8u *pSrc, Ipp8u *pDst, int len, const IppsSMS4Spec* pCtx);

IppStatus ippsSMS4DecryptECB(const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsSMS4Spec* pCtx);

IppStatus ippsSMS4EncryptCBC(const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsSMS4Spec* pCtx, const Ipp8u* pIV);

IppStatus ippsSMS4DecryptCBC(const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsSMS4Spec* pCtx, const Ipp8u* pIV);

IppStatus ippsSMS4EncryptCFB(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, const IppsSMS4Spec* pCtx, const Ipp8u *pIV);

IppStatus ippsSMS4DecryptCFB(const Ipp8u* pSrc, Ipp8u* pDst, int len, int cfbBlkSize, const IppsSMS4Spec* pCtx, const Ipp8u* pIV);

IppStatus ippsSMS4EncryptOFB (const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, const IppsSMS4Spec* pCtx, Ipp8u* pIV);

IppStatus ippsSMS4DecryptOFB (const Ipp8u* pSrc, Ipp8u* pDst, int len, int ofbBlkSize, const IppsSMS4Spec* pCtx, Ipp8u* pIV);

IppStatus ippsSMS4EncryptCTR(const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsSMS4Spec* pCtx, Ipp8u* pCtrValue , int ctrNumBitSize);

IppStatus ippsSMS4DecryptCTR(const Ipp8u* pSrc, Ipp8u* pDst, int len, const IppsSMS4Spec * pCtx, Ipp8u* pCtrValue, int ctrNumBitSize);

以下是在2018版中发现的新增接口,CBC的CS模式,2017版无。

IppStatus ipps SMS4EncryptCBC_CS1 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsSMS4Spec * pCtx, const Ipp8u* pIV);

IppStatus ipps SMS4EncryptCBC_CS2 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsSMS4Spec * pCtx, const Ipp8u* pIV);

IppStatus ipps SMS4EncryptCBC_CS3 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsSMS4Spec * pCtx, const Ipp8u* pIV);

IppStatus ipps SMS4DecryptCBC_CS1 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsSMS4Spec * pCtx, const Ipp8u* pIV);

IppStatus ipps SMS4DecryptCBC_CS2 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsSMS4Spec * pCtx, const Ipp8u* pIV);

IppStatus ipps SMS4DecryptCBC_CS3 (const Ipp8u* pSrc, Ipp8u* pDst, int srclen, const IppsSMS4Spec * pCtx, const Ipp8u* pIV);

表X 参数列表

SM4

pSrc

pDst

srcLen

pCtx

pIV

其它

ECB

Y

Y

Y

Y

CBC

Y

Y

Y

Y

Y

CBC-CS1

Y

Y

Y

Y

Y

CBC-CS2

Y

Y

Y

Y

Y

CBC-CS3

Y

Y

Y

Y

Y

CFB

Y

Y

Y

Y

Y

cfbBlkSize

OFB

Y

Y

Y

Y

Y

ofbBlkSize

CTR

Y

Y

Y

Y

pCtrValue

ctrNumBitSize

参数说明

  1. pSrc:IN,加密时为明文,解密时为密文。
  2. srclen:IN,Src的字节长度。
  3. pDst:OUT,加密时为密文,解密时为明文。长度等于srclen。
  4. pCtx:IO,密码算法上下文。
  5. pIV:IO,初始化向量,长度同分组大小,调用后会改变。ECB无。
  6. pCtrValue:IO,CTR的计数器,相当于其它模式的初始化向量。
  7. ctrNumBitSize:IN,计数器中有效的计数比特长度(从右端计)。
  8. cfbBlkSize/ ofbBlkSize:CFB/OFB每拍输出的密钥流字节数,小于分组大小。

备注1CBC_CS采用密文偷取技术,使得数据多次加密时使用不便。因此,建议这种模式下一次性输入完毕明文/密文。

备注2srcLen长度说明。

表X srcLen说明

AES

srcLen

ECB

16 | srcLen

CBC

16 | srcLen

CFB

cfbBlkSize | srcLen

OFB

ofbBlkSize | srcLen

CTR

任意长度。

但非最后一次调用时都要求16 | srcLen

CTRsrcLen长度的进一步说明

若srcLen不是16的整数倍,则生成的多余的密钥流会被丢弃。下次再送入数据时,会用新的CTR值加密作为密钥流。

例如,第1次送入33字节,第二次再送入31字节。第一次生成48字节密钥流,前33字节密钥流用于加密,后15字节密钥流丢弃;第二次重新产生32字节,前31字节密钥流用于加密,后1字节密钥流丢弃。这样一来,由于第一次加密时丢弃了15字节密钥流,就导致了其加密结果和我们期望的结果不一致。

2.3.8 SM4-CCM加解认证

在2018版中发现有SM4-CCM,但是SM4执行CCM的可能性较低,所以本部分略。

2.3.9 ARCFour加解密

ARCFour即RC4流密码。本部分略。

2.4 示例代码

2.4.1 AES示例代码

#include “ippcp.h”

// use of the CTR mode

int AES_sample(void)

{

// secret key

Ipp8u key[] = "\x00\x01\x02\x03\x04\x05\x06\x07"

"\x08\x09\x10\x11\x12\x13\x14\x15";

// define and setup AES cipher

int ctxSize;

ippsAESGetSize(&ctxSize);

IppsAESSpec* pAES = (IppsAESSpec*)( new Ipp8u [ctxSize] );

ippsAESInit(key, sizeof(key)-1, pAES, ctxSize);

// message to be encrypted

Ipp8u msg[] = "the quick brown fox jumps over the lazy dog";

// and initial counter

Ipp8u ctr0[] = "\xff\xee\xdd\xcc\xbb\xaa\x99\x88"

"\x77\x66\x55\x44\x33\x22\x11\x00";

// counter

Ipp8u ctr[16];

// init counter before encryption

memcpy(ctr, ctr0, sizeof(ctr));

// encrypted message

Ipp8u ctext[sizeof(msg)];

// encryption

ippsAESEncryptCTR(msg, ctext, sizeof(msg), pAES, ctr, 64);

// init counter before decryption

memcpy(ctr, ctr0, sizeof(ctr));

// decrypted message

Ipp8u rtext[sizeof(ctext)];

// decryption

ippsAESDecryptCTR(ctext, rtext, sizeof(ctext), pAES, ctr, 64);

// remove secret and release resource

ippsAESInit(0, sizeof(key)-1, pAES, ctxSize);

delete [] (Ipp8u*)pAES;

int error = memcmp(rtext, msg, sizeof(msg));

return 0==error;

}

2.4.2 TDES示例代码

// Use of the ECB mode

void TDES_sample(void){

// size of the TDES algorithm block is equal to 8

const int tdesBlkSize = 8;

// get size of the context needed for the encryption/decryption operation

int ctxSize;

ippsDESGetSize(&ctxSize);

// and allocate one

IppsDESSpec* pCtx1 = (IppsDESSpec*)( new Ipp8u [ctxSize] );

IppsDESSpec* pCtx2 = (IppsDESSpec*)( new Ipp8u [ctxSize] );

IppsDESSpec* pCtx3 = (IppsDESSpec*)( new Ipp8u [ctxSize] );

// define the key

Ipp8u key1[] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};

Ipp8u key2[] = {0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18};

Ipp8u key3[] = {0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28};

Ipp8u keyX[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

// and prepare the context for the TDES usage

ippsDESInit(key1, pCtx1);

ippsDESInit(key2, pCtx2);

ippsDESInit(key3, pCtx3);

// define the message to be encrypted

Ipp8u ptext[] = {"the quick brown fox jumps over the lazy dog"};

// allocate enough memory for the ciphertext

// note that

// the size of ciphertext is always a multiple of the cipher block size

Ipp8u ctext[(sizeof(ptext)+desBlkSize-1) &~(desBlkSize-1)];

// encrypt (ECB mode) ptext message

// pay attention to the 'length' parameter

// it defines the number of bytes to be encrypted

ippsTDESEncryptECB(ptext, ctext, sizeof(ctext), pCtx1, pCtx2, pCtx3, IppsCPPaddingNONE);

// allocate memory for the decrypted message

Ipp8u rtext[sizeof(ctext)];

// decrypt (ECB mode) ctext message

// pay attention to the 'length' parameter

// it defines the number of bytes to be decrypted

ippsTDESDecryptECB(ctext, rtext, sizeof(ctext), pCtx1, pCtx2, pCtx3, IppsCPPaddingNONE);

// remove actual secret from contexts

ippsDESInit(keyX, pCtx1);

ippsDESInit(keyX, pCtx2);

ippsDESInit(keyX, pCtx3);

// release resources

delete (Ipp8u*)pCtx1;

delete (Ipp8u*)pCtx2;

delete (Ipp8u*)pCtx3;

}

3. One-Way Hash

待更新。

4. Data Authentication

待更新。

5. Public Key Cryptography

待更新。

6. Finite Field Arithmetic

待更新。

附录A: Support Functions and Classes

略。

附录B: Removed Functions

略。

Part III. 实测效率

本章对Intel IPPCP 2018支持的分组密码算法AES、TDES、SM4和杂凑算法SHA1、SHA224、SHA256、SHA384、SHA512、SHA512-224、SHA512-256、SM3、MD5的效率进行测试。

SM2效率待后续更新。

1. 测试平台

表3.1 测试平台信息

测试平台1

CPU

Intel i7 4790@3.6GHz,支持AES NI指令

OS

Win7 SP1 64b

内存

8G

备注

测试机,安装Intel IPPCP 2018

测试平台2

CPU

Intel i3 4790@3.4GHz,不支持AES NI指令

OS

WinXP SP3 32b

内存

4G

备注

工作机,未安装IPPCP,利用复制的IPPCP静态库编译

测试平台3

CPU

Intel i5 6300U@2.4GHz,不支持AES NI指令

OS

Win7 SP1 64b

内存

8G

备注

笔记本,安装Intel IPPCP 2018

2. 测试方法

分组密码算法的测试:在两个平台下均测试分组密码算法的CBC加密的效率。因为测试ECB一次性送入大量数据(如1MB)做加密时的效率和反复送16字节的加密效率有天壤之别,怀疑内部用多线程并行的方式做了优化。

杂凑算法的测试:直接一次性送入大量数据,如1MB进行测试。

为了精确统计,时间采用RDTSC指令读取CPU的时钟周期。

3. 测试结果

表3.2 分组密码算法的密钥扩展性能

(单位cps = cycle/setup,数值越小表示密钥扩展速度越快)

密钥扩展性能

平台1的效率

平台2的效率

平台3的效率

AES

205.4

1178.3

724.4

SM4

752.9

4346.9

2511.5

TDES

5391.1

8091.8

4814.9

表3.3 分组密码算法的CBC加密性能

(单位mbps = 1000000bit/s,数值越大表示密钥扩展速度越快)

CBC加密性能

平台1的效率

平台2的效率

平台3的效率

AES

7110.9

1468.1

1287.5

SM4

508.0

98.9

119.3

TDES

201.9

171.8

156.7

表3.4 杂凑算法的性能

(单位mbps = 1000000bit/s,数值越大表示密钥扩展速度越快)

杂凑算法性能

平台1的效率

平台2的效率

平台3的效率

SHA1

5239.3

4141.9

3994.7

SHA224

2359.9

1949.6

1708.3

SHA256

2359.9

1945.6

1727.2

SHA384

2381.3

1896.8

1767.9

SHA512

2381.4

1898.6

1728.6

SHA512-224

2364.5

1853.8

1756.3

SHA512-256

2362.6

1852.883

1768.7

SM3

1687.2

1342.9

1240.9

md5

6043.4

4998.9

4221.9

平均

SHA224的本质是SHA256,所以二者速度一样。

SHA384的本质是SHA512,所以二者速度一样。

SHA512-224、SHA512-256的核心是SHA512,所以三者的速度一样。

表3.5 SM2算法的性能

(单位mbps = 次/秒,数值越大表示密钥扩展速度越快)

平台1的效率

平台2的效率

平台3的效率

我们的实现

SM2签名

3314.1

2681.1

2819.9

185.3

SM2验签

2701.8

2170.0

2311.6

149.1

注1:我们的实现是指我们标准C实现的SM2在平台2下测试的效率。

注2:Intel IPPCP无SM2加解密接口,只有签名验签接口。

4. 效率对比

效率和性能差异对比如下。

  1. 平台性能:平台1主频比平台2高5.9%。
  2. 分组算法效率:
    • AES有近5倍的差异,可能是AES-NI指令所致;
    • SM4有5倍的差异则很奇怪,暂时无法解释;
    • TDES的性能提升,与杂凑算法的性能提升接近。
  3. 杂凑算法效率:平台1比平台2提升20%—28%,平均为24.6%;平台2比平台3提升5%-15%,平均为9.4%。
  4. SM2效率:平台1比平台2提升24%左右;平台2比平台3反而降低6%左右。SM2比我们自己标准C实现的性能有了显著的提升。

5. 结论

从目前的分析的Intel IPP Cryptography效率测试结果看:

  1. SM4效率不如查大表效率高,在一些平台上的效率还不如查小表运算。
  2. SM3效率比目前的实现高17%。
  3. SM2效率待后续更新。
  4. AES在支持AES-NI的CPU上执行效率很高,但目前有使用AES-NI指令的开源代码,短小精炼。

国密算法在Intel IPP Cryptography上没有显著的综合性能提升,而且使用复杂,代码不开源,因此暂不推荐使用。

Intel IPP密码库 IPPCP 2018 开发笔记与总结(全)相关推荐

  1. Intel IPP密码库 IPPCP 2018——第二部分 对称密码算法开发说明与示例代码

    2. Symmetric Cryptography 2.1加解密步骤 其中<Alg>指具体的密码算法,<Mode>指ECB.CBC.OFB.CFB.CTR模式. 执行步骤: 步 ...

  2. 利用Intel IPP函数库实现信号频谱计算

    Intel IPP(Intel Integrated Performance Primitives)函数库是一套跨平台的软件函数库,它为用户提供了一套高效.实用的函数集,可用于实现通信.图像.语音等多 ...

  3. ESP8266开发笔记4-AT24C256读写全流程

    准备硬件 SCL,SDA默认引脚画反了,但是ESP8266的i2c引脚是可以任意的GPIO口. 这个是实物啦 代码 在SDK基础上照猫画虎- #include <stdio.h> #inc ...

  4. JNI开发笔记(七)--aar库的生成和调用

    aar库的生成和调用 引 前言 1. 新建一个空工程 2. 新建一个Module 3. 移植JNI工程到Module中 4. 生成aar库与so库 5. 在另一个工程中调用aar库 引 JNI开发笔记 ...

  5. JNI开发笔记(六)--一种更规范的so库生成方法

    一种更规范的JNI工程写法 引 前言 1. MainActivity中的两个重要的语句 2. 建立Util类来替代MainActivity 3. 在MainActivity中验证JNI工程并生成so库 ...

  6. JNI开发笔记(五)--JNI语法总结

    JNI语法总结 引 前言 1. 传参类型为变量/变量指针 1.1 变量 1.2 变量指针 2. 传参类型为数组指针 3. 传参类型为结构体指针 引 JNI开发笔记(一)–Android Studio安 ...

  7. Android开发笔记(序)写在前面的目录

    知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教训,与网友互相切磋,从而去芜存菁进一步提升自己的水平.因此博主就想,入门的东西咱就不写了,人不能老停留在入 ...

  8. Android开发笔记(序)

    本开发笔记,借鉴与其他开发者整理的文章范例与心得体会.在这里作为开发过程中的一个总结与笔记式记录. 如有侵犯作者权益,请及时联系告知删除.俗话说:集百家成一言,去粕成金. ************** ...

  9. Android开发笔记(序)写在前面的目录大全

    转自  湖前琴亭 的博客https://blog.csdn.net/aqi00/article/details/50012511 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面 ...

  10. Andriod开发之二十:Android开发笔记(序)写在前面的目录

    https://blog.csdn.net/aqi00/article/details/50038385 知识点分类 一方面写写自己走过的弯路掉进去的坑,避免以后再犯:另一方面希望通过分享自己的经验教 ...

最新文章

  1. pycaffe简明文档
  2. 数据结构--链表--判断一个字符串是否为回文串(单向链表,双向链表)
  3. 【DATAGUARD】物理dg在主库丢失归档文件的情况下的恢复(七)
  4. SharePoint快速调试技巧
  5. 软件测试面试题之自动化测试题大合集(下)
  6. 芯片工程师常用英文黑话
  7. 【数据挖掘算法】(一)MSET 算法
  8. 不小心删除的文件怎么找回,文件误删除恢复的方法
  9. 高质量前端:Code Review 很慢,你要忍一下。
  10. 正确地使用“respectively“
  11. javaScript 琐碎
  12. 点餐APP 冲刺二总结
  13. CSR867x — 如何修改BLE的蓝牙地址
  14. 和能力匹配的目标才是战略
  15. Typora页内跳转 ,亲测有效
  16. spring @Autowired用法
  17. 数字经济是什么?如何发展数字经济?
  18. uniapp-上传图片、上传视频
  19. 中国消费信贷行业市场供需与战略研究报告
  20. Python量化:计算KDJ指标

热门文章

  1. 生产环境和开发环境_生产环境 VS 开发环境,关于Kubernetes的四大认识误区
  2. ott盒子 MySQL_LAMP源码环境搭建与phpmyadmin的使用
  3. webpack在内存生成html,Vue学习之Webpack基本使用小结(十三)
  4. 陆振波的svm的matlab代码的解释,陆振波SVM的MATLAB代码解释
  5. php通过mysqldump数据库备份,mysql使用mysqldump进行数据库备份_MySQL
  6. 泰拉瑞亚服务器存档位置,泰拉瑞亚国服存档怎么恢复 国服存档位置
  7. java使用zxing_在Java中使用Zxing读取QRCode
  8. # 20175333曹雅坤 第八周课程学习总结
  9. bzoj3884: 上帝与集合的正确用法 扩展欧拉定理
  10. RTX——第13章 事件标志组